Чаще всего такая ошибка возникает из-за использования рекурсии - вызов из функции самой себя напрямую или опосредовано через вызов другой функции. Если последний вариант, то придется помучаться, чтобы найти ошибку, т. к. такая рекурсия неочевидна.
Другой вариант переполнения стека - наличие в глобальном контексте динамического массива, который неумеренно расширяется. С одной стороны, для устранения этой ошибки достаточно перенести этот массив в тело какой-нибудь функции или в класс, создающийся во время исполнения программы. Но, скорее всего, в логике расширения этого массива присутствует ошибка, т. к. он расширяется бесконечно. Лучше всего найти проблему такого бесконечного расширения.
Другой вариант переполнения стека - наличие в глобальном контексте динамического массива, который неумеренно расширяется.
Динамический массив использует память кучи и не может переполнить стек.
Как избежать ошибки "Stack overflow" в коде советника ?
Лучший вариант - обратиться к разработчику советника.
Если есть исходный код, но разработчика нет - либо заказать во фрилансе, либо опубликовать код на форуме (но не факт, что найдутся желающие тратить на это время за бесплатно).
Если нет ни исходного кода, ни связи с разработчиком, то "избежать" ошибки не получится.
Обычный Canvas при умелом использовании, легко вызывает такую ошибку.
У него там с деинициализация есть проблемы.
Так что если советник рисует красивые картинки, то ковыряйте Canvas.
Обычный Canvas при умелом использовании, легко вызывает такую ошибку.
У него там с деинициализация есть проблемы.
Так что если советник рисует красивые картинки, то ковыряйте Canvas.
Не замечал. Наверное, неумело использую.
Не сразу попал на нужную строчку, там в гифке через пару сек будет метатрейдер.
Гифка работает если нажать на неё.
Вот так можно скушать память, при "умелом использовании")))
#include <CommBag.mqh> //+------------------------------------------------------------------+ int OnInit(void) { EventSetMillisecondTimer(10); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ void OnTimer() { MqlTick tick; SymbolInfoTick(_Symbol, tick); if(tick.ask != 0 && tick.bid != 0) Comm(StringFormat("ask = %.5f\nbid = %.5f\ntime = %s", tick.ask, tick.bid, TimeToString(tick.time, TIME_DATE | TIME_SECONDS))); } //+------------------------------------------------------------------+ void OnDeinit(const int reason) { EventKillTimer(); } //+------------------------------------------------------------------+
#include <Canvas\Canvas.mqh> void Comm(string txt, color clr = clrYellow, int FontSize = 20, string Font = "Consolas", int flag = FW_BOLD) { CCanvas canvas; int shift = 0; if(ChartGetInteger(0, CHART_SHOW_ONE_CLICK)) shift = 60; canvas.Erase(0x00FFFFFF); canvas.FontNameSet(Font); canvas.FontFlagsSet(flag); canvas.FontSizeSet(FontSize); int width = 0, height = 0; string result[]; int size = StringSplit(txt, StringGetCharacter("\n", 0), result); height = (int)(FontSize * 1.8 * size); for(int i = 0; i < size; i++) { int w = canvas.TextWidth(result[i]); if(width < w) width = w; } canvas.CreateBitmapLabel(0, 0, "Comment", 5, 20 + shift, width, height, COLOR_FORMAT_ARGB_NORMALIZE); for(int i = 0; i < size; i++) canvas.TextOut(0, (int)(FontSize * 0.8 * i), result[i], ColorToARGB(clr, 255)); canvas.Update(true); }
Не сразу попал на нужную строчку, там в гифке через пару сек будет метатрейдер.
Гифка работает если нажать на неё.
Вот так можно скушать память, при "умелом использовании")))
Добрый вечер, день!
У меня советник на МТ4, не 5. За основу взял известный советник хеджирования НТН. Ошибка переполнения срабатывает не постоянно, периодически.
Ниже его код:
//+------------------------------------------------------------------+ //| HTH.mq4 | //| c0d3 | //| | //+------------------------------------------------------------------+ #property copyright "c0d3" #property link "" extern bool trade=true; extern string C1="EURUSD"; extern string C2="USDCHF"; extern string C3="GBPUSD"; extern string C4="AUDUSD"; extern bool show_profit=true; extern bool enable_profit=false; extern bool enable_loss=false; extern bool enable_emergency_trading=true; extern int emergency_loss=60; extern int profit=80; extern int loss=40; extern int MagicNumber1=243; extern int MagicNumber2=244; extern int MagicNumber3=245; extern int MagicNumber4=256; extern int E_MagicNumber=257; extern double lot=0.01; //---------------------------------------------------------------------------------------------------------------------------- void verifyorder(string symbol, int MN, string direction)//function which is used to verify that the orders have been placed { Sleep(1000); int ord_cnt=OrdersTotal(); for (int start=0;start<ord_cnt;start++) { OrderSelect(start, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber()==MN) {return;} } if(direction=="LONG"){OrderSend(symbol,OP_BUY,lot,MarketInfo(symbol,MODE_ASK),3,0,0,"Hedge"+symbol,MN);} if(direction=="SHORT"){OrderSend(symbol,OP_SELL,lot,MarketInfo(symbol,MODE_BID),3,0,0,"Hedge"+symbol,MN);} return; } //------------------------------------------------------------------------------------------------------------- void closeorders() { int close_ord1=OrdersTotal(); for (int qe1=0;qe1<close_ord1;qe1++) { OrderSelect(qe1, SELECT_BY_POS, MODE_TRADES); if( OrderMagicNumber()==MagicNumber1 || OrderMagicNumber()==MagicNumber2 || OrderMagicNumber()==MagicNumber3 || OrderMagicNumber()==E_MagicNumber || OrderMagicNumber()==MagicNumber4) { if(OrderType()==OP_BUY) {RefreshRates();OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3);Sleep(2000);} if(OrderType()==OP_SELL){RefreshRates();OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),3);Sleep(2000);} } } closeordersverify(); return; } //-------------------------------------------------------------------------------------------------------------------------------- void closeordersverify() { int close_ord11=OrdersTotal(); for (int qe11=0;qe11<close_ord11;qe11++) { OrderSelect(qe11, SELECT_BY_POS, MODE_TRADES); if( OrderMagicNumber()==MagicNumber1 || OrderMagicNumber()==MagicNumber2 || OrderMagicNumber()==MagicNumber3 || OrderMagicNumber()==E_MagicNumber || OrderMagicNumber()==MagicNumber4) {closeorders();} //if(OrderType()==OP_BUY) {OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3);Sleep(2000);} //if(OrderType()==OP_SELL){OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),3);Sleep(2000);} } return; } //------------------------------------------------------------------------------------- void doubleorders() { int ord_t=OrdersTotal(); for (int y=0;y<ord_t;y++) { OrderSelect(y, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber()==MagicNumber1 || OrderMagicNumber()==MagicNumber2 || OrderMagicNumber()==MagicNumber3 || OrderMagicNumber()==MagicNumber4) { if(OrderProfit()>0) { if(OrderType()==OP_BUY) {OrderSend(OrderSymbol(),OP_BUY,OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),3,0,0,"Emergency Double",E_MagicNumber);} if(OrderType()==OP_SELL){OrderSend(OrderSymbol(),OP_SELL,OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3,0,0,"Emergency Double",E_MagicNumber);} } } } enable_emergency_trading=false; } //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //----(100 * Close[0] / iClose(NULL,PERIOD_D1,1)) - 100 double d_c1,d_c2,d_c3,d_c4,d_c11,d_c22,d_c33,d_c44; d_c1=(100*iClose(C1,NULL,0)/iClose(C1,PERIOD_D1,1))-100; d_c2=(100*iClose(C2,NULL,0)/iClose(C2,PERIOD_D1,1))-100; d_c3=(100*iClose(C3,NULL,0)/iClose(C3,PERIOD_D1,1))-100; d_c4=(100*iClose(C4,NULL,0)/iClose(C4,PERIOD_D1,1))-100; d_c11=(100*iClose(C1,PERIOD_D1,1)/iClose(C1,PERIOD_D1,2))-100; d_c22=(100*iClose(C2,PERIOD_D1,1)/iClose(C2,PERIOD_D1,2))-100; d_c33=(100*iClose(C3,PERIOD_D1,1)/iClose(C3,PERIOD_D1,2))-100; d_c44=(100*iClose(C4,PERIOD_D1,1)/iClose(C4,PERIOD_D1,2))-100; //check for profit in PIP, and close if the goal is reached if(show_profit==true) { double profit1,profit2,profit3,profit4; int totalprofit; int profitcheck=OrdersTotal(); for (int tr=0;tr<profitcheck;tr++) { OrderSelect(tr, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber()==MagicNumber1) { if(OrderType()==OP_BUY) {profit1=(MarketInfo(OrderSymbol(),MODE_BID)-OrderOpenPrice())/MarketInfo(OrderSymbol(),MODE_POINT);} if(OrderType()==OP_SELL){profit1=(OrderOpenPrice()-MarketInfo(OrderSymbol(),MODE_ASK))/MarketInfo(OrderSymbol(),MODE_POINT);} } if(OrderMagicNumber()==MagicNumber2) { if(OrderType()==OP_BUY) {profit2=(MarketInfo(OrderSymbol(),MODE_BID)-OrderOpenPrice())/MarketInfo(OrderSymbol(),MODE_POINT);} if(OrderType()==OP_SELL){profit2=(OrderOpenPrice()-MarketInfo(OrderSymbol(),MODE_ASK))/MarketInfo(OrderSymbol(),MODE_POINT);} } if(OrderMagicNumber()==MagicNumber3) { if(OrderType()==OP_BUY) {profit3=(MarketInfo(OrderSymbol(),MODE_BID)-OrderOpenPrice())/MarketInfo(OrderSymbol(),MODE_POINT);} if(OrderType()==OP_SELL){profit3=(OrderOpenPrice()-MarketInfo(OrderSymbol(),MODE_ASK))/MarketInfo(OrderSymbol(),MODE_POINT);} } if(OrderMagicNumber()==MagicNumber4) { if(OrderType()==OP_BUY) {profit4=(MarketInfo(OrderSymbol(),MODE_BID)-OrderOpenPrice())/MarketInfo(OrderSymbol(),MODE_POINT);} if(OrderType()==OP_SELL){profit4=(OrderOpenPrice()-MarketInfo(OrderSymbol(),MODE_ASK))/MarketInfo(OrderSymbol(),MODE_POINT);} } //check profit of emergency trades int u_orders=OrdersTotal(); double e_profit=0; for (int h=0;h<=u_orders;h++) { OrderSelect(h, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber()==E_MagicNumber) { if(OrderType()==OP_BUY) {e_profit+=(MarketInfo(OrderSymbol(),MODE_BID)-OrderOpenPrice())/MarketInfo(OrderSymbol(),MODE_POINT);} if(OrderType()==OP_SELL){e_profit+=(OrderOpenPrice()-MarketInfo(OrderSymbol(),MODE_ASK))/MarketInfo(OrderSymbol(),MODE_POINT);} } } } totalprofit=profit1+profit2+profit3+profit4+e_profit; if(enable_emergency_trading==true && totalprofit<=-emergency_loss){doubleorders();} if(enable_profit==true && totalprofit>=profit){closeorders();} if(enable_loss==true && totalprofit<=-loss){closeorders();} } //end check for profit Comment("\n", C1+" Deviation: "+d_c1+" | Previous Deviation: "+d_c11, "\n",C2+" Deviation: "+d_c2+" | Previous Deviation: "+d_c22, "\n",C3+" Deviation: "+d_c3+" | Previous Deviation: "+d_c33, "\n",C4+" Deviation: "+d_c4+" | Previous Deviation: "+d_c44, "\n", "\n",C1+" "+C2+" Pair Deviation: "+(d_c1+d_c2), "\n",C1+" "+C3+" Pair Deviation: "+(d_c1-d_c3), "\n",C1+" "+C4+" Pair Deviation: "+(d_c1-d_c4), "\n",C2+" "+C3+" Pair Deviation: "+(d_c2+d_c3), "\n",C3+" "+C4+" Pair Deviation: "+(d_c3-d_c4), "\n",C2+" "+C4+" Pair Deviation: "+(d_c2+d_c4), "\n", "\n",C1+"/"+C2+" vs. "+C3+"/"+C4+" Pair Deviation: "+((d_c1+d_c2)+(d_c3-d_c4)), "\n","PIP Profit: "+totalprofit ); //close orders after one Day if(Hour()>=23) { int close_ord=OrdersTotal(); for (int qe=0;qe<close_ord;qe++) { OrderSelect(qe, SELECT_BY_POS, MODE_TRADES); if( OrderMagicNumber()==MagicNumber1 || OrderMagicNumber()==MagicNumber2 || OrderMagicNumber()==MagicNumber3 || OrderMagicNumber()==E_MagicNumber || OrderMagicNumber()==MagicNumber4) { if(OrderType()==OP_BUY) {OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3);Sleep(2000);} if(OrderType()==OP_SELL){OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),3);Sleep(2000);} } } closeorders(); } //end close orders //check for opened positions, do not continue if positions are opened int ord_cnt1=OrdersTotal(); for (int start1=0;start1<ord_cnt1;start1++) { OrderSelect(start1, SELECT_BY_POS, MODE_TRADES); if(OrderMagicNumber()==MagicNumber1 || OrderMagicNumber()==MagicNumber2 || OrderMagicNumber()==MagicNumber3 || OrderMagicNumber()==E_MagicNumber || OrderMagicNumber()==MagicNumber4) {return(0);} } int ticket1,ticket2,ticket3,ticket4; //if(trade==true) if(Hour()>=0 && Hour()<1 && (Minute()>=5 && Minute()<=12))//start of a new day { //turn on emergency_exit enable_emergency_trading=true; if(trade==true && d_c11>0 && IsTradeAllowed()==true) //Previous Day's Deviation is Positive { //LONG EURUSD RefreshRates(); ticket1=OrderSend(C1,OP_BUY,lot,MarketInfo(C1,MODE_ASK),3,0,0,"Hedge"+C1,MagicNumber1); if (ticket1<0){verifyorder(C1,MagicNumber1,"LONG");}Sleep(5000); //LONG USDCHF RefreshRates(); ticket2=OrderSend(C2,OP_BUY,lot,MarketInfo(C2,MODE_ASK),3,0,0,"Hedge"+C2,MagicNumber2); if (ticket2<0){verifyorder(C2,MagicNumber2,"LONG");}Sleep(5000); //SHORT GBPUSD RefreshRates(); ticket3=OrderSend(C3,OP_SELL,lot,MarketInfo(C3,MODE_BID),3,0,0,"Hedge"+C3,MagicNumber3); if (ticket3<0){verifyorder(C3,MagicNumber3,"SHORT");}Sleep(5000); //LONG AUDUSD RefreshRates(); ticket4=OrderSend(C4,OP_BUY,lot,MarketInfo(C4,MODE_ASK),3,0,0,"Hedge"+C4,MagicNumber4); if (ticket4<0){verifyorder(C4,MagicNumber4,"LONG");}Sleep(5000); } if(trade==true && d_c11<0 && IsTradeAllowed()==true) //Previous Day's Deviation is Negative { //LONG EURUSD RefreshRates(); ticket1=OrderSend(C1,OP_SELL,lot,MarketInfo(C1,MODE_BID),3,0,0,"Hedge"+C1,MagicNumber1); if (ticket1<0){verifyorder(C1,MagicNumber1,"SHORT");}Sleep(5000); //LONG USDCHF RefreshRates(); ticket2=OrderSend(C2,OP_SELL,lot,MarketInfo(C2,MODE_BID),3,0,0,"Hedge"+C2,MagicNumber2); if (ticket2<0){verifyorder(C2,MagicNumber2,"SHORT");}Sleep(5000); //SHORT GBPUSD RefreshRates(); ticket3=OrderSend(C3,OP_BUY,lot,MarketInfo(C3,MODE_ASK),3,0,0,"Hedge"+C3,MagicNumber3); if (ticket3<0){verifyorder(C3,MagicNumber3,"LONG");}Sleep(5000); //LONG AUDUSD RefreshRates(); ticket4=OrderSend(C4,OP_SELL,lot,MarketInfo(C4,MODE_BID),3,0,0,"Hedge"+C4,MagicNumber4); if (ticket4<0){verifyorder(C4,MagicNumber4,"SHORT");}Sleep(5000); } } //---- return(0); } //+------------------------------------------------------------------+
Добрый вечер, день!
У меня советник на МТ4, не 5. За основу взял известный советник хеджирования НТН. Ошибка переполнения срабатывает не постоянно, периодически.
Ниже его код:
void closeorders() { int close_ord1=OrdersTotal(); for (int qe1=0;qe1<close_ord1;qe1++) { OrderSelect(qe1, SELECT_BY_POS, MODE_TRADES); if( OrderMagicNumber()==MagicNumber1 || OrderMagicNumber()==MagicNumber2 || OrderMagicNumber()==MagicNumber3 || OrderMagicNumber()==E_MagicNumber || OrderMagicNumber()==MagicNumber4) { if(OrderType()==OP_BUY) {RefreshRates();OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3);Sleep(2000);} if(OrderType()==OP_SELL){RefreshRates();OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),3);Sleep(2000);} } } closeordersverify(); return; } //-------------------------------------------------------------------------------------------------------------------------------- void closeordersverify() { int close_ord11=OrdersTotal(); for (int qe11=0;qe11<close_ord11;qe11++) { OrderSelect(qe11, SELECT_BY_POS, MODE_TRADES); if( OrderMagicNumber()==MagicNumber1 || OrderMagicNumber()==MagicNumber2 || OrderMagicNumber()==MagicNumber3 || OrderMagicNumber()==E_MagicNumber || OrderMagicNumber()==MagicNumber4) {closeorders();} //if(OrderType()==OP_BUY) {OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3);Sleep(2000);} //if(OrderType()==OP_SELL){OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),3);Sleep(2000);} } return; }
Самое начало вашего кода. Дальше смотреть не стал.
closeorders() может вызывать closeordersverify(), а closeordersverify() может вызывать closeorders(). Вполне вероятно, что при каких-то обстоятельствах эти функции начинают бесконечно вызывать друг друга.
Проверьте подобные места.
Я бы не был уверен, что после закрытия ордера (и даже после Sleep(2000)) тот закрытый ордер пропадет из MODE_TRADES. Очень вероятно, что вы закрыли ордер в closeorders(), вызвали closeordersverify(), а там тот ваш закрытый ордер все еще благополучно присутствует в MODE_TRADES и вы снова вызываете closeorders(), а потом снова closeordersverify(), и так без конца

- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Периодически советник не включается в начале новых суток.
В журнале пишет такую ошибку : 2025.02.06 02:45:13.372 -Stack overflow in 'C:\Users\User\AppData\Roaming\MetaQuotes\Terminal\15039C815974EAFC08F5D72E8C042194\MQL4\Experts\Ping_pong_Limit_bs.ex4'
Cоветник выставляет сетку ордеров BUYLIMIT & SELLLIMIT по EURUSD.
Как избежать ошибки "Stack overflow" в коде советника ?
Подскажите кто знает.