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:
+37
-3
@@ -11,7 +11,7 @@ import math
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
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 calc_fee_breakdown
|
||||
from recommend_trend import analyze_product_daily, sort_recommend_by_trend
|
||||
from symbols import PRODUCTS, product_category, product_has_night_session
|
||||
@@ -24,6 +24,22 @@ SMALL_ACCOUNT_CAPITAL_MAX = 200_000.0
|
||||
DISCONNECTED_RECOMMEND_CAPITAL = 100_000.0
|
||||
SMALL_ACCOUNT_PRODUCT_THS = frozenset({"c", "m", "MA", "rb"})
|
||||
SMALL_ACCOUNT_SCOPE_LABEL = "玉米、豆粕、甲醇、螺纹钢"
|
||||
SMALL_ACCOUNT_RECOMMENDED_OPEN_MARGIN_PCT = 30.0
|
||||
SMALL_ACCOUNT_RECOMMENDED_ROLL_MARGIN_PCT = 40.0
|
||||
|
||||
|
||||
def small_account_margin_recommendations() -> dict:
|
||||
"""20 万以下账户建议的保证金比例(供系统设置参考)。"""
|
||||
wan = int(SMALL_ACCOUNT_CAPITAL_MAX // 10_000)
|
||||
return {
|
||||
"open_margin_pct": SMALL_ACCOUNT_RECOMMENDED_OPEN_MARGIN_PCT,
|
||||
"roll_margin_pct": SMALL_ACCOUNT_RECOMMENDED_ROLL_MARGIN_PCT,
|
||||
"label": (
|
||||
f"权益 {wan} 万以下建议:开仓保证金上限 "
|
||||
f"{int(SMALL_ACCOUNT_RECOMMENDED_OPEN_MARGIN_PCT)}%,"
|
||||
f"滚仓总保证金不超过 {int(SMALL_ACCOUNT_RECOMMENDED_ROLL_MARGIN_PCT)}%"
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
def small_account_scope_hint(*, ctp_connected: bool = True) -> str:
|
||||
@@ -146,6 +162,7 @@ def assess_product_for_capital(
|
||||
reward_risk_ratio: float = 2.0,
|
||||
trading_mode: str = "simulation",
|
||||
ctp_connected: bool = True,
|
||||
main_code: str = "",
|
||||
) -> dict:
|
||||
"""评估单品种在当前资金下是否可交易。"""
|
||||
ths = product.get("ths") or ""
|
||||
@@ -194,7 +211,18 @@ def assess_product_for_capital(
|
||||
"has_night_session": product_has_night_session(product),
|
||||
}
|
||||
|
||||
margin_one = p * mult * margin_rate
|
||||
margin_source = None
|
||||
code_for_margin = (main_code or "").strip() or (ths + "8888")
|
||||
if p > 0 and ctp_connected:
|
||||
margin_one, margin_source, spec_used = margin_one_lot(
|
||||
code_for_margin, p, trading_mode=trading_mode,
|
||||
)
|
||||
if spec_used.get("mult"):
|
||||
mult = spec_used["mult"]
|
||||
if spec_used.get("tick_size"):
|
||||
tick = float(spec_used["tick_size"])
|
||||
else:
|
||||
margin_one = p * mult * margin_rate
|
||||
min_capital = margin_one / (margin_pct / 100.0) if margin_pct > 0 else margin_one
|
||||
margin_budget = cap * margin_pct / 100.0 if cap > 0 else 0.0
|
||||
max_lots = int(math.floor(margin_budget / margin_one)) if margin_one > 0 and margin_budget > 0 else 0
|
||||
@@ -221,8 +249,10 @@ def assess_product_for_capital(
|
||||
status, label = "margin_ok", f"最大 {max_lots} 手·止损偏宽"
|
||||
else:
|
||||
status, label = "blocked", "资金不足"
|
||||
if margin_source == "ctp" and can_margin:
|
||||
label += "(柜台保证金)"
|
||||
|
||||
return {
|
||||
row_out = {
|
||||
"ths": ths,
|
||||
"name": name,
|
||||
"exchange": exchange,
|
||||
@@ -245,6 +275,9 @@ def assess_product_for_capital(
|
||||
"status_label": label,
|
||||
"has_night_session": product_has_night_session(product),
|
||||
}
|
||||
if margin_source:
|
||||
row_out["margin_source"] = margin_source
|
||||
return row_out
|
||||
|
||||
|
||||
def list_product_recommendations(
|
||||
@@ -267,6 +300,7 @@ def list_product_recommendations(
|
||||
max_margin_pct=max_margin_pct,
|
||||
trading_mode=trading_mode,
|
||||
ctp_connected=ctp_connected,
|
||||
main_code=main_code,
|
||||
)
|
||||
main_code = (quote.get("ths_code") or "").strip()
|
||||
row["main_code"] = main_code
|
||||
|
||||
Reference in New Issue
Block a user