Tutte le domande dei nuovi arrivati su MQL4 e MQL5, aiuto e discussione su algoritmi e codici - pagina 614

 
Vitaly Muzichenko:

Bene, avete mostrato gli errori non critici.

Come funziona la funzione, ti sei risposto da solo:


Nel tester va bene. Ecco come funziona in pratica.
File:
yOXZsAXZ-X4.jpg  479 kb
 
Tigerfreerun:
Nel tester è ok. È così che funziona in pratica.

In questo caso dovete trattare il codice, stampare( Print(...) ) tutti i valori e vedere da dove viene l'errore

 
Tigerfreerun:
Nel tester va bene. È così che funziona in pratica.

Hai appena avuto la tua risposta:

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Tutte le domande dei principianti su MQL4, aiuto e discussione su algoritmi e codici

Alexey Viktorov, 2018.09.06 21:00

Direzione a cui pensare: se il profitto è inferiore a zero... quanto sarà grande l'array durante l'ordinamento???

E qual è la dimensione dell'array se non ci sono ordini?
Pensate a quale sarebbe la dimensione dell'array ordinabile a[][2] nella prima dimensione se tutti i profitti NON sono maggiori di zero.
 

Buon pomeriggio, l'EA si chiama "Rollover", ma non funziona come previsto: raddoppia il lotto se chiude in meno, ma la successiva chiusura del TP per qualche motivo non permette di restituire i trade in meno che sono stati chiusi prima. Per favore, consigliatemi cosa c'è che non va, non riesco a capirlo. Vorrei porre la mia domanda in spagnolo.

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:
Non capisco bene cosa faccia esattamente questa funzione. Ma, come ha detto l'autore, il suo scopo è quello di coprire gli ordini perdenti con quelli redditizi tra i simboli. Sarei felice se poteste aiutarmi a correggere e capire la funzione
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;
}

Tu non capisci, e io non voglio capire cosa fa questa funzione. Lo usi. L'avete scelto per voi stessi. Come si può usare qualcosa senza capire a cosa serve.

Vi ho appena detto da dove viene l'errore, per quale motivo.

Un altro chiarimento:

Viene dichiarato un array. È evidenziato in verde. Ha lunghezza zero nella prima dimensione. La linea in blu non è chiara. Se volete azzerare la dimensione dell'array, c'è ArrayFree() Ma anche questa funzione sarà inutile, poiché l'array dinamico appena dichiarato ha lunghezza zero.

2. Se non ci sono ordini, il codice segnato in rosso non verrà eseguito. Pertanto, la dimensione dell'array rimarrà zero.

3. L'ordinamento delle matrici è fornito ad ogni tick. Segue dal codice. E cosa si può ordinare in una tasca vuota? A meno che non siano 2 uova di quaglia...?


E questo è il testo dell'errore... Cosa posso dire? Gli sviluppatori non hanno previsto che qualcuno potesse cercare di ordinare un array vuoto. Non hanno inventato un messaggio speciale per questo.

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

Tu non capisci, e io non voglio capire cosa fa questa funzione. Lo usi. L'avete scelto per voi stessi. Come si può usare qualcosa senza capire a cosa serve.

Vi ho appena detto da dove viene l'errore, per quale motivo.

Un altro chiarimento:

1. viene dichiarato un array. È evidenziato in verde nel codice. Ha lunghezza zero nella prima dimensione. La linea evidenziata in blu non è chiara. Se vogliamo azzerare la dimensione dell'array, c'è ArrayFree() , ma anche questa funzione sarà inutile, poiché l'array dinamico che abbiamo appena dichiarato ha lunghezza zero.

2. Se non ci sono ordini, il codice segnato in rosso non verrà eseguito. Pertanto, la dimensione dell'array rimarrà zero.

3. L'ordinamento delle matrici è fornito ad ogni tick. Segue dal codice. E cosa si può ordinare in una tasca vuota? A meno che non siano 2 uova di quaglia...?


E questo è il testo dell'errore... Cosa posso dire? Gli sviluppatori non hanno previsto che qualcuno potesse cercare di ordinare un array vuoto. Non hanno inventato un messaggio speciale per questo.

Alexey, ti sbagli. ArrayFree() serve a liberare la memoria dall'array quando non è più necessaria, il che è molto raramente necessario, e certamente non in questo caso.

ZeroMemory(a), ArrayInitialize(a,xxx) dovrebbe essere usato per azzerare l'array, e ArrayResize(a,xxx) dovrebbe essere usato per ridimensionarlo nella prima dimensione.

Tuttavia, questo emendamento non influisce sul suo ragionamento - è corretto.

 
Artyom Trishkin:

Alexey, questo non è corretto. ArrayFree() è usata per liberare memoria da un array quando questo array non è più necessario, il che è molto raro, e sicuramente non in questo caso.

ZeroMemory(a), ArrayInitialize(a,xxx) dovrebbe essere usato per azzerare l'array, e ArrayResize(a,xxx) dovrebbe essere usato per ridimensionarlo nella prima dimensione.

Tuttavia, questo emendamento non influisce sul suo ragionamento - è corretto.

Secondo la documentazione

ArrayFree .

libera il buffer di qualsiasi array dinamico e imposta la dimensione della dimensione zero a 0.

Forse non mi sono espresso abbastanza bene e mi hai frainteso.
 
Alexey Viktorov:

Secondo la documentazione

Forse non mi sono espresso abbastanza bene e mi hai frainteso.

E più indietro ancora:


Nota

L'uso della funzione ArrayFree() negli script e negli indicatori non è necessario molto spesso, poiché tutta la memoria utilizzata viene immediatamente rilasciata dopo che lo script smette di funzionare. Negli indicatori personalizzati, la maggior parte delle operazioni con gli array sono l'accesso ai buffer degli indicatori, le cui dimensioni sono gestite automaticamente dal sottosistema esecutivo del terminale client.

Se un programma ha bisogno di gestire autonomamente la memoria in condizioni dinamiche complesse, la funzione ArrayFree() permette di rilasciare esplicitamente e immediatamente la memoria occupata da un array dinamico non necessario.


Libera il buffer di qualsiasi array dinamico e imposta la dimensione della dimensione zero a 0

Hai capito? Hai letto la seconda parte e ti sei perso la prima - importante - parte? Libera la memoria allocata per l'array. E'... andato... Lo spazio di memoria allocato per l'array viene liberato e può essere occupato da altri dati. Perché, ogni volta che si rientra nella funzione, la memoria deve essere riallocata in questo array? Tu sei quello che dovrebbe liberarlo. Tutto quello che dovete fare è cambiare la dimensione - ArrayResize() o azzerare l'array - ArrayInitialize(), ZeroMemory(). E lo spazio di memoria per l'array non sarà rilasciato, e rimarrà riservato per questo array fino al completamento del programma.

 
Artyom Trishkin:

E più indietro ancora:


Nota

L'uso della funzione ArrayFree() negli script e negli indicatori non è necessario molto spesso, poiché tutta la memoria utilizzata viene immediatamente rilasciata al termine dell'operazione. Negli indicatori personalizzati, la maggior parte delle operazioni con gli array sono l'accesso ai buffer degli indicatori, le cui dimensioni sono gestite automaticamente dal sottosistema esecutivo del terminale client.

Se un programma ha bisogno di gestire autonomamente la memoria in condizioni dinamiche complesse, la funzione ArrayFree() permette di rilasciare esplicitamente e immediatamente la memoria occupata da un array dinamico non necessario.


Libera il buffer di qualsiasi array dinamico e imposta la dimensione della dimensione zero a 0

Hai capito? Hai letto la seconda parte e ti sei perso la prima importante, vero? Libera la memoria allocata per l'array. Questo è tutto... andato... Lo spazio di memoria allocato per l'array viene liberato e può essere ulteriormente occupato da altri dati. Perché, ogni volta che si rientra nella funzione, la memoria deve essere riallocata in questo array? Tu sei quello che dovrebbe liberarlo. Tutto quello che dovete fare è cambiare la dimensione - ArrayResize() o azzerare l'array - ArrayInitialize(), ZeroMemory(). E lo spazio di memoria per l'array non sarà rilasciato, e rimarrà riservato per questo array fino al completamento del programma.

Ok... E se un array locale è dichiarato ad ogni chiamata di una funzione o, più improbabilmente, ad ogni tick... Ma la memoria per l'array viene allocata ogni volta che l'array viene definito. Non è così? E che differenza fa se la memoria viene liberata o meno, ma la memoria viene allocata ogni volta...

La mia idea principale era che non si dovrebbe fare così... e se lo fate, fareste meglio a farlo attraverso ArrayFree().

Ecco la cosa interessante: se un array locale viene dichiarato ogni volta che una funzione viene chiamata, corrispondentemente, la memoria viene riservata per esso ogni volta. Ma quali indirizzi si usano quando si fa questo? Lo stesso di quando si dichiara l'array per la prima volta, o cosa verrà usato?

 
Denis Danilov:

Buon pomeriggio, l'EA si chiama "Rollover", ma non funziona come previsto: raddoppia il lotto se chiude in meno, ma la successiva chiusura del TP per qualche motivo non permette di restituire i trade in meno, che erano stati chiusi prima. Per favore, consigliatemi cosa c'è che non va, non riesco a capirlo. Vorrei ringraziare in anticipo tutti coloro che hanno commentato.

Cercate di controllare il raddoppio prima del lotto iniziale. Guarda la chiusura per tempo.