Controllo della candela aperta - pagina 3

 
  1. Il codice è stato scritto pre-build 600. Non si possono usare punti nei nomi delle variabili da febbraio 2014. Basta sostituire con dei trattini bassi.
  2. Ecco un esempio di codice indipendente dalla direzione
    double DIR, OOP, OCP, ISL;  int OP;
    
    if(     Bid > High[1]){
       DIR = +1; OOP = Ask; OCP = Bid; OP = OP_BUY;
    }
    else if(Bid <  Low[1]){
       DIR = -1; OOP = Bid; OCP = Ask; OP = OP_BUY;
    }
    else return;
    
    ISL = OCP -DIR* pips_to_change( extISL_Pips );
    ... OrderSend(...);
    Basta scambiare Ask/Bid per i prezzi di apertura/chiusura e scrivere tutto il resto come se fosse un acquisto: ISL è sotto OCP (OCP - ISL) e il -DIR* cambia il segno per una vendita.
    Se hai bisogno di un confronto (A > B) usa (A - B) *DIR> 0 per invertire il confronto per una vendita.
 
GumRai:

Sembra che tu abbia l'idea.

Modifica e pubblica il tuo codice e io o qualcun altro lo commenteremo

Ehi GumRai,

È passato un po' di tempo da quando ho postato un aggiornamento qui, ma ho lavorato al codice e finalmente l'ho finito - doloroso quando si lavora 10 ore al giorno. Tuttavia ho due problemi principali. 1) Non importa cosa faccio, genera un codice di errore: "Unknown ticket XYZ for OrderCloseFunction" e 2) Ho fatto un save-as del file, (chiamato uno USDCAD, un altro EURUSD), con magicnumbers diversi ecc, ma prende ancora solo un trade alla volta - e non tratta le coppie indipendentemente. Infatti, poi crea anche un errore "ticket non valido per OrderCloseFunction".

Ho provato a cercare su Google, ma senza successo. Vi sarei davvero grato se poteste guidarmi nella giusta direzione. Cosa sto facendo di sbagliato?

#property copyright "Copyright 2014, MetaQuotes Software Corp."
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict

//part with the extern int stating the terms of the MA removed to reduce space.

int MagicNumber = 1234;
int MagicNumber2 = 2345;
double Pips;
int BuyTicket;
int SellTicket;
int CloseTicket;
int CloseSellTicket;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   double Ticksize = MarketInfo(Symbol(), MODE_TICKSIZE);
   if (Ticksize == 0.00001 || Ticksize == 0.001)
   Pips = Ticksize*10;
   else Pips = Ticksize;
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
int start()
  {
//---

   static datetime bar_time=0;
  if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,1);
      double PreviousSlow2=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,2);
      double PreviousPriceClose=iClose(NULL,0,1);
      double PreviousPriceClose2=iClose(NULL,0,2);
      if((iOpen(NULL,0,1)<PreviousSlow && PreviousPriceClose>=PreviousSlow && Bid>=(PreviousSlow+PipsBeforeEntry*Pips)))
        {
         if(OrdersTotal()==0)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",MagicNumber,0,clrLimeGreen);
        }
        
      else
      for(int i = OrdersTotal()-1; i >= 0; i--) 
         {
         if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
      if(iClose(NULL, 0,0)<PreviousSlow)
        {
          CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
         }
         }
      if((iOpen(NULL,0,1)>PreviousSlow && PreviousPriceClose<PreviousSlow && Bid<=(PreviousSlow-PipsBeforeEntry*Pips)))
        {
         if(OrdersTotal()==0)
            SellTicket=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Entry EA",MagicNumber2,0,clrLimeGreen);
        }
      else
      for(i = OrdersTotal()-1; i >= 0; i--) 
         {
         if(!OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) continue;
          if(iClose(NULL, 0,1)>PreviousSlow)
        {
          CloseSellTicket=OrderClose(SellTicket,LotSize,Ask,Slippage,clrPink);
              }
     }
     }
    return(0);
    return(0); 
    }
//--------------

  

Molte grazie in anticipo!

 

Non usare mai OrdersTotal()==0 come condizione per inserire trade

Significa che se un trade è stato aperto manualmente o da un altro EA o dallo stesso EA collegato ad un altro simbolo grafico, solo 1 trade può essere aperto.

Hai la variabile globale BuyTicket, inizializzala a -1

int BuyTicket=-1;

      if((iOpen(NULL,0,1)<PreviousSlow && PreviousPriceClose>=PreviousSlow && Bid>=(PreviousSlow+PipsBeforeEntry*Pips)))
        {
         if(BuyTicket==-1)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),
                                "Main Entry EA",MagicNumber,0,clrLimeGreen);
        }

Non fare il loop degli ordini prima della chiusura, non è necessario

else
if(OrderSelect(BuyTicket,SELECT_BY_TICKET))
  {
   if(OrderCloseTime()==0)
     {
      if(Close[0]<PreviousSlow)
        {
         bool  CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
         if(CloseTicket)
            BuyTicket=-1;
        }
     }
   else
      BuyTicket=-1;  //Order has closed so reset variable
  }

Ora, quando si usano variabili dichiarate globalmente per i numeri di ticket ci possono essere problemi se il terminale viene chiuso e riavviato per qualche motivo

Quindi dichiarate una nuova variabile di portata globale

 bool Recovery=true;

  
  if(Recovery)
     {
     //loop through open orders and check for magic number, symbol and type
     //if you find a buy order with the magic number and symbol
     BuyTicket=OrderTicket();
     //if you find a sell order with the magic number and symbol
     SellTicket=OrderTicket();
     Recovery=false;
     }

Ho scritto questo velocemente, quindi potrei aver fatto degli errori, ma è abbastanza per darvi l'idea

 
GumRai:


Grazie mille per questo! La ragione per cui avevo messo il ciclo lì era perché quello che avevo notato era che quando chiudeva la vendita, non attivava l'acquisto per qualche motivo.

Sono andato avanti e ho fatto le modifiche necessarie... ma qualcosa sembra ancora sbagliato. Non sta prendendo nessun trade lungo ora, e genera un codice di errore di ticket non valido, e l'errore OrderClose 4051. Qualche suggerimento su cosa è ancora sbagliato qui?

La cosa strana è che sia nel codice precedente che in quello attuale (solo per la vendita), prendeva i trade ragionevolmente bene (se l'ho implementato solo su un grafico).

Non pensavo che sarebbe stato così difficile haha! Suppongo che mi sbagliavo quando pensavo che fosse una cosa molto semplice e diretta...comprare quando la candela incrocia e apre sopra la MA, chiudere e vendere quando la candela incrocia e va sotto la MA.


if((iOpen(NULL,0,1)<PreviousSlow && PreviousPriceClose>=PreviousSlow && Bid>=(PreviousSlow+PipsBeforeEntry*Pips)))
        {
         if(BuyTicket==-1)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",MagicNumber,0,clrLimeGreen);
        }
        
      else
      if(OrderSelect(SELECT_BY_POS,MODE_TRADES))
      {
      if(OrderCloseTime()==0)
      {
       if(Close[0]<PreviousSlow)
        {
          bool CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
          if(CloseTicket)
            BuyTicket=-1;
            }
         }
         else
            BuyTicket= -1;
            }
            
      if((iOpen(NULL,0,1)>PreviousSlow && PreviousPriceClose<PreviousSlow && Bid<=(PreviousSlow-PipsBeforeEntry*Pips)))
        {
         if(SellTicket==-1)
            SellTicket=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Entry EA",MagicNumber2,0,clrLimeGreen);
        }
      else
       if(OrderSelect(SELECT_BY_POS,MODE_TRADES))
       {
         if(Close[0]>PreviousSlow)
        {
        bool  CloseSellTicket=OrderClose(SellTicket,LotSize,Ask,Slippage,clrPink);
              if(CloseSellTicket)
                  SellTicket=-1;
                     }
         }
         else
            SellTicket= -1;
            }
            
    return(0);
    return(0); 
    }
 

Mi dispiace, ma non so davvero cosa stai cercando di fare

if(OrderSelect(SELECT_BY_POS,MODE_TRADES))

Non seleziona alcun ordine. Il codice si compila almeno?

      if(OrderCloseTime()==0)
      {
       if(Close[0]<PreviousSlow)
        {
          bool CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
          if(CloseTicket)
            BuyTicket=-1;
            }
         }
         else
            BuyTicket= -1;

Qui l'else si applica se (OrderCloseTime()==0) è falso

       if(OrderSelect(SELECT_BY_POS,MODE_TRADES))
       {
         if(Close[0]>PreviousSlow)
        {
        bool  CloseSellTicket=OrderClose(SellTicket,LotSize,Ask,Slippage,clrPink);
              if(CloseSellTicket)
                  SellTicket=-1;
                     }
         }
         else
            SellTicket= -1;

Qui si applica se OrderSelect fallisce, cosa che certamente fa

 
GumRai:

Mi dispiace, ma non so davvero cosa stai cercando di fare

Non seleziona alcun ordine. Il codice si compila almeno?

Qui l'else si applica se (OrderCloseTime()==0) è falso

Qui si applica se OrderSelect fallisce, cosa che certamente fa

Scusa, è tutta colpa mia. Non ho letto/applicato correttamente i tuoi suggerimenti; grazie mille per avermeli fatti notare. L'ho fatto correttamente qui. Nessun errore generato nel rapporto. L'unica cosa è che ora sta inserendo più ordini di vendita e di acquisto a volte, il che gli impedisce di chiudere gli scambi al momento giusto.

Edit: Per essere precisi, sta uscendo solo allo SL e al TP, non quando il prezzo attraversa l'altro lato della MA. Questo ha qualcosa a che fare con il bool?

int start()
  {
   static datetime bar_time=0;
  if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,1);
      double PreviousSlow2=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,2);
      double PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      if((iOpen(NULL,0,1)<PreviousSlow && PreviousPriceClose>=PreviousSlow && Bid>=(PreviousSlow+PipsBeforeEntry*Pips)))
        {
         if(BuyTicket==-1)
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",MagicNumber,0,clrLimeGreen);
        }
      else
      if(OrderSelect(BuyTicket,MODE_TRADES))
      {
         if(OrderCloseTime()==0)
         {
          if(Close[0]<PreviousSlow)
           {
             bool CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
             if(CloseTicket)
               BuyTicket=-1;
               }
            }
            else
               BuyTicket= -1; //Order has closed so reset variable
               }
            
      if((iOpen(NULL,0,1)>PreviousSlow && PreviousPriceClose<PreviousSlow && Bid<=(PreviousSlow-PipsBeforeEntry*Pips)))
        {
         if(SellTicket==-1)
            SellTicket=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Entry EA",MagicNumber2,0,clrLimeGreen);
        }
      else
       if(OrderSelect(SellTicket,MODE_TRADES))
       {
         if(Close[0]>PreviousSlow)
        {
        bool CloseSellTicket=OrderClose(SellTicket,LotSize,Ask,Slippage,clrPink);
              if(CloseSellTicket)
                  SellTicket=-1;
                     }
         }
         else 
            SellTicket= -1; //Order has closed so reset variable
            }
    return(0);
    return(0); 
    }
 
if(OrderSelect(BuyTicket,MODE_TRADES))
Questo non seleziona un trade, per favore segui l'esempio che ti ho dato e fallo correttamente
 
GumRai:
Questo non seleziona un trade, per favore segui l'esempio che ti ho dato e fallo correttamente

Mi sento... davvero stupido. lol. Grazie per averlo trovato!

1) Rimangono due cose... ora crea un codice di errore OrderClose 4108. Devo postare di nuovo il codice? È lo stesso di sopra con la correzione che avevi indicato. Però entra ed esce come da regole.

2) E non entra short immediatamente appena chiude la posizione long come mostrato nella foto. La freccia verde verso il basso mostra dove sarebbe dovuto andare short. Ha fatto un acquisto e l'ha chiuso in perdita una volta che ha chiuso sotto la MA gialla. Qui, sarebbe dovuto andare corto. Come posso fare questo loop?

Grazie mille GumRai. Onestamente non sarei arrivato da nessuna parte così vicino senza il tuo aiuto.

avrebbe dovuto andare corto qui

 
int start()
  {
   static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      double PreviousSlow=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,1);
      double PreviousSlow2=iMA(NULL,0,SlowMa,SlowMaShift,SlowMaMethod,SlowMaAppliedTo,2);
      double PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      if(BuyTicket==-1)
        {
         if((iOpen(NULL,0,1)<PreviousSlow && PreviousPriceClose>=PreviousSlow && Bid>=(PreviousSlow+PipsBeforeEntry*Pips)))
           {
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",MagicNumber,0,clrLimeGreen);
           }
        }
      else
      if(OrderSelect(BuyTicket,SELECT_BY_TICKET))
        {
         if(OrderCloseTime()==0)
           {
            if(Close[0]<PreviousSlow)
              {
               bool CloseTicket=OrderClose(BuyTicket,LotSize,Bid,Slippage,clrPink);
               if(CloseTicket)
                  BuyTicket=-1;
              }
           }
         else
            BuyTicket=-1; //Order has closed so reset variable
        }

      if(SellTicket==-1)
        {
         if((iOpen(NULL,0,1)>PreviousSlow && PreviousPriceClose<PreviousSlow && Bid<=(PreviousSlow-PipsBeforeEntry*Pips)))
           {
            SellTicket=OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Entry EA",MagicNumber2,0,clrLimeGreen);
           }
        }
      else
      if(OrderSelect(SellTicket,SELECT_BY_TICKET))
        {
         if(OrderCloseTime()==0)
           {
            if(Close[0]>PreviousSlow)
              {
               bool CloseSellTicket=OrderClose(SellTicket,LotSize,Ask,Slippage,clrPink);
               if(CloseSellTicket)
                  SellTicket=-1;
              }
           }
         else
            SellTicket=-1; //Order has closed so reset variable
        }
     }
   return(0);
  }

Piccolo cambiamento in quanto stava controllando di chiudere un ordine quando non ce n'era uno.

Secondo il codice non c'è motivo che una vendita venga aperta immediatamente dopo la chiusura di un acquisto.

La condizione per uscire da un acquisto non è la stessa di quella per aprire una vendita.

Ricorda che siccome stai controllando solo l'apertura della candela, Close[0] sarà il valore dell'offerta del primo tick ricevuto per la candela.

 
GumRai:

Piccolo cambiamento in quanto stava controllando di chiudere un ordine quando non ce n'era uno.

Secondo il codice non c'è motivo che una vendita venga aperta immediatamente dopo la chiusura di un acquisto.

La condizione per uscire da un acquisto non è la stessa di quella per aprire una vendita.

Ricorda che siccome stai controllando solo l'apertura della candela, Close[0] sarà il valore dell'offerta del primo tick ricevuto per la candela.

Santo cielo! Ce l'hai fatta! Grazie ancora e ancora GumRai. Sei il migliore.

Non posso inoltrare il test ora, ma una volta che i mercati aprono, penso che dovrei essere in grado di usare questo allora, con le altre coppie, a condizione di avere diversi magic#s sulla demo.