J'ai créé un EA croisé à 2 EMA, j'ai besoin de conseils. - page 3

 
deVries:


Non, si vous testez avec le spread actuel, c'est un mouvement très fou, donc le spread peut devenir très important.

Comment avez-vous effectué le test ?

spread fixe ou spread actuel ?


ok, donc c'est le moment où je vais chercher "spread" sur google.

J'apprécie que vous répondiez à mes questions stupides)))

Je serai de retour dans un moment

 
prupru:


ok, donc c'est le moment où je vais googler "spread".

J'apprécie que vous répondiez à mes questions stupides ;))

Je serai de retour dans un moment

Spread = Demande - Offre
 

et cette valeur peut changer à chaque tic-tac

La raison pour laquelle j'ai demandé de la méthode, comment vous avez fait le test.

 
deVries:

et cette valeur peut changer à chaque tic-tac

la raison pour laquelle j'ai demandé la méthode pour faire le test.

exactement !

La différence était due au test du spread actuel, lorsque j'ai effectué les tests avec un spread fixe, ils étaient exactement les mêmes !

Merci beaucoup à vous tous !

J'ai vraiment amélioré mes connaissances.

Et s'il vous plaît, faites-moi savoir s'il reste quelque chose à améliorer dans le code.

 
prupru:

exactement !

Si la différence était due au test de l'écart actuel, lorsque j'ai effectué les tests avec l'écart fixe, ils étaient exactement les mêmes !

Merci beaucoup à vous tous !

J'ai vraiment amélioré mes connaissances.

Et s'il vous plaît laissez-moi savoir s'il reste quelque chose à améliorer dans le code.


si vous montrez ce que votre code est devenu maintenant

J'aimerais aussi voir un nouveau traitement des erreurs, voir le commentaire de RaptorUK https://www.mql5.com/en/forum/148529.

 
deVries:


si vous montrez ce que votre code est devenu maintenant

aimerait voir aussi un nouveau traitement des erreurs, voir le commentaire RaptorUK https://www.mql5.com/en/forum/148529

Ok, c'est parti :

#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=0;
extern int  StopLoss=0;
extern int TrailingStop=0;
extern int Slippage = 10;

extern double MinDiff = 0.002;

int LastBars = 0;
//0 - undefined, 1 - bullish cross (fast MA above slow MA), -1 - bearish cross (fast MA below slow MA)
int PrevCross = 0;

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

normalisation des prix :

double NormPrice(double g_price)
{
   return (NormalizeDouble(g_price,MarketInfo(Symbol(),MODE_DIGITS)));
}

Fonction GetLot, je suppose qu'elle n'a pas changé.

//function GetLot, get size of the lot according to MaxRisk
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);}

Nouvelle fonction Order, utilise maintenant les prix normalisés :

//function NewOrder, place new order
int NewOrder(int Cmd,double Lot)
{double TP=0; //тейкпрофит
 double SL=0; //стоплосс
 double PR=0; //Цена
 color clr = CLR_NONE;
 while(!IsTradeAllowed()) Sleep(10);
 RefreshRates();
 if(Cmd==OP_BUY)
   {PR=Ask;
    if(TakeProfit>0) TP=NormPrice(Ask + Ask*TakeProfit/100);
    if(StopLoss>0) SL=NormPrice(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=NormPrice(Bid - Bid*TakeProfit/100);
    if(StopLoss>0) SL=NormPrice(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());
   Print("cmd ", Cmd, " Lot ", Lot, " PR ", PR, " Slip ", Slippage, " SL ", SL, " TP ", TP, " Ask ", Ask, " Bid ", Bid);
  }
return(tic);}

Fermer 1 ou tous les ordres

Je n'ai pas modifié la fonction de fermeture d'ordre pour vérifier le symbole et les nombres magiques, car je vais négocier sur un seul symbole et avec un seul EA par compte. Mais je le ferai après avoir réglé d'autres problèmes plus importants.

//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("Close order error: ",GetLastError());
   Print("Type ", OrderType()," PR ",PR, " Ask ", Ask, " Bid ", Bid, " OrderTicket ", OrderTicket(), " OrderLots ", OrderLots());
  }
return;}
//--------------------------- end of close order

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

J'ai modifié la détection du croisement des EMA en passant de la comparaison entre EmaDiff[2] et EmaDiff[1] à la comparaison entre EmaDiff[0] et zéro et en utilisant un drapeau supplémentaire (tout ceci provient d'un exemple que j'ai trouvé).

Sur un compte de démonstration à l'échelle de la minute, il fait de faux déclenchements lorsque l'écart est si élevé qu'une transaction d'achat fait se croiser les EMA et qu'une transaction de vente venant après dans la même barre de minute les sépare à nouveau.

[url=http://postimg.org/image/udq4ufmqf/][img]http://s15.postimg.org/udq4ufmqf/mess.jpg[/img][/url]

Je suis en train de réfléchir à la façon de traiter ce problème.

// check cross
void CheckCross()
{
   double FMA_Current = iMA(Symbol(),0,FastEma,0,MODE_EMA,PRICE_CLOSE,0);
   double SMA_Current = iMA(Symbol(),0,SlowEma,0,MODE_EMA,PRICE_CLOSE,0);
   double Poin = (FMA_Current + SMA_Current)/2;
   double Lot;
   if (PrevCross == 0) //Was undefined
   {
      if ((FMA_Current - SMA_Current) >= MinDiff * Poin) PrevCross = 1; //Bullish state
      else if ((SMA_Current - FMA_Current) >= MinDiff * Poin) PrevCross = -1; //Bearish state
      return;
   }
   else if (PrevCross == 1) //Was bullish
   {
      if ((SMA_Current - FMA_Current) >= MinDiff * Poin) //Became bearish
      {
         CloseAllOrders();
         Lot = GetLot(MaxRisk);
         NewOrder(OP_SELL,Lot);
         PrevCross = -1;
      }
   }
   else if (PrevCross == -1) //Was bearish
   {
      if ((FMA_Current - SMA_Current) >= MinDiff * Poin) //Became bullish
      {
         CloseAllOrders();
         Lot = GetLot(MaxRisk);
         NewOrder(OP_BUY,Lot);
         PrevCross = 1;
      }
   }
}

la fonction de trailing stop :

// trailing stop
void DoTrailing()
{
   int total = OrdersTotal();
   for (int pos = 0; pos < total; pos++)
   {
      if (OrderSelect(pos, SELECT_BY_POS) == false) continue;
      if (OrderSymbol() == Symbol())
      {
         if (OrderType() == OP_BUY)
         {
            RefreshRates();
            if (Bid - OrderOpenPrice() >= TrailingStop * Bid/100) //If profit is greater or equal to the desired Trailing Stop value
            {
               if (OrderStopLoss() < (Bid - TrailingStop * Bid/100)) //If the current stop-loss is below the desired trailing stop level
                  OrderModify(OrderTicket(), OrderOpenPrice(), NormPrice(Bid - TrailingStop * Bid/100), OrderTakeProfit(), 0);
            }
         }
         else if (OrderType() == OP_SELL)
         {
            RefreshRates();
            if (OrderOpenPrice() - Ask >= TrailingStop * Ask/100) //If profit is greater or equal to the desired Trailing Stop value
            {
                      if ((OrderStopLoss() > (Ask + TrailingStop * Ask/100)) || (OrderStopLoss() == 0)) //If the current stop-loss is below the desired trailing stop level
                  OrderModify(OrderTicket(), OrderOpenPrice(), NormPrice(Ask + TrailingStop * Ask/100), OrderTakeProfit(), 0);
            }
         }
      }
   }   
}

et le corps lui-même :

//main program
int start()
  {

   if (TrailingStop > 0) DoTrailing();
          
        static datetime Time0;
        if (Time0 == Time[0]) return;
        Time0 = Time[0];
      {
       CheckCross();     
              
      }

   return(0);
  }

Merci de votre intérêt !



 
prupru:


Je n'ai pas modifié la fonction de clôture de l'ordre pour vérifier le symbole et les nombres magiques, car je vais négocier sur un seul symbole et avec un seul EA par compte. Mais je le ferai après avoir réglé d'autres problèmes plus importants.


ne soyez pas paresseux, faites-le directement ! !!!

c'est une chose importante que vous devez toujours inclure

si tu veux réparer ton programme et que nous te donnons des conseils sur ce qu'il faut faire

alors si tu ne veux pas travailler pour le réparer, pourquoi est-ce qu'on t'aide ? ?

 
deVries:


ne soyez pas paresseux, faites-le directement ! !!!

c'est une chose importante que vous devez toujours inclure

si tu veux réparer ton programme et qu'on te donne des conseils sur ce qu'il faut faire

alors si tu ne veux pas travailler pour le réparer alors pourquoi on t'aide ? ?


ok, ok, on se calme)

voilà, je pense que ça devrait faire l'affaire.

ouvrir la fonction d' ordre :

OrderSend(Symbol(),Cmd,Lot,PR,Slippage,SL,TP,"",Expert_ID,0,clr);

fermer tous les ordres :

//Close all Orders
void CloseAllOrders()
{
  for(int i=OrdersTotal()-1;i>=0;i--)
   {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      if ((OrderSymbol() == Symbol()) && (OrderMagicNumber() == Expert_ID))  CloseOrder();
     }
    else
     {
      Print("Error selecting order: ",GetLastError());
      Print(" i= ", i, " Symbol= ", OrderSymbol());
     }
   }
return;}
 

J'ai un plus gros problème maintenant, mon courtier a tendance à exécuter partiellement les ordres.

Cher client,

Nous vous informons que votre transaction a été partiellement ouverte (2,32 lots sur 15,84) au prix de 587,318.

Si vous avez des questions supplémentaires sur ce sujet, n'hésitez pas à nous contacter.

Sincères salutations,

Courtier.

Voici ce que dit le support :

Veuillez noter que pendant les périodes de forte volatilité ou de faible liquidité, les ordres limités peuvent être partiellement exécutés. Cela signifie que la position sera immédiatement remplie entièrement ou partiellement si le prix est atteint. Dans votre cas, votre ordre a été exécuté partiellement, c'est pourquoi vous avez reçu une lettre de notification.

Je comprends comment fermer tous les ordres malgré qu'ils soient fermés partiellement, je dois juste faire Close all Orders while OrdersTotal() > 0, mais je ne sais pas encore quoi faire quand les ordres sont ouverts partiellement.

edit :

Je viens de réaliser que je dois vérifier les ordres Symbol et magicnumber, c'est un peu plus difficile.

edit : voici la fonction close all orders qui devrait fermer les ordres même avec une fermeture partielle

//Close all my Orders
void CloseAllOrders()
{
int notMyOrders = 0;

for(int j=OrdersTotal()-1;j>=0;j--)
{
    if(OrderSelect(j,SELECT_BY_POS,MODE_TRADES))
      {
       if ((OrderSymbol() != Symbol()) || (OrderMagicNumber() != Expert_ID)) notMyOrders++;
      }
    else
      {
       Print("Error selecting order: ",GetLastError());
       Print(" j= ", j, " Symbol= ", OrderSymbol());
      }    
}

 while (OrdersTotal()>notMyOrders)
 {
  for(int i=OrdersTotal()-1;i>=0;i--)
   {
    if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES))
     {
      if ((OrderSymbol() == Symbol()) && (OrderMagicNumber() == Expert_ID))  CloseOrder();
     }
    else
     {
      Print("Error selecting order: ",GetLastError());
      Print(" i= ", i, " Symbol= ", OrderSymbol());
     }
   }
 }


return;}
 

Voici comment je vais me battre avec l'exécution partielle des ordres ouverts,

L'ouverture d'un ordre ne se fera plus avec une fonction NewOrder, mais elle se fera avec celle-ci :

//OpenOrders in case of partial execution
int OpenPartOrders(int Cmd, double Lot)
{
 int NumOrders = 0;
 int LastTic = -1;
 double Step = MarketInfo(Symbol(),MODE_LOTSTEP);
 double LotRemains = Lot;
 
 //MathFloor( /Step)*Step;;
while (LotRemains>0)
 {
  LastTic = NewOrder(Cmd, LotRemains);
  NumOrders++;
  if(OrderSelect(LastTic, SELECT_BY_TICKET)==true)
     {
      LotRemains = LotRemains - OrderLots();
      Print("NumberOfOrders ", NumOrders, " Ticket ", LastTic, " LotRemains ", LotRemains, " initial Lot ", Lot);          
     }
  else
   {
    Print("OrderSelect returned the error of ",GetLastError());
    LotRemains = 0;//not to create an endless loop opening new orders again and again
   }
 } 
return(NumOrders);}
Raison: