fatto un 2 EMA cross EA, bisogno di consigli

 

Ciao a tutti!

Sono nuovo di mql 4 e ho fatto un semplice cross advisor a 2 EMA, che ho testato su un conto demo, ma ho un po' paura di metterlo su uno reale

Testarlo con piccoli lotti su scala 1h richiederebbe troppo tempo, e testarlo su scale di minuti è costoso, perché il lotto minimo al mio broker è di circa 7 usd.

Quindi, ti sarei grato se gli dessi un'occhiata e magari mi indicassi qualche errore evidente che potrei aver fatto.

Questo consulente dovrebbe operare sul mercato Bitcoin/USD che è estremamente volatile (il prezzo può andare + - 30% al giorno), quindi stop loss e take profit non sono in pip ma in percentuali di un'offerta o richiesta.

Le variabili e il resto:

#property copyright "me"
#property link      "killnosock.net"
extern int SlowEma = 21;
extern int FastEma = 10;
extern int MaxRisk = 100;// % of Depo to be traded per order
extern int  TakeProfit=100;
extern int  StopLoss=100;
extern int Slippage = 10;

int LastBars = 0;

int init(){return(0);}
int deinit() {return(0);}

Questa funzione serve a determinare la dimensione del lotto, in base alla % di deposito che è permesso usare per ordine (int Risk)

double GetLot(int Risk)
{double Free    =AccountFreeMargin();
 double One_Lot =MarketInfo(Symbol(),MODE_MARGINREQUIRED);
 double Min_Lot =MarketInfo(Symbol(),MODE_MINLOT);
 double Max_Lot =MarketInfo(Symbol(),MODE_MAXLOT);
 double Step    =MarketInfo(Symbol(),MODE_LOTSTEP);
 double Lot     =MathFloor(Free*Risk/100/One_Lot/Step)*Step;
 if(Lot<Min_Lot) Lot=Min_Lot;
 if(Lot>Max_Lot) Lot=Max_Lot;
 if(Lot*One_Lot>Free) {
 Alert(" free= ", AccountFreeMargin()," for one lot= ", MarketInfo(Symbol(),MODE_MARGINREQUIRED)," lot= ", Lot);
 return(0.0);}
return(Lot);}

Questa è la funzione che apre un nuovo ordine, Cmd è comprare o vendere

int NewOrder(int Cmd,double Lot)
{double TP=0; //takeprofit
 double SL=0; //stoploss
 double PR=0; //price
 color clr = CLR_NONE;
 while(!IsTradeAllowed()) Sleep(10);
 RefreshRates();
 if(Cmd==OP_BUY)
   {PR=Ask;
    if(TakeProfit>0) TP=Ask + Ask*TakeProfit/100;
    if(StopLoss>0) SL=Ask - Ask*StopLoss/100;
    if(SL<0) SL = 0;
    if(TP<0) TP = 0;
    clr = Green;}
 if(Cmd==OP_SELL)
   {PR=Bid;
    if(TakeProfit>0) TP=Bid - Bid*TakeProfit/100;
    if(StopLoss>0) SL=Bid + Bid*StopLoss/100;
    if(SL<0) SL = 0;
    if(TP<0) TP = 0;
    clr = Red;}
 int tic=OrderSend(Symbol(),Cmd,Lot,PR,Slippage,SL,TP,"",0,0,clr);
 if(tic<0) Print("Open order error: ",GetLastError());
return(tic);}

Qui chiudo 1 ordine o chiudo tutti gli ordini:

//CloseOrder
void CloseOrder()
{double PR=0;
 while(!IsTradeAllowed()) Sleep(10);
 RefreshRates();
 if(OrderType()==OP_BUY)  PR=Bid;
 if(OrderType()==OP_SELL) PR=Ask;
 if(!OrderClose(OrderTicket(),OrderLots(),PR,Slippage,CLR_NONE))
   Print("Order close error: ",GetLastError());
return;}
//Close all Orders
void CloseAllOrders()
{
  for(int i=OrdersTotal()-1;i>=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      CloseOrder();
     }
return;}

Questa funzione è usata per calcolare la differenza di EMA veloce e lenta (EMA veloce - EMA lenta):

double EmaDiff(int shift)
   {
      double difference;
      difference = iMA(Symbol(),0,FastEma,0,MODE_EMA,PRICE_CLOSE,shift)
                 - iMA(Symbol(),0,SlowEma,0,MODE_EMA,PRICE_CLOSE,shift);
      return(difference);
   }

E qui va il corpo principale:

int start()
  {
double Lot;
    // check if new bar opened
    if (LastBars == Bars) return(0);
    else LastBars = Bars;
      {         
         if ((EmaDiff(1) > 0) && (EmaDiff(2) < 0))
            {
               CloseAllOrders();
               Lot = GetLot(MaxRisk);
               NewOrder(OP_BUY,Lot);
            }
            
         if ((EmaDiff(2) > 0) && (EmaDiff(1) < 0))
            {
               CloseAllOrders();
               Lot = GetLot(MaxRisk);
               NewOrder(OP_SELL,Lot);
            }                    
      }
   return(0);
  }

Ho intenzione di aggiungere un trailing stop, e considerare il confronto di EmaDiff non a zero ma a qualche piccolo valore per non essere tagliato quando le EMA lente e veloci si avvicinano molto e si intersecano ad ogni barra.

 
 //CloseOrder
void CloseOrder()
{double PR=0;
 while(!IsTradeAllowed()) Sleep(10);
 RefreshRates();
 if(OrderType()==OP_BUY)  PR=Bid;
 if(OrderType()==OP_SELL) PR=Ask;
 if(!OrderClose(OrderTicket(),OrderLots(),PR,Slippage,CLR_NONE))
   Print("Order close error: ",GetLastError());
return;}



//Close all Orders
void CloseAllOrders()
{
  for(int i=OrdersTotal()-1;i>=0;i--)
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      CloseOrder();
     }
return;}

non controlla il simbolo non controlla un magicnumber....

allora cosa succederà usandolo dal vivo con diversi EA su di esso?

 
deVries:

non controlla il simbolo non controlla un magicnumber....

allora cosa succederà usandolo dal vivo con diversi EA su di esso?


Intendi l'esecuzione di due EA da 1 account?
 
prupru:

Intendi l'esecuzione di due EA da 1 conto?
Due EA o un EA e operazioni piazzate manualmente... o solo operazioni piazzate manualmente.
 
prupru:

Ciao a tutti!

Sono nuovo di mql 4 e ho fatto un semplice cross advisor a 2 EMA, che ho testato su un conto demo, ma ho un po' paura di metterlo su uno reale

Testarlo con piccoli lotti su scala 1h richiederebbe troppo tempo, e testarlo su scale di minuti è costoso, perché il lotto minimo al mio broker è di circa 7 usd.

Quindi, ti sarei grato se gli dessi un'occhiata e magari mi indicassi qualche errore evidente che potrei aver fatto.

È bello vedere qualcuno che controlla i valori di ritorno delle funzioni di trading senza essere sollecitato a farlo... ma hai bisogno di più informazioni se ottieni un errore in modo da poter diagnosticare cosa ha causato il problema, non puoi tornare indietro nel tempo nella situazione viva per controllare quale fosse lo Spread o quale fosse il livello di Freeze al momento...

if(tic < 0) Print("Open order error: ", GetLastError());

. . . questo è buono ma hai bisogno di più, quali variabili hai bisogno di stampare in modo da poter determinare la causa di qualsiasi errore che ottieni? quando hai determinato ciò di cui potresti aver bisogno aggiungile tutte nella tua chiamata Print() assicurandoti di usare il corretto numero di decimali (DoubeToStr(value, digits)) per qualsiasi variabile doppia come Ask, Bid, etc

 
RaptorUK:

È bello vedere qualcuno che controlla i valori di ritorno delle funzioni di trading senza essere sollecitato a farlo.

Scusa, ma non ho capito quella parte. L'unica cosa che ho capito è che devo aggiungere quante più variabili possibili alla chiamata Print(). Punto preso, grazie.

deVries, grazie anche per il tuo consiglio, ora capisco cosa intendi.

C'è qualcos'altro da sistemare?

 

naturalmente c'è

    // check if new bar opened
    if (LastBars == Bars) return(0);
    else LastBars = Bars;

supponiamo che abbiate già il massimo delle barre (c'è un limite) .....

 
deVries:

naturalmente c'è

supponiamo che abbiate già il massimo delle barre (c'è un limite) .....


Ok, allora come faccio a cogliere meglio il momento in cui si apre una nuova candela?
 
prupru:

ok, quindi come faccio a cogliere meglio il momento in cui si apre una nuova candela?


controlla il tempo dell'ultima barra Time[0]

cerca NewBar e troverai alcuni esempi

 
deVries:


controlla il tempo dell'ultima barra Time[0]

cercate NewBar e troverete alcuni esempi


grazie, ho trovato questo https://www.mql5.com/en/code/10370

 
 if(Cmd==OP_BUY)
   {PR=Ask;
    if(TakeProfit>0) TP=Ask + Ask*TakeProfit/100;
    if(StopLoss>0) SL=Ask - Ask*StopLoss/100;
    if(SL<0) SL = 0;
    if(TP<0) TP = 0;
    clr = Green;}

Non credo che questo sia giusto

come si fa ad avere 100 pips takeprofit e 150 pips Stoploss ???

aggiornamento vedi " così stop loss e take profit non sono in pips ma in percentuali di un bid o ask".

ancora si ottiene un prezzo valido in questo modo ... se il tuo simbolo ha 5 cifre il risultato sarà spesso 2 cifre in più