feat: 期货下单写入DB来源与开仓时间,CTP同步均价保证金现价
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+136
-54
@@ -39,6 +39,7 @@ from sl_tp_guard import (
|
|||||||
cancel_monitor_exit_orders,
|
cancel_monitor_exit_orders,
|
||||||
ensure_monitor_order_columns,
|
ensure_monitor_order_columns,
|
||||||
monitor_order_status,
|
monitor_order_status,
|
||||||
|
monitor_source_label,
|
||||||
place_monitor_exit_orders,
|
place_monitor_exit_orders,
|
||||||
reconcile_monitors_without_position,
|
reconcile_monitors_without_position,
|
||||||
start_sl_tp_guard_worker,
|
start_sl_tp_guard_worker,
|
||||||
@@ -188,8 +189,9 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
|
|||||||
continue
|
continue
|
||||||
existing = _find_active_monitor(conn, ths, direction)
|
existing = _find_active_monitor(conn, ths, direction)
|
||||||
if existing:
|
if existing:
|
||||||
_sync_monitor_lots_from_ctp(
|
_sync_monitor_from_ctp(
|
||||||
conn, int(existing["id"]), ths, direction, mode, ctp=p,
|
conn, int(existing["id"]), ths, direction, mode, ctp=p,
|
||||||
|
capital=_capital(conn),
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
sl, tp, trailing_be, initial_sl = _restore_sl_tp_from_closed(conn, ths, direction)
|
sl, tp, trailing_be, initial_sl = _restore_sl_tp_from_closed(conn, ths, direction)
|
||||||
@@ -409,6 +411,7 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
|
|||||||
tp,
|
tp,
|
||||||
trailing_be: int,
|
trailing_be: int,
|
||||||
ctp_open_time: Optional[str] = None,
|
ctp_open_time: Optional[str] = None,
|
||||||
|
open_time: Optional[str] = None,
|
||||||
monitor_type: str = "manual",
|
monitor_type: str = "manual",
|
||||||
) -> int:
|
) -> int:
|
||||||
ensure_monitor_order_columns(conn)
|
ensure_monitor_order_columns(conn)
|
||||||
@@ -428,13 +431,16 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
|
|||||||
initial_sl = sl_f
|
initial_sl = sl_f
|
||||||
if not trailing_be:
|
if not trailing_be:
|
||||||
trailing_be = int(existing.get("trailing_be") or 0)
|
trailing_be = int(existing.get("trailing_be") or 0)
|
||||||
open_time_val = existing.get("open_time") or now_s
|
open_time_val = (existing.get("open_time") or "").strip() or now_s
|
||||||
if ctp_open_time:
|
if open_time:
|
||||||
|
open_time_val = open_time
|
||||||
|
elif monitor_type == "ctp_sync" and ctp_open_time:
|
||||||
open_time_val = ctp_open_time
|
open_time_val = ctp_open_time
|
||||||
conn.execute(
|
conn.execute(
|
||||||
"""UPDATE trade_order_monitors SET
|
"""UPDATE trade_order_monitors SET
|
||||||
symbol=?, symbol_name=?, market_code=?, lots=?, entry_price=?,
|
symbol=?, symbol_name=?, market_code=?, lots=?, entry_price=?,
|
||||||
stop_loss=?, take_profit=?, initial_stop_loss=?, trailing_be=?, open_time=?
|
stop_loss=?, take_profit=?, initial_stop_loss=?, trailing_be=?, open_time=?,
|
||||||
|
monitor_type=?
|
||||||
WHERE id=?""",
|
WHERE id=?""",
|
||||||
(
|
(
|
||||||
sym,
|
sym,
|
||||||
@@ -447,11 +453,17 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
|
|||||||
initial_sl,
|
initial_sl,
|
||||||
trailing_be,
|
trailing_be,
|
||||||
open_time_val,
|
open_time_val,
|
||||||
|
monitor_type if monitor_type != "manual" else (existing.get("monitor_type") or "manual"),
|
||||||
mid,
|
mid,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
open_time_val = ctp_open_time or now_s
|
if open_time:
|
||||||
|
open_time_val = open_time
|
||||||
|
elif monitor_type == "ctp_sync" and ctp_open_time:
|
||||||
|
open_time_val = ctp_open_time
|
||||||
|
else:
|
||||||
|
open_time_val = now_s
|
||||||
conn.execute(
|
conn.execute(
|
||||||
"""INSERT INTO trade_order_monitors (
|
"""INSERT INTO trade_order_monitors (
|
||||||
symbol, symbol_name, market_code, direction, lots, entry_price,
|
symbol, symbol_name, market_code, direction, lots, entry_price,
|
||||||
@@ -477,10 +489,18 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
|
|||||||
_close_duplicate_monitors(conn, sym, direction, mid)
|
_close_duplicate_monitors(conn, sym, direction, mid)
|
||||||
return mid
|
return mid
|
||||||
|
|
||||||
def _sync_monitor_lots_from_ctp(
|
def _sync_monitor_from_ctp(
|
||||||
conn, mid: int, sym: str, direction: str, mode: str, *, ctp: Optional[dict] = None,
|
conn,
|
||||||
|
mid: int,
|
||||||
|
sym: str,
|
||||||
|
direction: str,
|
||||||
|
mode: str,
|
||||||
|
*,
|
||||||
|
ctp: Optional[dict] = None,
|
||||||
|
capital: float = 0.0,
|
||||||
) -> None:
|
) -> None:
|
||||||
positions = [ctp] if ctp else _ctp_positions(mode, refresh_if_empty=False, refresh_margin=False)
|
"""CTP 同步:均价、现价、保证金、仓位占比写入数据库;不覆盖期货下单的开仓时间。"""
|
||||||
|
positions = [ctp] if ctp else _ctp_positions(mode, refresh_if_empty=False, refresh_margin=True)
|
||||||
for p in positions:
|
for p in positions:
|
||||||
if not p or int(p.get("lots") or 0) <= 0:
|
if not p or int(p.get("lots") or 0) <= 0:
|
||||||
continue
|
continue
|
||||||
@@ -488,25 +508,55 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
|
|||||||
continue
|
continue
|
||||||
if not _match_ctp_symbol(p.get("symbol") or "", sym):
|
if not _match_ctp_symbol(p.get("symbol") or "", sym):
|
||||||
continue
|
continue
|
||||||
ctp_open = (p.get("open_time") or "").strip() or None
|
|
||||||
row = conn.execute(
|
row = conn.execute(
|
||||||
"SELECT open_time FROM trade_order_monitors WHERE id=?", (mid,),
|
"SELECT open_time, monitor_type FROM trade_order_monitors WHERE id=?", (mid,),
|
||||||
).fetchone()
|
).fetchone()
|
||||||
db_open = (row["open_time"] or "").strip() if row else ""
|
db_open = (row["open_time"] or "").strip() if row else ""
|
||||||
open_time_val = ctp_open or db_open
|
monitor_type = (row["monitor_type"] or "manual").strip().lower() if row else "manual"
|
||||||
|
ctp_open = (p.get("open_time") or "").strip() or None
|
||||||
|
open_time_val = db_open
|
||||||
|
if monitor_type == "ctp_sync" and ctp_open:
|
||||||
|
open_time_val = ctp_open
|
||||||
|
lots = int(p.get("lots") or 0)
|
||||||
|
entry = float(p.get("avg_price") or 0)
|
||||||
|
ctp_margin = float(p.get("margin") or 0)
|
||||||
|
float_pnl = p.get("pnl")
|
||||||
|
if float_pnl is not None:
|
||||||
|
float_pnl = round(float(float_pnl), 2)
|
||||||
|
mark = None
|
||||||
|
if ctp_status(mode).get("connected"):
|
||||||
|
mark = ctp_get_tick_price(mode, sym)
|
||||||
|
if mark is None or mark <= 0:
|
||||||
|
mark = entry if entry else None
|
||||||
|
margin = ctp_margin if ctp_margin > 0 else None
|
||||||
|
position_pct = None
|
||||||
|
if margin and capital > 0:
|
||||||
|
position_pct = round(float(margin) / float(capital) * 100, 2)
|
||||||
execute_retry(
|
execute_retry(
|
||||||
conn,
|
conn,
|
||||||
"""UPDATE trade_order_monitors SET lots=?, entry_price=?,
|
"""UPDATE trade_order_monitors SET lots=?, entry_price=?,
|
||||||
open_time=? WHERE id=?""",
|
open_time=?, margin=?, position_pct=?, mark_price=?, float_pnl=?
|
||||||
|
WHERE id=?""",
|
||||||
(
|
(
|
||||||
int(p.get("lots") or 0),
|
lots,
|
||||||
float(p.get("avg_price") or 0),
|
entry,
|
||||||
open_time_val,
|
open_time_val,
|
||||||
|
margin,
|
||||||
|
position_pct,
|
||||||
|
float(mark) if mark else None,
|
||||||
|
float_pnl,
|
||||||
mid,
|
mid,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def _sync_monitor_lots_from_ctp(
|
||||||
|
conn, mid: int, sym: str, direction: str, mode: str, *, ctp: Optional[dict] = None,
|
||||||
|
) -> None:
|
||||||
|
_sync_monitor_from_ctp(
|
||||||
|
conn, mid, sym, direction, mode, ctp=ctp, capital=_capital(conn),
|
||||||
|
)
|
||||||
|
|
||||||
def _compose_position_row(
|
def _compose_position_row(
|
||||||
conn,
|
conn,
|
||||||
*,
|
*,
|
||||||
@@ -519,44 +569,63 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
|
|||||||
) -> Optional[dict]:
|
) -> Optional[dict]:
|
||||||
if not mon and not ctp:
|
if not mon and not ctp:
|
||||||
return None
|
return None
|
||||||
if ctp:
|
|
||||||
sym = (ctp.get("symbol") or "").strip()
|
if mon:
|
||||||
direction = ctp.get("direction") or "long"
|
|
||||||
lots = int(ctp.get("lots") or 0)
|
|
||||||
if lots <= 0:
|
|
||||||
return None
|
|
||||||
entry = float(ctp.get("avg_price") or 0)
|
|
||||||
float_pnl = ctp.get("pnl")
|
|
||||||
if float_pnl is not None:
|
|
||||||
float_pnl = round(float(float_pnl), 2)
|
|
||||||
source_label = "CTP 柜台"
|
|
||||||
else:
|
|
||||||
sym = (mon.get("symbol") or "").strip()
|
sym = (mon.get("symbol") or "").strip()
|
||||||
direction = mon.get("direction") or "long"
|
direction = mon.get("direction") or "long"
|
||||||
lots = int(mon.get("lots") or 0)
|
lots = int(mon.get("lots") or 0)
|
||||||
if lots <= 0:
|
|
||||||
return None
|
|
||||||
entry = float(mon.get("entry_price") or 0)
|
entry = float(mon.get("entry_price") or 0)
|
||||||
float_pnl = None
|
source_label = monitor_source_label(mon.get("monitor_type"))
|
||||||
source_label = "本地监控"
|
open_time = (mon.get("open_time") or "").strip()
|
||||||
|
open_time_source = "order"
|
||||||
|
margin = mon.get("margin")
|
||||||
|
position_pct = mon.get("position_pct")
|
||||||
|
mark = mon.get("mark_price")
|
||||||
|
float_pnl = mon.get("float_pnl")
|
||||||
|
if float_pnl is not None:
|
||||||
|
float_pnl = round(float(float_pnl), 2)
|
||||||
|
else:
|
||||||
|
sym = (ctp.get("symbol") or "").strip()
|
||||||
|
direction = ctp.get("direction") or "long"
|
||||||
|
lots = int(ctp.get("lots") or 0)
|
||||||
|
entry = float(ctp.get("avg_price") or 0)
|
||||||
|
source_label = "CTP 柜台"
|
||||||
|
open_time = (ctp.get("open_time") or "").strip()
|
||||||
|
open_time_source = "ctp"
|
||||||
|
margin = None
|
||||||
|
position_pct = None
|
||||||
|
mark = None
|
||||||
|
float_pnl = ctp.get("pnl")
|
||||||
|
if float_pnl is not None:
|
||||||
|
float_pnl = round(float(float_pnl), 2)
|
||||||
|
|
||||||
|
if lots <= 0:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if ctp:
|
||||||
|
if ctp.get("pnl") is not None:
|
||||||
|
float_pnl = round(float(ctp["pnl"]), 2)
|
||||||
|
if not mon:
|
||||||
|
ctp_lots = int(ctp.get("lots") or 0)
|
||||||
|
if ctp_lots > 0:
|
||||||
|
lots = ctp_lots
|
||||||
|
if float(ctp.get("avg_price") or 0) > 0:
|
||||||
|
entry = float(ctp.get("avg_price") or 0)
|
||||||
|
ctp_margin = float(ctp.get("margin") or 0)
|
||||||
|
if (margin is None or float(margin or 0) <= 0) and ctp_margin > 0:
|
||||||
|
margin = ctp_margin
|
||||||
|
|
||||||
codes = ths_to_codes(sym)
|
codes = ths_to_codes(sym)
|
||||||
tick = calc_order_tick_metrics(sym, lots, entry)
|
tick = calc_order_tick_metrics(sym, lots, entry)
|
||||||
sl = float(mon["stop_loss"]) if mon and mon.get("stop_loss") is not None else None
|
sl = float(mon["stop_loss"]) if mon and mon.get("stop_loss") is not None else None
|
||||||
tp = float(mon["take_profit"]) if mon and mon.get("take_profit") is not None else None
|
tp = float(mon["take_profit"]) if mon and mon.get("take_profit") is not None else None
|
||||||
ctp_open = (ctp.get("open_time") or "").strip() if ctp else ""
|
|
||||||
if ctp and ctp_open:
|
|
||||||
open_time = ctp_open
|
|
||||||
open_time_source = "ctp"
|
|
||||||
else:
|
|
||||||
open_time = ((mon.get("open_time") or "") if mon else "")
|
|
||||||
open_time_source = "local" if open_time else ""
|
|
||||||
holding = _holding_duration(open_time, now_iso) if open_time else ""
|
holding = _holding_duration(open_time, now_iso) if open_time else ""
|
||||||
|
|
||||||
mark = None
|
if (mark is None or float(mark or 0) <= 0) and not fast and ctp_status(mode).get("connected"):
|
||||||
if not fast and ctp_status(mode).get("connected"):
|
live_mark = ctp_get_tick_price(mode, sym)
|
||||||
mark = ctp_get_tick_price(mode, sym)
|
if live_mark and live_mark > 0:
|
||||||
if not fast and (mark is None or mark <= 0) and codes:
|
mark = live_mark
|
||||||
|
if (mark is None or float(mark or 0) <= 0) and not fast and codes:
|
||||||
mark = fetch_price(
|
mark = fetch_price(
|
||||||
sym,
|
sym,
|
||||||
codes.get("market_code", ""),
|
codes.get("market_code", ""),
|
||||||
@@ -581,15 +650,21 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
|
|||||||
direction, entry, sl if sl is not None else entry,
|
direction, entry, sl if sl is not None else entry,
|
||||||
tp if tp is not None else entry, lots, mark, capital, sym,
|
tp if tp is not None else entry, lots, mark, capital, sym,
|
||||||
)
|
)
|
||||||
ctp_margin = float(ctp.get("margin") or 0) if ctp else 0.0
|
if margin is None or float(margin or 0) <= 0:
|
||||||
est_margin = pos_metrics.get("margin")
|
ctp_margin = float(ctp.get("margin") or 0) if ctp else 0.0
|
||||||
margin = ctp_margin if ctp_margin > 0 else est_margin
|
est_margin = pos_metrics.get("margin")
|
||||||
margin_source = "ctp" if ctp_margin > 0 else "estimate"
|
margin = ctp_margin if ctp_margin > 0 else est_margin
|
||||||
position_pct = (
|
margin_source = "ctp" if ctp_margin > 0 else "estimate"
|
||||||
round(float(margin) / capital * 100, 2)
|
else:
|
||||||
if capital > 0 and margin
|
margin_source = "ctp"
|
||||||
else pos_metrics.get("position_pct")
|
if position_pct is None or float(position_pct or 0) <= 0:
|
||||||
)
|
position_pct = (
|
||||||
|
round(float(margin) / capital * 100, 2)
|
||||||
|
if capital > 0 and margin
|
||||||
|
else pos_metrics.get("position_pct")
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
position_pct = float(position_pct)
|
||||||
order_st = monitor_order_status(
|
order_st = monitor_order_status(
|
||||||
mon or {}, mode=mode, ths_code=sym, direction=direction,
|
mon or {}, mode=mode, ths_code=sym, direction=direction,
|
||||||
)
|
)
|
||||||
@@ -709,9 +784,10 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
|
|||||||
elif key in ctp_by_key:
|
elif key in ctp_by_key:
|
||||||
used_ctp_keys.add(key)
|
used_ctp_keys.add(key)
|
||||||
if ctp and mon and not fast:
|
if ctp and mon and not fast:
|
||||||
_sync_monitor_lots_from_ctp(
|
_sync_monitor_from_ctp(
|
||||||
conn, int(mon["id"]), mon.get("symbol") or "",
|
conn, int(mon["id"]), mon.get("symbol") or "",
|
||||||
mon.get("direction") or "long", mode, ctp=ctp,
|
mon.get("direction") or "long", mode, ctp=ctp,
|
||||||
|
capital=capital,
|
||||||
)
|
)
|
||||||
mon = _find_active_monitor(conn, mon.get("symbol") or "", mon.get("direction") or "long") or mon
|
mon = _find_active_monitor(conn, mon.get("symbol") or "", mon.get("direction") or "long") or mon
|
||||||
try:
|
try:
|
||||||
@@ -1408,9 +1484,11 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
|
|||||||
conn.close()
|
conn.close()
|
||||||
return jsonify({"ok": False, "error": "开启移动保本须填写止损价"}), 400
|
return jsonify({"ok": False, "error": "开启移动保本须填写止损价"}), 400
|
||||||
if offset.startswith("open"):
|
if offset.startswith("open"):
|
||||||
|
from zoneinfo import ZoneInfo
|
||||||
sl = d.get("stop_loss")
|
sl = d.get("stop_loss")
|
||||||
tp = d.get("take_profit")
|
tp = d.get("take_profit")
|
||||||
trailing_be = 1 if d.get("trailing_be") else 0
|
trailing_be = 1 if d.get("trailing_be") else 0
|
||||||
|
open_ts = datetime.now(ZoneInfo("Asia/Shanghai")).strftime("%Y-%m-%d %H:%M:%S")
|
||||||
mid = _upsert_open_monitor(
|
mid = _upsert_open_monitor(
|
||||||
conn,
|
conn,
|
||||||
sym=sym,
|
sym=sym,
|
||||||
@@ -1420,12 +1498,16 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se
|
|||||||
sl=sl,
|
sl=sl,
|
||||||
tp=tp,
|
tp=tp,
|
||||||
trailing_be=trailing_be,
|
trailing_be=trailing_be,
|
||||||
|
open_time=open_ts,
|
||||||
|
monitor_type="manual",
|
||||||
)
|
)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
_push_position_snapshot_async()
|
_push_position_snapshot_async(fast=True)
|
||||||
import time
|
import time
|
||||||
time.sleep(2.0)
|
time.sleep(1.5)
|
||||||
_sync_monitor_lots_from_ctp(conn, mid, sym, direction, mode)
|
_sync_monitor_from_ctp(
|
||||||
|
conn, mid, sym, direction, mode, capital=_capital(conn),
|
||||||
|
)
|
||||||
mon_row = conn.execute(
|
mon_row = conn.execute(
|
||||||
"SELECT * FROM trade_order_monitors WHERE id=?", (mid,),
|
"SELECT * FROM trade_order_monitors WHERE id=?", (mid,),
|
||||||
).fetchone()
|
).fetchone()
|
||||||
|
|||||||
+11
-4
@@ -41,6 +41,10 @@ MONITOR_ORDER_COLUMNS = (
|
|||||||
"ALTER TABLE trade_order_monitors ADD COLUMN trailing_be INTEGER DEFAULT 0",
|
"ALTER TABLE trade_order_monitors ADD COLUMN trailing_be INTEGER DEFAULT 0",
|
||||||
"ALTER TABLE trade_order_monitors ADD COLUMN initial_stop_loss REAL",
|
"ALTER TABLE trade_order_monitors ADD COLUMN initial_stop_loss REAL",
|
||||||
"ALTER TABLE trade_order_monitors ADD COLUMN trailing_r_locked INTEGER DEFAULT 0",
|
"ALTER TABLE trade_order_monitors ADD COLUMN trailing_r_locked INTEGER DEFAULT 0",
|
||||||
|
"ALTER TABLE trade_order_monitors ADD COLUMN margin REAL",
|
||||||
|
"ALTER TABLE trade_order_monitors ADD COLUMN position_pct REAL",
|
||||||
|
"ALTER TABLE trade_order_monitors ADD COLUMN mark_price REAL",
|
||||||
|
"ALTER TABLE trade_order_monitors ADD COLUMN float_pnl REAL",
|
||||||
)
|
)
|
||||||
|
|
||||||
TRADE_RESULTS = ("止损", "止盈", "移动止盈", "保本止盈", "手动平仓")
|
TRADE_RESULTS = ("止损", "止盈", "移动止盈", "保本止盈", "手动平仓")
|
||||||
@@ -146,13 +150,16 @@ def _release_close(monitor_id: int) -> None:
|
|||||||
_closing_monitors.discard(monitor_id)
|
_closing_monitors.discard(monitor_id)
|
||||||
|
|
||||||
|
|
||||||
def _monitor_type_label(raw: str) -> str:
|
def monitor_source_label(raw: str) -> str:
|
||||||
|
"""持仓展示用来源文案。"""
|
||||||
mapping = {
|
mapping = {
|
||||||
"manual": "期货下单",
|
"manual": "期货下单",
|
||||||
"trend": "趋势回调",
|
"trend": "趋势回调",
|
||||||
"roll": "顺势加仓",
|
"roll": "顺势加仓",
|
||||||
|
"ctp_sync": "CTP 柜台",
|
||||||
}
|
}
|
||||||
return mapping.get(raw or "", raw or "程序监控")
|
key = (raw or "manual").strip().lower()
|
||||||
|
return mapping.get(key, raw or "期货下单")
|
||||||
|
|
||||||
|
|
||||||
def _result_for_close(mon: dict, reason: str) -> str:
|
def _result_for_close(mon: dict, reason: str) -> str:
|
||||||
@@ -284,7 +291,7 @@ def _write_trade_log(
|
|||||||
open_time=(mon.get("open_time") or "").strip(),
|
open_time=(mon.get("open_time") or "").strip(),
|
||||||
symbol_name=mon.get("symbol_name") or sym,
|
symbol_name=mon.get("symbol_name") or sym,
|
||||||
market_code=mon.get("market_code") or "",
|
market_code=mon.get("market_code") or "",
|
||||||
monitor_type=_monitor_type_label(mon.get("monitor_type") or ""),
|
monitor_type=monitor_source_label(mon.get("monitor_type") or ""),
|
||||||
capital=capital,
|
capital=capital,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -324,7 +331,7 @@ def write_manual_close_trade_log(
|
|||||||
open_time=(mon.get("open_time") or open_time).strip(),
|
open_time=(mon.get("open_time") or open_time).strip(),
|
||||||
symbol_name=mon.get("symbol_name") or symbol_name,
|
symbol_name=mon.get("symbol_name") or symbol_name,
|
||||||
market_code=mon.get("market_code") or market_code,
|
market_code=mon.get("market_code") or market_code,
|
||||||
monitor_type=_monitor_type_label(mon.get("monitor_type") or ""),
|
monitor_type=monitor_source_label(mon.get("monitor_type") or ""),
|
||||||
capital=capital,
|
capital=capital,
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|||||||
+1
-1
@@ -693,7 +693,7 @@
|
|||||||
(row.sync_pending ? ' · <span class="text-muted">同步柜台中…</span>' : '');
|
(row.sync_pending ? ' · <span class="text-muted">同步柜台中…</span>' : '');
|
||||||
var feeLabel = row.fee_source === 'ctp' ? '手续费(柜台)' : '手续费';
|
var feeLabel = row.fee_source === 'ctp' ? '手续费(柜台)' : '手续费';
|
||||||
var marginLabel = row.margin_source === 'ctp' ? '占用保证金(柜台)' : '占用保证金';
|
var marginLabel = row.margin_source === 'ctp' ? '占用保证金(柜台)' : '占用保证金';
|
||||||
var openLabel = row.open_time_source === 'ctp' ? '开仓(柜台)' : '开仓';
|
var openLabel = '开仓';
|
||||||
return (
|
return (
|
||||||
'<div class="pos-card">' +
|
'<div class="pos-card">' +
|
||||||
'<div class="pos-card-head"><div><div class="title">' + row.symbol + ' <span class="badge dir">' + dirBadge + '</span></div>' +
|
'<div class="pos-card-head"><div><div class="title">' + row.symbol + ' <span class="badge dir">' + dirBadge + '</span></div>' +
|
||||||
|
|||||||
Reference in New Issue
Block a user