Finalize EA architecture before strategy development
This commit is contained in:
+46
-19
@@ -34,6 +34,12 @@ CPositionManager *g_position_manager = NULL;
|
||||
CTradeManager *g_trade_manager = NULL;
|
||||
CTrailingStop *g_trailing_stop = NULL;
|
||||
|
||||
// Diagnostics counters for blocked entries
|
||||
long g_blocked_existing_position = 0;
|
||||
long g_blocked_spread = 0;
|
||||
long g_blocked_hours = 0;
|
||||
long g_blocked_max_positions = 0;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
// EA Initialization
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -84,11 +90,13 @@ int OnInit()
|
||||
// Log configuration
|
||||
g_logger.Info(StringFormat("Magic Number: %d", g_magic_number));
|
||||
g_logger.Info(StringFormat("Symbol: %s", _Symbol));
|
||||
g_logger.Info(StringFormat("Timeframe: %s", EnumToString(PERIOD_CURRENT)));
|
||||
g_logger.Info(StringFormat("Chart Timeframe: %s", EnumToString(PERIOD_CURRENT)));
|
||||
g_logger.Info(StringFormat("Strategy Evaluation: %s on %s",
|
||||
g_evaluate_every_tick ? "Every tick" : (g_evaluate_on_new_bar ? "New bar" : "Every tick"),
|
||||
EnumToString(g_strategy_entry_timeframe)));
|
||||
g_logger.Info(StringFormat("Lot Mode: %s",
|
||||
g_lot_mode == LOT_MODE_FIXED ? "FIXED" : "RISK"));
|
||||
g_logger.Info(StringFormat("Stop Loss: %d points, Take Profit: %d points",
|
||||
g_stop_loss_points, g_take_profit_points));
|
||||
g_logger.Info("Initial SL/TP source: Strategy TradeSetup");
|
||||
g_logger.Info(StringFormat("Max Positions: %d, Max Spread: %d points",
|
||||
g_max_positions, g_max_spread_points));
|
||||
|
||||
@@ -177,65 +185,84 @@ void OnTick()
|
||||
// Step 2: Check spread - if spread is too wide, don't trade
|
||||
if(!g_risk_manager.IsSpreadAcceptable())
|
||||
{
|
||||
g_blocked_spread++;
|
||||
if(g_debug_mode)
|
||||
g_logger.Info(StringFormat("Blocked entry due to spread (count=%d)", g_blocked_spread));
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 3: Check trading hours
|
||||
if(!g_risk_manager.IsTradingHourValid())
|
||||
{
|
||||
g_blocked_hours++;
|
||||
if(g_debug_mode)
|
||||
g_logger.Info(StringFormat("Blocked entry due to trading hours (count=%d)", g_blocked_hours));
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 4: Manage existing positions (trailing stop, break-even)
|
||||
g_trailing_stop.UpdateAllPositions();
|
||||
|
||||
// Step 5: Only process signals on new bar
|
||||
if(!g_market_data.IsNewBar())
|
||||
// Step 5: Evaluate strategy on configured entry timeframe unless every-tick mode is enabled
|
||||
bool should_evaluate_strategy = true;
|
||||
if(!g_evaluate_every_tick && g_evaluate_on_new_bar)
|
||||
should_evaluate_strategy = g_market_data.IsNewBar(g_strategy_entry_timeframe);
|
||||
|
||||
if(!should_evaluate_strategy)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 6: Get trading signal from strategy
|
||||
E_SIGNAL signal = g_strategy.GetSignal();
|
||||
// Log diagnostics on each new entry bar
|
||||
if(g_strategy != NULL)
|
||||
g_strategy.LogDiagnostics();
|
||||
if(g_logger != NULL && g_debug_mode)
|
||||
g_logger.Info(StringFormat("Blocked totals: existing=%d spread=%d hours=%d maxpos=%d", g_blocked_existing_position, g_blocked_spread, g_blocked_hours, g_blocked_max_positions));
|
||||
|
||||
if(signal == SIGNAL_NONE)
|
||||
// Step 6: Get the trade setup from strategy
|
||||
TradeSetup setup = g_strategy.GetTradeSetup();
|
||||
|
||||
if(setup.signal == SIGNAL_NONE)
|
||||
{
|
||||
if(g_debug_mode && g_logger != NULL)
|
||||
g_logger.Info(StringFormat("No trade setup: %s", setup.reason));
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 7: Check if we already have a position
|
||||
if(g_position_manager.HasOpenPosition(_Symbol))
|
||||
{
|
||||
g_blocked_existing_position++;
|
||||
if(g_debug_mode)
|
||||
g_logger.Info("Already have open position, skipping entry");
|
||||
g_logger.Info(StringFormat("Already have open position, skipping entry (count=%d)", g_blocked_existing_position));
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 8: Check if new position is allowed
|
||||
if(!g_position_manager.IsNewPositionAllowed(_Symbol))
|
||||
{
|
||||
g_logger.Warning("New position not allowed (max positions reached)");
|
||||
g_blocked_max_positions++;
|
||||
g_logger.Warning(StringFormat("New position not allowed (max positions reached) (count=%d)", g_blocked_max_positions));
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 9: Calculate lot size
|
||||
double lot = g_risk_manager.CalculateLotSize(g_stop_loss_points);
|
||||
if(lot <= 0)
|
||||
double lot = 0.0;
|
||||
if(!g_risk_manager.ValidateTradeSetup(setup, lot))
|
||||
{
|
||||
g_logger.Error("Invalid lot size calculated");
|
||||
if(g_logger)
|
||||
g_logger.Warning(StringFormat("Trade setup rejected: %s", setup.reason));
|
||||
return;
|
||||
}
|
||||
|
||||
// Step 10: Execute trade based on signal
|
||||
bool trade_success = false;
|
||||
|
||||
if(signal == SIGNAL_BUY)
|
||||
if(setup.signal == SIGNAL_BUY)
|
||||
{
|
||||
trade_success = g_trade_manager.OpenBuyTrade(_Symbol, lot);
|
||||
trade_success = g_trade_manager.OpenBuyTrade(_Symbol, lot, setup.stopLoss, setup.takeProfit, setup.entryPrice);
|
||||
}
|
||||
else if(signal == SIGNAL_SELL)
|
||||
else if(setup.signal == SIGNAL_SELL)
|
||||
{
|
||||
trade_success = g_trade_manager.OpenSellTrade(_Symbol, lot);
|
||||
trade_success = g_trade_manager.OpenSellTrade(_Symbol, lot, setup.stopLoss, setup.takeProfit, setup.entryPrice);
|
||||
}
|
||||
|
||||
if(trade_success)
|
||||
|
||||
Reference in New Issue
Block a user