Files
zhutoutoutousan 98a87a69ca Update
2026-02-13 08:03:25 +01:00

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()