Add key-level auto trade, AI analysis, and trading UX improvements.
Key monitors use 5m close triggers with WeChat alerts and box/convergence auto orders; add pending-order worker, structured WeChat notify, AI settings/messages, session clock, CTP margin sizing, and dual-layer position limits. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+16
-24
@@ -12,7 +12,7 @@ import math
|
||||
from datetime import datetime
|
||||
from typing import Callable, Optional
|
||||
|
||||
from contract_specs import get_contract_spec
|
||||
from contract_specs import get_contract_spec, margin_one_lot
|
||||
from fee_specs import ensure_fee_rates_schema
|
||||
from product_recommend import (
|
||||
_attach_turnover,
|
||||
@@ -128,16 +128,7 @@ def enrich_recommend_rows(
|
||||
cap = float(capital or 0)
|
||||
pct = max(1.0, min(100.0, float(max_margin_pct or 30.0)))
|
||||
budget = cap * pct / 100.0 if cap > 0 else 0.0
|
||||
ctp_connected = False
|
||||
ctp_lookup_spec = None
|
||||
ctp_estimate_margin_one_lot_fn = None
|
||||
try:
|
||||
from vnpy_bridge import ctp_estimate_margin_one_lot, ctp_lookup_contract_spec, ctp_status
|
||||
ctp_connected = bool(ctp_status(trading_mode).get("connected"))
|
||||
ctp_lookup_spec = ctp_lookup_contract_spec
|
||||
ctp_estimate_margin_one_lot_fn = ctp_estimate_margin_one_lot
|
||||
except Exception:
|
||||
pass
|
||||
ctp_connected = _ctp_connected_for_mode(trading_mode)
|
||||
enriched: list[dict] = []
|
||||
for raw in rows:
|
||||
row = dict(raw)
|
||||
@@ -150,26 +141,27 @@ def enrich_recommend_rows(
|
||||
row["mult"] = spec["mult"]
|
||||
if row.get("tick_size") in (None, ""):
|
||||
row["tick_size"] = float(spec.get("tick_size") or 1.0)
|
||||
if ctp_connected and main_code and ctp_lookup_spec:
|
||||
ctp_spec = ctp_lookup_spec(trading_mode, main_code)
|
||||
if ctp_spec:
|
||||
if ctp_spec.get("mult"):
|
||||
row["mult"] = ctp_spec["mult"]
|
||||
if ctp_spec.get("tick_size"):
|
||||
row["tick_size"] = ctp_spec["tick_size"]
|
||||
row["spec_source"] = "ctp"
|
||||
margin_one = 0.0
|
||||
try:
|
||||
margin_one = float(row.get("margin_one_lot") or 0)
|
||||
except (TypeError, ValueError):
|
||||
margin_one = 0.0
|
||||
price = float(row.get("price") or 0)
|
||||
if ctp_connected and main_code and price > 0 and ctp_estimate_margin_one_lot_fn:
|
||||
ctp_margin = ctp_estimate_margin_one_lot_fn(trading_mode, main_code, price)
|
||||
if ctp_margin and ctp_margin > 0:
|
||||
margin_one = ctp_margin
|
||||
row["margin_one_lot"] = ctp_margin
|
||||
code_for_margin = main_code or spec_code
|
||||
if price > 0 and code_for_margin:
|
||||
margin_one, margin_source, spec_used = margin_one_lot(
|
||||
code_for_margin,
|
||||
price,
|
||||
trading_mode=trading_mode if ctp_connected else None,
|
||||
)
|
||||
if spec_used.get("mult"):
|
||||
row["mult"] = spec_used["mult"]
|
||||
if spec_used.get("tick_size"):
|
||||
row["tick_size"] = spec_used["tick_size"]
|
||||
row["margin_one_lot"] = margin_one
|
||||
if margin_source == "ctp":
|
||||
row["margin_source"] = "ctp"
|
||||
row["spec_source"] = "ctp"
|
||||
if margin_one > 0 and budget > 0:
|
||||
lots = int(math.floor(budget / margin_one))
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user