I am backtesting my algo on MT5 Version 5.00 Build 4153 22 Jan 24 on OSX Sonoma 14.3 M1 Max (10 Cores) 64 GB Ram.
When I do it uses a lot of memory and even runs out of application memory space.
I am only using 1 core in this example because when I use more than 1 agent it runs out of space quicker.
I get no errors in Journal when running locally, I just run out of memory with the above errors:
When I run an optimisation with 7896 steps using MQL Cloud Network I get the following errors:
I tried to detect an issue with: `checkForMemLeak.mqh` but nothing was found. Each time I create a new Object I am deleting the object. I create all my arrays with a fixed size, and I a believe I only initialise my indicators once and I release my indicator handles via the destructor.
The 65 critical errors are just reporting: ` error "critical runtime error 505 in global initialization function (out of memory)"` below error might a symptom of running out of memory and maybe not the cause but I can't be sure. I can't seem to find this file: Trend.mqh in MT5 to view it. I can see it referenced here (which is not mine) and line 370 is: ` ((CIndicatorBuffer*)At(1)).Offset(ma_shift);`
Function From ` Trend.mqh`
- How can I see what is using all this memory?
- Is it just the candles/tick data being read from disk? Still seems excessive. If so is there a more efficient way to handle this data? only read chunks of it at a time?
The algo is pretty large so not easy to upload.. here is the some code from it:
The entry logic is where the Indicators are initialised:
Hoping someone can point me in the right direction to try find what is using all the memory?
TERMINAL_MEMORY_PHYSICAL | Physical memory in the system, MB | int |
TERMINAL_MEMORY_TOTAL | Memory available to the process of the terminal (agent), MB | int |
TERMINAL_MEMORY_AVAILABLE | Free memory of the terminal (agent) process, MB | int |
TERMINAL_MEMORY_USED | Memory used by the terminal (agent), MB | int |
I think it has something to do we how I am managing orders, the Used Memory: 412 MB seems to be growing after I create positions
2024.02.12 20:49:09.498 2024.02.09 10:00:00 Physical Memory: 71680 MB 2024.02.12 20:49:09.498 2024.02.09 10:00:00 Total Memory Available to Process: 143360 MB 2024.02.12 20:49:09.498 2024.02.09 10:00:00 Available Memory: 142948 MB 2024.02.12 20:49:09.498 2024.02.09 10:00:00 Used Memory: 412 MB 2024.02.12 20:49:09.502 2024.02.09 10:05:00 Physical Memory: 71680 MB 2024.02.12 20:49:09.502 2024.02.09 10:05:00 Total Memory Available to Process: 143360 MB 2024.02.12 20:49:09.502 2024.02.09 10:05:00 Available Memory: 142948 MB 2024.02.12 20:49:09.502 2024.02.09 10:05:00 Used Memory: 412 MB 2024.02.12 20:49:09.508 2024.02.09 10:10:00 Physical Memory: 71680 MB 2024.02.12 20:49:09.509 2024.02.09 10:10:00 Total Memory Available to Process: 143360 MB 2024.02.12 20:49:09.509 2024.02.09 10:10:00 Available Memory: 142948 MB 2024.02.12 20:49:09.509 2024.02.09 10:10:00 Used Memory: 412 MB ... 2024.02.12 20:49:09.517 2024.02.09 10:20:00 Physical Memory: 71680 MB 2024.02.12 20:49:09.517 2024.02.09 10:20:00 Total Memory Available to Process: 143360 MB 2024.02.12 20:49:09.517 2024.02.09 10:20:00 Available Memory: 142948 MB 2024.02.12 20:49:09.517 2024.02.09 10:20:00 Used Memory: 412 MB 2024.02.12 20:49:09.519 2024.02.09 10:20:00 Placing order: Symbol = EURUSD.i, Volume = 0.79, Price = 1.07729, SL = 1.07792, TP = 1.07527 2024.02.12 20:49:09.521 2024.02.09 10:20:00 sell stop 0.79 EURUSD.i at 1.07729 sl: 1.07792 tp: 1.07527 (1.07761 / 1.07762 / 1.07761) 2024.02.12 20:49:09.523 2024.02.09 10:20:00 Sell Stop Order Order placed successfully, Ticket: 2 2024.02.12 20:49:09.531 2024.02.09 10:25:00 Physical Memory: 71680 MB 2024.02.12 20:49:09.531 2024.02.09 10:25:00 Total Memory Available to Process: 143360 MB 2024.02.12 20:49:09.531 2024.02.09 10:25:00 Available Memory: 142930 MB 2024.02.12 20:49:09.531 2024.02.09 10:25:00 Used Memory: 430 MB ... 2024.02.12 20:49:09.551 2024.02.09 10:45:00 Physical Memory: 71680 MB 2024.02.12 20:49:09.551 2024.02.09 10:45:00 Total Memory Available to Process: 143360 MB 2024.02.12 20:49:09.551 2024.02.09 10:45:00 Available Memory: 142930 MB 2024.02.12 20:49:09.551 2024.02.09 10:45:00 Used Memory: 430 MB 2024.02.12 20:49:09.551 2024.02.09 10:49:03 order [#2 sell stop 0.79 EURUSD.i at 1.07729] triggered 2024.02.12 20:49:09.552 2024.02.09 10:49:03 deal #2 sell 0.79 EURUSD.i at 1.07729 done (based on order #2) 2024.02.12 20:49:09.552 2024.02.09 10:49:03 deal performed [#2 sell 0.79 EURUSD.i at 1.07729] 2024.02.12 20:49:09.552 2024.02.09 10:49:03 order performed sell 0.79 at 1.07729 [#2 sell stop 0.79 EURUSD.i at 1.07729] 2024.02.12 20:49:09.555 2024.02.09 10:49:03 Alert: OnTradeTransaction() DEAL_TYPE: 1 2024.02.12 20:49:09.555 2024.02.09 10:49:03 New Short Position executed. Total Short Trades: 1 2024.02.12 20:49:09.562 2024.02.09 10:50:00 Physical Memory: 71680 MB 2024.02.12 20:49:09.562 2024.02.09 10:50:00 Total Memory Available to Process: 143360 MB 2024.02.12 20:49:09.562 2024.02.09 10:50:00 Available Memory: 142912 MB 2024.02.12 20:49:09.562 2024.02.09 10:50:00 Used Memory: 448 MB ... 2024.02.12 20:49:09.948 2024.02.09 15:31:05 stop loss triggered #2 sell 0.79 EURUSD.i 1.07729 sl: 1.07792 tp: 1.07527 [#3 buy 0.79 EURUSD.i at 1.07792] 2024.02.12 20:49:09.949 2024.02.09 15:31:05 deal #3 buy 0.79 EURUSD.i at 1.07793 done (based on order #3) 2024.02.12 20:49:09.949 2024.02.09 15:31:05 deal performed [#3 buy 0.79 EURUSD.i at 1.07793] 2024.02.12 20:49:09.949 2024.02.09 15:31:05 order performed buy 0.79 at 1.07793 [#3 buy 0.79 EURUSD.i at 1.07792] 2024.02.12 20:49:09.949 2024.02.09 15:31:05 Alert: OnTradeTransaction() DEAL_TYPE: 0 2024.02.12 20:49:09.949 2024.02.09 15:31:05 Alert: Stop Loss activation 2024.02.12 20:49:09.949 2024.02.09 15:31:05 Alert: BUY: Stop Loss activation 2024.02.12 20:49:09.957 2024.02.09 15:35:00 Physical Memory: 71680 MB 2024.02.12 20:49:09.957 2024.02.09 15:35:00 Total Memory Available to Process: 143360 MB 2024.02.12 20:49:09.957 2024.02.09 15:35:00 Available Memory: 142912 MB 2024.02.12 20:49:09.957 2024.02.09 15:35:00 Used Memory: 448 MB
ulong OrderTicket; trade.PlaceSellStopOrder(_Symbol, RoundToDigits(positionSize,2), entryPrice, stopLossPrice, takeProfitPrice,OrderTicket);
// Utility function to place a sell stop order and capture order placement information void PlaceSellStopOrder(string symbol, double volume, double price, double sl, double tp, ulong &orderTicket) { string comment = "Sell Stop Order"; ENUM_ORDER_TYPE orderType = ORDER_TYPE_SELL_STOP; if (!AreTradingConditionsValid(symbol, price, false)) { Print("Trading conditions are not valid for placing a sell stop order."); comment = "Sell Limit Order, Instead of Stop"; orderType = ORDER_TYPE_SELL_LIMIT; //return; } MqlTradeRequest request = {}; MqlTradeResult result = {}; Print("Placing order: Symbol = ", symbol, ", Volume = ", volume, ", Price = ", price, ", SL = ", sl, ", TP = ", tp); request.action = TRADE_ACTION_PENDING; // Pending order request.symbol = symbol; // Trading symbol request.volume = volume; // Volume in lots request.type = orderType; // Order type request.price = price; // Price at which to sell request.sl = sl; // Stop loss request.tp = tp; // Take profit request.deviation = 10; // Deviation in points request.magic = 0; // Magic number request.comment = comment; // Comment int attempts = 3; // Number of attempts to send the order bool orderPlaced = false; for (int i = 0; i < attempts && !orderPlaced; i++) { if (OrderSend(request, result)) { orderPlaced = true; orderTicket = result.order; Print(comment," Order placed successfully, Ticket: ", result.order); datetime startTime = TimeCurrent(); // Start time (current time) datetime endTime = TimeCurrent() + PeriodSeconds(PERIOD_M5) * 3; // End time (3 bars ahead) string objectName = "EntryPriceLine" + StringFormat("%d", TimeCurrent()); // ObjectCreate(0, objectName, OBJ_TREND, 0, startTime, price, endTime, price); // ObjectSetInteger(0, objectName, OBJPROP_COLOR, clrRed); // Set color to red (optional) //return true; } else { Print("Attempt ", i + 1, " failed to place Sell Stop Order, Error code: ", GetLastError()); Sleep(1000); // Wait for 1 second before retrying } } if (!orderPlaced) { Print("Failed to place Sell Stop Order after ", attempts, " attempts."); //return false; } }
bool AreTradingConditionsValid(string symbol, double price, bool isBuyOrder) { double currentPrice = isBuyOrder ? SymbolInfoDouble(symbol, SYMBOL_ASK) : SymbolInfoDouble(symbol, SYMBOL_BID); // For a buy stop order, the entry price should be above the current ask price if (isBuyOrder && price <= currentPrice) { Print("Current ask price: ", currentPrice, " is too low for a buy stop order. Entry price: ", price); return false; } // For a sell stop order, the entry price should be below the current bid price if (!isBuyOrder && price >= currentPrice) { Print("Current bid price: ", currentPrice, " is too high for a sell stop order. Entry price: ", price); return false; } // Additional checks can be added here (e.g., market hours, symbol trade status) return true; }
This is where I manage some of the order events:
void OnTradeTransaction(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result) { //--- get transaction type as enumeration value ENUM_TRADE_TRANSACTION_TYPE type=trans.type; //--- if transaction is result of addition of the transaction in history if(type==TRADE_TRANSACTION_DEAL_ADD) { if(HistoryDealSelect(trans.deal)) m_deal.Ticket(trans.deal); else { Print(__FILE__," ",__FUNCTION__,", ERROR: HistoryDealSelect(",trans.deal,")"); return; } //--- long reason=-1; if(!m_deal.InfoInteger(DEAL_REASON,reason)) { Print(__FILE__," ",__FUNCTION__,", ERROR: InfoInteger(DEAL_REASON,reason)"); return; } ENUM_DEAL_TYPE dt = m_deal.DealType(); // Directly use DealType() method Alert("OnTradeTransaction() DEAL_TYPE: ", dt); if((ENUM_DEAL_REASON)reason==DEAL_REASON_SL) { Alert("Stop Loss activation"); if(dt == DEAL_TYPE_BUY) { Alert("BUY: Stop Loss activation"); // We had a short order originally asianRangeStrategy.SetEntryStrategyState(SHORT_STOP_LOSS_TRIGGERED); } else if(dt == DEAL_TYPE_SELL) { Alert("SELL: Stop Loss activation"); // We had a long order originally asianRangeStrategy.SetEntryStrategyState(LONG_STOP_LOSS_TRIGGERED); } // Reset the Entry Criteria so we can go long on the next RLxD } else { if((ENUM_DEAL_REASON)reason==DEAL_REASON_TP) { Alert("Take Profit activation"); if(dt == DEAL_TYPE_BUY) { Alert("BUY: Stop Loss activation"); // We had a short order originally asianRangeStrategy.SetEntryStrategyState(SHORT_TAKE_PROFIT_TRIGGERED); } else if(dt == DEAL_TYPE_SELL) { Alert("SELL: Stop Loss activation"); // We had a long order originally asianRangeStrategy.SetEntryStrategyState(LONG_TAKE_PROFIT_TRIGGERED); } } } // Check if the deal is for entry (opening a position) if(HistoryDealGetInteger(trans.deal, DEAL_ENTRY) == DEAL_ENTRY_IN) { // Now determine if the deal is a buy or sell to increment the correct counter ENUM_DEAL_TYPE dealType = (ENUM_DEAL_TYPE)HistoryDealGetInteger(trans.deal, DEAL_TYPE); if(dealType == DEAL_TYPE_BUY) { // Increment long trades counter for a new long position asianRangeStrategy.longTrades++; Print("New Long Position executed. Total Long Trades: ", asianRangeStrategy.longTrades); } else if(dealType == DEAL_TYPE_SELL) { // This would be for short trades, in case you want to track those separately asianRangeStrategy.shortTrades++; Print("New Short Position executed. Total Short Trades: ", asianRangeStrategy.shortTrades); } } } }
I am going to keep trying to narrow down what is increasing the memory usage, but if you can see anything obvious in what I am doing above please let me know.

Found the culprit. Will work out why
double atr =GetATR(14) * 100000; double stoploss = atr* rm.GetAtrMultiplier();
double GetATR(int atrPeriod) { int ATRHandle = iATR(_Symbol, _Period, atrPeriod); // Returns a handle for ATR. Use _Period for the current chart's timeframe double ATRValue[1]; // Array to store the ATR value if(ATRHandle != INVALID_HANDLE) { ArraySetAsSeries(ATRValue, true); // Set the ATRValue to timeseries, 0 is the current bar // Attempt to copy the latest ATR value if(CopyBuffer(ATRHandle, 0, 0, 1, ATRValue) > 0) { // Successfully copied the ATR value DPrint("ATR Value: "+ RoundToDigits(ATRValue[0],symbolDigits),DEBUG_DEBUG); // Print the value of the ATR IndicatorRelease(ATRHandle); // Release the handle now that we're done with it return RoundToDigits(ATRValue[0],symbolDigits); // Return the ATR value } else { // Failed to copy the ATR value Print("Error copying ATR buffer: ", GetLastError()); } IndicatorRelease(ATRHandle); // Release the handle here, inside the check for INVALID_HANDLE } else { // Failed to obtain the ATR handle Print("Failed to obtain ATR handle: ", GetLastError()); } return 0; // Return 0 or an appropriate error value if unable to obtain/copy the ATR value }
I'm not an expert in MQL5, but maybe it's worth trying to do this only from OnInit, and do this only from OnDeinit?
After all, you most likely call GetATR() from OnTick/OnCalculate, creating and deleting an indicator each time
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
I am backtesting my algo on MT5 Version 5.00 Build 4153 22 Jan 24 on OSX Sonoma 14.3 M1 Max (10 Cores) 64 GB Ram.
When I do it uses a lot of memory and even runs out of application memory space.
I am only using 1 core in this example because when I use more than 1 agent it runs out of space quicker.
I get no errors in Journal when running locally, I just run out of memory with the above errors:
When I run an optimisation with 7896 steps using MQL Cloud Network I get the following errors:
I tried to detect an issue with: `checkForMemLeak.mqh` but nothing was found. Each time I create a new Object I am deleting the object with new and delete. I create all my arrays with a fixed size, and I a believe I only initialise my indicators once and I release my indicator handles via the destructor.
The 65 critical errors are just reporting: ` error "critical runtime error 505 in global initialization function (out of memory)"` below error might a symptom of running out of memory and maybe not the cause but I can't be sure.
OnInit function (error code 0, module Experts\AsianRange\AsianRangeBackTest.ex5, file Trend.mqh, line 370, col 19
I can't seem to find this file: Trend.mqh in MT5 to view it. I can see it referenced here (which is not mine) and line 370 is: ` ((CIndicatorBuffer*)At(1)).Offset(ma_shift);`Function From ` Trend.mqh`
The algo is pretty large so not easy to upload.. here is the some code from it:
The entry logic is where the Indicators are initialised:
Hoping someone can point me in the right direction to try find what is using all the memory?