@@ -130,14 +130,14 @@
< div class = "stat-item" > < div class = "label" > 开单次数< / div > < div class = "value" > {{ s.opens_count }}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 平仓笔数< / div > < div class = "value" > {{ s.closed_count }}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 胜率< / div > < div class = "value" > {% if s.win_rate_pct is not none %}{{ s.win_rate_pct }}%{% else %}-{% endif %}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 净盈亏(U)< / div > < div class = "value" > {{ s.net_pnl_u }}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 亏损额合计(U)< / div > < div class = "value" > {{ s.loss_sum_u }}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 单笔最大亏损(U)< / div > < div class = "value" > {% if s.max_single_loss is not none %}{{ s.max_single_loss }}{% else %}-{% endif %}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 单笔最大盈利(U)< / div > < div class = "value" > {% if s.max_single_profit is not none %}{{ s.max_single_profit }}{% else %}-{% endif %}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 最大回撤(U)< / div > < div class = "value" > {{ s.max_drawdown_u }}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 净盈亏(U)< / div > < div class = "value" > {{ funds_fmt( s.net_pnl_u) }}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 亏损额合计(U)< / div > < div class = "value" > {{ funds_fmt( s.loss_sum_u) }}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 单笔最大亏损(U)< / div > < div class = "value" > {% if s.max_single_loss is not none %}{{ funds_fmt( s.max_single_loss) }}{% else %}-{% endif %}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 单笔最大盈利(U)< / div > < div class = "value" > {% if s.max_single_profit is not none %}{{ funds_fmt( s.max_single_profit) }}{% else %}-{% endif %}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 最大回撤(U)< / div > < div class = "value" > {{ funds_fmt( s.max_drawdown_u) }}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 当前连续亏损笔数< / div > < div class = "value" > {{ s.consecutive_losses }}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 最长连续亏损(交易日)< / div > < div class = "value" > {{ s.max_loss_streak_days }} 天< / div > < / div >
< div class = "stat-item" > < div class = "label" > 期内最大亏损日< / div > < div class = "value" > {% if s.worst_day %}{{ s.worst_day }}( {{ s.worst_day_pnl }}U) {% else %}-{% endif %}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 期内最大亏损日< / div > < div class = "value" > {% if s.worst_day %}{{ s.worst_day }}( {{ funds_fmt( s.worst_day_pnl) }}U) {% else %}-{% endif %}< / div > < / div >
< / div >
< / div >
{% endmacro %}
@@ -165,9 +165,9 @@
< div class = "stat-item" > < div class = "label" > 总交易< / div > < div class = "value" > {{ total }}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 错过次数< / div > < div class = "value" > {{ miss_count }}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 胜率< / div > < div class = "value" > {{ rate }}%< / div > < / div >
< div class = "stat-item" > < div class = "label" > 资金账户(USDT)< / div > < div class = "value" id = "total-capital" > {% if funding_usdt is not none %}{{ funding_usdt }}U{% else %}—{% endif %}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 资金账户(USDT)< / div > < div class = "value" id = "total-capital" > {% if funding_usdt is not none %}{{ funds_fmt( funding_usdt) }}U{% else %}—{% endif %}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 交易日< / div > < div class = "value" > {{ trading_day }}< / div > < / div >
< div class = "stat-item" > < div class = "label" > 当日资金(交易账户)< / div > < div class = "value" id = "current-capital" > {{ current_capital }}U< / div > < / div >
< div class = "stat-item" > < div class = "label" > 当日资金(交易账户)< / div > < div class = "value" id = "current-capital" > {{ funds_fmt( current_capital) }}U< / div > < / div >
< / div >
< div class = "rule-tip" > 实时价格更新时间:< span id = "price-last-updated" > --< / span > (北京时间 UTC+8) < / div >
@@ -300,14 +300,14 @@
< div class = "list-item" >
< div > < strong > {{ o.symbol }}< / strong > | < span class = "badge direction" > {{ '做多' if o.direction == 'long' else '做空' }}< / span > < / div >
< div >
风格:{{ o.trade_style or 'trend' }} | 风险:{{ o.risk_percent or '-' }}%≈{{ o.risk_amount or '-' }}U
| {% if o.breakeven_enabled %}移动保本:开 {{ o.breakeven_rr_trigger or '-' }}R→{{ o.breakeven_price or '-' }}{% else %}移动保本:关{% endif %}
风格:{{ o.trade_style or 'trend' }} | 风险:{{ o.risk_percent or '-' }}%≈{{ funds_fmt( o.risk_amount) if o.risk_amount is not none else '-' }}U
| {% if o.breakeven_enabled %}移动保本:开 {{ o.breakeven_rr_trigger or '-' }}R→{{ price_fmt(o.symbol, o.breakeven_price) }}{% else %}移动保本:关{% endif %}
< br >
成交:{{ o.trigger_price }} 止损:{{ o.stop_loss }} 止盈:{{ o.take_profit }}
成交:{{ price_fmt(o.symbol, o.trigger_price) }} 止损:{{ price_fmt(o.symbol, o.stop_loss) }} 止盈:{{ price_fmt(o.symbol, o.take_profit) }}
| 盈亏比:< span id = "order-rr-{{ o.id }}" > {% if o.rr_ratio is not none %}1:{{ '%.2f'|format(o.rr_ratio) }}{% else %}-{% endif %}< / span >
| 现价:< span id = "order-price-{{ o.id }}" > -< / span >
| 浮盈亏:< span id = "order-pnl-{{ o.id }}" > -< / span >
| 计划基数:{{ o.margin_capital }}U | 所保证金:< span id = "order-ex-margin-{{ o.id }}" > -< / span >
| 计划基数:{{ funds_fmt( o.margin_capital) if o.margin_capital is not none else '-' }}U | 所保证金:< span id = "order-ex-margin-{{ o.id }}" > -< / span >
| 杠杆:{{ o.leverage }}x | 仓位占比:{{ o.position_ratio }}%
< / div >
< a href = "/del_order/{{ o.id }}" class = "btn-del" onclick = "return confirm('删除会触发手动平仓,继续?')" > 平仓< / a >
@@ -335,18 +335,18 @@
< td > {{ r.symbol }}< / td >
< td > {{ r.monitor_type }}< / td >
< td > < span class = "badge {{ 'direction-long' if r.direction == 'long' else 'direction-short' }}" > {{ '做多' if r.direction == 'long' else '做空' }}< / span > < / td >
< td > {{ r.trigger_price }}< / td >
< td > {{ price_fmt(r.symbol, r.trigger_price) }}< / td >
{% set stop_show = r.effective_stop_loss or r.initial_stop_loss or r.stop_loss %}
{% set tp_show = r.effective_take_profit or r.take_profit %}
< td > {{ price_fmt(r.symbol, stop_show) }}< / td >
< td > {{ price_fmt(r.symbol, tp_show) }}< / td >
< td > {{ r.margin_capital or '- ' } }< / td >
< td > {% if r.margin_capital is not none and r.margin_capital != '' %}{{ funds_fmt(r.margin_capital) }}{% else %}-{% endif % }< / td >
< td > {{ r.leverage or '-' }}< / td >
< td > {{ r.effective_hold_minutes or 0 }}< / td >
< td > {{ (r.effective_opened_at or '-')[:16] }}< / td >
< td > {{ (r.effective_closed_at or r.created_at or '-')[:16] }}< / td >
{% set pnl_val = (r.effective_pnl_amount or 0)|float %}
< td > < span class = "{{ 'pnl-profit' if pnl_val > 0 else ('pnl-loss' if pnl_val < 0 else '') }}" > {{ r.effective_pnl_amount or 0 }}< / span > < / td >
< td > < span class = "{{ 'pnl-profit' if pnl_val > 0 else ('pnl-loss' if pnl_val < 0 else '') }}" > {{ funds_fmt( r.effective_pnl_amount or 0) }}< / span > < / td >
< td >
{% set effective_result = r.effective_result %}
{% if effective_result in ["止盈","保本止盈","移动止盈"] %}< span class = "badge profit" > {{ effective_result }}< / span >
@@ -1091,7 +1091,7 @@ setTimeout(() => {
let latestAvailableUsdt = null ;
const lastPriceMap = { } ;
function formatSigned ( v , digits = 4 ) {
function formatSigned ( v , digits = 2 ) {
if ( v === null || typeof v === "undefined" || Number . isNaN ( Number ( v ) ) ) return "-" ;
const n = Number ( v ) ;
const sign = n > 0 ? "+" : "" ;
@@ -1121,7 +1121,7 @@ function refreshPriceSnapshot(){
( data . key _prices || [ ] ) . forEach ( k => {
const pEl = document . getElementById ( ` key-price- ${ k . id } ` ) ;
if ( pEl ) {
pEl . innerText = Number ( k . price ) . toFixed ( 6 ) ;
pEl . innerText = k . price _display || ( Number . isFinite ( Number ( k . price ) ) ? Number ( k . price ) . toFixed ( 6 ) : "-" ) ;
paintPriceTrend ( pEl , ` k- ${ k . id } ` , Number ( k . price ) ) ;
}
const upEl = document . getElementById ( ` key-up-diff- ${ k . id } ` ) ;
@@ -1146,17 +1146,25 @@ function refreshPriceSnapshot(){
const pEl = document . getElementById ( ` order-price- ${ o . id } ` ) ;
if ( pEl ) {
const hasMark = ( ( ) => { const x = o . exchange _mark _price ; if ( x === null || x === undefined || x === "" ) return false ; const n = Number ( x ) ; return ! Number . isNaN ( n ) ; } ) ( ) ;
const px = hasMark ? Number ( o . exchange _mark _price ) : Number ( o . price ) ;
const decimals = hasMark ? 8 : 6 ;
pEl . innerText = px . toFixed ( decimals ) ;
paintPriceTrend ( pEl , ` o- ${ o . id } ` , px ) ;
let disp = "" ;
if ( hasMark && o . exchange _mark _price _display ) {
disp = o . exchange _mark _price _display ;
} else if ( o . price _display ) {
disp = o . price _display ;
} else {
const px = hasMark ? Number ( o . exchange _mark _price ) : Number ( o . price ) ;
disp = Number . isFinite ( px ) ? px . toFixed ( 6 ) : "-" ;
}
pEl . innerText = disp ;
const pxNum = hasMark ? Number ( o . exchange _mark _price ) : Number ( o . price ) ;
paintPriceTrend ( pEl , ` o- ${ o . id } ` , Number . isFinite ( pxNum ) ? pxNum : px ) ;
}
const exM = document . getElementById ( ` order-ex-margin- ${ o . id } ` ) ;
if ( exM ) {
const mv = o . exchange _initial _margin ;
const mn = ( mv === null || mv === undefined || mv === "" ) ? NaN : Number ( mv ) ;
if ( ! Number . isNaN ( mn ) ) {
exM . innerText = ` ${ mn . toFixed ( 4 ) } U ` ;
exM . innerText = ` ${ mn . toFixed ( 2 ) } U ` ;
} else {
const prc = ( typeof data . positions _raw _count === "number" ) ? data . positions _raw _count : null ;
exM . innerText = ( prc === 0 ) ? "无仓数据" : "-" ;
@@ -1164,7 +1172,7 @@ function refreshPriceSnapshot(){
}
const pnlEl = document . getElementById ( ` order-pnl- ${ o . id } ` ) ;
if ( pnlEl ) {
pnlEl . innerText = ` ${ formatSigned ( o . float _pnl , 4 ) } U ( ${ formatSigned ( o . float _pct , 2 ) } %) ` ;
pnlEl . innerText = ` ${ formatSigned ( o . float _pnl , 2 ) } U ( ${ formatSigned ( o . float _pct , 2 ) } %) ` ;
pnlEl . classList . remove ( "price-up" , "price-down" , "price-flat" ) ;
if ( Number ( o . float _pnl ) > 0 ) pnlEl . classList . add ( "price-up" ) ;
else if ( Number ( o . float _pnl ) < 0 ) pnlEl . classList . add ( "price-down" ) ;
@@ -1198,7 +1206,7 @@ function refreshOrderDefaults(){
const fullEl = document . getElementById ( "use-full-margin" ) ;
const marginEl = document . getElementById ( "order-margin" ) ;
if ( fullEl && marginEl && fullEl . checked ) {
const m = Math . max ( latestAvailableUsdt * { { full _margin _buffer _ratio } } , 0 ) . toFixed ( 4 ) ;
const m = Math . max ( latestAvailableUsdt * { { full _margin _buffer _ratio } } , 0 ) . toFixed ( 2 ) ;
marginEl . value = m ;
}
}
@@ -1209,18 +1217,18 @@ function refreshAccountSnapshot(){
fetch ( "/api/account_snapshot" ) . then ( r => r . json ( ) ) . then ( data => {
if ( typeof data . funding _usdt !== "undefined" ) {
const el = document . getElementById ( "total-capital" ) ;
if ( el ) el . innerText = ( data . funding _usdt === null || data . funding _usdt === undefined ) ? "—" : ` ${ data . funding _usdt } U ` ;
if ( el ) el . innerText = ( data . funding _usdt === null || data . funding _usdt === undefined ) ? "—" : ` ${ Number ( data . funding _usdt ) . toFixed ( 2 ) } U ` ;
}
if ( typeof data . current _capital !== "undefined" ) {
const el = document . getElementById ( "current-capital" ) ;
if ( el ) el . innerText = ` ${ data . current _capital } U ` ;
if ( el ) el . innerText = ` ${ Number ( data . current _capital ) . toFixed ( 2 ) } U ` ;
}
if ( typeof data . available _trading _usdt !== "undefined" && data . available _trading _usdt !== null ) {
latestAvailableUsdt = Number ( data . available _trading _usdt ) ;
}
const canTradeText = data . can _trade ? "可开仓" : "不可开仓(有持仓或未到北京时间 {{ reset_hour }}:00) " ;
const tip = document . getElementById ( "order-rule-tip" ) ;
const avail = ( latestAvailableUsdt !== null && ! Number . isNaN ( latestAvailableUsdt ) ) ? ` ;交易账户可用约 ${ latestAvailableUsdt } U ` : "" ;
const avail = ( latestAvailableUsdt !== null && ! Number . isNaN ( latestAvailableUsdt ) ) ? ` ;交易账户可用约 ${ latestAvailableUsdt . toFixed ( 2 ) } U ` : "" ;
if ( tip ) {
tip . innerText = ` 规则:单仓;BTC {{ btc_leverage }}x / 山寨 {{ alt_leverage }}x; ${ canTradeText } ${ avail } ` ;
}
@@ -1236,7 +1244,7 @@ if(fullMarginEl){
fullMarginEl . addEventListener ( "change" , function ( ) {
const marginEl = document . getElementById ( "order-margin" ) ;
if ( marginEl && this . checked && latestAvailableUsdt !== null && ! Number . isNaN ( latestAvailableUsdt ) ) {
marginEl . value = Math . max ( latestAvailableUsdt * { { full _margin _buffer _ratio } } , 0 ) . toFixed ( 4 ) ;
marginEl . value = Math . max ( latestAvailableUsdt * { { full _margin _buffer _ratio } } , 0 ) . toFixed ( 2 ) ;
}
} ) ;
}