Controllo della candela aperta

 

Ciao ragazzi,

Sono abbastanza nuovo nella codifica in mql4 e sto cercando di far funzionare il mio primo EA. Onestamente apprezzerei un aiuto per quanto segue. E' solo un cross-over di base per così dire, ma invece di incrociare le medie mobili, è solo il prezzo che attraversa una media mobile.

Ho bisogno di un ordine da attivare su Candle Open se: (il prezzo di apertura della candela corrente è > della media mobile) e se (la candela precedente ha chiuso sotto la media mobile).

Finora ho il seguente codice nell'area principale:


//+------------------------------------------------------------------+

int start()

{

//---

double PreviousSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,1);

double CurrentSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,0);

double PreviousFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,1);

double CurrentFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,0);

double PreviousPriceClose= iClose(NULL, 0, 1);

double CurrentCandleOpen= iOpen(NULL,0,0);

//----------------------Il calcolo principale inizia qui


if(PreviousPriceClose<PreviousSlow && (CurrentCandleOpen>(CurrentSlow))

if(OrdiniTotali () == 0)

BuyTicket = OrderSend(Symbol(),OP_BUY, LotSize,CurrentCandleOpen, Slippage, Ask-(StopLoss*Pips), Ask+(TakeProfit*Pips), "Main Entry EA", 0,0,clrLimeGreen);

//--------------

return(0);

return(0);

}

//+------------------------------------------------------------------+

Qualunque cosa io faccia, sembra che non possa funzionare e non credo di fare qualcosa di giusto qui. Di nuovo, apprezzerei molto l'aiuto!

 
    

  double CurrentSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,0);   

Questo valore sta cambiando mentre la candela è in corso

double CurrentCandleOpen= iOpen(NULL,0,0);

Questo non è

BuyTicket = OrderSend(Symbol(),OP_BUY, LotSize,CurrentCandleOpen, Slippage, Ask-(StopLoss*Pips), Ask+(TakeProfit*Pips), "Main Entry EA", 0,0,clrLimeGreen);

È improbabile che CurrentCandleOpen sia un prezzo di entrata valido per molti tick

Se dovete usare questa logica, calcolate solo una volta quando si apre una nuova barra.

Controlla i valori di ritorno se OrderSend fallisce

 
GumRai:

Questo valore sta cambiando mentre la candela è in corso

Questo non è

È improbabile che CurrentCandleOpen sia un prezzo di entrata valido per molti tick

Se dovete usare questa logica, calcolate solo una volta quando si apre una nuova barra.

Controlla i valori di ritorno se l'OrderSend fallisce


Grazie per la risposta rapida! Vediamo se ho capito bene:

  1. Il CurrentSlow non funziona davvero, perché si sta ancora formando. Ok, va bene, posso usare il valore della media mobile che si è formata per la candela precedente. Questo non dovrebbe essere un problema.
  2. Dato che CurrentCandleOpen non è un valore mobile... allora presumo che quella parte del codice sia corretta?
  3. Come posso farlo funzionare, in modo che sia abbastanza vicino a CandleOpen?--Hai detto di calcolare solo una volta quando si apre una nuova barra. Potresti per favore espandere questo concetto? Non so bene come farlo
Grazie ancora GumRai.

 
   static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
      //Code to process the signal
     }

   
Il codice all'interno delle parentesi graffe sarà eseguito solo al primo tick di una nuova barra
 
GumRai:
Il codice tra le parentesi graffe sarà eseguito solo al primo tick di una nuova barra

Grazie per il codice! Ho aggiornato quanto segue come discusso in precedenza:

  1. Cambiato il lento corrente di MA in Lento precedente.
  2. Rimosso CurrentCandleOpen con Ask. Ogni volta che ho usato CurrentCandleOpen, invece di Ask, non ha preso alcun trade. Tuttavia, quando l'ho sostituito con Ask, ha funzionato, ma ovviamente scambia ogni volta che Ask incrocia la MA, e non su Candle open.

Ma dopo questo, quando l'ho inserito nel tuo codice come segue, non prende più nessun trade. L'ho inserito correttamente?

int start()
  {
//---
    
  double PreviousSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,1);     //1 at the end signifies that we want it on candle close
  double CurrentSlow = iMA(NULL,0,SlowMa,SlowMaShift, SlowMaMethod, SlowMaAppliedTo,0);     //1 at the end signifies that we want it on candle close

  double PreviousFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,1);     //1 at the end signifies that we want it on candle close
  double CurrentFast = iMA(NULL,0,FastMa,FastMaShift, FastMaMethod, FastMaAppliedTo,0);     //1 at the end signifies that we want it on candle close
   
  double PreviousPriceClose= iClose(NULL, 0, 1);
  double CurrentPriceClose= iOpen(NULL, 0, 0);
  
//----------------------Main calculation starts here

 static datetime bar_time=0;
   if(bar_time!=Time[0])
     {
      bar_time=Time[0];
   if(PreviousPriceClose<PreviousSlow && Ask>PreviousSlow)
      if(OrdersTotal () == 0)
         BuyTicket = OrderSend(Symbol(),OP_BUY, LotSize,Ask, Slippage, Ask-(StopLoss*Pips), Ask+(TakeProfit*Pips), "Main Entry EA", 0,0,clrLimeGreen);
   }
//--------------
   return(0);
   return(0);
  }
 

Perché mettere le chiamate iMA al di fuori del nuovo codice a barre? Ciò significa che vengono chiamate ogni tick quando non sono necessarie - inefficiente.

   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 PreviousPriceClose=iClose(NULL,0,1);   //You can just use Close[1]
      if(PreviousPriceClose<PreviousSlow && Bid>PreviousSlow)
         if(OrdersTotal()==0)
            {
            BuyTicket=OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-(StopLoss*Pips),Ask+(TakeProfit*Pips),"Main Entry EA",0,0,clrLimeGreen);
            if(BuyTicket==-1)
               {
               //Error checking code
               }
     }

Non usare Ask per confrontare i valori su un grafico MT4, sono basati sul prezzo Bid

Controlla gli errori se l'OrderSend fallisce.

Non puoi avere molti casi in cui il primo tick di una nuova barra è sopra una MA quando l'ultimo tick della barra precedente era sotto di essa.

 

Grazie mille GumRai. Apprezzo sinceramente l'aiuto.

Il tuo codice funziona a meraviglia. Sto ancora cercando di imparare le corde qui, e ho visto che l'iMA è stato messo da solo così, separatamente. Seguirò invece il tuo metodo.

***si dà uno schiaffo sulla testa***

Rielaborerò il mio codice. La tua ultima riga ha evidenziato il difetto di ciò che volevo e di ciò che ho effettivamente codificato.

Quello che in realtà devo fare è:

  • Passo 1 la candela chiude sotto la MA,
  • passo 2: la candela incrocia e chiude sopra la MA
  • Passo 3: inserire il trade sulla nuova candela aperta.

Ultima domanda, e penso di averla fatta...

per il passo 1 sopra, l'iMA, lo SlowMaShift sarebbe 2 corretto? Dato che è 2 barre dietro? e l'iClose sarebbe: iClose(NULL,0,2) per quel confronto corretto?

 

Sembra che tu abbia l'idea.

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

 
GumRai:

Sembra che tu abbia l'idea.

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

Sono riuscito a farlo funzionare! Grazie GumRai.
Ora sto facendo lo stesso ma usando le regole opposte per prendere lo short. Indipendentemente questo funziona bene, ma non so come usare la funzione OrderCloseBy in modo che se il long è aperto, e lo short scatta, si chiude il long principalmente perché non ho idea di come trovare il ticket dell'ordine... Ho provato a bypassare la funzione OrderCloseBy facendo quanto segue:

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]
      double PreviousPriceClose2=iClose(NULL, 0,2);
      if(PreviousPriceClose2<PreviousSlow2 && 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",0,0,clrLimeGreen);
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow)
         if(OrdersTotal()==1)
         {
            OrderClose(BuyTicket,LotSize,Ask,Slippage,clrPink) && OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
                  }
         if(OrdersTotal()==0)
         {
            OrderSend(Symbol(), OP_SELL, LotSize, Bid, Slippage, Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
            }
     }
//--------------
   return(0);
   return(0);
  }
  return(0);
  }
 
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow)
         if(OrdersTotal()==1)

non può essere soddisfatta perché si trova all'interno del blocco di condizioni

         if(OrdersTotal()==0)

   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]
      double PreviousPriceClose2=iClose(NULL,0,2);
      if(PreviousPriceClose2<PreviousSlow2 && 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",0,0,clrLimeGreen);
        }
      else
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow)
        {
         if(OrdersTotal()==1)
           {
            OrderClose(BuyTicket,LotSize,Ask,Slippage,clrPink);
            OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
           }
         else
         if(OrdersTotal()==0)
           {
            OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+(StopLoss*Pips),Bid-(TakeProfit*Pips),"Main Sell EA",0,0,clrAliceBlue);
           }
        }
     }

Penso che quanto sopra sia più simile a quello che intendevi

Dovresti controllare i codici di ritorno degli errori

 
GumRai:

Penso che quanto sopra sia più simile a quello che intendevi

Dovresti controllare i codici di ritorno degli errori

Grazie per il codice... purtroppo non ha funzionato, dato che ora entra in uno short più di una volta. Ecco cosa ho provato a fare invece - lo sto rompendo separatamente - entrata e uscita long, e poi creerò l'opposto per l'entrata e l'uscita short. Sarà più gestibile per me, e un po' più facile da modificare. Sto lavorando per ottenere prima la parte di entrata e uscita lunga. Ma in qualche modo, questo non chiude i trade quando la candela chiude sotto la media mobile per lo short. Qualche idea su cosa sto sbagliando? Dà un errore: Il valore di ritorno di 'OrderClose' dovrebbe essere controllato. Ho cercato su Google una soluzione per tutta la mattina, ma non sembra funzionare.

   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]
      double PreviousPriceClose2=iClose(NULL,0,2);
      if(PreviousPriceClose2<PreviousSlow2 && 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",0,0,clrLimeGreen);
        }
      else
      if(PreviousPriceClose2>PreviousSlow2 && PreviousPriceClose<PreviousSlow && Bid<PreviousSlow)
        {
          OrderClose(BuyTicket,LotSize,Ask,Slippage,clrPink);
          
        }
     

Aggiornamento: mi sono sbarazzato del codice di errore, ma il ticket close continua a non funzionare. Tutto quello che voglio è che chiuda l'acquisto una volta che la candela attraversa e chiude sotto la MA.