OrderSend and OrderModify Help

 

Hi, my strategy is based on taking trades off of the four hour 5 EMA - in a buy, the stoploss is set at the lowest low of the last four candles, and the opposite in a sell. Somehow, in the backtest, only 4 trades are executed, and the inital stop is 4.0000 in the EUR/USD(for the sell order it took). Also, the journal keeps showing orderSend() error 1


Help would be appreciated


//+------------------------------------------------------------------+
//|                                                  EMA control.mq4 |
//|                      Copyright © 2011, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"


#define SIGNAL_NONE 0
#define SIGNAL_BUY   1
#define SIGNAL_SELL  2

extern double MagicNumber = 78652;
extern double Accuracy = 10;
extern double Lots = 0.1;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   if(Digits == 5)  
      {
         Accuracy = Accuracy * 10;
      }
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   int Order = SIGNAL_NONE;
   int Ticket;
   
   
//Initialize Indicator variables

double Five = iMA(NULL,0,5,0,MODE_EMA,PRICE_CLOSE,1);
double Eight = iMA(NULL,0,8,0,MODE_SMA,PRICE_CLOSE,1);
double TwentyOne = iMA(NULL,0,21,0,MODE_EMA,PRICE_CLOSE,1);
double FiftyFive = iMA(NULL,0,55,0,MODE_EMA,PRICE_CLOSE,1);
double TwoHundred = iMA(NULL,0,200,0,MODE_EMA,PRICE_CLOSE,1);
double RSIval = iRSI(NULL,0,14,PRICE_CLOSE,1);

//Check position
   bool IsTrade = False;
   int Total = OrdersTotal();
         int BuyShift = 0, SellShift = 0;

   for (int i = 0; i < Total; i ++) {//:for
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if(OrderType() == OP_BUY && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {//:1
            //Adjust Stops
               IsTrade = True;
               RefreshRates();
         
               for(int a = 0;a<10;a++)
                  {
                     if(MathAbs(Low[a] - Five) <= Accuracy*Point && OrderType() == OP_BUY) break;
                     else BuyShift++;
                   }
                   
                     
               if(Open[1] > Close[1] && Low[1] > Low[BuyShift] && Low[1] > OrderStopLoss()) OrderModify(OrderTicket(),OrderOpenPrice(),Low[1],OrderTakeProfit(),0,CLR_NONE);
               }//:1
       
       if(OrderType() == OP_SELL && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {//:2
            //Adjust Stops
               IsTrade = true;
                   for(int b = 0;b<10;b++)
                  {
                     if(MathAbs(High[b] - Five) <= Accuracy*Point && OrderType() == OP_SELL) break;
                     else SellShift++;
                   }
               RefreshRates();
               if(Close[1] < Open[1] && High[1] < High[SellShift] && High[1] < OrderStopLoss()) OrderModify(OrderTicket(),OrderOpenPrice(),High[1],OrderTakeProfit(),0,CLR_NONE);
               }//:2
         
         
         }//:for 
            

   
   
//Check conditions

if(Five > Eight && Eight > TwentyOne && TwentyOne > FiftyFive && FiftyFive > TwoHundred) bool Uptrend = true; else Uptrend = false;
if(Five < TwentyOne && Eight > TwentyOne && TwentyOne < FiftyFive && FiftyFive < TwoHundred) bool Downtrend = true; else Downtrend = false;

if(Uptrend)
   {
      if(Open[2] >= Five && MathAbs(Low[1] - Five) <= Accuracy*Point && RSIval > 50) Order = SIGNAL_BUY;
    }
if(Downtrend)
   {
      if(Open[2] <= Five && MathAbs(High[1] - Five) <= Accuracy * Point && RSIval < 50) Order = SIGNAL_SELL;
   }
   
//Place Orders 

if(Order == SIGNAL_BUY && IsTrade == false)
   {
       if (AccountFreeMargin() < (1000 * Lots)) {
            Print("We have no money. Free Margin = ", AccountFreeMargin());
            return(0);
         }
         double BuyStop = iLowest(NULL,0,MODE_LOW,3,2);
         Ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,MarketInfo(Symbol(),MODE_SPREAD),BuyStop,0,NULL,MagicNumber,0,CLR_NONE);
         if (Ticket==-1)   ShowERROR(Ticket,0,0);
         
    }

if(Order == SIGNAL_SELL && IsTrade == false)
   {
             if (AccountFreeMargin() < (1000 * Lots)) {
            Print("We have no money. Free Margin = ", AccountFreeMargin());
            return(0);
         }
         double SellStop = iHighest(NULL,0,MODE_HIGH,3,2);
         Ticket = OrderSend(Symbol(),OP_SELL,Lots,Bid,MarketInfo(Symbol(),MODE_SPREAD),SellStop,0,NULL,MagicNumber,0,CLR_NONE);
         if (Ticket==-1)   ShowERROR(Ticket,0,0);
         
    }

         


      
   
//----
   return(0);
  }
//+------------------------------------------------------------------+

void ShowERROR(int Ticket,double SL,double TP)
{
   int err=GetLastError();
   switch ( err )
   {                  
      case 1:                                                                               return;
      case 2:   Alert("No connection with the trading server ",        Ticket," ",Symbol());return;
      case 130: Alert("Error close foot Ticket ",                      Ticket," ",Symbol());return;
      case 134: Alert("Not enough money ",                             Ticket," ",Symbol());return;
      case 146: Alert("Error Subsystem busy trade ",                   Ticket," ",Symbol());return;
      case 129: Alert("Error Invalid price ",                          Ticket," ",Symbol());return;
      case 131: Alert("Error Invalid volume ",                         Ticket," ",Symbol());return;
      default:  Alert("Error : ",err, "   ",                           Ticket," ",Symbol());return;
   }
}

//+---------------------------------------------------------------------+
 
  1. int init()
      {
    //----
       if(Digits == 5)  
          {
             Accuracy = Accuracy * 10;
    Don't do that. Each time you change pair, period, or refresh the chart you get a deinit/init cycle. So accuracy becomes 10, 100, 1000, etc. In addition if you use a fixed slippage that also must be adjusted.
    //++++ 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.    for (int i = 0; i < Total; i ++) {//:for
          OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
          if(OrderType() == OP_BUY && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {//:1
    Always test return codes (order select). On closing/deleteing or modifying in the presence of multiple orders (multiple charts) you must count down
        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.
    

  3. OrderModify(OrderTicket(),OrderOpenPrice(),Low[1],OrderTakeProfit(),0,CLR_NONE);
    After the first modify, all others within the same bar will try to set the same values, thus the error 1.
    • Only call modify if Low[1] > OrderStopLoss()
    • Always test return codes
      if (!OrderModify(...)) Alert("OrderModify failed: ", GetLastError());

  4. // if(Five > Eight && Eight > TwentyOne && TwentyOne > FiftyFive && FiftyFive > TwoHundred) 
    //    bool Uptrend = true; else Uptrend = false;
    
    bool Uptrend = Five > Eight && Eight > TwentyOne && TwentyOne > FiftyFive && FiftyFive > TwoHundred;
    
    x
 
WHRoeder:
  1. Don't do that. Each time you change pair, period, or refresh the chart you get a deinit/init cycle. So accuracy becomes 10, 100, 1000, etc. In addition if you use a fixed slippage that also must be adjusted.
  2. Always test return codes (order select). On closing/deleteing or modifying in the presence of multiple orders (multiple charts) you must count down

  3. After the first modify, all others within the same bar will try to set the same values, thus the error 1.
    • Only call modify if Low[1] > OrderStopLoss()
    • Always test return codes
  4. x

Hi - thanks for such a fast reply - I will make your suggested changes -

Regarding orderModify(), I already test whether Low[1] > OrderStopLoss()

if(Open[1] > Close[1] && Low[1] > Low[BuyShift] && Low[1] > OrderStopLoss()) OrderModify(OrderTicket(),

I get OrderSend() errors:

2011.08.14 23:46:28 2011.07.27 07:59 EMA control EURUSD,H4: Alert: Error close foot Ticket -1 EURUSD
2011.08.14 23:46:28 2011.07.27 07:59 EMA control EURUSD,H4: OrderSend error 130

Also, my stops are messed up:

1 2010.11.23 00:00 sell 1 0.10 1.35990 4.00000 0.00000 0.00 10000.00
2 2010.11.23 12:00 modify 1 0.10 1.35990 1.35970 0.00000 0.00 10000.00
3 2010.11.23 16:00 modify 1 0.10 1.35990 1.35550 0.00000 0.00 10000.00
4 2010.11.23 20:00 modify 1 0.10 1.35990 1.34330 0.00000 0.00 10000.00
5 2010.11.24 20:00 modify 1 0.10 1.35990 1.33930 0.00000 0.00 10000.00
6 2010.11.26 08:00 modify 1 0.10 1.35990 1.33310 0.00000 0.00 10000.00
7 2010.11.26 12:00 modify 1 0.10 1.35990 1.32950 0.00000 0.00 10000.00
8 2010.11.29 07:56 s/l 1 0.10 1.32950 1.32950 0.00000 301.49 10301.49

As you can see, in the first sell, my stop is 4.0000 - how does the number get so high? I calculate my stop using the following code:

 double BuyStop = iLowest(NULL,0,MODE_LOW,3,2);

So it starts from two candles back, and counts three more candles, and uses whichever price is the lowest of the three.

The rest of the modify actions are good - it keeps moving the stop down provided the low is lower than the last one.

Also, in the 8 month backtest, it only took 3 trades - presumably because of the errors -


Thanks again!

 
gulzaar:

Also, my stops are messed up:

1 2010.11.23 00:00 sell 1 0.10 1.35990 4.00000 0.00000 0.00 10000.00
2 2010.11.23 12:00 modify 1 0.10 1.35990 1.35970 0.00000 0.00 10000.00
3 2010.11.23 16:00 modify 1 0.10 1.35990 1.35550 0.00000 0.00 10000.00
4 2010.11.23 20:00 modify 1 0.10 1.35990 1.34330 0.00000 0.00 10000.00
5 2010.11.24 20:00 modify 1 0.10 1.35990 1.33930 0.00000 0.00 10000.00
6 2010.11.26 08:00 modify 1 0.10 1.35990 1.33310 0.00000 0.00 10000.00
7 2010.11.26 12:00 modify 1 0.10 1.35990 1.32950 0.00000 0.00 10000.00
8 2010.11.29 07:56 s/l 1 0.10 1.32950 1.32950 0.00000 301.49 10301.49

As you can see, in the first sell, my stop is 4.0000 - how does the number get so high? I calculate my stop using the following code:


Maybe that 4.0 is your slippage ? Scratch that . . I see what the problem is . . . iLowest returns a BarShift value not a price . . . try . . .

double BuyStop = iLow(NULL, iLowest(NULL,0,MODE_LOW,3,2));
 
RaptorUK:
Maybe that 4.0 is your slippage ?

don't think so, because all the numbers below that are stops..
 
gulzaar:

don't think so, because all the numbers below that are stops..
Edited my reply . . take a look. ;-)
 

ok got it, lol, iLowest returns the shift value - my mistake:)


help with the other problem would be appreciated though:)

 
RaptorUK:
Edited my reply . . take a look. ;-)

Saw it, thanks! :)

So fixed that problem - now, for some reason, over a period of 8 months, on a 4 hour chart, it took nearly 800 trades - most of them being small 4-5 pip trades -


I have put a filter to not place more than one trade:

 bool IsTrade = False;
if(Order == SIGNAL_BUY && IsTrade == false)
   {
       if (AccountFreeMargin() < (1000 * Lots)) {
            Print("We have no money. Free Margin = ", AccountFreeMargin());
            return(0);
         }
         int BuyStop = iLowest(NULL,0,MODE_LOW,3,2);
         int StopLossShift = BuyStop + 2;
         Ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,MarketInfo(Symbol(),MODE_SPREAD),Low[StopLossShift],0,NULL,MagicNumber,0,CLR_NONE);
         if (Ticket==-1)   ShowERROR(Ticket,0,0);
         
    }


Still takes way too many trades though

 
gulzaar:
I get OrderSend() errors:

Best I can suggest right now is add a Print() statement right before the OrderSend, print all the variables and values used in the order send to make sure they are what they should be, you should be able to figure out the error 130 then.

Something like this is what I use and I use it lots . . .

Print(TradeType,": TradeSize= ",TradeSize ," Trade_Entry= ",Trade_Entry ," Bid= ",Bid," Trade_SL= " ,Trade_SL ," Trade_TP= ",Trade_TP);
 
RaptorUK:

Best I can suggest right now is add a Print() statement right before the OrderSend, print all the variables and values used in the order send to make sure they are what they should be, you should be able to figure out the error 130 then.

Something like this is what I use and I use it lots . . .


I don't get OrderSend errors anymore - but I am attaching the new code and the strategy tester report


it opens too many trades, and all of them close at stop.

//+------------------------------------------------------------------+
//|                                                  EMA control.mq4 |
//|                      Copyright © 2011, MetaQuotes Software Corp. |
//|                                        http://www.metaquotes.net |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2011, MetaQuotes Software Corp."
#property link      "http://www.metaquotes.net"


#define SIGNAL_NONE 0
#define SIGNAL_BUY   1
#define SIGNAL_SELL  2

extern double MagicNumber = 78652;
extern double Accuracy = 10;
extern double Lots = 0.1;

//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
  
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {
//----
   int Order = SIGNAL_NONE;
   int Ticket;
   
   
//Initialize Indicator variables

double Five = iMA(NULL,0,5,0,MODE_EMA,PRICE_CLOSE,1);
double Eight = iMA(NULL,0,8,0,MODE_SMA,PRICE_CLOSE,1);
double TwentyOne = iMA(NULL,0,21,0,MODE_EMA,PRICE_CLOSE,1);
double FiftyFive = iMA(NULL,0,55,0,MODE_EMA,PRICE_CLOSE,1);
double TwoHundred = iMA(NULL,0,200,0,MODE_EMA,PRICE_CLOSE,1);
double RSIval = iRSI(NULL,0,14,PRICE_CLOSE,1);

//Check position
   bool IsTrade;
   int Total = OrdersTotal();
         int BuyShift = 0, SellShift = 0;

   for (int i = 0; i < Total; i ++) {//:for
      OrderSelect(i, SELECT_BY_POS, MODE_TRADES);
      if(OrderType() == OP_BUY && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {//:1
            //Adjust Stops
               RefreshRates();
         
               for(int a = 0;a<10;a++)
                  {
                     if(MathAbs(Low[a] - Five) <= Accuracy*Point && OrderType() == OP_BUY) break;
                     else BuyShift++;
                   }
                   
                     
               if(Open[1] > Close[1] && Low[1] > Low[BuyShift] && Low[1] > OrderStopLoss()) OrderModify(OrderTicket(),OrderOpenPrice(),Low[1],OrderTakeProfit(),0,CLR_NONE);
               }//:1
       
       if(OrderType() == OP_SELL && OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) {//:2
            //Adjust Stops
                               for(int b = 0;b<10;b++)
                  {
                     if(MathAbs(High[b] - Five) <= Accuracy*Point && OrderType() == OP_SELL) break;
                     else SellShift++;
                   }
               RefreshRates();
               if(Close[1] < Open[1] && High[1] < High[SellShift] && High[1] < OrderStopLoss()) OrderModify(OrderTicket(),OrderOpenPrice(),High[1],OrderTakeProfit(),0,CLR_NONE);
               }//:2
         
         
         }//:for 
            

   
   
//Check conditions

 if(Digits == 5)  
      {
         Accuracy = Accuracy * 10;
      }

if(Five > Eight && Eight > TwentyOne && TwentyOne > FiftyFive && FiftyFive > TwoHundred) bool Uptrend = true; else Uptrend = false;
if(Five < TwentyOne && Eight > TwentyOne && TwentyOne < FiftyFive && FiftyFive < TwoHundred) bool Downtrend = true; else Downtrend = false;

if(Uptrend)
   {
      if(Open[2] >= Five && MathAbs(Low[1] - Five) <= Accuracy*Point && RSIval > 50) Order = SIGNAL_BUY;
    }
if(Downtrend)
   {
      if(Open[2] <= Five && MathAbs(High[1] - Five) <= Accuracy * Point && RSIval < 50) Order = SIGNAL_SELL;
   }
   
//Place Orders 

if(Order == SIGNAL_BUY && IsTrade == false)
   {
       if (AccountFreeMargin() < (1000 * Lots)) {
            Print("We have no money. Free Margin = ", AccountFreeMargin());
            return(0);
         }
         int BuyStop = iLowest(NULL,0,MODE_LOW,3,2);
         int StopLossShift = BuyStop + 2;
         Ticket = OrderSend(Symbol(),OP_BUY,Lots,Ask,MarketInfo(Symbol(),MODE_SPREAD),Low[StopLossShift],0,NULL,MagicNumber,0,CLR_NONE);
                        IsTrade = True;
         if (Ticket==-1)   ShowERROR(Ticket,0,0);
         
    }

if(Order == SIGNAL_SELL && IsTrade == false)
   {
             if (AccountFreeMargin() < (1000 * Lots)) {
            Print("We have no money. Free Margin = ", AccountFreeMargin());
            return(0);
         }
         int SellStop = iHighest(NULL,0,MODE_HIGH,3,2);
         StopLossShift = SellStop + 2;
         Ticket = OrderSend(Symbol(),OP_SELL,Lots,Bid,MarketInfo(Symbol(),MODE_SPREAD),High[StopLossShift],0,NULL,MagicNumber,0,CLR_NONE);
                        IsTrade = True;
         if (Ticket==-1)   ShowERROR(Ticket,0,0);
         
    }

         


      
   
//----
   return(0);
  }
//+------------------------------------------------------------------+

void ShowERROR(int Ticket,double SL,double TP)
{
   int err=GetLastError();
   switch ( err )
   {                  
      case 1:                                                                               return;
      case 2:   Alert("No connection with the trading server ",        Ticket," ",Symbol());return;
      case 130: Alert("Error close foot Ticket ",                      Ticket," ",Symbol());return;
      case 134: Alert("Not enough money ",                             Ticket," ",Symbol());return;
      case 146: Alert("Error Subsystem busy trade ",                   Ticket," ",Symbol());return;
      case 129: Alert("Error Invalid price ",                          Ticket," ",Symbol());return;
      case 131: Alert("Error Invalid volume ",                         Ticket," ",Symbol());return;
      default:  Alert("Error : ",err, "   ",                           Ticket," ",Symbol());return;
   }
}

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

What value does IsTrade have when you declare it ? Either make this static or give it a global scope . . .

bool IsTrade;
Reason: