Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| """C13: Add SOX + TNX cross-asset features (sox_ret_1d, sox_ret_5d, sox_ma20_ratio, | |
| tnx_level, tnx_change_5d). Already computed in fetch_df, just not in FEATURE_COLUMNS. | |
| Pass gate: dir_accuracy > 43.5% AND up_precision > 54% (updated post-C5 thresholds). | |
| """ | |
| import sys | |
| from pathlib import Path | |
| ROOT = Path(__file__).resolve().parent.parent | |
| sys.path.insert(0, str(ROOT)) | |
| try: | |
| from dotenv import load_dotenv; load_dotenv(ROOT / ".env") | |
| except ImportError: | |
| pass | |
| import warnings; warnings.filterwarnings("ignore") | |
| import json | |
| sys.path.insert(0, str(ROOT / "scripts")) | |
| from improvement_harness import BASELINE_FEATURES, run_comparison | |
| STOCKS = ["2330", "0050", "2317", "2454", "2881"] | |
| CURRENT_FEATURES = [f for f in BASELINE_FEATURES if f not in { | |
| "macd_cross_up", "macd_cross_down", "price_volume_div", | |
| "foreign_net_vol_ratio", "trust_net_vol_ratio", "dealer_net_vol_ratio", | |
| "institutional_net_vol_ratio", "institutional_5d_net_vol_ratio", | |
| "institutional_20d_zscore", "foreign_trust_alignment", "institutional_streak", | |
| }] | |
| SOX_TNX_FEATURES = CURRENT_FEATURES + [ | |
| "sox_ret_1d", | |
| "sox_ret_5d", | |
| "sox_ma20_ratio", | |
| "tnx_level", | |
| "tnx_change_5d", | |
| ] | |
| PASS_DIR_ACC = 43.5 | |
| PASS_UP_PREC = 54.0 | |
| def main(): | |
| print(f"C13: baseline={len(CURRENT_FEATURES)} features β candidate={len(SOX_TNX_FEATURES)} features") | |
| print(f"New features: sox_ret_1d, sox_ret_5d, sox_ma20_ratio, tnx_level, tnx_change_5d\n") | |
| cmp = run_comparison( | |
| feature_sets={"baseline": CURRENT_FEATURES, "sox_tnx": SOX_TNX_FEATURES}, | |
| label_mode="triple_barrier", | |
| stocks=STOCKS, | |
| output_path=None, | |
| pass_criterion={"dir_accuracy": PASS_DIR_ACC}, | |
| verbose=True, | |
| ) | |
| b = cmp["aggregate"].get("baseline", {}) | |
| c = cmp["aggregate"].get("sox_tnx", {}) | |
| dir_delta = c.get("dir_accuracy", 0) - b.get("dir_accuracy", 0) | |
| prec_delta = c.get("up_precision", 0) - b.get("up_precision", 0) | |
| passed = ( | |
| c.get("dir_accuracy", 0) >= PASS_DIR_ACC and | |
| c.get("up_precision", 0) >= PASS_UP_PREC and | |
| dir_delta >= -0.5 and prec_delta >= -0.5 | |
| ) | |
| print("\nββ Results ββββββββββββββββββββββββββββββββββββββ") | |
| print(f" baseline dir_acc={b.get('dir_accuracy')}% up_prec={b.get('up_precision')}%") | |
| print(f" sox_tnx dir_acc={c.get('dir_accuracy')}% up_prec={c.get('up_precision')}%") | |
| print(f" Ξ dir_acc={dir_delta:+.1f}pp Ξ up_prec={prec_delta:+.1f}pp") | |
| print(f" Pass gate: dir>{PASS_DIR_ACC}% AND up_prec>{PASS_UP_PREC}%") | |
| print(f" Result: {'PASSED' if passed else 'FAILED'}") | |
| result = { | |
| "experiment": "C13_sox_tnx", | |
| "new_features": ["sox_ret_1d", "sox_ret_5d", "sox_ma20_ratio", "tnx_level", "tnx_change_5d"], | |
| "aggregate": cmp["aggregate"], | |
| "results": cmp["results"], | |
| "passed": passed, | |
| } | |
| Path("docs").mkdir(exist_ok=True) | |
| with open("docs/c13_result.json", "w") as f: | |
| json.dump(result, f, indent=2) | |
| print(f" Saved β docs/c13_result.json") | |
| if passed: | |
| print("\n ACTION: Add these to FEATURE_COLUMNS in models/predictor.py:") | |
| for f in ["sox_ret_1d", "sox_ret_5d", "sox_ma20_ratio", "tnx_level", "tnx_change_5d"]: | |
| print(f" \"{f}\",") | |
| if __name__ == "__main__": | |
| main() | |