Spaces:
Running
Running
| #!/usr/bin/env python3 | |
| """C14: TAIEX regime features β taiex_ma200_ratio (market above/below 200MA) + | |
| taiex_return_20d (monthly momentum). Literature: regime filter cuts false BUY signals | |
| by ~20% when market is below 200-day MA. | |
| Pass gate: dir_accuracy > 43.5% AND up_precision > 54%. | |
| """ | |
| 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", | |
| }] | |
| C14_FEATURES = CURRENT_FEATURES + [ | |
| "taiex_ma200_ratio", # TAIEX / 200-day MA β regime state (>1 = bull, <1 = bear) | |
| "taiex_return_20d", # TAIEX 20-day return β monthly momentum direction | |
| ] | |
| PASS_DIR_ACC = 43.5 | |
| PASS_UP_PREC = 54.0 | |
| def main(): | |
| print(f"C14: baseline={len(CURRENT_FEATURES)} β candidate={len(C14_FEATURES)} features") | |
| print(f"New: taiex_ma200_ratio, taiex_return_20d\n") | |
| cmp = run_comparison( | |
| feature_sets={"baseline": CURRENT_FEATURES, "c14_regime": C14_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("c14_regime", {}) | |
| 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" c14_regime 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": "C14_taiex_regime", | |
| "new_features": ["taiex_ma200_ratio", "taiex_return_20d"], | |
| "aggregate": cmp["aggregate"], | |
| "results": cmp["results"], | |
| "passed": passed, | |
| } | |
| Path("docs").mkdir(exist_ok=True) | |
| with open("docs/c14_result.json", "w") as f: | |
| json.dump(result, f, indent=2) | |
| print(f" Saved β docs/c14_result.json") | |
| if passed: | |
| print("\n ACTION: Add to FEATURE_COLUMNS in models/predictor.py:") | |
| for f in ["taiex_ma200_ratio", "taiex_return_20d"]: | |
| print(f" \"{f}\",") | |
| if __name__ == "__main__": | |
| main() | |