Need help with EA , many thanks

 
Hi,


I am new to programing and I am trying to write an EA that trades between 3 trend lines (red, yellow & violet)

for example, if the open price lies between yellow&violet, then StopLoss(SL)=violet & target(TG)=yellow(bullish market)

once price breaks through TG, scale out 50% and the remaining 50% is updated with new SL=yellow & new TG=red

Below is the code I tempted, but the scale out feature is not working at all

this code also generates error=1, error=130 & error=146

Could someone please point out the major issues or give directions?

I really appreciate it, Many Thanks!!!!!!




if(bullorbear==1)    //bull
    {           
        if (Ask>red&&over_red==true)
            {TG=NormalizeDouble(Ask+TS*pip,Digits); band=1.1; SL=NormalizeDouble(Bid-5*pip,Digits);}
               
        if (red>=Ask&&Ask>yellow)
            {TG=red; SL=yellow; band=2.2; }
           
        if (yellow>=Ask&&Ask>=violet)
            {TG=yellow; SL=violet; band=3.3; }
           
        if (Ask<violet&&under_violet==true)
            {TG=violet; band=4.4; SL=NormalizeDouble(Bid-5*pip,Digits);}
       
        CloseSellOrders(Magic);   
    }       
           

    if(bullorbear==2)    //bear
    {           
        if (Bid<red&&over_red==true)
            {TG=NormalizeDouble(Bid-TS*pip,Digits); band=1.1; SL=NormalizeDouble(Ask+5*pip,Digits); }
                       
        if (red<=Bid&&Bid<yellow)
            {TG=red; SL=yellow; band=2.2;}
           
        if (yellow<=Bid&&Bid<=violet)
            {TG=yellow; SL=violet; band=3.3;}
           
        if (Bid>violet&&under_violet==true)
            {TG=violet; band=4.4; SL=NormalizeDouble(Ask+5*pip,Digits); }
               
        CloseBuyOrders(Magic);   

    } 

int index=OrdersTotal();   

if(TradeIsBusy() < 0)
return(-1);
RefreshRates();    // refresh the market info
   
   
    if(signal==true&&total<allowed_order)
    ticket=MoveOpenOrder(Magic, SL, bullorbear, spread, TG);
   
TradeIsNotBusy();

   double table[][5];
   ArrayInitialize(table,0);
   ArrayResize(table,ArraySize(table)+1);
   ticket_no=ticket/10;
   table[0,0]=ticket_no;
   table[0,1]=SL;
   table[0,2]=TG;
   table[0,3]=band;



   MoveTrailingStop(table, index, TS);

return(0)  //end of start()



  
   //|--------------Move Open Orders
int MoveOpenOrder(int Magic, double SL, int bullorbear, double spread, double TG)
{ 
   int ticket;
     
   if((CountOrders(OP_BUY,Magic)+CountOrders(OP_SELL,Magic))<MaxOrders)
   { 
      if(bullorbear==1)
      {     ticket=OrderSend(Symbol(),OP_BUY,lot,Ask,Slippage,0,0,EAName,Magic,0,Blue);
         OrderModify(OrderTicket(),OrderOpenPrice(),SL,TG,0,Blue);
         if(OrderModify(OrderTicket(),OrderOpenPrice(),SL,TG,0,Blue)==false)
            Alert("BUY!! ",Symbol(),", err=", GetLastError(),", SL=",SL);
         return(ticket);
      }
     
      if(bullorbear==2)
      {
         ticket=OrderSend(Symbol(),OP_SELL,lot,Bid,Slippage,0,0,EAName,Magic,0,Red);
         OrderModify(OrderTicket(),OrderOpenPrice(),SL,TG,0,Red);
         if(OrderModify(OrderTicket(),OrderOpenPrice(),SL,TG,0,Red)==false)
            Alert("SELL!! ",Symbol(),", err=", GetLastError(),", SL=",SL);
         return(ticket);
      }
    }
   

}   


//|------------trailingstop with array TS=20pips
void MoveTrailingStop(double& table[][], int index, int TS)

{
   int cnt,total=OrdersTotal();
   double new_lot;
   double SL;
  
     
   for(cnt=0;cnt<total;cnt++)
   {
      OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
      if(OrderType()<=OP_SELL&&OrderSymbol()==Symbol()&&OrderMagicNumber()==Magic) //check all opened ticket
      {
         if(OrderType()==OP_BUY)    //buy ticket(Bull)
         {
            if(table[cnt,3]==1.1&&Bid>table[cnt,2])
                       
            {   
                SL=NormalizeDouble(Bid-TS*pip,Digits);
                table[cnt,1]=SL; table[cnt,2]=Bid;
                OrderModify(OrderTicket(),OrderOpenPrice(),SL,0,0, Violet);    //no TG added
                if(OrderModify(OrderTicket(),OrderOpenPrice(),SL,0,0, Violet)==false)
                Alert("band1 trailing profit error:", GetLastError());
           
            }
           
            if(table[cnt,3]>table[index,3])    //meaning band upgraded
            {
               table[cnt,1]=table[index,1];table[cnt,2]=table[index,2];table[cnt,3]=table[index,3];
                OrderModify(OrderTicket(),OrderOpenPrice(),table[cnt,1],0,0, Violet);   
                if(OrderModify(OrderTicket(),OrderOpenPrice(),table[cnt,1],0, 0,Violet)==false)
                Alert("upgrade band err:", GetLastError());
               
                if(scaling==true)
                {
                    new_lot=lot/2;
                    OrderClose(OrderTicket(),new_lot, Bid, Slippage);
                    if(OrderClose(OrderTicket(),new_lot, Bid, Slippage)==false)
                    Alert("scale out error:", GetLastError());
                   
                    for(int i=total; i>=0; i--)
                    {   
                        if ((table[i,1]==table[index,1])&&(table[i,2]==table[index,2]))
                        {table[i,0]=OrderTicket();break;}
                    }
                }
               
            }
           
         }
       
         if(OrderType()==OP_SELL)    //SELL ticket(Bear)
        {
            if(table[cnt,3]==1.1&&Ask<table[cnt,2])
                       
            {    SL=NormalizeDouble(Ask+TS*pip,Digits);
                table[cnt,1]=SL; table[cnt,2]=Ask;
                OrderModify(OrderTicket(),OrderOpenPrice(),SL,0, 0,Violet);
                if(OrderModify(OrderTicket(),OrderOpenPrice(),SL,0,0, Violet)==false)
                Alert("band1 trailing profit error:", GetLastError());
           
            }
           
            if(table[cnt,3]>table[index,3])   
            {    table[cnt,1]=table[index,1];table[cnt,2]=table[index,2];table[cnt,3]=table[index,3];
                OrderModify(OrderTicket(),OrderOpenPrice(),table[cnt,1],0,0, Violet);
                if(OrderModify(OrderTicket(),OrderOpenPrice(),table[cnt,1],0,0, Violet)==false)
                Alert("upgrade band err:", GetLastError());
               
                if(scaling==true)
                {
                    new_lot=lot/2;
                    OrderClose(OrderTicket(),new_lot, Ask, Slippage);
                    if(OrderClose(OrderTicket(),new_lot, Ask, Slippage)==false)
                    Alert("scale out error:", GetLastError());
                   
                    for( i=total; i>=0; i--)
                    {   
                        if ((table[i,1]==table[index,1])&&(table[i,2]==table[index,2]))
                        {table[i,0]=OrderTicket();break;}
                    }
                }
               
            }
           
         }
      }
   }
   return(0);
}


 
What is pip ?
 
int init()
{
 pip=Point*MathPow(10,Digits%2);
 string symbol=Symbol();
 double spread=GetInfo(symbol);
 
return(0);
}
Thanks for your attention
 

Small remark.

You always have Point = MathPow(10, Digits % -2) !!

So pip = Point * MathPow(10, Digits % 2) = 1.

 

Ah I see, it's how you adjust for 4/5 digit brokers, OK

I just noticed you are doing an OrderModify twice after the OrderSend ? you don't need the first one . . . also capture the errors from the OrderSend and print some of the relevant variables so you can track down what is going on, for example . . .

if(bullorbear==1)
      { ticket=OrderSend(Symbol(),OP_BUY,lot,Ask,Slippage,0,0,EAName,Magic,0,Blue);
        if (ticket < 0)
                                           // OrderModify(OrderTicket(),OrderOpenPrice(),SL,TG,0,Blue);   // this isn't needed
         {
         print("Order failed: error ", GetLastError(), " Buy Order @ ", Ask, " Size = ", lot); 
         return(ticket);
         }           
         else if(!OrderModify(OrderTicket(),OrderOpenPrice(),SL,TG,0,Blue))                     //  don't need the  ==false just use  !
            Alert("BUY Modify!! ",Symbol(),", err=", GetLastError(),", SL=",SL, " TG=", TG);    //  add the TG
          
         return(ticket);
      }
 
  1. EA's must adjust for 4/5 digit brokers, TP, SL, AND slippage. Filthy, stinking, rich, two out of three ain't bad. On ECN brokers you must open first and THEN set stops.
    //++++ These are adjusted for 5 digit brokers.
    int     pips2points;    // slippage  3 pips    3=points    30=points
    double  pips2dbl;       // Stoploss 15 pips    0.0015      0.00150
    int     Digits.pips;    // DoubleToStr(dbl/pips2dbl, Digits.pips)
    int     init(){
        if (Digits == 5 || Digits == 3){    // Adjust for five (5) digit brokers.
                    pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;
        } else {    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0; }
        // OrderSend(... Slippage.Pips * pips2points, Bid - StopLossPips * pips2dbl
    

  2.       {     ticket=OrderSend(Symbol(),OP_BUY,lot,Ask,Slippage,0,0,EAName,Magic,0,Blue);
             OrderModify(OrderTicket(),OrderOpenPrice(),SL,TG,0,Blue);
    OrderTicket and OOP can NOT be used until after you orderSelect.
    int ticket = OrderSend(...)
    if (ticket < 0) 
       Alert("OrderSend failed: ", GetLastError());
    else if (!OrderSelect(ticket, SELECT_BY_POS))
       Alert("OrderSelect failed: ", GetLastError());
    else if (!OrderModify(OrderTicket()...)
       Alert("OrderModify failed: ", GetLastError());
    

  3. if(bullorbear==1)    //bull
    Self documenting code makes things clearer.
    #define BULL 1
    #define BEAR 2
    :
    int bullOrBear = BULL;
    :
    if(bullOrBear==BULL)    //bull
    ============================= or
    bool isBull = true;
    :
    if (isBull) ...
    if (!isBull) //bear
    

  4. Likewise:
    #define T_TICKET 0
    #define T_SL     1
    #define T_TG     2
    #define T_BAND   3
       #define T_COUNT 4
    double table[][T_COUNT];
       table[0,TICKET]=ticket_no;
       table[0,SL]=SL;
       table[0,TG]=TG;
       table[0,BAND]=band;
    

  5.  for(cnt=0;cnt<total;cnt++)
       {
          OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
          if(OrderType()<=OP_SELL&&OrderSymbol()==Symbol()&&OrderMagicNumber()==Magic) //check all opened ticket
          {
             if(OrderType()==OP_BUY)    //buy ticket(Bull)
             {
                if(table[cnt,3]==1.1&&Bid>table[cnt,2])
    In the presence of other EAs (including itself on other pairs) the EA's position will be changing. your table will not be indexed. Also you MUST count down when closing or modifying in the presence of multiple order (multiple charts)
    int cnt=0;
        for(pos = OrdersTotal()-1; pos >= 0 ; pos--) if (
            OrderSelect(pos, SELECT_BY_POS)                 // Only my orders w/
        &&  OrderMagicNumber()  == magic.number             // my magic number
        &&  OrderSymbol()       == Symbol()                 // and my pair.
        ){
             cnt++;
             if(OrderType()==OP_BUY)    //buy ticket(Bull)
             {
                if(table[cnt,3]==1.1&&Bid>table[cnt,2])
    

  6. if(table[cnt,3]>table[index,3])    //meaning band upgraded
    index is the count of all orders. Again will be changing outside of the EA's control and your table is junk.
  7.        OrderModify(OrderTicket(),OrderOpenPrice(),table[cnt,1],0,0, Violet);   
                    if(OrderModify(OrderTicket(),OrderOpenPrice(),table[cnt,1],0, 0,Violet)==false)
    Delete first modify and first close. I prefer if (!OrderModify(...)) which reads if not modified, rather than if modified is false.
  8. new_lot=lot/2;
                        if(OrderClose(OrderTicket(),new_lot, Bid, Slippage)==false)
    This will not work. Lot sized must be a multiple of lot step and no smaller than min lot.
        double  lotStep         = MarketInfo(Symbol(), MODE_LOTSTEP),   //IBFX= 0.01
                minLot          = MarketInfo(Symbol(), MODE_MINLOT );   //IBFX= 0.10
        double  new_lot=MathRound(lot/2/lotStep)*lotStep;
        if (new_lot < minLot) new_lot = lot; // Close all
    

  9.  if(OrderClose(OrderTicket(),new_lot, Bid, Slippage)==false)
                        Alert("scale out error:", GetLastError());
                       
                        for(int i=total; i>=0; i--)
                        {   
                            if ((table[i,1]==table[index,1])&&(table[i,2]==table[index,2]))
                            {table[i,0]=OrderTicket();break;}
    The moment you partially close, you get a new ticket number so OrderTicket is now invalid and so is your table. On a terminal restart, (OS reboot, power failure, click close button instead of minimize, etc.) are you rebuilding your table so the EA can recover?
 

Thank you all for your reply.

WHRoeder & RaptorUK, you two have helped a lot to this forum, I respect you sincerely

I will learn what you have wrote here and fix my codes

With regards to the "scaling-out" function, I thought about the issue that once the EA is off, the table will be a mess.

(what if I have a function inside the init() to check the table before the start()???)

Could you please give me a direction, maybe there is a different approach rather than the 2D array?

Thanks in advance.


 
//|---------initialization

int init()
{
 pip=Point*MathPow(10,Digits%2);
 string symbol=Symbol();
 double spread=GetInfo(symbol);
 int err=GetLastError();
 
 if (Digits == 5 || Digits == 3)
        {    // Adjust for five (5) digit brokers.
                 pips2double = Point*10; 
                 pips2point = 10;   
                 Digits.pips = 1;
    } 
        else 
        {    
                pips2double = Point;    
                pips2point =  1;   
                Digits.pips = 0; 
        }
    // OrderSend(... Slippage.Pips * pips2points, Bid - StopLossPips * pips2dbl
        
double table[][5];
int cnt=0;
for(int pos = OrdersTotal()-1; pos >= 0 ; pos--)        //check ALL orders in the terminal
{       
        if  (
                 OrderSelect(pos, SELECT_BY_POS)           // select Only my orders with
                 &&  OrderMagicNumber()  == Magic          // my magic number
                 &&  OrderSymbol()       == Symbol()       // and my pair.
                )
                
                {
                        cnt++;
                        ArrayResize(table,cnt);         //increase table's 1st dimension 
                        if(OrderStopLoss()==0) 
                        { 
                          if(OrderType()== OP_BUY)
                                double SL=NormalizeDouble((Bid-10*pips2double),Digits.pips);
                          if(OrderType()== OP_SELL)
                                double SL=NormalizeDouble((Ask+10*pips2double),Digits.pips);    
                        }
                        else SL=OrderStopLoss();
                        
                        if(OrderTakeProfit()==0) 
                        { 
                          if(OrderType()== OP_BUY)
                                double TG=NormalizeDouble((Bid+10*pips2double),Digits.pips);
                          if(OrderType()== OP_SELL)
                                double TG=NormalizeDouble((Ask-10*pips2double),Digits.pips);    
                        }
                        
                        else TG=OrderTakeProfit();
                        
                        table[cnt-1,t_ticket]=OrderTicket();//is it ok with integer in a double array?
                        table[cnt-1,t_SL]=SL;
                        table[cnt-1,t_TG]=TG;
                        table[cnt-1,t_band]=0;
                        table[cnt-1,t_modified]=0;
                        
                }
}       
return(0);
}


 
//|--------------Move Open Orders
int MoveOpenOrder(int Magic, double SL, double TG, int bullorbear, double spread)
{  
   int ticket;
      
   if((CountOrders(OP_BUY,Magic)+CountOrders(OP_SELL,Magic))<MaxOrders)
   {  
          if(bullorbear==BULL)
          {             double SL2=NormalizeDouble(Bid-(spread+7)*pips2double,Digits.pips);
         
         ticket=OrderSend(Symbol(),OP_BUY,lot,Ask,Slippage*pips2point,0,0,EAName,Magic,0,Blue);
                 if(ticket<0) Alert("Order failed: error ", err, " Buy Order @ ", Ask, " Size = ", lot);
         else if(!OrderSelect(ticket,SELECT_BY_TICKET)) Alert("cannot find BUY ticket");
                 else if(!OrderModify(OrderTicket(),OrderOpenPrice(),SL,TG,0,Blue))
         Alert("BUY!! ",Symbol(),", err=", err,", SL=",SL, ", TG=", TG);
                 
                 return(ticket);
         
      }
      
          if(bullorbear==BEAR)
      {         SL2=NormalizeDouble(Ask+(spread+7)*pip,Digits.pips);
         
                 ticket=OrderSend(Symbol(),OP_SELL,lot,Bid,Slippage*pips2point,0,0,EAName,Magic,0,Red);
                 if(ticket<0)Alert("Order failed: error ", err, " Sell Order @ ", Bid, " Size = ", lot);
                 else if(!OrderSelect(ticket,SELECT_BY_TICKET)) Alert("SELL ticket not found");
                 else if (!OrderModify(OrderTicket(),OrderOpenPrice(),SL,TG,0,Red))
                 Alert("SELL!! ",Symbol(),", err=", err,", SL=",SL, ", TG=", TG);
         
                 return(ticket);
      }
        }
        
}
 
holdenmcgorin:
With regards to the "scaling-out" function, I thought about the issue that once the EA is off, the table will be a mess.

The question is how many times are you scaling out? If you want only once and let the remainder ride, it's easy - no table - no persistent storage needed.

Just move the SL to break even and then do the partial close. Use a OrderSelect loop and if SL is at BE or better, no scaling - just trailing stops.

 
WHRoeder:

Just move the SL to break even and then do the partial close. Use a OrderSelect loop and if SL is at BE or better, no scaling - just trailing stops.

Not too sure if I understand it

even just to scale out once, the target is not always a fixed pip like 30pips or 50pips, it depends on the distance between two trendlines

for example, on a M5 chart, target maybe 10pips away, but on a H1/H4 chart, the target maybe 100pips away.

Also, the trend lines change when signal changes so target distance varies even on the same chart

To be able to scale out, TP=0 when OrderSend/OrderModify, how do I keep track when to scale out for each ticket?

Can you please explain a bit more, maybe I am missing something?

Reason: