From 53f996ef489700f325a5b750355d644f4aed7270 Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Mon, 6 Apr 2026 07:11:13 +0800 Subject: [PATCH] rename tech pullback cash buffer profile --- README.md | 6 +-- ..._pullback_cash_buffer_feature_snapshot.py} | 10 ++--- src/us_equity_strategies/catalog.py | 18 ++++----- ...efault.py => tech_pullback_cash_buffer.py} | 2 +- ...efault.py => tech_pullback_cash_buffer.py} | 4 +- tests/test_catalog.py | 37 +++++++++++-------- tests/test_platform_registry_support.py | 14 +++---- ...t.py => test_tech_pullback_cash_buffer.py} | 12 +++--- ..._pullback_cash_buffer_feature_snapshot.py} | 8 ++-- 9 files changed, 57 insertions(+), 54 deletions(-) rename scripts/{generate_cash_buffer_branch_feature_snapshot.py => generate_tech_pullback_cash_buffer_feature_snapshot.py} (91%) rename src/us_equity_strategies/snapshots/{cash_buffer_branch_default.py => tech_pullback_cash_buffer.py} (99%) rename src/us_equity_strategies/strategies/{cash_buffer_branch_default.py => tech_pullback_cash_buffer.py} (99%) rename tests/{test_cash_buffer_branch_default.py => test_tech_pullback_cash_buffer.py} (92%) rename tests/{test_cash_buffer_branch_feature_snapshot.py => test_tech_pullback_cash_buffer_feature_snapshot.py} (91%) diff --git a/README.md b/README.md index 9dd068ad..4116783e 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,11 @@ This repository is the strategy layer: it owns pure signal, allocation, and targ | --- | --- | --- | --- | --- | --- | --- | --- | | `global_etf_rotation` | Global ETF Rotation Defense | `global_macro_etf_rotation` | `InteractiveBrokersPlatform` | `quarterly + daily canary` | `VOO` | `defensive_rotation` | `runtime_enabled` | | `russell_1000_multi_factor_defensive` | Russell 1000 Multi-Factor Defensive | `r1000_multifactor_defensive` | `InteractiveBrokersPlatform` | `monthly` | `SPY` | `defensive_stock_baseline` | `runtime_enabled` | -| `cash_buffer_branch_default` | Tech Pullback Cash Buffer | `tech_pullback_cash_buffer` | `InteractiveBrokersPlatform` | `monthly` | `QQQ` | `parallel_cash_buffer_branch` | `paper_dry_run` | +| `tech_pullback_cash_buffer` | Tech Pullback Cash Buffer | `—` | `InteractiveBrokersPlatform` | `monthly` | `QQQ` | `parallel_cash_buffer_branch` | `paper_dry_run` | | `hybrid_growth_income` | QQQ/TQQQ Growth Income | `qqq_tqqq_growth_income` | `CharlesSchwabPlatform` | `daily` | `QQQ` | `offensive_income` | `runtime_enabled` | | `semiconductor_rotation_income` | Semiconductor Trend Income | `semiconductor_trend_income` | `LongBridgePlatform` | `daily` | `SOXX` | `sector_offensive_income` | `runtime_enabled` | -These strategies are consumed by platform repositories through `QuantPlatformKit` strategy contracts and component loaders. Canonical profile keys stay stable for runtime compatibility; display names and aliases are the human-facing layer. Compatibility here means the strategy is structurally usable on that broker stack. Whether a profile is actually enabled, default, or rollback is now owned by each platform repository. +These strategies are consumed by platform repositories through `QuantPlatformKit` strategy contracts and component loaders. Canonical profile keys are the runtime-facing layer; display names are the human-facing layer. Compatibility here means the strategy is structurally usable on that broker stack. Whether a profile is actually enabled, default, or rollback is now owned by each platform repository. ### global_etf_rotation @@ -279,7 +279,7 @@ PYTHONPATH=src:. python3 scripts/backtest_russell_1000_multi_factor_defensive.py | --- | --- | --- | --- | --- | | `global_etf_rotation` | 全球 ETF 轮动防守 | `global_macro_etf_rotation` | `InteractiveBrokersPlatform` | 22 只全球 ETF 的季度 Top 2 轮动,带每日 canary 防守 | | `russell_1000_multi_factor_defensive` | Russell 1000 多因子防守 | `r1000_multifactor_defensive` | `InteractiveBrokersPlatform` | Russell 1000 个股月频 price-only 选股,带 SPY + breadth 防守和 BOXX 停泊 | -| `cash_buffer_branch_default` | 科技回调现金缓冲分支 | `tech_pullback_cash_buffer` | `InteractiveBrokersPlatform` | tech-heavy 月频个股选择,做受控回调,并显式保留 BOXX 缓冲 | +| `tech_pullback_cash_buffer` | 科技回调现金缓冲分支 | `—` | `InteractiveBrokersPlatform` | tech-heavy 月频个股选择,做受控回调,并显式保留 BOXX 缓冲 | | `hybrid_growth_income` | QQQ/TQQQ 增长收入混合 | `qqq_tqqq_growth_income` | `CharlesSchwabPlatform` | 由 QQQ 驱动的 TQQQ 攻击层,加上 SPYI / QQQI 收入层和 BOXX 防守层 | | `semiconductor_rotation_income` | 半导体趋势收入增强 | `semiconductor_trend_income` | `LongBridgePlatform` | SOXL / SOXX 趋势切换,剩余资金停在 BOXX,并叠加收入层 | diff --git a/scripts/generate_cash_buffer_branch_feature_snapshot.py b/scripts/generate_tech_pullback_cash_buffer_feature_snapshot.py similarity index 91% rename from scripts/generate_cash_buffer_branch_feature_snapshot.py rename to scripts/generate_tech_pullback_cash_buffer_feature_snapshot.py index b30258aa..505a3309 100644 --- a/scripts/generate_cash_buffer_branch_feature_snapshot.py +++ b/scripts/generate_tech_pullback_cash_buffer_feature_snapshot.py @@ -6,12 +6,12 @@ from datetime import datetime, timezone from pathlib import Path -from us_equity_strategies.snapshots.cash_buffer_branch_default import ( +from us_equity_strategies.snapshots.tech_pullback_cash_buffer import ( build_feature_snapshot, read_table, write_table, ) -from us_equity_strategies.strategies.cash_buffer_branch_default import ( +from us_equity_strategies.strategies.tech_pullback_cash_buffer import ( PROFILE_NAME, SNAPSHOT_CONTRACT_VERSION, ) @@ -34,7 +34,7 @@ def _default_config_path() -> Path | None: / "InteractiveBrokersPlatform" / "research" / "configs" - / "growth_pullback_cash_buffer_branch_default.json" + / "growth_pullback_tech_pullback_cash_buffer.json" ) return sibling if sibling.exists() else None @@ -49,7 +49,7 @@ def write_snapshot_manifest( resolved_manifest = manifest_path or Path(f"{snapshot_path}.manifest.json") if config_path is None or not config_path.exists(): raise FileNotFoundError( - f"cash_buffer_branch_default snapshot manifest requires a valid config_path, got: {config_path}" + f"tech_pullback_cash_buffer snapshot manifest requires a valid config_path, got: {config_path}" ) config_payload = json.loads(config_path.read_text(encoding="utf-8")) config_sha256 = _sha256_file(config_path) @@ -72,7 +72,7 @@ def write_snapshot_manifest( def build_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser( - description="Generate a cash_buffer_branch_default feature snapshot.", + description="Generate a tech_pullback_cash_buffer feature snapshot.", ) parser.add_argument("--prices", required=True, help="Input price history file (.csv/.json/.jsonl/.parquet)") parser.add_argument("--universe", required=True, help="Input universe file (.csv/.json/.jsonl/.parquet)") diff --git a/src/us_equity_strategies/catalog.py b/src/us_equity_strategies/catalog.py index c74af507..0d35c6cc 100644 --- a/src/us_equity_strategies/catalog.py +++ b/src/us_equity_strategies/catalog.py @@ -19,7 +19,7 @@ HYBRID_GROWTH_INCOME_PROFILE = "hybrid_growth_income" SEMICONDUCTOR_ROTATION_INCOME_PROFILE = "semiconductor_rotation_income" RUSSELL_1000_MULTI_FACTOR_DEFENSIVE_PROFILE = "russell_1000_multi_factor_defensive" -CASH_BUFFER_BRANCH_DEFAULT_PROFILE = "cash_buffer_branch_default" +TECH_PULLBACK_CASH_BUFFER_PROFILE = "tech_pullback_cash_buffer" STRATEGY_PLATFORM_COMPATIBILITY: dict[str, frozenset[str]] = { @@ -27,7 +27,7 @@ HYBRID_GROWTH_INCOME_PROFILE: frozenset({"schwab"}), SEMICONDUCTOR_ROTATION_INCOME_PROFILE: frozenset({"longbridge"}), RUSSELL_1000_MULTI_FACTOR_DEFENSIVE_PROFILE: frozenset({"ibkr"}), - CASH_BUFFER_BRANCH_DEFAULT_PROFILE: frozenset({"ibkr"}), + TECH_PULLBACK_CASH_BUFFER_PROFILE: frozenset({"ibkr"}), } # `supported_platforms` 仍保留为兼容镜像,避免一次性改动所有平台 runtime。 @@ -72,10 +72,10 @@ def _build_strategy_definition( component_name="signal_logic", module_path="us_equity_strategies.strategies.russell_1000_multi_factor_defensive", ), - CASH_BUFFER_BRANCH_DEFAULT_PROFILE: _build_strategy_definition( - CASH_BUFFER_BRANCH_DEFAULT_PROFILE, + TECH_PULLBACK_CASH_BUFFER_PROFILE: _build_strategy_definition( + TECH_PULLBACK_CASH_BUFFER_PROFILE, component_name="signal_logic", - module_path="us_equity_strategies.strategies.cash_buffer_branch_default", + module_path="us_equity_strategies.strategies.tech_pullback_cash_buffer", ), } @@ -125,11 +125,11 @@ def _build_strategy_definition( role="defensive_stock_baseline", status="runtime_enabled", ), - CASH_BUFFER_BRANCH_DEFAULT_PROFILE: StrategyMetadata( - canonical_profile=CASH_BUFFER_BRANCH_DEFAULT_PROFILE, + TECH_PULLBACK_CASH_BUFFER_PROFILE: StrategyMetadata( + canonical_profile=TECH_PULLBACK_CASH_BUFFER_PROFILE, display_name="Tech Pullback Cash Buffer", description="Tech-heavy monthly stock selection with controlled pullback entry and explicit BOXX cash buffer.", - aliases=("tech_pullback_cash_buffer",), + aliases=(), cadence="monthly", asset_scope="us_tech_communication_stocks", benchmark="QQQ", @@ -180,12 +180,10 @@ def get_strategy_definition(profile: str) -> StrategyDefinition: return get_catalog_strategy_definition(STRATEGY_CATALOG, profile) - def get_strategy_index_rows() -> list[dict[str, object]]: return build_strategy_index_rows(STRATEGY_CATALOG) - def get_strategy_metadata_map() -> dict[str, StrategyMetadata]: return dict(STRATEGY_METADATA) diff --git a/src/us_equity_strategies/snapshots/cash_buffer_branch_default.py b/src/us_equity_strategies/snapshots/tech_pullback_cash_buffer.py similarity index 99% rename from src/us_equity_strategies/snapshots/cash_buffer_branch_default.py rename to src/us_equity_strategies/snapshots/tech_pullback_cash_buffer.py index 58c1ea4b..56b0a6b1 100644 --- a/src/us_equity_strategies/snapshots/cash_buffer_branch_default.py +++ b/src/us_equity_strategies/snapshots/tech_pullback_cash_buffer.py @@ -7,7 +7,7 @@ import numpy as np import pandas as pd -from us_equity_strategies.strategies.cash_buffer_branch_default import ( +from us_equity_strategies.strategies.tech_pullback_cash_buffer import ( BENCHMARK_SYMBOL, DEFAULT_MIN_ADV20_USD, DEFAULT_SECTOR_WHITELIST, diff --git a/src/us_equity_strategies/strategies/cash_buffer_branch_default.py b/src/us_equity_strategies/strategies/tech_pullback_cash_buffer.py similarity index 99% rename from src/us_equity_strategies/strategies/cash_buffer_branch_default.py rename to src/us_equity_strategies/strategies/tech_pullback_cash_buffer.py index d0cb135f..7c66a036 100644 --- a/src/us_equity_strategies/strategies/cash_buffer_branch_default.py +++ b/src/us_equity_strategies/strategies/tech_pullback_cash_buffer.py @@ -11,7 +11,7 @@ SIGNAL_SOURCE = "feature_snapshot" STATUS_ICON = "🧲" -PROFILE_NAME = "cash_buffer_branch_default" +PROFILE_NAME = "tech_pullback_cash_buffer" BRANCH_ROLE = "cash-buffered parallel branch" BENCHMARK_SYMBOL = "QQQ" SAFE_HAVEN = "BOXX" @@ -33,7 +33,7 @@ SNAPSHOT_DATE_COLUMNS = ("as_of", "snapshot_date") MAX_SNAPSHOT_MONTH_LAG = 1 REQUIRE_SNAPSHOT_MANIFEST = True -SNAPSHOT_CONTRACT_VERSION = "cash_buffer_branch_default.feature_snapshot.v1" +SNAPSHOT_CONTRACT_VERSION = "tech_pullback_cash_buffer.feature_snapshot.v1" REQUIRED_FEATURE_COLUMNS = frozenset( { diff --git a/tests/test_catalog.py b/tests/test_catalog.py index 056f0d35..5eea1b88 100644 --- a/tests/test_catalog.py +++ b/tests/test_catalog.py @@ -3,7 +3,7 @@ from quant_platform_kit.common.strategies import get_strategy_component_map from us_equity_strategies import get_strategy_definitions from us_equity_strategies.catalog import ( - CASH_BUFFER_BRANCH_DEFAULT_PROFILE, + TECH_PULLBACK_CASH_BUFFER_PROFILE, GLOBAL_ETF_ROTATION_PROFILE, HYBRID_GROWTH_INCOME_PROFILE, RUSSELL_1000_MULTI_FACTOR_DEFENSIVE_PROFILE, @@ -38,9 +38,9 @@ def test_catalog_contains_supported_profiles(self): self.assertEqual(catalog[RUSSELL_1000_MULTI_FACTOR_DEFENSIVE_PROFILE].domain, "us_equity") self.assertEqual(get_compatible_platforms(RUSSELL_1000_MULTI_FACTOR_DEFENSIVE_PROFILE), frozenset({"ibkr"})) - self.assertIn(CASH_BUFFER_BRANCH_DEFAULT_PROFILE, catalog) - self.assertEqual(catalog[CASH_BUFFER_BRANCH_DEFAULT_PROFILE].domain, "us_equity") - self.assertEqual(get_compatible_platforms(CASH_BUFFER_BRANCH_DEFAULT_PROFILE), frozenset({"ibkr"})) + self.assertIn(TECH_PULLBACK_CASH_BUFFER_PROFILE, catalog) + self.assertEqual(catalog[TECH_PULLBACK_CASH_BUFFER_PROFILE].domain, "us_equity") + self.assertEqual(get_compatible_platforms(TECH_PULLBACK_CASH_BUFFER_PROFILE), frozenset({"ibkr"})) def test_supported_platforms_remains_only_a_compatibility_mirror(self): catalog = get_strategy_definitions() @@ -81,41 +81,46 @@ def test_known_profile_resolves(self): "us_equity_strategies.strategies.russell_1000_multi_factor_defensive", ) - cash_buffer_definition = get_strategy_definition("cash_buffer_branch_default") - self.assertEqual(cash_buffer_definition.profile, CASH_BUFFER_BRANCH_DEFAULT_PROFILE) + cash_buffer_definition = get_strategy_definition("tech_pullback_cash_buffer") + self.assertEqual(cash_buffer_definition.profile, TECH_PULLBACK_CASH_BUFFER_PROFILE) cash_buffer_module = get_strategy_component_map(cash_buffer_definition)["signal_logic"] self.assertEqual( cash_buffer_module.module_path, - "us_equity_strategies.strategies.cash_buffer_branch_default", + "us_equity_strategies.strategies.tech_pullback_cash_buffer", ) def test_aliases_resolve_to_canonical_profiles(self): - self.assertEqual(resolve_canonical_profile("tech_pullback_cash_buffer"), CASH_BUFFER_BRANCH_DEFAULT_PROFILE) + self.assertEqual(resolve_canonical_profile("global_macro_etf_rotation"), GLOBAL_ETF_ROTATION_PROFILE) self.assertEqual(resolve_canonical_profile("r1000_multifactor_defensive"), RUSSELL_1000_MULTI_FACTOR_DEFENSIVE_PROFILE) self.assertEqual(resolve_canonical_profile("qqq_tqqq_growth_income"), HYBRID_GROWTH_INCOME_PROFILE) self.assertEqual(resolve_canonical_profile("semiconductor_trend_income"), SEMICONDUCTOR_ROTATION_INCOME_PROFILE) - self.assertEqual(get_strategy_definition("tech_pullback_cash_buffer").profile, CASH_BUFFER_BRANCH_DEFAULT_PROFILE) + self.assertEqual(get_strategy_definition("tech_pullback_cash_buffer").profile, TECH_PULLBACK_CASH_BUFFER_PROFILE) def test_metadata_map_exposes_display_names_and_roles(self): metadata_map = get_strategy_metadata_map() - self.assertEqual(metadata_map[CASH_BUFFER_BRANCH_DEFAULT_PROFILE].display_name, "Tech Pullback Cash Buffer") - self.assertEqual(metadata_map[CASH_BUFFER_BRANCH_DEFAULT_PROFILE].role, "parallel_cash_buffer_branch") + self.assertEqual(metadata_map[TECH_PULLBACK_CASH_BUFFER_PROFILE].display_name, "Tech Pullback Cash Buffer") + self.assertEqual(metadata_map[TECH_PULLBACK_CASH_BUFFER_PROFILE].role, "parallel_cash_buffer_branch") self.assertEqual(metadata_map[GLOBAL_ETF_ROTATION_PROFILE].benchmark, "VOO") - self.assertEqual(get_strategy_metadata("tech_pullback_cash_buffer").canonical_profile, CASH_BUFFER_BRANCH_DEFAULT_PROFILE) + self.assertEqual(get_strategy_metadata("tech_pullback_cash_buffer").canonical_profile, TECH_PULLBACK_CASH_BUFFER_PROFILE) aliases = get_profile_aliases() - self.assertEqual(aliases["tech_pullback_cash_buffer"], CASH_BUFFER_BRANCH_DEFAULT_PROFILE) + self.assertNotIn("tech_pullback_cash_buffer", aliases) compatibility = get_strategy_platform_compatibility_map() - self.assertEqual(compatibility[CASH_BUFFER_BRANCH_DEFAULT_PROFILE], frozenset({"ibkr"})) + self.assertEqual(compatibility[TECH_PULLBACK_CASH_BUFFER_PROFILE], frozenset({"ibkr"})) def test_strategy_index_rows_are_human_readable(self): rows = get_strategy_index_rows() by_profile = {row["canonical_profile"]: row for row in rows} - self.assertEqual(by_profile[CASH_BUFFER_BRANCH_DEFAULT_PROFILE]["display_name"], "Tech Pullback Cash Buffer") + self.assertEqual(by_profile[TECH_PULLBACK_CASH_BUFFER_PROFILE]["display_name"], "Tech Pullback Cash Buffer") self.assertEqual(by_profile[HYBRID_GROWTH_INCOME_PROFILE]["aliases"], ("qqq_tqqq_growth_income",)) self.assertIn("signal_logic", by_profile[GLOBAL_ETF_ROTATION_PROFILE]["component_names"]) - self.assertEqual(by_profile[CASH_BUFFER_BRANCH_DEFAULT_PROFILE]["compatible_platforms"], frozenset({"ibkr"})) + self.assertEqual(by_profile[TECH_PULLBACK_CASH_BUFFER_PROFILE]["compatible_platforms"], frozenset({"ibkr"})) +class LegacyProfileCompatibilityTest(unittest.TestCase): + def test_legacy_cash_buffer_profile_is_not_supported_anymore(self): + with self.assertRaises(ValueError): + get_strategy_definition("cash_buffer_branch_default") + if __name__ == "__main__": unittest.main() diff --git a/tests/test_platform_registry_support.py b/tests/test_platform_registry_support.py index b24bf0ed..62dfe7c5 100644 --- a/tests/test_platform_registry_support.py +++ b/tests/test_platform_registry_support.py @@ -9,7 +9,7 @@ class PlatformRegistrySupportTest(unittest.TestCase): def test_get_enabled_profiles_for_platform_filters_by_platform(self): - enabled = frozenset({"cash_buffer_branch_default"}) + enabled = frozenset({"tech_pullback_cash_buffer"}) self.assertEqual( get_enabled_profiles_for_platform( "ibkr", @@ -30,27 +30,27 @@ def test_get_enabled_profiles_for_platform_filters_by_platform(self): def test_build_platform_profile_matrix_uses_metadata(self): rows = build_platform_profile_matrix( platform_id="ibkr", - enabled_profiles=frozenset({"cash_buffer_branch_default"}), + enabled_profiles=frozenset({"tech_pullback_cash_buffer"}), default_profile="global_etf_rotation", rollback_profile="global_etf_rotation", ) self.assertEqual(len(rows), 1) - self.assertEqual(rows[0]["canonical_profile"], "cash_buffer_branch_default") + self.assertEqual(rows[0]["canonical_profile"], "tech_pullback_cash_buffer") self.assertEqual(rows[0]["display_name"], "Tech Pullback Cash Buffer") - self.assertEqual(rows[0]["aliases"], ("tech_pullback_cash_buffer",)) + self.assertEqual(rows[0]["aliases"], ()) self.assertFalse(rows[0]["is_default"]) self.assertFalse(rows[0]["is_rollback"]) - def test_resolve_platform_strategy_definition_supports_alias(self): + def test_resolve_platform_strategy_definition_supports_canonical_profile(self): definition = resolve_platform_strategy_definition( "tech_pullback_cash_buffer", platform_id="ibkr", expected_platform_id="ibkr", - enabled_profiles=frozenset({"cash_buffer_branch_default"}), + enabled_profiles=frozenset({"tech_pullback_cash_buffer"}), platform_supported_domains={"ibkr": frozenset({"us_equity"})}, require_explicit=True, ) - self.assertEqual(definition.profile, "cash_buffer_branch_default") + self.assertEqual(definition.profile, "tech_pullback_cash_buffer") if __name__ == "__main__": diff --git a/tests/test_cash_buffer_branch_default.py b/tests/test_tech_pullback_cash_buffer.py similarity index 92% rename from tests/test_cash_buffer_branch_default.py rename to tests/test_tech_pullback_cash_buffer.py index efa59aca..cb6c0ef8 100644 --- a/tests/test_cash_buffer_branch_default.py +++ b/tests/test_tech_pullback_cash_buffer.py @@ -98,7 +98,7 @@ def _feature_snapshot() -> pd.DataFrame: class CashBufferBranchDefaultStrategyTest(unittest.TestCase): def test_build_target_weights_is_geometry_honest(self): - from us_equity_strategies.strategies.cash_buffer_branch_default import build_target_weights + from us_equity_strategies.strategies.tech_pullback_cash_buffer import build_target_weights weights, signal, metadata = build_target_weights( _feature_snapshot(), @@ -113,7 +113,7 @@ def test_build_target_weights_is_geometry_honest(self): self.assertAlmostEqual(weights["BOXX"], 0.2, places=8) def test_compute_signals_noops_outside_execution_window(self): - from us_equity_strategies.strategies.cash_buffer_branch_default import compute_signals + from us_equity_strategies.strategies.tech_pullback_cash_buffer import compute_signals weights, _signal, _emergency, status_desc, metadata = compute_signals( _feature_snapshot(), @@ -126,14 +126,14 @@ def test_compute_signals_noops_outside_execution_window(self): self.assertIn("no-op", status_desc) def test_load_runtime_parameters_reads_canonical_config(self): - from us_equity_strategies.strategies.cash_buffer_branch_default import load_runtime_parameters + from us_equity_strategies.strategies.tech_pullback_cash_buffer import load_runtime_parameters with TemporaryDirectory() as tmp_dir: - config_path = Path(tmp_dir) / "cash_buffer_branch_default.json" + config_path = Path(tmp_dir) / "tech_pullback_cash_buffer.json" config_path.write_text( json.dumps( { - "name": "cash_buffer_branch_default", + "name": "tech_pullback_cash_buffer", "family": "tech_heavy_pullback", "branch_role": "cash-buffered parallel branch", "benchmark_symbol": "QQQ", @@ -157,7 +157,7 @@ def test_load_runtime_parameters_reads_canonical_config(self): params = load_runtime_parameters(config_path=config_path) self.assertEqual(params["runtime_config_source"], "external_config") - self.assertEqual(params["runtime_config_name"], "cash_buffer_branch_default") + self.assertEqual(params["runtime_config_name"], "tech_pullback_cash_buffer") self.assertEqual(params["sector_whitelist"], ("Information Technology", "Communication")) self.assertEqual(params["execution_cash_reserve_ratio"], 0.0) diff --git a/tests/test_cash_buffer_branch_feature_snapshot.py b/tests/test_tech_pullback_cash_buffer_feature_snapshot.py similarity index 91% rename from tests/test_cash_buffer_branch_feature_snapshot.py rename to tests/test_tech_pullback_cash_buffer_feature_snapshot.py index 028f9c61..249768e2 100644 --- a/tests/test_cash_buffer_branch_feature_snapshot.py +++ b/tests/test_tech_pullback_cash_buffer_feature_snapshot.py @@ -25,7 +25,7 @@ def _price_frame() -> pd.DataFrame: class CashBufferBranchFeatureSnapshotTest(unittest.TestCase): def test_build_feature_snapshot_filters_to_tech_sectors(self): - from us_equity_strategies.snapshots.cash_buffer_branch_default import build_feature_snapshot + from us_equity_strategies.snapshots.tech_pullback_cash_buffer import build_feature_snapshot snapshot = build_feature_snapshot( _price_frame(), @@ -50,14 +50,14 @@ def test_build_feature_snapshot_filters_to_tech_sectors(self): self.assertFalse(base_flags["BOXX"]) def test_cli_writes_snapshot(self): - from scripts.generate_cash_buffer_branch_feature_snapshot import main + from scripts.generate_tech_pullback_cash_buffer_feature_snapshot import main with TemporaryDirectory() as tmp_dir: tmp_path = Path(tmp_dir) prices_path = tmp_path / "prices.csv" universe_path = tmp_path / "universe.csv" output_path = tmp_path / "snapshot.csv" - config_path = tmp_path / "cash_buffer_branch_default.json" + config_path = tmp_path / "tech_pullback_cash_buffer.json" _price_frame().to_csv(prices_path, index=False) universe_path.write_text( @@ -67,7 +67,7 @@ def test_cli_writes_snapshot(self): config_path.write_text( json.dumps( { - "name": "cash_buffer_branch_default", + "name": "tech_pullback_cash_buffer", } ), encoding="utf-8",