From e4d95afade9affb8ae832c157e74f6ea50de3b38 Mon Sep 17 00:00:00 2001 From: kenorb Date: Sat, 12 Aug 2023 01:24:57 +0100 Subject: [PATCH] Workaround for closing order conditions after orders are loaded from active pool (GH-705) --- EA.mqh | 15 ++++++++++++++- Strategy.mqh | 45 +++++++++++++++++++++++++++++++++++++++++++++ Trade.mqh | 4 ++-- 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/EA.mqh b/EA.mqh index 55b6f4130..63368f947 100644 --- a/EA.mqh +++ b/EA.mqh @@ -765,8 +765,21 @@ class EA { * Loads existing trades for the given strategy. */ bool StrategyLoadTrades(Strategy *_strat) { + bool _result = true; Trade *_trade = trade.GetByKey(_Symbol); - return _trade.OrdersLoadByMagic(_strat.Get(STRAT_PARAM_ID)); + // Load active trades. + _result &= _trade.OrdersLoadByMagic(_strat.Get(STRAT_PARAM_ID)); + // Load strategy-specific order parameters (e.g. conditions). + // This is a temporary workaround for GH-705. + // @todo: To move to Strategy class. + Ref _order; + for (DictStructIterator> iter = _trade.GetOrdersActive().Begin(); iter.IsValid(); ++iter) { + _order = iter.Value(); + if (_order.IsSet() && _order.Ptr().IsOpen()) { + _strat.OnOrderLoad(_order.Ptr()); + } + } + return _result; } /* Trade methods */ diff --git a/Strategy.mqh b/Strategy.mqh index 0e2e6c979..624ea4654 100644 --- a/Strategy.mqh +++ b/Strategy.mqh @@ -865,6 +865,51 @@ class Strategy : public Object { virtual void OnInit() { SetStops(GetPointer(this), GetPointer(this)); // trade.SetStrategy(&this); // @fixme + // Sets strategy's trade spread limit. + trade.Set(TRADE_PARAM_MAX_SPREAD, sparams.Get(STRAT_PARAM_MAX_SPREAD)); + // Load active trades. + if (Get(STRAT_PARAM_ID) > 0) { + trade.OrdersLoadByMagic(Get(STRAT_PARAM_ID)); + } + Ref _order; + for (DictStructIterator> iter = trade.GetOrdersActive().Begin(); iter.IsValid(); ++iter) { + _order = iter.Value(); + if (_order.IsSet() && _order.Ptr().IsOpen()) { + Strategy::OnOrderLoad(_order.Ptr()); + } + } + } + + /** + * Event on strategy's order load. + * + * @param + * _oparams Order parameters to update. + */ + virtual void OnOrderLoad(Order *_order) { + int _index = 0; + ENUM_TIMEFRAMES _stf = Get(STRAT_PARAM_TF); + unsigned int _stf_secs = ChartTf::TfToSeconds(_stf); + if (sparams.order_close_time != 0) { + long _close_time_arg = sparams.order_close_time > 0 ? sparams.order_close_time * 60 + : (int)round(-sparams.order_close_time * _stf_secs); + _order.Set(ORDER_PARAM_COND_CLOSE, ORDER_COND_LIFETIME_GT_ARG, _index); + _order.Set(ORDER_PARAM_COND_CLOSE_ARG_VALUE, _close_time_arg, _index); + _index++; + } + if (sparams.order_close_loss != 0.0f) { + float _loss_limit = sparams.order_close_loss; + _order.Set(ORDER_PARAM_COND_CLOSE, ORDER_COND_IN_LOSS, _index); + _order.Set(ORDER_PARAM_COND_CLOSE_ARG_VALUE, _loss_limit, _index); + _index++; + } + if (sparams.order_close_profit != 0.0f) { + float _profit_limit = sparams.order_close_profit; + _order.Set(ORDER_PARAM_COND_CLOSE, ORDER_COND_IN_PROFIT, _index); + _order.Set(ORDER_PARAM_COND_CLOSE_ARG_VALUE, _profit_limit, _index); + _index++; + } + _order.Set(ORDER_PARAM_UPDATE_FREQ, _stf_secs); } /** diff --git a/Trade.mqh b/Trade.mqh index 121347014..bdd048743 100644 --- a/Trade.mqh +++ b/Trade.mqh @@ -845,8 +845,8 @@ HistorySelect(0, TimeCurrent()); // Select history for access. OrderMoveToHistory(_order.Ptr()); order_last = _order; } else { - logger.AddLastError(__FUNCTION_LINE__, _order.Ptr().Get(ORDER_PROP_LAST_ERROR)); - return -1; + logger.AddLastError(__FUNCTION_LINE__, _order.Ptr().Get(ORDER_PROP_LAST_ERROR)); + continue; } } else { OrderMoveToHistory(_order.Ptr());