From 0109b59f271c535d1c07ed76a31007cd7ce0e31e Mon Sep 17 00:00:00 2001 From: dekun Date: Sun, 28 Jun 2026 09:16:22 +0800 Subject: [PATCH] Use 100k equity for recommend list when CTP is offline. When SimNow or live CTP is disconnected, the tradable-products section shows four whitelisted symbols and calculates max lots from a fixed 100,000 capital instead of reference capital in settings. Co-authored-by: Cursor --- app.py | 4 ++-- docs/FEATURES.md | 2 +- docs/TRADING.md | 6 +++--- install_trading.py | 14 ++++++++++---- product_recommend.py | 5 ++++- templates/trade.html | 2 +- trading_context.py | 9 +++++++++ 7 files changed, 30 insertions(+), 12 deletions(-) diff --git a/app.py b/app.py index 022bb13..89d1beb 100644 --- a/app.py +++ b/app.py @@ -811,16 +811,16 @@ def api_symbols_recommended(): """品种下拉:仅展示当前资金下可开仓品种(与下方可开仓品种表一致)。""" from recommend_store import recommend_payload from trading_context import ( - get_account_capital, get_fixed_lots, get_max_margin_pct, + get_recommend_capital, get_sizing_mode, get_trading_mode, ) conn = get_db() try: - capital = get_account_capital(conn, get_setting) + capital = get_recommend_capital(conn, get_setting) payload = recommend_payload( conn, live_capital=capital, diff --git a/docs/FEATURES.md b/docs/FEATURES.md index c0f3395..ceb5fa5 100644 --- a/docs/FEATURES.md +++ b/docs/FEATURES.md @@ -61,7 +61,7 @@ ### 可开仓品种 - 按当前权益与保证金上限筛选可开品种,养成开仓纪律、限制仓位 -- **权益 ≤20 万** 或 **CTP 未连接** 时,仅展示并可交易:玉米、豆粕、甲醇、螺纹钢(SimNow/实盘一致) +- **权益 ≤20 万** 或 **CTP 未连接** 时,仅展示并可交易:玉米、豆粕、甲醇、螺纹钢(SimNow/实盘一致);未连接时最大手数按 **10 万权益** 估算 - **夜盘时段** 仅显示有夜盘品种,并标注「夜盘」 - **行业分类**、走势(多头/空头/震荡/转多/转空)、跳空、昨日成交量(手)、成交额 - 支持行业筛选与多字段排序 diff --git a/docs/TRADING.md b/docs/TRADING.md index e814496..4f59723 100644 --- a/docs/TRADING.md +++ b/docs/TRADING.md @@ -55,9 +55,9 @@ - 期货下单品种联想 / 下拉 - 开仓报单校验(含趋势策略首仓) -**SimNow 与实盘规则一致**:**CTP 未连接** 时,无论系统设置中的参考资金是否大于 20 万,均 **默认按 20 万以下四品种范围** 展示与校验;连接 CTP 后改用柜台权益判断是否启用上述白名单。 +**SimNow 与实盘规则一致**:**CTP 未连接** 时,可开仓表 **当前权益固定按 10 万** 估算最大手数,并 **仅展示四品种**(玉米、豆粕、甲醇、螺纹钢);与系统设置中的参考资金无关。连接 CTP 后改用柜台权益;若柜台权益 ≤20 万,同样仅上述四品种。 -页面会提示:「未连接 CTP,默认按 20 万以下账户:仅显示并可交易 玉米、豆粕、甲醇、螺纹钢」。 +页面会提示:「未连接 CTP,按 10 万权益估算最大手数,仅显示并可交易 …」。 ## 期货下单 · 止盈止损与移动保本 @@ -100,7 +100,7 @@ 系统设置中的「参考资金」在 **CTP 未连接** 时用于以损定仓估算;连接后自动改用柜台权益。 -可开仓品种与品种白名单:**未连接 CTP 时一律按 20 万以下四品种范围**(见上文);连接后若柜台权益 ≤20 万,同样仅上述四品种。 +可开仓品种与品种白名单:**未连接 CTP 时** 可开仓表按 **10 万权益** 估算最大手数,且仅四品种;连接后若柜台权益 ≤20 万,同样仅上述四品种。 ## 首次使用 SimNow diff --git a/install_trading.py b/install_trading.py index d6cb5fa..a89ece1 100644 --- a/install_trading.py +++ b/install_trading.py @@ -92,6 +92,7 @@ from trading_context import ( get_max_margin_pct, get_pending_order_timeout_min, get_pending_order_timeout_sec, + get_recommend_capital, get_risk_percent, get_sizing_mode, get_trailing_be_tick_buffer, @@ -148,7 +149,7 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se schedule_recommend_refresh( db_path=DB_PATH, - get_capital_fn=_capital, + get_capital_fn=_recommend_capital, quote_fn=_main_quote, init_tables_fn=lambda c: init_strategy_tables(c), get_mode_fn=lambda: get_trading_mode(get_setting), @@ -161,13 +162,16 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se mode = get_trading_mode(get_setting) return recommend_payload( conn, - live_capital=_capital(conn), + live_capital=_recommend_capital(conn), max_margin_pct=get_max_margin_pct(get_setting), trading_mode=mode, sizing_mode=get_sizing_mode(get_setting), fixed_lots=get_fixed_lots(get_setting), ) + def _recommend_capital(conn) -> float: + return get_recommend_capital(conn, get_setting) + def _settings_dict() -> dict: return { "trading_mode": get_trading_mode(get_setting), @@ -1613,6 +1617,7 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se mode = get_trading_mode(get_setting) ctp_st = ctp_status(mode) capital = _capital(conn) + recommend_capital = _recommend_capital(conn) risk = get_risk_status(conn, active_count=_effective_active_position_count(conn, mode)) ctp_acc = _ctp_account(mode) if ctp_st.get("connected") else {} active_trend = conn.execute( @@ -1636,6 +1641,7 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se trading_mode=mode, trading_mode_label=trading_mode_label(get_setting), capital=capital, + recommend_capital=recommend_capital, risk_status=risk, ctp_status=ctp_st, ctp_account=ctp_acc, @@ -2459,7 +2465,7 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se conn = get_db() try: init_strategy_tables(conn) - capital = _capital(conn) + capital = _recommend_capital(conn) mode = get_trading_mode(get_setting) rows = refresh_recommend_cache( conn, capital, _main_quote, trading_mode=mode, @@ -2815,7 +2821,7 @@ def install_trading(app, *, login_required, require_nav, get_db, get_setting, se start_recommend_worker( db_path=DB_PATH, - get_capital_fn=_capital, + get_capital_fn=_recommend_capital, quote_fn=_main_quote, init_tables_fn=_init_tables, get_mode_fn=lambda: get_trading_mode(get_setting), diff --git a/product_recommend.py b/product_recommend.py index 91122e9..d57a5d5 100644 --- a/product_recommend.py +++ b/product_recommend.py @@ -20,6 +20,8 @@ logger = logging.getLogger(__name__) # 权益不超过该值时,仅允许下列品种(可开仓列表、品种下拉、开仓报单) SMALL_ACCOUNT_CAPITAL_MAX = 200_000.0 +# 未连接 CTP 时,可开仓品种表按该权益估算最大手数(与参考资金设置无关) +DISCONNECTED_RECOMMEND_CAPITAL = 100_000.0 SMALL_ACCOUNT_PRODUCT_THS = frozenset({"c", "m", "MA", "rb"}) SMALL_ACCOUNT_SCOPE_LABEL = "玉米、豆粕、甲醇、螺纹钢" @@ -27,8 +29,9 @@ SMALL_ACCOUNT_SCOPE_LABEL = "玉米、豆粕、甲醇、螺纹钢" def small_account_scope_hint(*, ctp_connected: bool = True) -> str: wan = int(SMALL_ACCOUNT_CAPITAL_MAX // 10_000) if not ctp_connected: + rec_wan = int(DISCONNECTED_RECOMMEND_CAPITAL // 10_000) return ( - f"未连接 CTP,默认按 {wan} 万以下账户:" + f"未连接 CTP,按 {rec_wan} 万权益估算最大手数," f"仅显示并可交易 {SMALL_ACCOUNT_SCOPE_LABEL}" ) return f"权益 {wan} 万以下仅显示并可交易:{SMALL_ACCOUNT_SCOPE_LABEL}" diff --git a/templates/trade.html b/templates/trade.html index d77a116..a547999 100644 --- a/templates/trade.html +++ b/templates/trade.html @@ -132,7 +132,7 @@

可开仓品种

-

最大手数 = floor(权益 × 保证金上限 {{ max_margin_pct }}% ÷ 1手保证金);当前权益 {{ '%.2f'|format(capital) }} 元。 +

最大手数 = floor(权益 × 保证金上限 {{ max_margin_pct }}% ÷ 1手保证金);当前权益 {{ '%.2f'|format(recommend_capital) }} 元。 {% if sizing_mode == 'fixed' %}仅显示最大手数 ≥ {{ fixed_lots }} 手的品种。{% endif %} {% if small_account_scope %}{{ small_account_scope_hint }}。{% endif %} {% if night_session %}当前为夜盘时段,品种下拉与下表仅显示有夜盘品种;带「夜盘」标记。{% elif not small_account_scope %}有夜盘交易的品种带「夜盘」标记。{% endif %} diff --git a/trading_context.py b/trading_context.py index 7dd1e70..94f332d 100644 --- a/trading_context.py +++ b/trading_context.py @@ -91,6 +91,15 @@ def get_account_capital(conn, get_setting: Callable[[str, str], str]) -> float: return 0.0 +def get_recommend_capital(conn, get_setting: Callable[[str, str], str]) -> float: + """可开仓品种表用权益:已连接 CTP 用柜台权益,未连接固定 10 万。""" + from product_recommend import DISCONNECTED_RECOMMEND_CAPITAL + + if is_ctp_connected(get_setting): + return get_account_capital(conn, get_setting) + return float(DISCONNECTED_RECOMMEND_CAPITAL) + + def is_ctp_connected(get_setting: Callable[[str, str], str]) -> bool: """当前交易模式(SimNow / 实盘)是否已连接 CTP。""" try: