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
8 changes: 4 additions & 4 deletions notifications/telegram.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,8 @@
"market_status_blend_gate_defensive": "🛡️ 降杠杆({asset})",
"signal_blend_gate_risk_on": "{trend_symbol} 站上 {window} 日门槛线,持有 SOXL {soxl_ratio} + SOXX {soxx_ratio}",
"signal_blend_gate_defensive": "{trend_symbol} 跌破门槛线,防守持有 SOXX {soxx_ratio}",
"market_status_blend_gate_overlay_capped": "🧯 过热降档({asset})",
"signal_blend_gate_overlay_capped": "{trend_symbol} 仍在 {window} 日门槛线上方,但触发过热降档({reasons}),目标仓位 {allocation_text}",
"market_status_blend_gate_overlay_capped": "🧯 风控降档({asset})",
"signal_blend_gate_overlay_capped": "{trend_symbol} 仍在 {window} 日门槛线上方,但触发风控降档({reasons}),目标仓位 {allocation_text}",
"blend_gate_reason_rsi_cap": "RSI 超阈值",
"blend_gate_reason_bollinger_cap": "突破布林上轨",
"blend_gate_reason_volatility_delever": "{symbol} {window} 日年化波动率 {volatility} 高于 {threshold},SOXL 转向 {redirect_symbol}",
Expand Down Expand Up @@ -207,8 +207,8 @@
"market_status_blend_gate_defensive": "🛡️ DE-LEVER ({asset})",
"signal_blend_gate_risk_on": "{trend_symbol} above {window}d gated entry, hold SOXL {soxl_ratio} + SOXX {soxx_ratio}",
"signal_blend_gate_defensive": "{trend_symbol} below gated entry, hold defensive SOXX {soxx_ratio}",
"market_status_blend_gate_overlay_capped": "🧯 HEAT-CAP ({asset})",
"signal_blend_gate_overlay_capped": "{trend_symbol} stays above the {window}d gate, but overlay cap ({reasons}) cuts exposure to {allocation_text}",
"market_status_blend_gate_overlay_capped": "🧯 RISK-CAP ({asset})",
"signal_blend_gate_overlay_capped": "{trend_symbol} stays above the {window}d gate, but risk cap ({reasons}) cuts exposure to {allocation_text}",
"blend_gate_reason_rsi_cap": "RSI over threshold",
"blend_gate_reason_bollinger_cap": "price above upper band",
"blend_gate_reason_volatility_delever": "{symbol} {window}d annualized volatility {volatility} is above {threshold}; redirect SOXL to {redirect_symbol}",
Expand Down
4 changes: 2 additions & 2 deletions tests/test_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def test_build_translator_supports_chinese(self):
)
self.assertEqual(
translate("market_status_blend_gate_overlay_capped", asset="SOXX"),
"🧯 过热降档(SOXX)",
"🧯 风控降档(SOXX)",
)
self.assertEqual(
translate(
Expand All @@ -60,7 +60,7 @@ def test_build_translator_supports_chinese(self):
reasons="RSI 超阈值 + 突破布林上轨",
allocation_text="SOXX 15.0%",
),
"SOXX 仍在 140 日门槛线上方,但触发过热降档(RSI 超阈值 + 突破布林上轨),目标仓位 SOXX 15.0%",
"SOXX 仍在 140 日门槛线上方,但触发风控降档(RSI 超阈值 + 突破布林上轨),目标仓位 SOXX 15.0%",
)
self.assertEqual(
translate(
Expand Down
62 changes: 31 additions & 31 deletions tests/test_rebalance_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -1012,7 +1012,7 @@ def test_strategy_target_keeps_cash_when_only_risk_target_is_unbuyable(self):
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=1191.03,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="15.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
Expand Down Expand Up @@ -1051,7 +1051,7 @@ def test_small_account_cash_substitution_note_is_not_duplicated_after_sell_refre
current_min_trade=10.0,
trade_threshold_value=10.0,
investable_cash=1420.53,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="15.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
Expand All @@ -1071,7 +1071,7 @@ def test_small_account_cash_substitution_note_is_not_duplicated_after_sell_refre
current_min_trade=10.0,
trade_threshold_value=10.0,
investable_cash=1420.01,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="15.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
Expand Down Expand Up @@ -1141,11 +1141,11 @@ def test_strategy_target_buy_floors_to_cash_backed_whole_shares(self):
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=726.38,
market_status="🧯 过热降档(SOXX+SOXL)",
market_status="🧯 风控降档(SOXX+SOXL)",
deploy_ratio_text="65.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发过热降档,目标仓位 SOXL 65.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发风控降档,目标仓位 SOXL 65.0%",
available_cash=758.56,
total_strategy_equity=1072.67,
portfolio_rows=(("SOXL",),),
Expand All @@ -1172,11 +1172,11 @@ def test_limit_buy_floors_to_whole_shares(self):
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=726.38,
market_status="🧯 过热降档(SOXX+SOXL)",
market_status="🧯 风控降档(SOXX+SOXL)",
deploy_ratio_text="65.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发过热降档,目标仓位 SOXL 65.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发风控降档,目标仓位 SOXL 65.0%",
available_cash=758.56,
total_strategy_equity=1072.67,
portfolio_rows=(("SOXL",),),
Expand Down Expand Up @@ -1260,7 +1260,7 @@ def test_limit_sell_floors_to_whole_shares(self):
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=0.0,
market_status="🧯 过热降档(BOXX)",
market_status="🧯 风控降档(BOXX)",
deploy_ratio_text="0.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
Expand Down Expand Up @@ -1321,7 +1321,7 @@ def test_zero_target_sell_uses_sellable_quantity_not_price_derived_floor(self):
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=891.03,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="0.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
Expand Down Expand Up @@ -1510,11 +1510,11 @@ def test_cash_sweep_symbol_can_fund_buy_when_investable_cash_is_zero(self):
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=0.0,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="15.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发过热降档,目标仓位 SOXL 15.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发风控降档,目标仓位 SOXL 15.0%",
available_cash=0.0,
total_strategy_equity=1000.0,
portfolio_rows=(("SOXL", "SOXX"), ("BOXX",)),
Expand All @@ -1530,11 +1530,11 @@ def test_cash_sweep_symbol_can_fund_buy_when_investable_cash_is_zero(self):
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=1200.0,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="15.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发过热降档,目标仓位 SOXL 15.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发风控降档,目标仓位 SOXL 15.0%",
available_cash=500.0,
total_strategy_equity=1000.0,
portfolio_rows=(("SOXL", "SOXX"), ("BOXX",)),
Expand Down Expand Up @@ -1568,11 +1568,11 @@ def test_cash_sweep_symbol_can_fund_buy_when_investable_cash_is_positive_but_sho
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=200.0,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="15.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发过热降档,目标仓位 SOXL 15.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发风控降档,目标仓位 SOXL 15.0%",
available_cash=200.0,
total_strategy_equity=1000.0,
portfolio_rows=(("SOXL", "SOXX"), ("BOXX",)),
Expand All @@ -1588,11 +1588,11 @@ def test_cash_sweep_symbol_can_fund_buy_when_investable_cash_is_positive_but_sho
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=700.0,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="15.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发过热降档,目标仓位 SOXL 15.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发风控降档,目标仓位 SOXL 15.0%",
available_cash=700.0,
total_strategy_equity=1000.0,
portfolio_rows=(("SOXL", "SOXX"), ("BOXX",)),
Expand Down Expand Up @@ -1625,11 +1625,11 @@ def test_cash_sweep_symbol_does_not_sell_when_sweep_cannot_fund_one_share(self):
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=14.46,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="15.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发过热降档,目标仓位 SOXL 15.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发风控降档,目标仓位 SOXL 15.0%",
available_cash=14.46,
total_strategy_equity=1000.0,
portfolio_rows=(("SOXL", "SOXX"), ("BOXX",)),
Expand All @@ -1645,11 +1645,11 @@ def test_cash_sweep_symbol_does_not_sell_when_sweep_cannot_fund_one_share(self):
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=114.46,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="15.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发过热降档,目标仓位 SOXL 15.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发风控降档,目标仓位 SOXL 15.0%",
available_cash=114.46,
total_strategy_equity=1000.0,
portfolio_rows=(("SOXL", "SOXX"), ("BOXX",)),
Expand Down Expand Up @@ -1684,11 +1684,11 @@ def test_cash_sweep_symbol_sells_full_position_when_helper_cannot_fund_buy(self)
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=14.46,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="15.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发过热降档,目标仓位 SOXL 15.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发风控降档,目标仓位 SOXL 15.0%",
available_cash=14.46,
total_strategy_equity=1000.0,
portfolio_rows=(("SOXL", "SOXX"), ("BOXX",)),
Expand All @@ -1704,11 +1704,11 @@ def test_cash_sweep_symbol_sells_full_position_when_helper_cannot_fund_buy(self)
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=175.46,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="15.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发过热降档,目标仓位 SOXL 15.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发风控降档,目标仓位 SOXL 15.0%",
available_cash=175.46,
total_strategy_equity=1000.0,
portfolio_rows=(("SOXL", "SOXX"), ("BOXX",)),
Expand Down Expand Up @@ -1744,11 +1744,11 @@ def test_dry_run_cash_sweep_can_simulate_buy_after_sell_settlement(self):
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=0.0,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="15.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发过热降档,目标仓位 SOXL 15.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发风控降档,目标仓位 SOXL 15.0%",
available_cash=0.0,
total_strategy_equity=1000.0,
portfolio_rows=(("SOXL", "SOXX"), ("BOXX",)),
Expand Down Expand Up @@ -1779,11 +1779,11 @@ def test_dry_run_cash_sweep_reports_note_when_estimator_is_zero(self):
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=0.0,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="15.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发过热降档,目标仓位 SOXL 15.0%",
signal_message="SOXX 仍在 140 日门槛线上方,但触发风控降档,目标仓位 SOXL 15.0%",
available_cash=0.0,
total_strategy_equity=1000.0,
portfolio_rows=(("SOXL", "SOXX"), ("BOXX",)),
Expand Down Expand Up @@ -1817,7 +1817,7 @@ def test_dry_run_rebuys_cash_sweep_symbol_with_remaining_investable_cash(self):
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=1200.0,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="0.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
Expand Down Expand Up @@ -1850,7 +1850,7 @@ def test_cash_sweep_rebuy_skips_when_broker_estimate_is_zero(self):
current_min_trade=100.0,
trade_threshold_value=100.0,
investable_cash=1200.0,
market_status="🧯 过热降档(SOXX)",
market_status="🧯 风控降档(SOXX)",
deploy_ratio_text="0.0%",
income_ratio_text="0.0%",
income_locked_ratio_text="0.0%",
Expand Down