177 lines
6.7 KiB
Python
177 lines
6.7 KiB
Python
"""
|
|
Debug ONNX Model Predictions
|
|
|
|
This script helps debug why the model isn't generating trades.
|
|
It shows actual predictions and checks if they meet trading criteria.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
from datetime import datetime, timedelta
|
|
import MetaTrader5 as mt5
|
|
import numpy as np
|
|
import pandas as pd
|
|
import onnxruntime as ort
|
|
import pickle
|
|
|
|
# Add paths
|
|
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
backtest_dir = os.path.join(os.path.dirname(current_dir), 'backtesting', 'MT5')
|
|
sys.path.insert(0, backtest_dir)
|
|
|
|
from backtest_engine import BacktestEngine
|
|
from onnx_backtest_strategy import ONNXBacktestStrategy
|
|
|
|
|
|
def main():
|
|
"""Debug ONNX predictions."""
|
|
print("="*60)
|
|
print("ONNX Model Prediction Debug")
|
|
print("="*60)
|
|
|
|
# Configuration
|
|
symbol = 'XAUUSD'
|
|
timeframe = mt5.TIMEFRAME_H1
|
|
model_path = 'models/XAUUSD_H1_model.onnx'
|
|
scaler_path = 'models/XAUUSD_H1_scaler.pkl'
|
|
|
|
if not os.path.exists(model_path):
|
|
print(f"ERROR: Model not found: {model_path}")
|
|
return
|
|
|
|
# Initialize MT5
|
|
if not mt5.initialize():
|
|
print("ERROR: Failed to initialize MT5")
|
|
return
|
|
|
|
try:
|
|
# Load model and scaler
|
|
session = ort.InferenceSession(model_path)
|
|
input_name = session.get_inputs()[0].name
|
|
output_name = session.get_outputs()[0].name
|
|
|
|
with open(scaler_path, 'rb') as f:
|
|
scaler = pickle.load(f)
|
|
|
|
# Get recent data
|
|
end_date = datetime.now()
|
|
start_date = end_date - timedelta(days=10)
|
|
|
|
rates = mt5.copy_rates_range(symbol, timeframe, start_date, end_date)
|
|
if rates is None or len(rates) == 0:
|
|
print("ERROR: No data available")
|
|
return
|
|
|
|
df = pd.DataFrame(rates)
|
|
df['time'] = pd.to_datetime(df['time'], unit='s')
|
|
|
|
print(f"\nLoaded {len(df)} bars")
|
|
print(f"Date range: {df['time'].min()} to {df['time'].max()}")
|
|
|
|
# Create strategy to get features
|
|
strategy = ONNXBacktestStrategy(
|
|
symbol=symbol,
|
|
timeframe=timeframe,
|
|
model_path=model_path,
|
|
scaler_path=scaler_path,
|
|
initial_balance=10000.0,
|
|
prediction_threshold=0.0001,
|
|
min_confidence=0.3,
|
|
lot_size=0.1,
|
|
stop_loss_pips=50,
|
|
take_profit_pips=100
|
|
)
|
|
|
|
# Simulate a few bars
|
|
print("\n" + "="*60)
|
|
print("Predictions Analysis")
|
|
print("="*60)
|
|
|
|
predictions_data = []
|
|
|
|
for i in range(60, min(100, len(df))): # Start from bar 60 (need lookback)
|
|
bar = df.iloc[i]
|
|
bar_time = bar['time'] if isinstance(bar['time'], datetime) else datetime.fromtimestamp(bar['time'])
|
|
current_price = bar['close']
|
|
|
|
# Build historical buffer
|
|
bar_data = {
|
|
'time': bar_time,
|
|
'open': float(bar['open']),
|
|
'high': float(bar['high']),
|
|
'low': float(bar['low']),
|
|
'close': float(bar['close']),
|
|
'tick_volume': int(bar['tick_volume']),
|
|
'rsi': 50.0, # Simplified
|
|
'ema': current_price, # Simplified
|
|
'atr': 0.0 # Simplified
|
|
}
|
|
|
|
strategy.historical_bars.append(bar_data)
|
|
|
|
if len(strategy.historical_bars) >= strategy.lookback:
|
|
# Get prediction
|
|
features = strategy.prepare_features()
|
|
if features is not None:
|
|
input_data = features.astype(np.float32)
|
|
outputs = session.run([output_name], {input_name: input_data})
|
|
predicted_price = float(outputs[0][0][0])
|
|
|
|
# Calculate metrics
|
|
price_change = predicted_price - current_price
|
|
price_change_pct = (price_change / current_price) if current_price > 0 else 0.0
|
|
confidence = min(abs(price_change_pct) / 0.01, 1.0)
|
|
|
|
predictions_data.append({
|
|
'time': bar_time,
|
|
'current_price': current_price,
|
|
'predicted_price': predicted_price,
|
|
'price_change': price_change,
|
|
'price_change_pct': price_change_pct * 100,
|
|
'confidence': confidence,
|
|
'meets_threshold': abs(price_change_pct) >= 0.0001,
|
|
'meets_confidence': confidence >= 0.3,
|
|
'would_trade': abs(price_change_pct) >= 0.0001 and confidence >= 0.3
|
|
})
|
|
|
|
# Display results
|
|
if predictions_data:
|
|
pred_df = pd.DataFrame(predictions_data)
|
|
print(f"\nAnalyzed {len(pred_df)} predictions")
|
|
print(f"\nPrediction Statistics:")
|
|
print(f" Mean price change: {pred_df['price_change_pct'].mean():.4f}%")
|
|
print(f" Std price change: {pred_df['price_change_pct'].std():.4f}%")
|
|
print(f" Min price change: {pred_df['price_change_pct'].min():.4f}%")
|
|
print(f" Max price change: {pred_df['price_change_pct'].max():.4f}%")
|
|
print(f"\n Mean confidence: {pred_df['confidence'].mean():.4f}")
|
|
print(f" Predictions meeting threshold: {pred_df['meets_threshold'].sum()}/{len(pred_df)}")
|
|
print(f" Predictions meeting confidence: {pred_df['meets_confidence'].sum()}/{len(pred_df)}")
|
|
print(f" Predictions that would trade: {pred_df['would_trade'].sum()}/{len(pred_df)}")
|
|
|
|
print(f"\nSample predictions (first 10):")
|
|
print(pred_df[['time', 'current_price', 'predicted_price', 'price_change_pct', 'confidence', 'would_trade']].head(10).to_string(index=False))
|
|
|
|
if pred_df['would_trade'].sum() == 0:
|
|
print("\n" + "="*60)
|
|
print("RECOMMENDATIONS:")
|
|
print("="*60)
|
|
print("No trades would be generated. Try:")
|
|
print(f" 1. Lower prediction_threshold (current: 0.0001)")
|
|
print(f" Suggested: {pred_df['price_change_pct'].abs().quantile(0.1):.6f}")
|
|
print(f" 2. Lower min_confidence (current: 0.3)")
|
|
print(f" Suggested: {pred_df['confidence'].quantile(0.1):.2f}")
|
|
print(f" 3. Check if model predictions are reasonable")
|
|
else:
|
|
print("No predictions generated (need more historical data)")
|
|
|
|
except Exception as e:
|
|
print(f"\nERROR: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
finally:
|
|
mt5.shutdown()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|