Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
# Auto-updated by update-qpk-pin.yml on every push to QPK main.

quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@b0eacd2fe4884f7f2447b704a232e9a121f396c4
us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@c8df5f9659340965bd7f53998892ed1018ed4254
us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@c57fb20528d40f363ae149ae6e3f6b1a240ec237
hk-equity-strategies @ git+https://github.com/QuantStrategyLab/HkEquityStrategies.git@700c8b19c46336d3d8fcba687e58553afcf0235f
cn-equity-strategies @ git+https://github.com/QuantStrategyLab/CnEquityStrategies.git@e09fd557c2bd9ae5f4d44228915c4e52c4b0dd21
crypto-strategies @ git+https://github.com/QuantStrategyLab/CryptoStrategies.git@565be005e4186fd6d750884e7b0bc59f779f9549
13 changes: 9 additions & 4 deletions notifications/telegram.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ def format_small_account_whole_share_bootstrap_notes(
"account_overview_title": "📌 策略账户概览",
"equity": "净值",
"total_assets": "总资产(策略标的+现金)",
"total_assets_margin": "总资产(策略净值)",
"buying_power": "可用现金",
"buying_power_margin": "购买力",
"reserved_cash": "预留现金",
Expand Down Expand Up @@ -353,6 +354,7 @@ def format_small_account_whole_share_bootstrap_notes(
"account_overview_title": "📌 Strategy Account",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid labeling buying-power totals as net liquidation

When margin mode is enabled, FirstradeBrokerAdapters._resolve_total_equity returns buying_power + position_market_value before falling back to the broker's account total, and run_strategy_cycle passes managed symbols so that branch is used for strategy portfolios. For margin accounts where buying power includes loan capacity, the value rendered here is therefore not net liquidation, so the new label can make users read a levered purchasing-power figure as account equity. Please either feed an actual net-liquidation/account-value field into this label or keep the wording aligned with the underlying buying-power-plus-positions value.

Useful? React with 👍 / 👎.

"equity": "Equity",
"total_assets": "Total assets",
"total_assets_margin": "Total assets (strategy net liquidation)",
"buying_power": "Available cash",
"buying_power_margin": "Buying power",
"reserved_cash": "Reserved cash",
Expand Down Expand Up @@ -724,11 +726,15 @@ def _is_dashboard_account_metric_line(line: str, *, translator: Callable[..., st
translator("investable_cash"),
translator("equity"),
"Total assets (strategy symbols + cash)",
"Total assets (strategy symbols + cash, ex-margin)",
"Total assets (strategy net liquidation)",
"Buying power",
"Reserved cash",
"Investable cash",
"Equity",
"总资产(策略标的+现金)",
"总资产(策略标的+现金,不含融资额度)",
"总资产(策略净值)",
"购买力",
"预留现金",
"可投资现金",
Expand All @@ -744,14 +750,15 @@ def _format_generated_dashboard_lines(
translator: Callable[..., str],
) -> list[str]:
lines = [translator("account_overview_title")]
cash_only_execution = bool(execution.get("cash_only_execution", portfolio.get("cash_only_execution", True)))
total_equity = _safe_float(portfolio.get("total_equity"))
if total_equity is not None:
lines.append(f" - {translator('total_assets')}: {_format_money(total_equity)}")
total_assets_label = "total_assets" if cash_only_execution else "total_assets_margin"
lines.append(f" - {translator(total_assets_label)}: {_format_money(total_equity)}")
buying_power = _safe_float(portfolio.get("liquid_cash"))
if buying_power is None:
buying_power = _safe_float(portfolio.get("buying_power"))
if buying_power is not None:
cash_only_execution = bool(execution.get("cash_only_execution", portfolio.get("cash_only_execution", True)))
buying_power_label = "buying_power" if cash_only_execution else "buying_power_margin"
lines.append(f" - {translator(buying_power_label)}: {_format_money(buying_power)}")
reserved_cash = _safe_float(execution.get("reserved_cash"))
Expand Down Expand Up @@ -1224,8 +1231,6 @@ def render_cycle_summary(result: Mapping[str, Any], *, lang: str = "en") -> str:
lines.append(SEPARATOR)
lines.extend(dashboard_lines)
lines.append(SEPARATOR)
lines.extend(_format_timing_lines(execution, translator=translator))
lines.extend(_format_signal_lines(execution, translator=translator))
lines.extend(target_diff_lines)
lines.extend(
str(line).strip()
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ pytest
pytz
requests
quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@b0eacd2fe4884f7f2447b704a232e9a121f396c4
us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@c8df5f9659340965bd7f53998892ed1018ed4254
us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@c57fb20528d40f363ae149ae6e3f6b1a240ec237
34 changes: 28 additions & 6 deletions tests/test_notifications_telegram.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def test_render_cycle_summary_dashboard_text_does_not_hide_account_overview():
assert "Total assets (strategy symbols + cash): $2,000.00" not in message
assert "Buying power: $100.00" not in message
assert "📌 Strategy portfolio" not in message
assert message.count("🎯 Signal:") == 1
assert "🎯 Signal:" not in message


def test_render_cycle_summary_includes_tqqq_volatility_delever_risk_control():
Expand Down Expand Up @@ -94,8 +94,30 @@ def test_render_cycle_summary_includes_tqqq_volatility_delever_risk_control():
lang="en",
)

assert (
"🛡️ Risk control: QQQ 5d annualized volatility 31.2% is above effective threshold 30.0% "
"(dynamic p90, 252d lookback, bounded 24.0%-36.0%, samples 252); TQQQ redirects to QQQM "
"(leveraged sleeve: TQQQ retained 0.0%, QQQM 100.0%)"
) in message
assert "🛡️ Risk control:" not in message


def test_render_cycle_summary_relabels_total_assets_when_margin_is_enabled():
message = render_cycle_summary(
{
"account": "****1234",
"strategy_profile": "tqqq_growth_income",
"dry_run_only": False,
"portfolio": {
"total_equity": 50000.0,
"liquid_cash": 75000.0,
"portfolio_rows": (("TQQQ",),),
"market_values": {"TQQQ": 8000.0},
"quantities": {"TQQQ": 10},
},
"allocation": {"targets": {"TQQQ": 8000.0}},
"execution": {"cash_only_execution": False},
"submitted_orders": [],
"skipped_orders": [],
},
lang="zh",
)

assert "总资产(策略净值): $50,000.00" in message
assert "购买力: $75,000.00" in message
assert "不含融资额度" not in message
15 changes: 7 additions & 8 deletions tests/test_rebalance_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -795,8 +795,8 @@ def test_render_cycle_summary_formats_skipped_orders_in_unified_chinese_template
assert "🔔 【调仓指令】" in message
assert "🆔 账户: ****1234" in message
assert "📌 策略账户概览" in message
assert "⏱ 执行时点: 2026-05-20 -> 2026-05-21 (次一交易日执行)" in message
assert "🎯 信号: 入场信号" in message
assert "⏱ 执行时点:" not in message
assert "🎯 信号:" not in message
assert "调仓变化: BOXX +7.89 USD, QQQ +44.39 USD, TQQQ +44.39 USD" in message
assert "🧾 执行明细" in message
assert "未下单: 原因=TQQQ,QQQ(整数股不足 1 股,无需下单), BOXX(低于调仓阈值)" in message
Expand Down Expand Up @@ -842,10 +842,9 @@ def test_render_cycle_summary_localizes_strategy_signal_codes():
lang="zh",
)

assert "📊 市场状态: 🚀 风险开启(SOXX+SOXL)" in message
assert "🎯 信号: SOXX 站上 140 日门槛线,持有 SOXL 70.0% + SOXX 20.0%" in message
assert " - 小账户提示:净值 $0 低于建议 $1,000;整数股和最小仓位限制可能导致实盘无法完全复现回测" in message
assert message.count("🎯 信号:") == 1
assert "📊 市场状态:" not in message
assert "🎯 信号:" not in message
assert "小账户提示" not in message
assert "signal_blend_gate_risk_on" not in message
assert "soxl_ratio" not in message
assert "small_account_warning_note" not in message
Expand Down Expand Up @@ -970,8 +969,8 @@ def test_render_cycle_summary_formats_skipped_orders_in_unified_english_template
assert "🔔 【Rebalance Instruction】" in message
assert "🆔 Account: ****1234" in message
assert "📌 Strategy Account" in message
assert "⏱ Timing: 2026-05-20 -> 2026-05-21 (next trading day)" in message
assert "🎯 Signal: Entry Signal" in message
assert "⏱ Timing:" not in message
assert "🎯 Signal:" not in message
assert "Target changes: BOXX +7.89 USD, QQQ +44.39 USD, TQQQ +44.39 USD" in message
assert "🧾 Execution details" in message
assert (
Expand Down
Loading