From 33e0bc3bb87ce4f42fe0610e2221b54fabe8de88 Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Wed, 3 Jun 2026 03:33:43 +0800 Subject: [PATCH 1/4] Enable HK low-vol dividend switch plan --- requirements.txt | 6 ++-- scripts/print_strategy_switch_env_plan.py | 14 +++++++-- tests/test_runtime_config_support.py | 38 +++++++++++++++++++++++ 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/requirements.txt b/requirements.txt index 3009974..32928a4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ flask gunicorn -quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@v0.7.35 -us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@v0.7.49 -hk-equity-strategies @ git+https://github.com/QuantStrategyLab/HkEquityStrategies.git@71141ce9e8a343cec8e2140994071eea66422bc6 +quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@v0.7.36 +us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@v0.7.50 +hk-equity-strategies @ git+https://github.com/QuantStrategyLab/HkEquityStrategies.git@1b7a357 pandas numpy requests diff --git a/scripts/print_strategy_switch_env_plan.py b/scripts/print_strategy_switch_env_plan.py index 1289e94..f0178d2 100644 --- a/scripts/print_strategy_switch_env_plan.py +++ b/scripts/print_strategy_switch_env_plan.py @@ -81,6 +81,12 @@ def _should_add_local_src(candidate: Path) -> bool: ] +def _feature_snapshot_filenames(profile: str, snapshot_contract_version: str | None) -> tuple[str, str]: + suffix = "factor_snapshot" if ".factor_snapshot." in str(snapshot_contract_version or "") else "feature_snapshot" + snapshot_filename = f"{profile}_{suffix}_latest.csv" + return snapshot_filename, f"{snapshot_filename}.manifest.json" + + def build_switch_plan( profile: str, *, @@ -223,10 +229,12 @@ def build_switch_plan( hints: dict[str, str] = {} if requires_feature_snapshot: - hints["feature_snapshot_filename"] = f"{definition.profile}_feature_snapshot_latest.csv" - hints["feature_snapshot_manifest_filename"] = ( - f"{definition.profile}_feature_snapshot_latest.csv.manifest.json" + snapshot_filename, manifest_filename = _feature_snapshot_filenames( + definition.profile, + runtime_requirements.get("snapshot_contract_version"), ) + hints["feature_snapshot_filename"] = snapshot_filename + hints["feature_snapshot_manifest_filename"] = manifest_filename if artifact_paths.bundled_config_path is not None: hints["bundled_strategy_config_path"] = str(artifact_paths.bundled_config_path) diff --git a/tests/test_runtime_config_support.py b/tests/test_runtime_config_support.py index 8bbdafe..6062afc 100644 --- a/tests/test_runtime_config_support.py +++ b/tests/test_runtime_config_support.py @@ -63,7 +63,9 @@ "soxl_soxx_trend_income", "tech_communication_pullback_enhancement", "tqqq_growth_income", + "hk_high_dividend_low_vol_trend", "hk_listed_global_etf_rotation", + "hk_low_vol_dividend_quality", } ) HK_DISABLED_PROFILES = frozenset( @@ -1058,6 +1060,42 @@ def test_print_strategy_switch_env_plan_for_mega_cap_top50_balanced_profile(): assert plan["hints"]["feature_snapshot_filename"] == "mega_cap_leader_rotation_top50_balanced_feature_snapshot_latest.csv" +def test_print_strategy_switch_env_plan_for_hk_low_vol_dividend_quality_profile(): + result = subprocess.run( + [ + sys.executable, + str(SWITCH_PLAN_SCRIPT_PATH), + "--profile", + "hk_low_vol_dividend_quality", + "--dry-run-only", + "--deployment-selector", + "hk-verify", + "--account-scope", + "HK", + "--service-name", + "interactive-brokers-hk-verify-service", + "--json", + ], + check=True, + capture_output=True, + text=True, + ) + + plan = json.loads(result.stdout) + assert plan["canonical_profile"] == "hk_low_vol_dividend_quality" + assert plan["enabled"] is True + assert plan["profile_group"] == "snapshot_backed" + assert plan["input_mode"] == "feature_snapshot" + assert plan["snapshot_contract_version"] == "hk_low_vol_dividend_quality.factor_snapshot.v1" + assert plan["set_env"]["IBKR_DRY_RUN_ONLY"] == "true" + assert plan["set_env"]["IBKR_FEATURE_SNAPSHOT_PATH"] == "" + assert plan["set_env"]["IBKR_FEATURE_SNAPSHOT_MANIFEST_PATH"] == "" + assert plan["hints"]["feature_snapshot_filename"] == "hk_low_vol_dividend_quality_factor_snapshot_latest.csv" + assert plan["hints"]["feature_snapshot_manifest_filename"] == ( + "hk_low_vol_dividend_quality_factor_snapshot_latest.csv.manifest.json" + ) + + @pytest.mark.parametrize("profile", sorted(HK_DISABLED_PROFILES)) def test_print_strategy_switch_env_plan_rejects_hk_disabled_profiles(profile): result = subprocess.run( From 3bbe93b1a0625370e239caa76a7438efa95aa881 Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Wed, 3 Jun 2026 03:44:59 +0800 Subject: [PATCH 2/4] Update HK strategy live-enable dependency --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 32928a4..7068ff9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ flask gunicorn quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@v0.7.36 us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@v0.7.50 -hk-equity-strategies @ git+https://github.com/QuantStrategyLab/HkEquityStrategies.git@1b7a357 +hk-equity-strategies @ git+https://github.com/QuantStrategyLab/HkEquityStrategies.git@623ca96 pandas numpy requests From 3afdbbf19450f1ae927b0c6091e9f879e38cb42d Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Wed, 3 Jun 2026 03:52:08 +0800 Subject: [PATCH 3/4] Add HK low-vol dividend notification names --- notifications/telegram.py | 4 ++++ tests/test_notifications.py | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/notifications/telegram.py b/notifications/telegram.py index a406f7e..707f4e4 100644 --- a/notifications/telegram.py +++ b/notifications/telegram.py @@ -140,6 +140,8 @@ "strategy_name_mega_cap_leader_rotation_top50_balanced": "Mega Cap Top50 平衡龙头轮动", "strategy_name_nasdaq_sp500_smart_dca": "纳斯达克 / 标普智能定投", "strategy_name_hk_listed_global_etf_rotation": "港股上市全球 ETF 轮动", + "strategy_name_hk_high_dividend_low_vol_trend": "港股高股息低波趋势", + "strategy_name_hk_low_vol_dividend_quality": "港股低波股息质量", "strategy_name_tqqq_growth_income": "TQQQ 增长收益", "strategy_name_soxl_soxx_trend_income": "SOXL/SOXX 半导体趋势收益", }, @@ -279,6 +281,8 @@ "strategy_name_mega_cap_leader_rotation_top50_balanced": "Mega Cap Leader Rotation Top50 Balanced", "strategy_name_nasdaq_sp500_smart_dca": "Nasdaq/S&P 500 Smart DCA", "strategy_name_hk_listed_global_etf_rotation": "HK-listed Global ETF Rotation", + "strategy_name_hk_high_dividend_low_vol_trend": "HK High Dividend Low-Volatility Trend", + "strategy_name_hk_low_vol_dividend_quality": "HK Low-Volatility Dividend Quality", "strategy_name_tqqq_growth_income": "TQQQ Growth Income", "strategy_name_soxl_soxx_trend_income": "SOXL/SOXX Semiconductor Trend Income", }, diff --git a/tests/test_notifications.py b/tests/test_notifications.py index b3f9992..bdbe712 100644 --- a/tests/test_notifications.py +++ b/tests/test_notifications.py @@ -86,6 +86,10 @@ def test_strategy_display_name_translates_new_live_profiles(): assert en_name("nasdaq_sp500_smart_dca") == "Nasdaq/S&P 500 Smart DCA" assert zh_name("hk_listed_global_etf_rotation") == "港股上市全球 ETF 轮动" assert en_name("hk_listed_global_etf_rotation") == "HK-listed Global ETF Rotation" + assert zh_name("hk_high_dividend_low_vol_trend") == "港股高股息低波趋势" + assert en_name("hk_high_dividend_low_vol_trend") == "HK High Dividend Low-Volatility Trend" + assert zh_name("hk_low_vol_dividend_quality") == "港股低波股息质量" + assert en_name("hk_low_vol_dividend_quality") == "HK Low-Volatility Dividend Quality" def test_supported_strategy_profiles_have_translated_names(): From 8ad8ba6e274f9db99e24e08ad17781119feb0c14 Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Wed, 3 Jun 2026 03:59:44 +0800 Subject: [PATCH 4/4] Pin HK low-vol strategy release --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7068ff9..4793e51 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ flask gunicorn quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@v0.7.36 us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@v0.7.50 -hk-equity-strategies @ git+https://github.com/QuantStrategyLab/HkEquityStrategies.git@623ca96 +hk-equity-strategies @ git+https://github.com/QuantStrategyLab/HkEquityStrategies.git@hk-low-vol-dividend-quality-20260603 pandas numpy requests