From 2ea1a7e2346c7627e130d5b8a86e0680aff8c4f9 Mon Sep 17 00:00:00 2001 From: kenorb Date: Sun, 7 Nov 2021 20:22:58 +0000 Subject: [PATCH] EA/Trade: Improves handling of errors on 'not enough money' error --- EA.mqh | 22 ++++++++++++---------- Trade.mqh | 22 +++++++++++++--------- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/EA.mqh b/EA.mqh index 83d81c2a6..1877ac534 100644 --- a/EA.mqh +++ b/EA.mqh @@ -294,6 +294,8 @@ class EA { _strat.OnOrderClose(ORDER_TYPE_SELL); } } + _trade_allowed &= _trade.IsTradeAllowed(); + _trade_allowed &= !_strat.IsSuspended(); if (_trade_allowed) { float _sig_open = _signal.GetSignalOpen(); unsigned int _sig_f = eparams.Get(STRUCT_ENUM(EAParams, EA_PARAM_PROP_SIGNAL_FILTER)); @@ -329,13 +331,13 @@ class EA { _signal.Set(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_FLAG_PROCESSED), true); } else { _last_error = GetLastError(); - switch (_last_error) { - case ERR_NOT_ENOUGH_MEMORY: - logger.Error(StringFormat("Not enough money to open trades! Code: %d", _last_error), __FUNCTION_LINE__, - _strat.GetName()); - logger.Warning(StringFormat("Suspending strategy.", _last_error), __FUNCTION_LINE__, _strat.GetName()); - _strat.Suspended(true); - break; + if (_last_error > 0) { + logger.Warning(StringFormat("Error: %d", _last_error), __FUNCTION_LINE__, _strat.GetName()); + ResetLastError(); + } + if (_trade.Get(TRADE_STATE_MONEY_NOT_ENOUGH)) { + logger.Warning(StringFormat("Suspending strategy.", _last_error), __FUNCTION_LINE__, _strat.GetName()); + _strat.Suspended(true); } } } @@ -403,9 +405,9 @@ class EA { eresults.stg_processed_periods++; } if (_strat.TickFilter(_tick)) { - _can_trade &= _can_trade && !_strat.IsSuspended(); - _can_trade &= _can_trade && !_strat.CheckCondition(STRAT_COND_TRADE_COND, TRADE_COND_HAS_STATE, - TRADE_STATE_TRADE_CANNOT); + _can_trade &= !_strat.IsSuspended(); + _can_trade &= + !_strat.CheckCondition(STRAT_COND_TRADE_COND, TRADE_COND_HAS_STATE, TRADE_STATE_TRADE_CANNOT); TradeSignalEntry _sentry = GetStrategySignalEntry(_strat, _can_trade, _strat.Get(STRAT_PARAM_SHIFT)); if (_sentry.Get(STRUCT_ENUM(TradeSignalEntry, TRADE_SIGNAL_PROP_SIGNALS)) > 0) { TradeSignal _signal(_sentry); diff --git a/Trade.mqh b/Trade.mqh index 7d7cc3ea4..254f6bbff 100644 --- a/Trade.mqh +++ b/Trade.mqh @@ -641,7 +641,7 @@ HistorySelect(0, TimeCurrent()); // Select history for access. StringFormat("Code: %d, Msg: %s", _last_error, Terminal::GetErrorText(_last_error))); tstats.Add(TRADE_STAT_ORDERS_ERRORS); // Pass-through. - case ERR_NO_ERROR: + case ERR_NO_ERROR: // 0 orders_active.Set(_order.Get(ORDER_PROP_TICKET), _ref_order); order_last = _order; tstates.AddState(TRADE_STATE_ORDERS_ACTIVE); @@ -649,9 +649,15 @@ HistorySelect(0, TimeCurrent()); // Select history for access. // Trigger: OnOrder(); _result = true; break; - case TRADE_RETCODE_INVALID: - logger.Error("Cannot process order!", __FUNCTION_LINE__, - StringFormat("Code: %d, Msg: %s", _last_error, Terminal::GetErrorText(_last_error))); + case TRADE_RETCODE_INVALID: // 10013 + logger.Error("Cannot process order!", __FUNCTION_LINE__, StringFormat("Code: %d", _last_error)); + _result = false; + break; + case TRADE_RETCODE_NO_MONEY: // 10019 + logger.Error("Not enough money to complete the request!", __FUNCTION_LINE__, + StringFormat("Code: %d", _last_error)); + tstates.AddState(TRADE_STATE_MONEY_NOT_ENOUGH); + _result = false; break; default: logger.Error("Cannot add order!", __FUNCTION_LINE__, @@ -660,7 +666,7 @@ HistorySelect(0, TimeCurrent()); // Select history for access. _result = false; break; } - UpdateStates(true); + UpdateStates(_result); return _result; } @@ -1337,11 +1343,10 @@ HistorySelect(0, TimeCurrent()); // Select history for access. * Returns true on no errors. * */ - bool UpdateStates(bool _force = false) { + void UpdateStates(bool _force = false) { static datetime _last_check = 0; - static unsigned int _states_prev = tstates.GetStates(); - ResetLastError(); if (_force || _last_check + 60 < TimeCurrent()) { + static unsigned int _states_prev = tstates.GetStates(); // Infrequent checks (each minute). /* Limit checks */ tstates.SetState(TRADE_STATE_PERIOD_LIMIT_REACHED, tparams.IsLimitGe(tstats)); @@ -1390,7 +1395,6 @@ HistorySelect(0, TimeCurrent()); // Select history for access. _states_prev = tstates.GetStates(); } } - return GetLastError() == ERR_NO_ERROR; } /* Normalization methods */