Cualquier pregunta de los recién llegados sobre MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos - página 614

 
Vitaly Muzichenko:

Bueno, usted ha mostrado los errores no críticos.

Cómo funciona la función, te has contestado a ti mismo:


En el probador está bien. Así es como funciona en la práctica.
Archivos adjuntos:
yOXZsAXZ-X4.jpg  479 kb
 
Tigerfreerun:
En el probador está bien. Así es como funciona en la práctica.

En este caso hay que tratar el código, imprimir( Print(...) ) todos los valores y ver de dónde viene el error

 
Tigerfreerun:
En el probador está bien. Así es como funciona en la práctica.

Tienes tu respuesta:

Foro sobre trading, sistemas de trading automatizados y pruebas de estrategias de trading

Cualquier pregunta de los novatos en MQL4, ayuda y discusión sobre algoritmos y códigos

Alexey Viktorov, 2018.09.06 21:00

Dirección para pensar: Si el beneficio es menor que cero... ¿qué tamaño tendrá la matriz durante la clasificación?

¿Y cuál es el tamaño de la matriz si no hay ningún pedido?
Piensa en cuál sería el tamaño del array ordenable a[][2] en la primera dimensión si todos los beneficios NO son mayores que cero.
 

Buenas tardes, el EA se llama "Rollover", pero no funciona como estaba previsto, duplica el lote si se cierra en menos, pero el cierre posterior del TP por alguna razón no permite devolver las operaciones en menos, que se cerraron antes. Por favor, indíqueme qué es lo que está mal, no puedo entenderlo. Me gustaría hacer mi pregunta en mi buzón.

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:
No entiendo muy bien qué hace exactamente esta función. Pero, como ha dicho el autor, su objetivo es cubrir las órdenes perdedoras con las rentables entre los símbolos. Me gustaría que me ayudaran a corregir y entender la función
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;
}

No entiendes, y no quiero entender lo que hace esta función. Lo usas. Lo has elegido tú mismo. Cómo se puede utilizar algo sin entender para qué sirve.

Acabo de decirte de dónde viene el error, por qué razón.

Una aclaración más:

Se declara un array. Está resaltado en verde. Tiene una longitud cero en la primera dimensión. La línea en azul no es clara. Si quieres restablecer el tamaño del array, existe ArrayFree() Pero incluso esta función será inútil, ya que el array dinámico recién declarado tiene longitud cero.

2. Si no hay órdenes, el código marcado en rojo no se ejecutará. Por lo tanto, el tamaño de la matriz seguirá siendo cero.

3. La ordenación de matrices se proporciona en cada tic. Se deduce del código. ¿Y qué se puede clasificar en un bolsillo vacío? ¿A menos que sean 2 huevos de codorniz...?


Y este es el texto del error... ¿Qué puedo decir? Los desarrolladores no previeron que alguien podría intentar ordenar un array vacío. No han inventado un mensaje especial para eso.

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

No entiendes, y no quiero entender, lo que hace esta función. Lo usas. Lo has elegido tú mismo. Cómo se puede utilizar algo sin entender para qué sirve.

Acabo de decirte de dónde viene el error, por qué razón.

Una aclaración más:

1. Se declara un array. En el código está resaltado en verde. Tiene longitud cero en la primera dimensión. La línea resaltada en azul no es clara. Si queremos restablecer el tamaño del array, existe ArrayFree() , pero incluso esta función será inútil, ya que el array dinámico que acabamos de declarar tiene longitud cero.

2. Si no hay órdenes, el código marcado en rojo no se ejecutará. Por lo tanto, el tamaño de la matriz seguirá siendo cero.

3. La ordenación de matrices se proporciona en cada tic. Se deduce del código. ¿Y qué se puede clasificar en un bolsillo vacío? ¿A menos que sean 2 huevos de codorniz...?


Y este es el texto del error... ¿Qué puedo decir? Los desarrolladores no previeron que alguien podría intentar ordenar un array vacío. No han inventado un mensaje especial para eso.

Alexey, te equivocas. ArrayFree() sirve para liberar memoria del array cuando ya no se necesita, lo cual es muy poco necesario, y desde luego no en este caso.

ZeroMemory(a), ArrayInitialize(a,xxx) se debe utilizar para poner a cero el array, y ArrayResize(a,xxx) se debe utilizar para cambiar su tamaño en la primera dimensión.

Sin embargo, esta enmienda no afecta a su razonamiento: es correcto.

 
Artyom Trishkin:

Alexey, eso no es correcto. ArrayFree() se utiliza para liberar la memoria de un array cuando éste ya no se necesita, lo cual es muy raro, y definitivamente no en este caso.

ZeroMemory(a), ArrayInitialize(a,xxx) se debe utilizar para poner a cero el array, y ArrayResize(a,xxx) se debe utilizar para cambiar su tamaño en la primera dimensión.

Sin embargo, esta enmienda no afecta a su razonamiento: es correcto.

Según la documentación

ArrayFree .

libera el buffer de cualquier array dinámico y establece el tamaño de la dimensión cero a 0.

Tal vez no me expresé correctamente y me malinterpretaste.
 
Alexey Viktorov:

Según la documentación

Tal vez no me expresé correctamente y me malinterpretaste.

Y más atrás:


Nota

El uso de la función ArrayFree() en scripts e indicadores no es necesario muy a menudo, ya que toda la memoria utilizada se libera inmediatamente después de que el script deja de funcionar. En los indicadores personalizados, la mayoría de las operaciones con arrays están accediendo a los buffers del indicador, cuyos tamaños son gestionados automáticamente por el subsistema ejecutivo del terminal cliente.

Si un programa necesita gestionar la memoria de forma independiente en condiciones dinámicas complejas, la función ArrayFree() permitirá liberar de forma explícita e inmediata la memoria ocupada por un array dinámico innecesario.


Libera el buffer de cualquier array dinámico y establece el tamaño de la dimensión cero a 0

¿Lo entiendes? ¿Leíste la segunda parte y te perdiste la primera -importante-? Libera la memoria asignada para el array. Se ha... ido... El espacio de memoria asignado a la matriz se libera y puede ser ocupado por otros datos. ¿Por qué, cada vez que se vuelve a entrar en la función, se debe reasignar memoria a esta matriz? Tú eres el que debe liberarlo. Todo lo que necesitas hacer es cambiar el tamaño - ArrayResize() o poner a cero el array - ArrayInitialize(), ZeroMemory(). Y el espacio de memoria para el array no se liberará, y permanecerá reservado para este array hasta que el programa se complete.

 
Artyom Trishkin:

Y más atrás:


Nota

El uso de la función ArrayFree() en los scripts e indicadores no es necesario muy a menudo, ya que toda la memoria utilizada se libera inmediatamente al finalizar la operación. En los indicadores personalizados, la mayoría de las operaciones con arrays están accediendo a los buffers del indicador, cuyos tamaños son gestionados automáticamente por el subsistema ejecutivo del terminal cliente.

Si un programa necesita gestionar la memoria de forma independiente en condiciones dinámicas complejas, la función ArrayFree() permitirá liberar de forma explícita e inmediata la memoria ocupada por un array dinámico innecesario.


Libera el buffer de cualquier array dinámico y establece el tamaño de la dimensión cero a 0

¿Lo entiendes? Has leído la segunda parte y te has perdido la primera importante, ¿no? Libera la memoria asignada al array. Eso es todo... se fue... El espacio de memoria asignado a la matriz se libera y puede ser ocupado por otros datos. ¿Por qué, cada vez que se vuelve a entrar en la función, se debe reasignar memoria a esta matriz? Tú eres el que debe liberarlo. Todo lo que necesitas hacer es cambiar el tamaño - ArrayResize() o poner a cero el array - ArrayInitialize(), ZeroMemory(). Y el espacio de memoria para el array no se liberará, y permanecerá reservado para este array hasta que el programa se complete.

Bien... Y si se declara un array local en cada llamada de una función o, lo que es más improbable, en cada tick... Pero la memoria para el array se asigna cada vez que se define el array. ¿No es así? Y qué más da que se libere o no memoria, sino que se asigne memoria cada vez...

Mi idea principal era que no deberías hacer eso... y si lo haces, será mejor que lo hagas a través de ArrayFree().

Esto es lo interesante: si se declara una matriz local cada vez que se llama a una función, se reserva memoria para ella cada vez. ¿Y qué direcciones se utilizan al hacerlo? ¿Igual que al declarar el array por primera vez, o que se utilizará?

 
Denis Danilov:

Buenas tardes, el EA se llama "Rollover", pero no funciona como estaba previsto, duplica el lote si se cierra en menos, pero el cierre posterior del TP por alguna razón no permite devolver las operaciones en menos, que se cerraron antes. Por favor, indíqueme qué es lo que está mal, no puedo entenderlo. Me gustaría agradecer de antemano a todos los que han comentado.

Intente comprobar la duplicación antes del lote inicial. Vigila el cierre por tiempo.

Razón de la queja: