156 lines
4.6 KiB
Python
156 lines
4.6 KiB
Python
"""
|
|
Runner script for GARCH vs MMAR comparison.
|
|
|
|
Fits multiple GARCH models and compares forecasts with MMAR and realized volatility.
|
|
"""
|
|
|
|
from garch_model import run_garch_comparison
|
|
from compare_forecast import run_forecast_comparison
|
|
import pickle
|
|
from pathlib import Path
|
|
import numpy as np
|
|
import pandas as pd
|
|
import config
|
|
|
|
|
|
if __name__ == "__main__":
|
|
print("\n" + "="*70)
|
|
print(" "*15 + "MMAR vs GARCH COMPARISON")
|
|
print("="*70)
|
|
|
|
# Step 1: Fit GARCH model
|
|
print("\n[STEP 1] Fitting GARCH model...")
|
|
print("-"*70)
|
|
|
|
garch_results = run_garch_comparison(
|
|
p=1,
|
|
q=1,
|
|
dist='normal',
|
|
verbose=True
|
|
)
|
|
|
|
# Step 2: Load MMAR forecast
|
|
print("\n" + "="*70)
|
|
print("[STEP 2] Loading MMAR forecast...")
|
|
print("-"*70)
|
|
|
|
mmar_path = Path(config.OUTPUT_DIR) / "step7_forecaster.pkl"
|
|
if not mmar_path.exists():
|
|
print(f"✗ MMAR forecast not found: {mmar_path}")
|
|
print(f" You must run Step 7 first: python run_step7.py")
|
|
exit(1)
|
|
|
|
with open(mmar_path, 'rb') as f:
|
|
mmar_forecaster = pickle.load(f)
|
|
|
|
mmar_forecast = mmar_forecaster.mean_forecast
|
|
|
|
print(f"✓ MMAR forecast loaded: {mmar_forecast:.10f}")
|
|
|
|
# Step 3: Compare with realized volatility
|
|
print("\n" + "="*70)
|
|
print("[STEP 3] Comparing with realized volatility...")
|
|
print("-"*70)
|
|
|
|
# Run forecast comparison to get realized volatility
|
|
try:
|
|
comparison = run_forecast_comparison(
|
|
start_date=None,
|
|
end_date=None,
|
|
days_ahead=None,
|
|
save_plots=False
|
|
)
|
|
|
|
realized_vol = comparison.realized_volatility
|
|
|
|
print(f"✓ Realized volatility: {realized_vol:.10f}")
|
|
|
|
# Step 4: Comparison table
|
|
print("\n" + "="*70)
|
|
print("FULL COMPARISON: MMAR vs GARCH vs REALIZED")
|
|
print("="*70)
|
|
|
|
# Prepare comparison data
|
|
comparison_data = []
|
|
|
|
# Add MMAR
|
|
mmar_error = abs(mmar_forecast - realized_vol)
|
|
mmar_pct_error = 100 * mmar_error / realized_vol
|
|
comparison_data.append({
|
|
'Model': 'MMAR',
|
|
'Forecast': mmar_forecast,
|
|
'Error': mmar_error,
|
|
'Error %': mmar_pct_error,
|
|
'AIC': np.nan,
|
|
'BIC': np.nan
|
|
})
|
|
|
|
# Add GARCH models
|
|
for model_type, result in garch_results.items():
|
|
if result is not None:
|
|
forecast = result['forecast_volatility']
|
|
error = abs(forecast - realized_vol)
|
|
pct_error = 100 * error / realized_vol
|
|
|
|
comparison_data.append({
|
|
'Model': model_type,
|
|
'Forecast': forecast,
|
|
'Error': error,
|
|
'Error %': pct_error,
|
|
'AIC': result['aic'],
|
|
'BIC': result['bic']
|
|
})
|
|
|
|
# Create DataFrame and sort by error
|
|
df = pd.DataFrame(comparison_data)
|
|
df = df.sort_values('Error %')
|
|
|
|
print(f"\n{'Model':<15} {'Forecast':<15} {'Error':<15} {'Error %':<10} {'AIC':<12} {'BIC':<12}")
|
|
print("-"*85)
|
|
|
|
for _, row in df.iterrows():
|
|
aic_str = f"{row['AIC']:>10.2f}" if not np.isnan(row['AIC']) else " N/A"
|
|
bic_str = f"{row['BIC']:>10.2f}" if not np.isnan(row['BIC']) else " N/A"
|
|
|
|
print(f"{row['Model']:<15} "
|
|
f"{row['Forecast']:.10f} "
|
|
f"{row['Error']:.10f} "
|
|
f"{row['Error %']:>7.2f}% "
|
|
f"{aic_str} "
|
|
f"{bic_str}")
|
|
|
|
print("-"*85)
|
|
print(f"{'REALIZED':<15} {realized_vol:.10f}")
|
|
print("="*85)
|
|
|
|
# Determine winner
|
|
best_model = df.iloc[0]['Model']
|
|
best_error = df.iloc[0]['Error %']
|
|
|
|
print(f"\nBEST MODEL: {best_model} (Error: {best_error:.2f}%)")
|
|
|
|
# MMAR vs GARCH
|
|
print(f"\n" + "="*70)
|
|
print("MMAR vs GARCH")
|
|
print("="*70)
|
|
|
|
mmar_row = df[df['Model'] == 'MMAR'].iloc[0]
|
|
garch_row = df[df['Model'] == 'GARCH'].iloc[0]
|
|
diff = mmar_row['Error %'] - garch_row['Error %']
|
|
|
|
if diff < 0:
|
|
print(f"\n MMAR is {abs(diff):.2f}% better")
|
|
else:
|
|
print(f"\n GARCH is {diff:.2f}% better")
|
|
|
|
# Save comparison results
|
|
results_path = Path(config.PLOT_DIR) / "mmar_vs_garch_comparison.csv"
|
|
df['Realized'] = realized_vol
|
|
df.to_csv(results_path, index=False)
|
|
print(f"\n✓ Comparison saved to: {results_path}")
|
|
|
|
except Exception as e:
|
|
print(f"\n✗ Error during comparison: {e}")
|
|
print(f"\nMake sure forecast period data is available in MT5")
|
|
|
|
print("\n" + "="*70 + "\n")
|