From ce9ba1770111df6edb984534659415907b98d6f0 Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Sat, 20 Jun 2026 04:43:47 +0800 Subject: [PATCH] Add SOXL signal consumer contract --- src/us_equity_strategies/signals/__init__.py | 2 + .../signals/runtime_market_signal_inputs.py | 3 + .../signals/signal_bundle_contract.py | 18 ++++ tests/test_runtime_market_signal_inputs.py | 12 +++ tests/test_signal_bundle_cli.py | 94 ++++++++++++++++--- tests/test_signal_bundle_contract.py | 92 ++++++++++++++---- tests/test_smart_dca_research_cli.py | 48 ++++++++-- 7 files changed, 235 insertions(+), 34 deletions(-) diff --git a/src/us_equity_strategies/signals/__init__.py b/src/us_equity_strategies/signals/__init__.py index 93a1495..109d5b9 100644 --- a/src/us_equity_strategies/signals/__init__.py +++ b/src/us_equity_strategies/signals/__init__.py @@ -74,6 +74,7 @@ MARKET_SIGNAL_REFERENCE_CONSUMPTION_AUDIT, MARKET_SIGNAL_REFERENCE_PLATFORM_HANDOFF, MARKET_SIGNAL_REFERENCE_PLATFORM_HANDOFF_INDEX, + SOXL_SOXX_TREND_INCOME_MARKET_SIGNAL_CONSUMER, SUPPORTED_MARKET_SIGNAL_REFERENCE_TYPES, extract_consumer_market_signal_inputs_from_reference, normalize_market_signal_fallback_mode, @@ -152,6 +153,7 @@ "MARKET_SIGNAL_REFERENCE_CONSUMPTION_AUDIT", "MARKET_SIGNAL_REFERENCE_PLATFORM_HANDOFF", "MARKET_SIGNAL_REFERENCE_PLATFORM_HANDOFF_INDEX", + "SOXL_SOXX_TREND_INCOME_MARKET_SIGNAL_CONSUMER", "SUPPORTED_MARKET_SIGNAL_REFERENCE_TYPES", "extract_consumer_market_signal_inputs_from_reference", "normalize_market_signal_fallback_mode", diff --git a/src/us_equity_strategies/signals/runtime_market_signal_inputs.py b/src/us_equity_strategies/signals/runtime_market_signal_inputs.py index c2661e8..7a68533 100644 --- a/src/us_equity_strategies/signals/runtime_market_signal_inputs.py +++ b/src/us_equity_strategies/signals/runtime_market_signal_inputs.py @@ -23,6 +23,9 @@ IBIT_SMART_DCA_MARKET_SIGNAL_CONSUMER = "us_equity:ibit_smart_dca" NASDAQ_SP500_SMART_DCA_MARKET_SIGNAL_CONSUMER = "us_equity:nasdaq_sp500_smart_dca" +SOXL_SOXX_TREND_INCOME_MARKET_SIGNAL_CONSUMER = ( + "us_equity:soxl_soxx_trend_income" +) MARKET_SIGNAL_REFERENCE_CONSUMPTION_AUDIT = "consumption_audit" MARKET_SIGNAL_REFERENCE_PLATFORM_HANDOFF = "platform_handoff" MARKET_SIGNAL_REFERENCE_PLATFORM_HANDOFF_INDEX = "platform_handoff_index" diff --git a/src/us_equity_strategies/signals/signal_bundle_contract.py b/src/us_equity_strategies/signals/signal_bundle_contract.py index 7946ca9..bf13727 100644 --- a/src/us_equity_strategies/signals/signal_bundle_contract.py +++ b/src/us_equity_strategies/signals/signal_bundle_contract.py @@ -64,6 +64,24 @@ "rsi14", ), }, + "us_equity:soxl_soxx_trend_income": { + "SOXL": ( + "price", + "ma_trend", + ), + "SOXX": ( + "price", + "ma_trend", + "ma20", + "ma20_slope", + "rsi14", + "rsi14_dynamic_threshold", + "bb_upper", + "realized_volatility_10", + "realized_volatility_10_dynamic_threshold", + "realized_volatility_10_dynamic_sample_count", + ), + }, "research:nasdaq_sp500_external_context_precomputed": { "US-EQUITY-CONTEXT": ( "breadth_above_sma200_pct", diff --git a/tests/test_runtime_market_signal_inputs.py b/tests/test_runtime_market_signal_inputs.py index 2e4adab..a99c735 100644 --- a/tests/test_runtime_market_signal_inputs.py +++ b/tests/test_runtime_market_signal_inputs.py @@ -5,6 +5,18 @@ from us_equity_strategies.signals import runtime_market_signal_inputs as runtime_inputs +def test_runtime_market_signal_consumer_constants_are_exported(): + assert runtime_inputs.IBIT_SMART_DCA_MARKET_SIGNAL_CONSUMER == ( + "us_equity:ibit_smart_dca" + ) + assert runtime_inputs.NASDAQ_SP500_SMART_DCA_MARKET_SIGNAL_CONSUMER == ( + "us_equity:nasdaq_sp500_smart_dca" + ) + assert runtime_inputs.SOXL_SOXX_TREND_INCOME_MARKET_SIGNAL_CONSUMER == ( + "us_equity:soxl_soxx_trend_income" + ) + + def test_extract_consumer_market_signal_inputs_from_reference_uses_handoff_index(monkeypatch, tmp_path): calls: dict[str, object] = {} diff --git a/tests/test_signal_bundle_cli.py b/tests/test_signal_bundle_cli.py index a8e41cd..be3305c 100644 --- a/tests/test_signal_bundle_cli.py +++ b/tests/test_signal_bundle_cli.py @@ -103,6 +103,31 @@ def _write_platform_handoff_inputs(tmp_path: Path) -> Path: ], "research_consumers": [], }, + { + "family": "us_equity.semiconductor_rotation_daily", + "canonical_input": "derived_indicators", + "transform": "us_equity.semiconductor_rotation.v1", + "symbols": ["SOXL", "SOXX"], + "derived_indicator_fields": [ + "price", + "ma_trend", + "ma20", + "ma20_slope", + "rsi14", + "rsi14_dynamic_threshold", + "bb_upper", + "realized_volatility_10", + "realized_volatility_10_dynamic_threshold", + "realized_volatility_10_dynamic_sample_count", + ], + "compatible_profiles": [ + "us_equity:soxl_soxx_trend_income", + ], + "runtime_consumers": [ + "us_equity:soxl_soxx_trend_income", + ], + "research_consumers": [], + }, ], }, indent=2, @@ -123,8 +148,8 @@ def _write_platform_handoff_inputs(tmp_path: Path) -> Path: "catalog_sha256": _sha256_path(source_catalog_path), "catalog_size_bytes": source_catalog_path.stat().st_size, "catalog_schema_version": "market_signal_source_families.v1", - "family_count": 2, - "known_family_count": 2, + "family_count": 3, + "known_family_count": 3, "missing_known_families": [], "all_known_families_present": True, "all_consumer_contracts_satisfied": True, @@ -179,6 +204,28 @@ def _write_platform_handoff_inputs(tmp_path: Path) -> Path: ], }, }, + { + "consumer": "us_equity:soxl_soxx_trend_income", + "canonical_input": "derived_indicators", + "required_indicator_fields_by_symbol": { + "SOXL": [ + "price", + "ma_trend", + ], + "SOXX": [ + "price", + "ma_trend", + "ma20", + "ma20_slope", + "rsi14", + "rsi14_dynamic_threshold", + "bb_upper", + "realized_volatility_10", + "realized_volatility_10_dynamic_threshold", + "realized_volatility_10_dynamic_sample_count", + ], + }, + }, { "consumer": "research:ibit_btc_ahr999_precomputed", "canonical_input": "derived_indicators", @@ -265,8 +312,8 @@ def _write_platform_handoff_inputs(tmp_path: Path) -> Path: "registry_size_bytes": registry_path.stat().st_size, "registry_schema_version": "market_signal_consumer_contracts.v1", "canonical_input": "derived_indicators", - "consumer_count": 9, - "known_consumer_count": 9, + "consumer_count": 10, + "known_consumer_count": 10, "missing_known_consumers": [], "all_known_consumers_present": True, }, @@ -304,10 +351,11 @@ def _write_platform_handoff_inputs(tmp_path: Path) -> Path: "consumer_contract_registry_manifest_sha256": _sha256_path( registry_manifest_path ), - "source_family_count": 2, + "source_family_count": 3, "source_families": [ "crypto.btc_cycle_daily", "us_equity.technical_daily", + "us_equity.semiconductor_rotation_daily", ], "all_known_source_families_present": True, "all_consumer_contracts_satisfied": True, @@ -654,9 +702,10 @@ def test_signal_bundle_cli_validates_platform_handoff_manifest( assert summary["source_families"] == [ "crypto.btc_cycle_daily", "us_equity.technical_daily", + "us_equity.semiconductor_rotation_daily", ] assert summary["matched_source_families"] == ["crypto.btc_cycle_daily"] - assert summary["consumer_contract_count"] == 9 + assert summary["consumer_contract_count"] == 10 assert summary["all_known_consumers_present"] is True assert summary["all_runtime_consumers_covered"] is True assert summary["handoff_linked_manifest_sha256s_verified"] is True @@ -699,6 +748,7 @@ def test_signal_bundle_cli_validates_platform_handoff_index( assert summary["source_families"] == [ "crypto.btc_cycle_daily", "us_equity.technical_daily", + "us_equity.semiconductor_rotation_daily", ] assert summary["matched_source_families"] == ["crypto.btc_cycle_daily"] assert summary["handoff_linked_manifest_sha256s_verified"] is True @@ -802,7 +852,7 @@ def test_signal_bundle_cli_validates_research_handoff_manifest( assert summary["research_artifact_type"] == "btc_cycle_research_csv" assert summary["research_transform"] == "crypto.btc.ahr999.v1" assert summary["matched_source_families"] == ["crypto.btc_cycle_daily"] - assert summary["consumer_contract_count"] == 9 + assert summary["consumer_contract_count"] == 10 assert summary["research_export_output_csv_verified"] is True assert summary["handoff_linked_manifest_sha256s_verified"] is True @@ -814,7 +864,7 @@ def test_signal_bundle_cli_prints_local_consumer_contract_registry(capsys) -> No payload = json.loads(capsys.readouterr().out) assert payload["schema_version"] == "market_signal_consumer_contracts.v1" assert payload["canonical_input"] == "derived_indicators" - assert len(payload["contracts"]) == 9 + assert len(payload["contracts"]) == 10 consumers = [contract["consumer"] for contract in payload["contracts"]] assert "research:nasdaq_sp500_price_proxy" in consumers price_proxy_contract = next( @@ -942,6 +992,28 @@ def test_signal_bundle_cli_validates_consumer_contract_registry_manifest( ], }, }, + { + "consumer": "us_equity:soxl_soxx_trend_income", + "canonical_input": "derived_indicators", + "required_indicator_fields_by_symbol": { + "SOXL": [ + "price", + "ma_trend", + ], + "SOXX": [ + "price", + "ma_trend", + "ma20", + "ma20_slope", + "rsi14", + "rsi14_dynamic_threshold", + "bb_upper", + "realized_volatility_10", + "realized_volatility_10_dynamic_threshold", + "realized_volatility_10_dynamic_sample_count", + ], + }, + }, { "consumer": "research:ibit_btc_ahr999_precomputed", "canonical_input": "derived_indicators", @@ -1038,8 +1110,8 @@ def test_signal_bundle_cli_validates_consumer_contract_registry_manifest( "registry_size_bytes": registry_path.stat().st_size, "registry_schema_version": "market_signal_consumer_contracts.v1", "canonical_input": "derived_indicators", - "consumer_count": 9, - "known_consumer_count": 9, + "consumer_count": 10, + "known_consumer_count": 10, "missing_known_consumers": [], "all_known_consumers_present": True, }, @@ -1069,7 +1141,7 @@ def test_signal_bundle_cli_validates_consumer_contract_registry_manifest( assert summary["registry_sha256"] == hashlib.sha256( registry_path.read_bytes() ).hexdigest() - assert summary["consumer_count"] == 9 + assert summary["consumer_count"] == 10 assert summary["all_known_consumers_present"] is True assert summary["local_contract_registry_verified"] is True assert summary["canonical_registry_payload_sha256"] == summary[ diff --git a/tests/test_signal_bundle_contract.py b/tests/test_signal_bundle_contract.py index 7e93526..567c870 100644 --- a/tests/test_signal_bundle_contract.py +++ b/tests/test_signal_bundle_contract.py @@ -214,6 +214,31 @@ def _complete_consumer_contract_registry() -> dict[str, object]: ) contracts.insert( 2, + { + "consumer": "us_equity:soxl_soxx_trend_income", + "canonical_input": "derived_indicators", + "required_indicator_fields_by_symbol": { + "SOXL": [ + "price", + "ma_trend", + ], + "SOXX": [ + "price", + "ma_trend", + "ma20", + "ma20_slope", + "rsi14", + "rsi14_dynamic_threshold", + "bb_upper", + "realized_volatility_10", + "realized_volatility_10_dynamic_threshold", + "realized_volatility_10_dynamic_sample_count", + ], + }, + }, + ) + contracts.insert( + 3, { "consumer": "research:nasdaq_sp500_external_context_precomputed", "canonical_input": "derived_indicators", @@ -227,7 +252,7 @@ def _complete_consumer_contract_registry() -> dict[str, object]: }, ) contracts.insert( - 3, + 4, { "consumer": "research:nasdaq_sp500_cape_vix_external_context_precomputed", "canonical_input": "derived_indicators", @@ -240,7 +265,7 @@ def _complete_consumer_contract_registry() -> dict[str, object]: }, ) contracts.insert( - 4, + 5, { "consumer": "research:nasdaq_sp500_price_proxy", "canonical_input": "derived_indicators", @@ -253,7 +278,7 @@ def _complete_consumer_contract_registry() -> dict[str, object]: }, ) contracts.insert( - 5, + 6, { "consumer": "research:ibit_btc_ahr999_precomputed", "canonical_input": "derived_indicators", @@ -263,7 +288,7 @@ def _complete_consumer_contract_registry() -> dict[str, object]: }, ) contracts.insert( - 6, + 7, { "consumer": "research:ibit_btc_ahr999_helper_precomputed_variants", "canonical_input": "derived_indicators", @@ -277,7 +302,7 @@ def _complete_consumer_contract_registry() -> dict[str, object]: }, ) contracts.insert( - 7, + 8, { "consumer": "research:ibit_btc_ahr999_mayer_precomputed", "canonical_input": "derived_indicators", @@ -305,6 +330,7 @@ def _write_consumer_contract_registry_manifest( { "us_equity:ibit_smart_dca", "us_equity:nasdaq_sp500_smart_dca", + "us_equity:soxl_soxx_trend_income", "research:ibit_btc_ahr999_precomputed", "research:ibit_btc_ahr999_helper_precomputed_variants", "research:ibit_btc_ahr999_mayer_precomputed", @@ -329,7 +355,7 @@ def _write_consumer_contract_registry_manifest( "registry_schema_version": registry["schema_version"], "canonical_input": registry["canonical_input"], "consumer_count": len(contracts), - "known_consumer_count": 9, + "known_consumer_count": 10, "missing_known_consumers": missing_consumers, "all_known_consumers_present": not missing_consumers, }, @@ -407,6 +433,33 @@ def _source_family_catalog() -> dict[str, object]: "runtime_consumers": ["us_equity:nasdaq_sp500_smart_dca"], "research_consumers": [], }, + { + "family": "us_equity.semiconductor_rotation_daily", + "domain": "us_equity", + "bundle_type": "derived_indicators", + "bundle_id_prefix": "us_equity.semiconductor_rotation.daily", + "canonical_input": "derived_indicators", + "transform": "us_equity.semiconductor_rotation.v1", + "provider_dataset": "us_equity_semiconductor_daily_ohlcv", + "freshness_policy": "us_equity_daily_close_t_plus_1", + "minimum_history_rows": 420, + "symbols": ["SOXL", "SOXX"], + "derived_indicator_fields": [ + "price", + "ma_trend", + "ma20", + "ma20_slope", + "rsi14", + "rsi14_dynamic_threshold", + "bb_upper", + "realized_volatility_10", + "realized_volatility_10_dynamic_threshold", + "realized_volatility_10_dynamic_sample_count", + ], + "compatible_profiles": ["us_equity:soxl_soxx_trend_income"], + "runtime_consumers": ["us_equity:soxl_soxx_trend_income"], + "research_consumers": [], + }, ], } @@ -427,8 +480,8 @@ def _write_source_family_catalog_manifest(tmp_path: Path) -> tuple[Path, Path]: "catalog_sha256": _sha256_path(catalog_path), "catalog_size_bytes": catalog_path.stat().st_size, "catalog_schema_version": "market_signal_source_families.v1", - "family_count": 2, - "known_family_count": 2, + "family_count": 3, + "known_family_count": 3, "missing_known_families": [], "all_known_families_present": True, "all_consumer_contracts_satisfied": True, @@ -506,7 +559,7 @@ def _write_platform_handoff_manifest( "all_runtime_consumers_covered": True, "consumer_contract_count": len(consumers), "consumer_contracts": list(consumers), - "all_known_consumers_present": len(consumers) == 9, + "all_known_consumers_present": len(consumers) == 10, "canonical_registry_payload_sha256": registry_summary[ "canonical_registry_payload_sha256" ], @@ -809,7 +862,7 @@ def _write_research_handoff_manifest( ), "consumer_contract_count": len(consumers), "consumer_contracts": list(consumers), - "all_known_consumers_present": len(consumers) == 9, + "all_known_consumers_present": len(consumers) == 10, "canonical_registry_payload_sha256": registry_summary[ "canonical_registry_payload_sha256" ], @@ -1218,6 +1271,7 @@ def test_external_consumer_contract_registry_matches_local_contracts(tmp_path) - "research:nasdaq_sp500_external_context_precomputed", "research:nasdaq_sp500_price_proxy", "us_equity:nasdaq_sp500_smart_dca", + "us_equity:soxl_soxx_trend_income", ) assert summary["local_contract_registry_verified"] is True assert summary["canonical_registry_payload_sha256"] == summary[ @@ -1255,7 +1309,7 @@ def test_external_consumer_contract_registry_manifest_matches_local_contracts( registry_path.read_bytes() ).hexdigest() assert summary["registry_schema_version"] == "market_signal_consumer_contracts.v1" - assert summary["consumer_count"] == 9 + assert summary["consumer_count"] == 10 assert summary["all_known_consumers_present"] is True assert summary["local_contract_registry_verified"] is True assert summary["canonical_registry_payload_sha256"] == summary[ @@ -1287,6 +1341,7 @@ def test_source_family_catalog_manifest_matches_required_consumers(tmp_path) -> assert summary["families"] == ( "crypto.btc_cycle_daily", "us_equity.technical_daily", + "us_equity.semiconductor_rotation_daily", ) assert summary["matched_families"] == ("crypto.btc_cycle_daily",) assert summary["required_signal_consumers_present"] is True @@ -1337,7 +1392,7 @@ def test_platform_handoff_manifest_validates_linked_artifacts(tmp_path) -> None: ) source_manifest["catalog_sha256"] = _sha256_path(source_catalog_path) source_manifest["catalog_size_bytes"] = source_catalog_path.stat().st_size - source_manifest["family_count"] = 3 + source_manifest["family_count"] = 4 source_catalog_manifest_path.write_text( json.dumps(source_manifest, indent=2, sort_keys=True) + "\n", encoding="utf-8", @@ -1386,11 +1441,12 @@ def test_platform_handoff_manifest_validates_linked_artifacts(tmp_path) -> None: assert summary["source_families"] == ( "crypto.btc_cycle_daily", "us_equity.technical_daily", + "us_equity.semiconductor_rotation_daily", "us_equity.nasdaq_sp500_context_daily", ) assert summary["matched_source_family_count"] == 1 assert summary["matched_source_families"] == ("crypto.btc_cycle_daily",) - assert summary["consumer_contract_count"] == 9 + assert summary["consumer_contract_count"] == 10 assert summary["all_known_source_families_present"] is True assert summary["all_consumer_contracts_satisfied"] is True assert summary["all_known_consumers_present"] is True @@ -1465,9 +1521,9 @@ def test_runtime_consumption_audit_validates_linked_bundle_for_injection( assert summary["consumer"] == "us_equity:ibit_smart_dca" assert summary["lookup_as_of"] == "2026-06-20" assert summary["as_of"] == "2026-06-19" - assert summary["source_family_count"] == 2 + assert summary["source_family_count"] == 3 assert summary["matched_source_family_count"] == 1 - assert summary["consumer_contract_count"] == 9 + assert summary["consumer_contract_count"] == 10 assert summary["all_known_source_families_present"] is True assert summary["all_consumer_contracts_satisfied"] is True assert summary["all_known_consumers_present"] is True @@ -1611,7 +1667,7 @@ def test_research_handoff_manifest_validates_linked_research_export( assert handoff_summary["matched_source_families"] == ("crypto.btc_cycle_daily",) assert handoff_summary["source_family_count"] == 1 assert handoff_summary["source_families"] == ("crypto.btc_cycle_daily",) - assert handoff_summary["consumer_contract_count"] == 9 + assert handoff_summary["consumer_contract_count"] == 10 assert handoff_summary["all_runtime_consumers_covered"] is True assert handoff_summary["canonical_registry_payload_sha256"] == handoff_summary[ "local_registry_payload_sha256" @@ -1651,6 +1707,7 @@ def test_platform_handoff_index_resolves_matching_handoff_manifest(tmp_path) -> consumers=( "us_equity:ibit_smart_dca", "us_equity:nasdaq_sp500_smart_dca", + "us_equity:soxl_soxx_trend_income", "research:nasdaq_sp500_external_context_precomputed", "research:nasdaq_sp500_cape_vix_external_context_precomputed", "research:nasdaq_sp500_price_proxy", @@ -1727,6 +1784,7 @@ def test_external_consumer_contract_registry_can_require_all_known_consumers() - "research:nasdaq_sp500_price_proxy", "us_equity:ibit_smart_dca", "us_equity:nasdaq_sp500_smart_dca", + "us_equity:soxl_soxx_trend_income", ) assert [ contract["consumer"] @@ -1751,7 +1809,7 @@ def test_external_consumer_contract_registry_can_require_all_known_consumers() - local_registry, require_all_known_consumers=True, ) - assert summary["consumer_count"] == 9 + assert summary["consumer_count"] == 10 assert summary["all_known_consumers_present"] is True assert summary["missing_known_consumers"] == () assert summary["local_contract_registry_verified"] is True diff --git a/tests/test_smart_dca_research_cli.py b/tests/test_smart_dca_research_cli.py index a9bfe66..4f24ede 100644 --- a/tests/test_smart_dca_research_cli.py +++ b/tests/test_smart_dca_research_cli.py @@ -1718,6 +1718,37 @@ def test_smart_dca_research_cli_can_use_precomputed_ibit_cycle_columns( ], "research_consumers": [], }, + { + "family": "us_equity.semiconductor_rotation_daily", + "domain": "us_equity", + "bundle_type": "derived_indicators", + "bundle_id_prefix": "us_equity.semiconductor_rotation.daily", + "canonical_input": "derived_indicators", + "transform": "us_equity.semiconductor_rotation.v1", + "provider_dataset": "us_equity_semiconductor_daily_ohlcv", + "freshness_policy": "us_equity_daily_close_t_plus_1", + "minimum_history_rows": 420, + "symbols": ["SOXL", "SOXX"], + "derived_indicator_fields": [ + "price", + "ma_trend", + "ma20", + "ma20_slope", + "rsi14", + "rsi14_dynamic_threshold", + "bb_upper", + "realized_volatility_10", + "realized_volatility_10_dynamic_threshold", + "realized_volatility_10_dynamic_sample_count", + ], + "compatible_profiles": [ + "us_equity:soxl_soxx_trend_income", + ], + "runtime_consumers": [ + "us_equity:soxl_soxx_trend_income", + ], + "research_consumers": [], + }, ], }, sort_keys=True, @@ -1735,8 +1766,8 @@ def test_smart_dca_research_cli_can_use_precomputed_ibit_cycle_columns( "catalog_sha256": _sha256_file(source_catalog), "catalog_size_bytes": source_catalog.stat().st_size, "catalog_schema_version": "market_signal_source_families.v1", - "family_count": 2, - "known_family_count": 2, + "family_count": 3, + "known_family_count": 3, "missing_known_families": [], "all_known_families_present": True, "all_consumer_contracts_satisfied": True, @@ -1790,7 +1821,7 @@ def test_smart_dca_research_cli_can_use_precomputed_ibit_cycle_columns( "registry_schema_version": "market_signal_consumer_contracts.v1", "canonical_input": "derived_indicators", "consumer_count": 2, - "known_consumer_count": 9, + "known_consumer_count": 10, "missing_known_consumers": [ "research:ibit_btc_ahr999_helper_precomputed_variants", "research:ibit_btc_ahr999_precomputed", @@ -1799,6 +1830,7 @@ def test_smart_dca_research_cli_can_use_precomputed_ibit_cycle_columns( "research:nasdaq_sp500_price_proxy", "us_equity:ibit_smart_dca", "us_equity:nasdaq_sp500_smart_dca", + "us_equity:soxl_soxx_trend_income", ], "all_known_consumers_present": False, } @@ -1888,10 +1920,11 @@ def test_smart_dca_research_cli_can_use_precomputed_ibit_cycle_columns( "consumer_contract_registry_manifest_sha256": _sha256_file( consumer_contract_registry_manifest ), - "source_family_count": 2, + "source_family_count": 3, "source_families": [ "crypto.btc_cycle_daily", "us_equity.technical_daily", + "us_equity.semiconductor_rotation_daily", ], "all_known_source_families_present": True, "all_consumer_contracts_satisfied": True, @@ -1986,10 +2019,11 @@ def test_smart_dca_research_cli_can_use_precomputed_ibit_cycle_columns( "consumer_contract_registry_manifest_sha256": _sha256_file( consumer_contract_registry_manifest ), - "source_family_count": 2, + "source_family_count": 3, "source_families": [ "crypto.btc_cycle_daily", "us_equity.technical_daily", + "us_equity.semiconductor_rotation_daily", ], "matched_source_family_count": 1, "matched_source_families": ["crypto.btc_cycle_daily"], @@ -2174,6 +2208,7 @@ def test_smart_dca_research_cli_can_use_precomputed_ibit_cycle_columns( assert platform_handoff_record["source_families"] == [ "crypto.btc_cycle_daily", "us_equity.technical_daily", + "us_equity.semiconductor_rotation_daily", ] assert platform_handoff_record["matched_source_families"] == [ "crypto.btc_cycle_daily" @@ -2479,7 +2514,7 @@ def test_smart_dca_research_cli_can_use_precomputed_ibit_cycle_columns( "registry_schema_version": "market_signal_consumer_contracts.v1", "canonical_input": "derived_indicators", "consumer_count": 1, - "known_consumer_count": 9, + "known_consumer_count": 10, "missing_known_consumers": [ "research:ibit_btc_ahr999_helper_precomputed_variants", "research:ibit_btc_ahr999_mayer_precomputed_variants", @@ -2489,6 +2524,7 @@ def test_smart_dca_research_cli_can_use_precomputed_ibit_cycle_columns( "research:nasdaq_sp500_price_proxy", "us_equity:ibit_smart_dca", "us_equity:nasdaq_sp500_smart_dca", + "us_equity:soxl_soxx_trend_income", ], "all_known_consumers_present": False, }