220 lines
10 KiB
Python
220 lines
10 KiB
Python
"""
|
|
Debug ONNX Strategy - Find out why no trades are generated
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
from datetime import datetime, timedelta
|
|
import MetaTrader5 as mt5
|
|
|
|
# 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 strategy to find why no trades."""
|
|
print("="*60)
|
|
print("Debugging ONNX Strategy - Why No Trades?")
|
|
print("="*60)
|
|
|
|
symbol = 'XAUUSD'
|
|
timeframe = mt5.TIMEFRAME_H1
|
|
model_path = 'models/XAUUSD_H1_model.onnx'
|
|
scaler_path = 'models/XAUUSD_H1_scaler.pkl'
|
|
initial_balance = 10000.0
|
|
|
|
if not os.path.exists(model_path):
|
|
print(f"ERROR: Model not found: {model_path}")
|
|
return
|
|
|
|
end_date = datetime.now()
|
|
start_date = end_date - timedelta(days=30) # Shorter period for debugging
|
|
|
|
print(f"\nModel: {model_path}")
|
|
print(f"Date Range: {start_date.date()} to {end_date.date()}")
|
|
print(f"Parameters:")
|
|
print(f" Prediction Threshold: 0.00005 (0.005%)")
|
|
print(f" Min Confidence: 0.1 (10%)")
|
|
print("\n")
|
|
|
|
if not mt5.initialize():
|
|
print("ERROR: Failed to initialize MT5")
|
|
return
|
|
|
|
try:
|
|
# Create strategy with debug enabled
|
|
strategy = ONNXBacktestStrategy(
|
|
symbol=symbol,
|
|
timeframe=timeframe,
|
|
model_path=model_path,
|
|
scaler_path=scaler_path,
|
|
initial_balance=initial_balance,
|
|
prediction_threshold=0.00005,
|
|
min_confidence=0.1,
|
|
lot_size=0.1,
|
|
stop_loss_pips=50,
|
|
take_profit_pips=100
|
|
)
|
|
|
|
# Override on_bar to add detailed debugging
|
|
original_on_bar = strategy.on_bar
|
|
|
|
def debug_on_bar(bar_data):
|
|
"""Debug version of on_bar."""
|
|
# Add current bar to historical buffer
|
|
strategy.historical_bars.append(bar_data.copy())
|
|
|
|
# Keep only necessary history
|
|
if len(strategy.historical_bars) > strategy.lookback + 50:
|
|
strategy.historical_bars = strategy.historical_bars[-(strategy.lookback + 50):]
|
|
|
|
# Check if we have enough data
|
|
if len(strategy.historical_bars) < strategy.lookback:
|
|
if len(strategy.historical_bars) % 20 == 0:
|
|
print(f" [Bar {len(strategy.historical_bars)}] Not enough data yet (need {strategy.lookback})")
|
|
return
|
|
|
|
current_price = bar_data['close']
|
|
|
|
# Check existing position
|
|
if strategy.position is not None:
|
|
strategy.check_stop_loss_take_profit(current_price)
|
|
return
|
|
|
|
# Make prediction
|
|
try:
|
|
predicted_change_pct = strategy.predict_price()
|
|
if predicted_change_pct is None:
|
|
if len(strategy.historical_bars) % 10 == 0:
|
|
print(f" [Bar {len(strategy.historical_bars)}] Prediction returned None - checking why...")
|
|
# Try to debug why prediction is None
|
|
features = strategy.prepare_features()
|
|
if features is None:
|
|
print(f" -> Features preparation returned None")
|
|
else:
|
|
print(f" -> Features shape: {features.shape}")
|
|
return
|
|
except Exception as e:
|
|
print(f" [Bar {len(strategy.historical_bars)}] Prediction exception: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
return
|
|
|
|
# Process prediction
|
|
if abs(predicted_change_pct) < 1.0:
|
|
price_change_pct = predicted_change_pct
|
|
else:
|
|
predicted_price = predicted_change_pct
|
|
if predicted_price <= 0 or predicted_price > 10000:
|
|
if len(strategy.historical_bars) % 50 == 0:
|
|
print(f" [Bar {len(strategy.historical_bars)}] Invalid prediction: {predicted_price}")
|
|
return
|
|
price_change = predicted_price - current_price
|
|
price_change_pct = (price_change / current_price) if current_price > 0 else 0.0
|
|
|
|
# Calculate confidence
|
|
if abs(price_change_pct) < 1.0:
|
|
confidence = min(abs(price_change_pct) / 0.01, 1.0)
|
|
else:
|
|
confidence = min(abs(price_change_pct) / 1.0, 1.0)
|
|
|
|
# Debug output for every 10th bar
|
|
if len(strategy.historical_bars) % 10 == 0:
|
|
print(f"\n [Bar {len(strategy.historical_bars)}]")
|
|
print(f" Current Price: {current_price:.2f}")
|
|
print(f" Raw Prediction: {predicted_change_pct:.6f}")
|
|
print(f" Price Change %: {price_change_pct*100:.4f}%")
|
|
print(f" Abs Change: {abs(price_change_pct):.6f}")
|
|
print(f" Threshold: {strategy.prediction_threshold:.6f}")
|
|
print(f" Confidence: {confidence:.3f}")
|
|
print(f" Min Confidence: {strategy.min_confidence:.2f}")
|
|
print(f" Threshold Check: {abs(price_change_pct) >= strategy.prediction_threshold} (need True)")
|
|
print(f" Confidence Check: {confidence >= strategy.min_confidence} (need True)")
|
|
|
|
if abs(price_change_pct) >= strategy.prediction_threshold and confidence >= strategy.min_confidence:
|
|
print(f" -> WOULD TRADE! Direction: {'BUY' if price_change_pct > 0 else 'SELL'}")
|
|
else:
|
|
if abs(price_change_pct) < strategy.prediction_threshold:
|
|
print(f" -> BLOCKED: Abs change {abs(price_change_pct):.6f} < threshold {strategy.prediction_threshold:.6f}")
|
|
if confidence < strategy.min_confidence:
|
|
print(f" -> BLOCKED: Confidence {confidence:.3f} < min {strategy.min_confidence:.2f}")
|
|
|
|
# Check if we should trade
|
|
if confidence < strategy.min_confidence:
|
|
return
|
|
|
|
if abs(price_change_pct) < strategy.prediction_threshold:
|
|
return
|
|
|
|
# Open position based on prediction
|
|
if price_change_pct > strategy.prediction_threshold:
|
|
# Bullish prediction
|
|
sl = current_price - (strategy.stop_loss_pips / 10000) if strategy.stop_loss_pips > 0 else None
|
|
tp = current_price + (strategy.take_profit_pips / 10000) if strategy.take_profit_pips > 0 else None
|
|
print(f"\n *** ATTEMPTING BUY POSITION at bar {len(strategy.historical_bars)} ***")
|
|
print(f" Price: {current_price:.2f}, Predicted Change: {price_change_pct*100:.4f}%")
|
|
print(f" SL: {sl:.2f}, TP: {tp:.2f}, Volume: {strategy.lot_size}")
|
|
print(f" Equity: {strategy.equity:.2f}, Current Position: {strategy.position}")
|
|
# Check margin requirement manually
|
|
contract_size = 100000
|
|
margin_required = strategy.lot_size * contract_size * current_price * 0.01
|
|
print(f" Margin Required: {margin_required:.2f}, Available: {strategy.equity * 0.9:.2f}")
|
|
result = strategy.open_position('BUY', strategy.lot_size, current_price, sl, tp, 'ONNX Buy')
|
|
print(f" Open Position Result: {result}")
|
|
if result:
|
|
print(f" -> Position opened! New position: {strategy.position}")
|
|
else:
|
|
if strategy.position is not None:
|
|
print(f" -> Position NOT opened! Reason: Already have position")
|
|
else:
|
|
print(f" -> Position NOT opened! Reason: Margin insufficient or other validation failed")
|
|
elif price_change_pct < -strategy.prediction_threshold:
|
|
# Bearish prediction
|
|
sl = current_price + (strategy.stop_loss_pips / 10000) if strategy.stop_loss_pips > 0 else None
|
|
tp = current_price - (strategy.take_profit_pips / 10000) if strategy.take_profit_pips > 0 else None
|
|
print(f"\n *** ATTEMPTING SELL POSITION at bar {len(strategy.historical_bars)} ***")
|
|
print(f" Price: {current_price:.2f}, Predicted Change: {price_change_pct*100:.4f}%")
|
|
print(f" SL: {sl:.2f}, TP: {tp:.2f}, Volume: {strategy.lot_size}")
|
|
print(f" Equity: {strategy.equity:.2f}, Current Position: {strategy.position}")
|
|
# Check margin requirement manually
|
|
contract_size = 100000
|
|
margin_required = strategy.lot_size * contract_size * current_price * 0.01
|
|
print(f" Margin Required: {margin_required:.2f}, Available: {strategy.equity * 0.9:.2f}")
|
|
result = strategy.open_position('SELL', strategy.lot_size, current_price, sl, tp, 'ONNX Sell')
|
|
print(f" Open Position Result: {result}")
|
|
if result:
|
|
print(f" -> Position opened! New position: {strategy.position}")
|
|
else:
|
|
if strategy.position is not None:
|
|
print(f" -> Position NOT opened! Reason: Already have position")
|
|
else:
|
|
print(f" -> Position NOT opened! Reason: Margin insufficient or other validation failed")
|
|
|
|
strategy.on_bar = debug_on_bar
|
|
|
|
print("Running backtest with detailed debugging...\n")
|
|
engine = BacktestEngine(strategy, start_date, end_date)
|
|
results = engine.run()
|
|
|
|
print("\n" + "="*60)
|
|
print("Backtest Complete")
|
|
print("="*60)
|
|
print(f"Total Trades: {len(strategy.closed_trades)}")
|
|
print(f"Open Positions: {1 if strategy.position else 0}")
|
|
|
|
except Exception as e:
|
|
print(f"\nERROR: {e}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
finally:
|
|
mt5.shutdown()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|