Un piccolo aiuto?

 

Così sto imparando mql4 dopo alcune altre lingue, e ho (o così pensavo) appena finito la prima versione del mio primo EA, un semplice trader di medie mobili. L'ho lasciato girare per tutta la giornata di ieri senza preoccupazioni, l'entrata e l'uscita erano come previsto, e ho pensato che fosse pronto a partire. Questa mattina mi sono imbattuto in tutti i tipi di problemi, in primo luogo, il codice quando l'ho rilanciato avrebbe solo venduto indipendentemente dalla posizione, e ora, dopo un po' di confusione, comprerà e venderà nelle posizioni corrette MA quando compro il trade si chiuderà al prossimo tick indipendentemente. Questo non succede quando sto vendendo nonostante abbia lo stesso formato - qualcuno può indicarmi il perché?

(Come nota a margine, il mio computer è stato in grado di eseguire il codice tutto il giorno ieri senza molto più di un ronzio (CPU in media 12%) oggi il suo andare come le campane dell'inferno per eseguire il codice (~60-90%))

Codice:

int total;
//+------------------------------------------------------------------+
//| expert init function                                            |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }
   else 
      {
      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }
   }
}
//----
   return;
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert start function                                   |
//+------------------------------------------------------------------+
int start()
  {
//----
   int p,q,z,i,L;
   while (AccountBalance()>50)                                                                                    //---- ensures an infinite loop for 1 trade a run 
   {                                                                                                              //---- (no infibuying!) (*) but always run
//---- 
RefreshRates();
//----
if ((iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)<70)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))&&(total==0))
      {                                                                                                                             //---------- ^ conditions to buy
      p=OrderSend(Symbol(),OP_BUY,0.1,Bid,0,0,0,"",z,0,Red);                                                                        //---------- Buy Order
      OrderSelect(p,SELECT_BY_TICKET);
         while (iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))                             //- whilst the above remains true
            {
            RefreshRates();                                                                                                         //- refresh then do nothing
            Sleep(1000);
         }
      OrderClose(OrderTicket(),0.1,OrderClosePrice(),0,Green);                                                                      //---when above is broken, close
         while (TimeSeconds(TimeCurrent())!=0)                                                                                      //---wait until a new minute
            {
            Sleep(1000);
         }
         continue;
      }
//-----         
if ((iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)>30)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))&&(total==0))
       {                                                                                                                            //---Same steps as above for sell
       q=OrderSend(Symbol(),OP_SELL,0.1,Ask,0,0,0,"",z,0,Blue);
       OrderSelect(q,SELECT_BY_TICKET);
         while (iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0))
            {
            RefreshRates();
            Sleep(1000);
         }
      OrderClose(OrderTicket(),0.1,OrderClosePrice(),0,Green);
         while (TimeSeconds(TimeCurrent())!=0)
            {
            Sleep(1000);
         }      
         continue;
      }
if (total!=0)
   {
   L=0;
   for (i=1; i<=OrdersTotal(); i++)                                                       //--- if trades were open which werent initially closed
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- close them if now the position has change
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  L++;
               }
            }
            total=L;
         }
      }
   }
else 
   {
   Sleep(1000);
} 
}
//----
return;
}
//--------------------------------------------------------------+
 

Non sono andato troppo in profondità nel tuo codice

Perché RefreshRates e poi dormire per 1 secondo, quando il mercato si muove rapidamente, i dati non saranno più aggiornati?

Stai calcolando sui tick, non sulle barre, quindi 1 tick può far scattare un ordine se una MA si muove sopra/sotto l'altra di una quantità minima. Se il tick seguente (dopo il sonno) si inverte, le MA si incrociano di nuovo e l'ordine sarà chiuso.

 

L'idea è di mantenere semplicemente il ciclo mentre le condizioni aspettano che si verifichino le condizioni di chiusura (Aka le sma passano) - ammesso che non sia il modo migliore per farlo, ma uno dei più economici a livello computazionale.

Le SMA si muovono rapidamente sopra/sotto l'altra è uno dei problemi del codice - ma non vedo perché, quando c'è attualmente 10 - 15 pip tra le due su cui sto correndo, dovrebbe portare alla chiusura? le condizioni stanno sicuramente tenendo per il while loop per rimanere in controllo, invece di saltare istantaneamente alla chiusura (la mia ipotesi è che il while loop viene ignorato per l'acquisto ma non la vendita - e non so perché)

 
j.w.msb:

L'idea è quella di mantenere semplicemente il ciclo mentre le condizioni aspettano che si verifichino le condizioni di chiusura (Aka le sma passano) - ammesso che non sia il modo migliore per farlo, ma uno dei più economici a livello computazionale.

Le SMA che si muovono rapidamente sopra/sotto l'altra è uno dei problemi del codice - ma non vedo perché, quando c'è attualmente 10 - 15 pip tra le due su cui sto correndo, dovrebbe portare alla chiusura? le condizioni stanno sicuramente tenendo per il while loop per rimanere in controllo, invece di saltare istantaneamente alla chiusura (la mia ipotesi è che il while loop viene ignorato per l'acquisto ma non la vendita - e non so perché)


Se stai solo controllando se una MA è sopra/sotto l'altra, dubito che sia di solito 10-15 pip di differenza, può essere 0,1 pip e quindi il prossimo tick può facilmente invertire la situazione.

È solo la mia opinione, ma quando si lavora con i crossover, credo che sia meglio calcolare solo su barre chiuse per evitare troppi segnali opposti

 

Anche nel tuo init

 int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }
   else 
      {
      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair
         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }
   }
}

il tuo else si applica solo all'ultimo if, quindi se l'EA non chiude un ordine di vendita aperto, il totale sarà aumentato di 1. Perché vuoi questo?

 
GumRai:


Se stai solo controllando se una MA è sopra/sotto l'altra, dubito che di solito sia 10-15 pip di differenza, può essere 0,1 pip e quindi il prossimo tick può facilmente invertire.

È solo la mia opinione, ma quando si lavora con i crossover, credo che sia meglio calcolare solo su barre chiuse per evitare troppi segnali opposti


è stato un errore di calcolo da parte mia in termini di pip! colpa mia! Ma il punto è che c'è certamente spazio di respiro tra i due in modo che non ci sia un segnale di cross over per forzare la vendita. Sostituire lo Sleep(1000) con while (TimeSecond(TimeCurrent)!=59) {Sleep(1000)} garantirebbe il test del crossover solo alla chiusura della candela?


Ho tolto l'OrderClose nella sezione buy e l'ordine viene ancora aperto all'esecuzione e poi chiuso al prossimo pip :s


Poi ho scambiato OP_BUY e OP_SELL e la vendita sta tenendo come previsto quando il 6SMA è sopra il 21SMA - sto aspettando il prossimo incrocio per vedere cosa succede (ovviamente sto testando questo nel time frame a minuti per il momento)

 

C'è molto da cambiare..... una cosa su cui lavorare

Che magicnumber hanno i trade che il tuo EA sta creando...

perché non lo rendi una variabile di input esterna in modo da poterlo rendere un numero unico e che non chiuda i trade di altri EA

int init()
  {

//---- 
   int i;
   total=0;
   if (OrdersTotal()==0)
      {
      total=OrdersTotal();
   }

cosa succede qui...

      for (i=1; i<=OrdersTotal(); i++)                                                       //--- counter for any trades open on the pair

         {
         if (OrderSelect(i-1,SELECT_BY_POS)==true)
            {
            if (OrderSymbol()==Symbol())
               {
               if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  { 
                  OrderClose( OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- with an open buy if the conditions have reversed close on initiation
               }
               if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                  {
                  OrderClose(O rderTicket(),OrderLots(),OrderClosePrice(),0,Green);                   //--- same with sell
               }
               else 
                  {
                  total++;                                                                   //--- if there are open trades yet to be completed add to tally (*)
               }
           }
       }

non contare il controllo delle operazioni, fallirà se chiudi le operazioni all'interno del ciclo come fai ora

Dai un'occhiata qui per vedere perché devi lavorare e come il conteggio alla rovescia

https://www.mql5.com/en/forum/139654

(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)

questa condizione può cambiare più volte in pochi istanti quando arriva un nuovo tick in ogni trade che paghi lo spread

la condizione non è sempre cambiare una volta ....on una singola barra

   while (AccountBalance()>50)                                                                                    //---- ensures an infinite loop for 1 trade a run 
   {                                                                                                              //---- (no infibuying!) (*) but always run
//---- 

quello che corre sempre si lascia dormire

e in modo normale quando il tick è fatto e arriva un nuovo tick si chiama di nuovo start()

    while (TimeSeconds(TimeCurrent())!=0)                                                                                      //---wait until a new minute
            {
            Sleep(1000);
         }
         continue;
      }

in questo modo l'esecuzione del codice solo quando il secondo è 0 fallirà spesso

perché può succedere spesso che in un secondo non ci sia un nuovo tick in arrivo

se il primo tick del minuto arriva a 1 secondo devi aspettare il nuovo minuto e sperare che un nuovo tick arrivi al secondo 0 del prossimo minuto

Controllare la funzione RefreshRates()

ci sono altre cose come far funzionare anche il broker a 4 e 5 cifre

controllare returncodes....

Slippage il tuo valore 0 perché è necessario ??? per averlo più grande

 
deVries:

C'è molto da cambiare..... una cosa su cui lavorare

Che magicnumber hanno i trade che il tuo EA sta creando...

perché non lo rendi una variabile di input esterna in modo da poterlo rendere un numero unico e che non chiuda i trade di altri EA

cosa succede qui...

non contare il controllo delle operazioni, fallirà se chiudi le operazioni all'interno del ciclo come fai ora

Dai un'occhiata qui per vedere perché devi lavorare e come il conto alla rovescia

https://www.mql5.com/en/forum/139654

questa condizione può cambiare più volte in pochi istanti quando arriva un nuovo tick in ogni trade che paghi lo spread

la condizione non è sempre cambiare una volta ....on una singola barra

quello che corre sempre si lascia dormire

e in modo normale quando il tick è fatto e arriva un nuovo tick si chiama di nuovo start()

in questo modo l'esecuzione del codice solo quando il secondo è 0 fallirà spesso

perché può succedere spesso che in un secondo non ci sia un nuovo tick in arrivo

se il primo tick del minuto arriva a 1 secondo devi aspettare il nuovo minuto e sperare che un nuovo tick arrivi al secondo 0 del prossimo minuto

Controlla la funzione RefreshRates()

ci sono altre cose come far funzionare anche il broker a 4 e 5 cifre

controllare returncodes....

Slippage il tuo valore 0 perché è necessario ??? per averlo più grande

Grazie per il vostro aiuto, ora sto facendo delle modifiche e vedrò come va! Errori stupidi aggravati da errori stupidi da parte mia! È quasi una meraviglia che abbia funzionato in primo luogo!
 

Quindi, ho spogliato il codice per eseguirlo nella più semplice delle capacità (cioè crossover = posizioni invertite) - la sua causa molti ordini di acquisto/vendita quando le due SMA sono vicine, ma non sono preoccupato di questo (per ora) e funziona bene su un conto demo. Quello che ora mi preoccupa è che se eseguo il mio codice sullo Strategy Tester, apre la prima posizione correttamente, ma poi non riesce a muoversi in avanti nel tempo, quindi le SMA non si incrociano mai. Cosa sto facendo di sbagliato? La mia lista di stampa è:

2013.10.22 23:41:26 2013.09.18 00:41 Tester: ordine #1 è chiuso

2013.10.22 23:41:26 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

...

2013.10.22 23:40:53 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:40:52 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:40:51 2013.09.18 00:41 SMACode3 GBPJPY,M1: 0

2013.10.22 23:56:18 SMACode3 GBPJPY,M1: caricato con successo

Codice:



//+------------------------------------------------------------------+
//|                                                   SMA scripy.mq4 |
//|                        Copyright 2013, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright 2013, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"
extern int z=1234;
int total;
//----

//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int init()
  {
//---- 
   int i;
   total=0;
   if (OrdersTotal()!=0)
      {
      for (i=OrdersTotal()-1; i>=0; i--)                                                     
         {
         if (OrderSelect(i,SELECT_BY_POS))
            {
            if (OrderSymbol()==Symbol())
               {
               if (OrderMagicNumber()==z) 
                  {
                  if ((OrderType()==OP_BUY)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)<iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                     { 
                     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                  
                  }
                  if ((OrderType()==OP_SELL)&&(iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0)>iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0)))
                     {
                     OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                  
                  }
                  else 
                     {
                     total++;                                                                 
                  }
               }
           }
       }
   }
}
//----
   return;
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
//----
   return(0);
}
//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int start()
   {
//----
   int i,L;
   while (AccountBalance()>50)                                                                                     
   {
   RefreshRates();
//-----
double SMA6=iMA(Symbol(),0,6,0,MODE_SMA,PRICE_CLOSE,0);
double SMA21=iMA(Symbol(),0,21,0,MODE_SMA,PRICE_CLOSE,0);
double RSI70=iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)<70;
double RSI30=iRSI(Symbol(),PERIOD_D1,14,PRICE_CLOSE,0)>30;                                                                                                            
//-----   
if (IsTesting()==true)
{
Sleep(60000);
Print(GetLastError());
}
//----
   if (total==0)
      {
      if ((RSI70)&&(SMA6>SMA21))
         {                                                                                                                       
         OrderSend(Symbol(),OP_BUY,0.1,Ask,0,0,0,"",z,0,Red); 
         total+=1;                                                       
         continue;
      }
      if ((RSI30)&&(SMA6<SMA21))
         {
         OrderSend(Symbol(),OP_SELL,0.1,Bid,0,0,0,"",z,0,Blue);
         total+=1;
         continue;
      }  
   }
//---
if (total!=0)
   {
   L=0;
   for (i=OrdersTotal()-1; i>=0; i--)                                                    
      {
      if (OrderSelect(i,SELECT_BY_POS))
         {
         if (OrderSymbol()==Symbol())
            {
            if (OrderMagicNumber()==z) 
               {
               if ((OrderType()==OP_BUY)&&(SMA6<SMA21))
                  { 
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);
                     total+=-1;
                 return;
               }
               if ((OrderType()==OP_SELL)&&(SMA6>SMA21))
                  {
                  OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);                 
                     total+=-1;
                  return;
               }
               else 
                  {
                  L++;                                                                  
               }
            }
            total=L;
         }
      }
   }
}
//----
}
//----
return;
}
//--------------------------------------------------------------+
 
j.w.msb: Quello che ora mi preoccupa è che se eseguo il mio codice sullo Strategy Tester, esso apre correttamente la prima posizione, ma poi non riesce ad andare avanti nel tempo,
  1. int start(){
       while (AccountBalance()>50){
          :
    Certo che no. RTFM. Si ottiene un nuovo tick solo quando si ritorna dall'inizio.
  2. if (IsTesting()==true){
        Sleep(60000);
        Print(GetLastError());
    }
    RTFM & limitazioni del Tester non puoi dormire nel tester
  3.         OrderSend(Symbol(),OP_SELL,0.1,Bid,0,0,0,"",z,0,Blue);
                      OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),0,Green);
    
    Cosa sono i valori di ritorno delle funzioni? Come si usano? - MQL4 forum
 
RefreshRates non cambia alcun valore nel tester, quindi siete bloccati in un ciclo while perché non ha alcun nuovo valore con cui lavorare.