Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 614

 
Vitaly Muzichenko:

Ну это вы показали не критические ошибки.

Как работает функция, вы сами ответили:


В тестере норм. Вот так вот происходит на деле. 
Файлы:
yOXZsAXZ-X4.jpg  479 kb
 
Tigerfreerun:
В тестере норм. Вот так вот происходит на деле. 

Ну в этом случае нужно разбираться с кодом, принтовать( Print(...) ) все значения, и смотреть откуда лезет ошибка

 
Tigerfreerun:
В тестере норм. Вот так вот происходит на деле. 

Вам ответили же:

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Любые вопросы новичков по MQL4, помощь и обсуждение по алгоритмам и кодам

Alexey Viktorov, 2018.09.06 21:00

Направление в котором надо думать: Если профит меньше нуля... какого размера будет массив во время сортировки???

И какого размера будет массив если ордеров вообще нет???
Подумайте каков размер сортируемого массива a[][2] в первом измерении будет если вся прибыль НЕ больше нуля.
 

Добрый день! Советник называется неваляшка, но работает не так как планировалось. удваивается лот если закрывается в минус, но последующее закрытие по ТП почему-то не позволяет возвращать минусовые сделки, закрытые до этого. Подскажите что не так, не могу разобраться. Заранее благодарю всех откликнувшихся. 

extern string TimeStart    = "04:00";  //Время начала контрольного периода
extern string TimeEnd      = "09:00";  //Время окончания контрольного периода
extern string TimeCloseOrder = "23:30";//Время в которое происходит закрытие всех ордеров
extern double LOT          = 0.1;
extern int    Magic        = 777;
extern double K_martin     = 2;
extern bool   No_Loss      = true;
int slippage = 3;
double marga,Lot,SL,TP;
int tip,Orders,tipOrders,TradeDey;
//-------------------------------------------------------------------+
int init()
{
   if (Digits==5 || Digits==3) slippage = 30;
}
int start()
{
   datetime Time_Start      = StrToTime(StringConcatenate(Day(),".",Month(),".",Year()," ",TimeStart,     ":00"));
   datetime Time_End        = StrToTime(StringConcatenate(Day(),".",Month(),".",Year()," ",TimeEnd,       ":00"));
   datetime Time_CloseOrder = StrToTime(StringConcatenate(Day(),".",Month(),".",Year()," ",TimeCloseOrder,":00"));

   if (Time_CloseOrder>Time_End) if (CurTime()>=Time_CloseOrder) CLOSEORDERS();

   int tip;
   if (Orders>OrdersTotal()) tip=CloseOrder();
   Orders=OrdersTotal();

   if (ORDERS(0)==0 && tip==0 && (CurTime()<Time_CloseOrder || Time_CloseOrder<=Time_End) && TradeDey!=TimeDay(CurTime()))
   {
      int BarStart = iBarShift(NULL,0,Time_Start,false);
      int BarEnd   = iBarShift(NULL,0,Time_End  ,false);
      double Max_Price=iHigh(NULL,0,iHighest(NULL,0,MODE_HIGH,BarStart-BarEnd,BarEnd));
      double Min_Price=iLow (NULL,0,iLowest (NULL,0,MODE_LOW, BarStart-BarEnd,BarEnd));
   
      if (TimeCurrent()>Time_End && ObjectFind("bar0"+Time_End)==-1)
      {
         ObjectCreate("bar0"+Time_End, OBJ_RECTANGLE, 0, 0,0, 0,0);
         ObjectSet   ("bar0"+Time_End, OBJPROP_STYLE, STYLE_SOLID);
         ObjectSet   ("bar0"+Time_End, OBJPROP_COLOR, Blue);
         ObjectSet   ("bar0"+Time_End, OBJPROP_BACK,  true);
         ObjectSet   ("bar0"+Time_End, OBJPROP_TIME1 ,Time_Start);
         ObjectSet   ("bar0"+Time_End, OBJPROP_PRICE1,Max_Price);
         ObjectSet   ("bar0"+Time_End, OBJPROP_TIME2 ,Time_End);
         ObjectSet   ("bar0"+Time_End, OBJPROP_PRICE2,Min_Price);
      }
      
      if (Bid>Max_Price) OrderSend(Symbol(),OP_BUY,LOT,Bid,slippage,Min_Price,
         NormalizeDouble(Ask + Max_Price-Min_Price,Digits),"BreakdownLevel",Magic,Blue);
      if (Bid<Min_Price) OrderSend(Symbol(),OP_SELL,LOT,Bid,slippage,Max_Price,
         NormalizeDouble(Bid - Max_Price+Min_Price,Digits),"BreakdownLevel",Magic,Blue);
      return;
   }
   if (No_Loss) No_Loss();
   if (tip==1 && TradeDey!=TimeDay(CurTime()))
   {
      Lot=Lot*K_martin;
      if (tipOrders==0) OrderSend(Symbol(),OP_SELL,Lot,Bid,slippage,SL,TP,"Nevalyashka",Magic,Blue);
      if (tipOrders==1) OrderSend(Symbol(),OP_BUY ,Lot,Ask,slippage,SL,TP,"Nevalyashka",Magic,Blue);
   }
   return(0);
}
//-------------------------------------------------------------------+
int CloseOrder()
{
   string txt;
   double loss;
   int i=OrdersHistoryTotal()-1;
   if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)==true)
   {                                     
      if (OrderSymbol()==Symbol() && Magic==OrderMagicNumber())
      {
         tipOrders=OrderType();
         Lot=OrderLots();
         loss = MathAbs(OrderProfit()/MarketInfo(Symbol(),MODE_TICKVALUE)/Lot/K_martin);
         if (tipOrders==0)
         {
            TP=NormalizeDouble(Bid - loss*Point,Digits);
            SL=NormalizeDouble(Ask + loss*Point,Digits);
         }
         if (tipOrders==1)
         {
            SL=NormalizeDouble(Bid - loss*Point,Digits);
            TP=NormalizeDouble(Ask + loss*Point,Digits);
         }
         if (OrderClosePrice()==OrderTakeProfit() || OrderProfit()>=0) TradeDey=TimeDay(CurTime());
         if (OrderClosePrice()==OrderStopLoss()) return(1);
      }
   }  
   return(0);
}
//+-----------------------------------------------------------------+
int ORDERS(int tip)
{
   int N_Sell,N_Buy;
   for (int i=0; i<OrdersTotal(); i++)
   {                                               
      if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
      {
         if (OrderSymbol()==Symbol() && Magic==OrderMagicNumber())
         {
            if (OrderType()==OP_BUY ) N_Buy++;
            if (OrderType()==OP_SELL) N_Sell++;
         }
      }   
   }
if (tip== 0) return(N_Buy+N_Sell);
if (tip== 1) return(N_Buy);
if (tip==-1) return(N_Sell);
}                  
//-------------------------------------------------------------------+
void No_Loss()
{
   int tip;
   double TP,OOP;
   for (int i=OrdersTotal()-1; i>=0; i--) 
   {
      if (OrderSelect(i, SELECT_BY_POS)==true)
      {
         tip = OrderType();
         if (tip<2 && OrderSymbol()==Symbol())
         {
            if (OrderMagicNumber()!=Magic) continue;
            TP = OrderTakeProfit();
            OOP = OrderOpenPrice();
            if (tip==0) //Bay               
            {  
               if (OrderStopLoss()>OrderOpenPrice()+Ask-Bid) return;
               if ((TP-OOP)/2+OOP<=Bid)
               OrderModify(OrderTicket(),OOP,NormalizeDouble(OOP+Ask-Bid,Digits),TP,0,White);
            }                                         
            if (tip==1) //Sell               
            {                                         
               if (OrderStopLoss()<OrderOpenPrice()-Ask+Bid) return;
               if (OOP-(OOP-TP)/2>=Ask)
               OrderModify(OrderTicket(),OOP,NormalizeDouble(OOP-Ask+Bid,Digits),TP,0,White);
            } 
         }
      }
   }
}
//------------------------------------------------------------------+
void CLOSEORDERS()
{
   bool error;
   int err;
   while (true)
   {  error=true;
      for (int i=OrdersTotal()-1; i>=0; i--)
      {                                               
         if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==true)
         {
            if (OrderSymbol()!=Symbol()||Magic!=OrderMagicNumber()) continue;
            if (OrderType()==OP_BUY)
               error=OrderClose(OrderTicket(),OrderLots(),Bid,3,CLR_NONE);
            if (OrderType()==OP_SELL)
               error=OrderClose(OrderTicket(),OrderLots(),Ask,3,CLR_NONE);
         }   
      }
      if (!error) {err++;Sleep(2000);RefreshRates();}
      if (error || err >5) return;
   }
}
//-------------------------------------------------------------------+
 
Tigerfreerun:
Я не очень понимаю, что именно выполняет эта функция. Но как говорил автор - задача перекрывать ордера убыточные - прибыльными между символами. Буду рад, если поможете исправить и понять функцию 
void MaxMinProfit()
{
int i, N, MaxTic, MinTic;
double   MinProf=0, MaxProf=0, OP, g, a[][2];
string MinSym, MaxSym;
ArrayResize(a, 0);
 
for (i=OrdersTotal()-1; i>=0; i--) 
  {    
   if (OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) 
    { 
     if (OrderType()==OP_SELL ||  OrderType()==OP_BUY )
      {
       OP = NormalizeDouble(OrderProfit()+OrderSwap()+OrderCommission(),2);
       
      if (MinProf>OP) 
      {
       
          MinProf=OP;
          MinTic=OrderTicket();
          MinSym=OrderSymbol();
          
         }
         
      if (OP>0) 
      {
       
          N++;
            ArrayResize(a, N);
            a[N-1][0]=OP;
            a[N-1][1]=OrderTicket();
          
         }
         
         }
         }
         
         }
         
      ArraySort(a, WHOLE_ARRAY, 0, MODE_DESCEND);//MODE_ASCEND);
      
      for (i=0; i<Level; i++) 
       {
     
     g+=a[i][0];
     //int ti=a[i-2][1];
     }
         
         
     
     if(MinProf <0 && (g+MinProf)>=ProcMax)
      {
       for (i=0; i<Level; i++) 
       {
       if (OrderSelect(a[i][1], SELECT_BY_TICKET, MODE_TRADES))
        {
        //Alert(a[i][1]);
         if (OrderType()== OP_BUY)
         {
          OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(),MODE_BID), Slip, CLR_NONE);
          }
          if (OrderType()== OP_SELL)
           {
           OrderClose(OrderTicket(), OrderLots(), MarketInfo(OrderSymbol(),MODE_ASK), Slip, CLR_NONE);
           }
          }
         }
          
          
          
          if (OrderSelect(MinTic, SELECT_BY_TICKET, MODE_TRADES))
        {
         if (OrderType()== OP_BUY)
         {
          OrderClose(MinTic, OrderLots(), MarketInfo(OrderSymbol(),MODE_BID), Slip, CLR_NONE);
          }
          if (OrderType()== OP_SELL)
           {
          OrderClose(MinTic, OrderLots(), MarketInfo(OrderSymbol(),MODE_ASK), Slip, CLR_NONE);
           }
          }}       
return;
}

Вы не понимаете, а я не хочу понимать что выполняет эта функция. Вам ей пользоваться. Вы её выбрали себе. Как можно пользоваться чем-то не понимая для чего это надо.

Я только сказал откуда, по какой причине возникает ошибка.

Ещё одно пояснение:

1. Объявлен массив. В коде выделено зелёным. Пока он нулевой длинны в первом измерении. Строка выделенная синим не понятно для чего. Если сбросить размер массива, то для этого существует ArrayFree() Но даже эта функция будет бесполезна так-как только-что объявленный динамический массив имеет нулевую длину.

2. Если ордеров нет, то код выделенный красным выполняться не будет. Соответственно размер массива останется нулевым.

3. Сортировка массива предусмотрена на каждом тике. Это следует из кода... И что можно сортировать в пустом кармане??? Разве-что 2 перепелиных яйца...


А вот такой текст ошибки... Ну что можно сказать? Разработчики не предусмотрели что кто-то сможет попытаться сортировать пустой массив. Специального сообщения для этого не придумали.

ArrayFree - Операции с массивами - Справочник MQL4
ArrayFree - Операции с массивами - Справочник MQL4
  • docs.mql4.com
При написании скриптов и индикаторов необходимость в использовании функции ArrayFree() может возникнуть не часто: так как при завершении работы скрипта вся использованная память сразу же освобождается, а в пользовательских индикаторах основная работа с массивами представляет собою доступ к индикаторным буферам, размеры которых автоматически...
 
Alexey Viktorov:

Вы не понимаете, а я не хочу понимать что выполняет эта функция. Вам ей пользоваться. Вы её выбрали себе. Как можно пользоваться чем-то не понимая для чего это надо.

Я только сказал откуда, по какой причине возникает ошибка.

Ещё одно пояснение:

1. Объявлен массив. В коде выделено зелёным. Пока он нулевой длинны в первом измерении. Строка выделенная синим не понятно для чего. Если сбросить размер массива, то для этого существует ArrayFree() Но даже эта функция будет бесполезна так-как только-что объявленный динамический массив имеет нулевую длину.

2. Если ордеров нет, то код выделенный красным выполняться не будет. Соответственно размер массива останется нулевым.

3. Сортировка массива предусмотрена на каждом тике. Это следует из кода... И что можно сортировать в пустом кармане??? Разве-что 2 перепелиных яйца...


А вот такой текст ошибки... Ну что можно сказать? Разработчики не предусмотрели что кто-то сможет попытаться сортировать пустой массив. Специального сообщения для этого не придумали.

Алексей, не верно. ArrayFree() служит для высвобождения памяти от массива в случае, когда этот массив уже не нужен, что нужно очень редко, и точно не в данном случае.

Для обнуления массива нужно использовать ZeroMemory(a), ArrayInitialize(a,xxx), а для изменения размера в первом измерении - ArrayResize(a,xxx).

Впрочем, эта поправка не влияет на ход твоих рассуждений - они верны.

 
Artyom Trishkin:

Алексей, не верно. ArrayFree() служит для высвобождения памяти от массива в случае, когда этот массив уже не нужен, что нужно очень редко, и точно не в данном случае.

Для обнуления массива нужно использовать ZeroMemory(a), ArrayInitialize(a,xxx), а для изменения размера в первом измерении - ArrayResize(a,xxx).

Впрочем, эта поправка не влияет на ход твоих рассуждений - они верны.

Согласно документации

ArrayFree

Освобождает буфер любого динамического массива и устанавливает размер нулевого измерения в 0.

Может я выразился не достаточно грамотно и ты меня не так понял.
 
Alexey Viktorov:

Согласно документации

Может я выразился не достаточно грамотно и ты меня не так понял.

И дальше там же:


Примечание

При написании скриптов и индикаторов необходимость в использовании функции ArrayFree() может возникнуть не часто: так как при завершении работы скрипта вся использованная память сразу же освобождается, а в пользовательских индикаторах основная работа с массивами представляет собою доступ к индикаторным буферам, размеры которых автоматически управляются исполняющей подсистемой терминала.

Если в программе необходимо самостоятельно управлять памятью в сложных динамических условиях, то функция ArrayFree() позволит явным образом и немедленно освобождать память, занятую ненужным уже динамическим массивом.


Освобождает буфер любого динамического массива и устанавливает размер нулевого измерения в 0

Понимаешь? Ты прочёл вторую часть, а первую - важную - пропустил? Высвобождает выделенную под массив память. Его всё... нету... Место в памяти, выделенное под массив, высвобождается и далее может быть занято другими данными. Зачем каждый раз при входе в функцию заново перераспределять память под этот массив? Ведь ты её высвобождать предлагаешь. А нужно лишь размер менять - ArrayResize() или обнулять массив - ArrayInitialize(), ZeroMemory(). При этом место в памяти под массив не будет высвобождаться и будет оставаться зарезервированным под этот массив до завершения работы программы.

 
Artyom Trishkin:

И дальше там же:


Примечание

При написании скриптов и индикаторов необходимость в использовании функции ArrayFree() может возникнуть не часто: так как при завершении работы скрипта вся использованная память сразу же освобождается, а в пользовательских индикаторах основная работа с массивами представляет собою доступ к индикаторным буферам, размеры которых автоматически управляются исполняющей подсистемой терминала.

Если в программе необходимо самостоятельно управлять памятью в сложных динамических условиях, то функция ArrayFree() позволит явным образом и немедленно освобождать память, занятую ненужным уже динамическим массивом.


Освобождает буфер любого динамического массива и устанавливает размер нулевого измерения в 0

Понимаешь? Ты прочёл вторую часть, а первую - важную - пропустил? Высвобождает выделенную под массив память. Его всё... нету... Место в памяти, выделенное под массив, высвобождается и далее может быть занято другими данными. Зачем каждый раз при входе в функцию заново перераспределять память под этот массив? Ведь ты её высвобождать предлагаешь. А нужно лишь размер менять - ArrayResize() или обнулять массив - ArrayInitialize(), ZeroMemory(). При этом место в памяти под массив не будет высвобождаться и будет оставаться зарезервированным под этот массив до завершения работы программы.

Ну хорошо... А если локальный массив объявляется при каждом обращении к функции или, самое невероятное, на каждом тике... так ведь память под массив распределяется при каждом объявлении массива. Разве не так? И какая разница освобождать память или нет, но память перераспределять каждый раз...

Основной посыл был в том, что этого делать не надо... а если уж делаете, то лучше сделать это посредством ArrayFree()

Вот что интересно: если локальный массив объявляется при каждом обращении к функции, соответственно память резервируется под него каждый раз. А какие адреса при этом используются??? Те-же что и при первом объявлении массива или какие получится?

 
Denis Danilov:

Добрый день! Советник называется неваляшка, но работает не так как планировалось. удваивается лот если закрывается в минус, но последующее закрытие по ТП почему-то не позволяет возвращать минусовые сделки, закрытые до этого. Подскажите что не так, не могу разобраться. Заранее благодарю всех откликнувшихся. 

Попробуйте проверять на удвоение раньше, чем на начальную лотность. Закрытие по времени смотрите.

Причина обращения: