#!/usr/bin/env python3 """Debug MA gap scoring to understand parameter insensitivity.""" import sys from pathlib import Path import numpy as np import pandas as pd # Add backtester to path sys.path.insert(0, str(Path(__file__).parent.parent)) from backtester.data_loader import load_csv from backtester.indicators.money_line import MoneyLineInputs, ema def analyze_ma_gap_distribution(csv_path: str): """Analyze MA gap score distribution to understand parameter behavior.""" print("=" * 80) print("MA GAP DISTRIBUTION ANALYSIS") print("=" * 80) # Load data data_slice = load_csv(Path(csv_path), "SOL-PERP", "5m") df = data_slice.data # DataSlice.data is the DataFrame print(f"Loaded {len(df)} bars\n") # Calculate EMAs df["ema_fast"] = ema(df["close"], 50) df["ema_slow"] = ema(df["close"], 200) # Calculate raw MA gap percentage ma_gap = 100.0 * (df["ema_fast"] - df["ema_slow"]) / df["close"] print("RAW MA GAP (%) DISTRIBUTION:") print(f" Min: {ma_gap.min():.4f}%") print(f" 25th: {ma_gap.quantile(0.25):.4f}%") print(f" Median: {ma_gap.median():.4f}%") print(f" 75th: {ma_gap.quantile(0.75):.4f}%") print(f" Max: {ma_gap.max():.4f}%") print(f" Std: {ma_gap.std():.4f}%\n") # Test different thresholds for threshold in [0.2, 0.3, 0.35, 0.4, 0.5]: gap_score = np.tanh(ma_gap / threshold) print(f"\nTHRESHOLD = {threshold} (default: 0.35):") print(f" gap_score min: {gap_score.min():.6f}") print(f" gap_score max: {gap_score.max():.6f}") print(f" gap_score median: {gap_score.median():.6f}") # Check flip_threshold comparisons for flip_pct in [0.4, 0.5, 0.6, 0.7]: flip_threshold = flip_pct / 100.0 # Convert to decimal # Count how many bars exceed threshold long_signals = (gap_score > flip_threshold).sum() short_signals = (gap_score < -flip_threshold).sum() total_signals = long_signals + short_signals print(f" flip_threshold={flip_pct}% → {total_signals} potential signals") print(f" (LONG: {long_signals}, SHORT: {short_signals})") if __name__ == "__main__": if len(sys.argv) != 2: print("Usage: python debug_ma_gap.py ") sys.exit(1) analyze_ma_gap_distribution(sys.argv[1])