Bizarre error

 

hi Coders,


I was programming a EA that i had in mind but after doing some backtesting i realized that i'd be better if the system had a Trailing Stop or Breakeven, then i started to code the break even first. And this is the code:

for(int k=0;k<=OrdersTotal();k++)
{
OrderSelect(k,SELECT_BY_POS);
{
if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
{
if(OrderType()==OP_BUY)
{
RefreshRates();

Comment("\n BreakEven=", DoubleToStr(OrderOpenPrice() + BreakEven*Point, 4)," ASK=", DoubleToStr(MarketInfo(Symbol(),MODE_ASK), 4));
if(MarketInfo(Symbol(),MODE_ASK) >= OrderOpenPrice() + BreakEven*Point)
{
if(OrderStopLoss()!=OrderOpenPrice())
OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Green);
}
}
else if(OrderType()==OP_SELL)
{

RefreshRates();
Comment("BreakEven=", OrderOpenPrice() - BreakEven*Point," BID=", Bid);
if(MarketInfo(Symbol(),MODE_BID) <= OrderOpenPrice() - BreakEven*Point)
{
if(OrderStopLoss()!=OrderOpenPrice())
OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Green);
}
}
}
}
}


Aparently the logic is ok (correct me if i'm wrong), however in my tests nothing happened, like if the conditions never come true, so i put a comment right before the condition, and for my surprise, the Ask price is not the Ask price of the market, but instead the opening price of the order, or at least this is what MT shows on screen. This is why the conditions never are accomplished because the Breakeven price will be always higher (Longs) or Lower (Shorts) than the OrderOpenPrice.

But this is not the issue, the issue is why it shows the OrderOpenPrice when i'm coding to work with the ask price? (the same happens with shorts breakvens)

Maybe a is there a stupid error that i cant see?

I'm puzzled!

 

Code:

string comment = ""; //Comment() function always renews the comment, it doesn't append. Using a variable allows for better comment management.
for(int k=OrdersTotal()-1;k>=0;k--){ //Always decrement here instead of incrementing.. avoids errors when closing/deleting trades
   if(OrderSelect(k, SELECT_BY_POS)){ //Put this in a condition to ensure that it was selected successfully before proceeding
      if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber){
         RefreshRates(); //save a line of code by refreshing rates here instead of inside buy/sell below
         if(OrderType() == OP_BUY){
            comment = comment + "\nBreakEven=" + DoubleToStr(OrderOpenPrice() + BreakEven*Point, 4) + " ASK=" + DoubleToStr(Ask, 4);
            
            if(Ask >= OrderOpenPrice() + BreakEven*Point && OrderStopLoss() != OrderOpenPrice()){ //might as well put both conditions in the same one, won't hurt performance
               OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Green);
            }
         }
         else if(OrderType() == OP_SELL){
            comment = comment + "BreakEven=" + DoubleToStr(OrderOpenPrice() - BreakEven*Point, 4) + " BID=" + Bid;
            
            if(Bid <= OrderOpenPrice() - BreakEven*Point && OrderStopLoss() != OrderOpenPrice()){ //might as well put both conditions in the same one, won't hurt performance
               OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Green);
            }
         }
      }
   }
}
Comment(comment);

Try running this fixed code before we continue. I don't trust the integrity of your previous post because the syntax error would have prevented compilation -- which leads me to believe we're not seeing the actual code. Fixing is always best on code currently being used. Let me know clearly what problem is still occurring and we'll take it from there.

Jon

 
Thanks Jon, I will test it a few hours and let you know.
 

Hi Jon,

I'm sorry to say that your solution didnt work either. When the EA opens a position takes the Ask/Bid price as it were the OrderOpenPrice and therefore it doesnt make the Breakeven. I copy/paste your code. Look the screenshot which illustrates it. This smells to me like a bug of MT?? you tell me..


 

It isn't quite clear to me what the problem is. I use this type of logic all the time and it never fails me. The only thing I can think of that could be problematic is if you're not running this at every tick or something. I went over the code i pasted and there really isn't any error there. The only thing that could be problematic that I see is if you try to add a trailing stop or something, then this code would keep changing it back to a breakeven. To avoid this, change:

OrderStopLoss() != OrderOpenPrice()

to

OrderStopLoss() < OrderOpenPrice() // for buys
OrderStopLoss() > OrderOpenPrice() // for sells

I haven't seen your whole code so I'm afraid you're gonna be on your own to find the problem. If I were you though, I'd stop looking at the above block of code and look for the cause elsewhere.

Jon

 

the code is rather simple, the code as it is here it's not working for me:

extern int    FastMA=7;
extern int    SlowMA=15;
extern int    SlowerMA=90;
extern int    RSI=14;
extern int    Momentum=14;
extern int    Slippage=3;
extern int    MagicNumber=144000;
extern int    BreakEven=20;
extern int    TakeProfit=100;
extern double Lots=1.0;



//+------------------------------------------------------------------+
//| expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+

double DetermineSLShort()
   {
      double SLShort;
      for(int i=1;i<=20;i++)
        {
          if(High[i]<High[i+2] && High[i+1]<High[i+2]&& High[i+2]>High[i+3] && High[i+2]>=High[i+4])
              {
                SLShort=High[i+2]+15*Point;
                break;
              }
        }
      
      return(SLShort);
   }

double DetermineSLLong()
   {
      double SLLong;
      for(int i=1;i<=20;i++)
        {
          if( Low[i]>Low[i+2] && Low[i+1]>Low[i+2] && Low[i+2]<Low[i+3] && Low[i+2]<=Low[i+4])
              {
                SLLong=Low[i+2]-15*Point;
                break;
              }
        }
      
      return(SLLong);
   }



int start()
  {
//----
   int i;
   int CountTrades;
   int BuyTicket;
   int SellTicket;
   double ValueFastMA1=iMA(Symbol(),0,FastMA,0,MODE_EMA,PRICE_CLOSE,1);
   double ValueFastMA2=iMA(Symbol(),0,FastMA,0,MODE_EMA,PRICE_CLOSE,2);
   
   double ValueSlowMA1=iMA(Symbol(),0,SlowMA,0,MODE_EMA,PRICE_CLOSE,1);
   double ValueSlowMA2=iMA(Symbol(),0,SlowMA,0,MODE_EMA,PRICE_CLOSE,2);

   
  for(i=0;i<=OrdersTotal();i++)
   { 
    OrderSelect(i,SELECT_BY_POS);
    {
     if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber)
       CountTrades++;
     if(CountTrades>=1)
      return (0);
    }
   }
   

   
 

second part

   //LONG ROUTINE//
   
   double NormalizedAsk=NormalizeDouble(Ask,4);
   if(ValueFastMA2<ValueFastMA1 && ValueFastMA1>ValueSlowMA1 && ValueSlowMA2>ValueFastMA2)
     {
        if(iRSI(Symbol(),0,RSI,PRICE_CLOSE,1)>50)
           {
              if(iMomentum(Symbol(),0,Momentum,PRICE_CLOSE,1)>100)
                 {
                     RefreshRates();
                     BuyTicket=OrderSend(Symbol(),OP_BUY,Lots,NormalizedAsk,Slippage,DetermineSLLong(), NormalizedAsk+(TakeProfit*Point),"Forex_v.1",MagicNumber,0,Green);
                     if(BuyTicket<0)
                        {
                           Print("Buy OrderSend error",GetLastError());
                           return(0);
    
                        }  
                 }
           }

      } 
      
   //SHORT ROUTINE//
     double NormalizedBid=NormalizeDouble(Bid,4);
     if(ValueFastMA2>ValueFastMA1 && ValueSlowMA1>ValueFastMA1 && ValueFastMA2>ValueSlowMA1)
     {
        if(iRSI(Symbol(),0,RSI,PRICE_CLOSE,1)<50)
           {
              if(iMomentum(Symbol(),0,Momentum,PRICE_CLOSE,1)<100)
                 {
                     RefreshRates();
                     SellTicket=OrderSend(Symbol(),OP_SELL,Lots,NormalizedBid,Slippage,DetermineSLShort(), NormalizedBid-(TakeProfit*Point),"Forex_v.1",MagicNumber,0,Red);
                     if(SellTicket<0)
                        {
                           Print("Sell OrderSend error",GetLastError());
                           return(0);
    
                        }  
                 }
           }

      } 
   

string comment = ""; //Comment() function always renews the comment, it doesn't append. Using a variable allows for better comment management.
for(int k=OrdersTotal()-1;k>=0;k--){ //Always decrement here instead of incrementing.. avoids errors when closing/deleting trades
   if(OrderSelect(k, SELECT_BY_POS)){ //Put this in a condition to ensure that it was selected successfully before proceeding
      if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber){
         RefreshRates(); //save a line of code by refreshing rates here instead of inside buy/sell below
         if(OrderType() == OP_BUY){
            comment = comment + "\nBreakEven=" + DoubleToStr(OrderOpenPrice() + BreakEven*Point, 4) + " ASK=" + DoubleToStr(NormalizedAsk, 4);
            
            if(NormalizedAsk >= OrderOpenPrice() + BreakEven*Point && OrderStopLoss() != OrderOpenPrice()){ //might as well put both conditions in the same one, won't hurt performance
               OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Green);
            }
         }
         else if(OrderType() == OP_SELL){
            comment = comment + "BreakEven=" + DoubleToStr(OrderOpenPrice() - BreakEven*Point, 4) + " BID=" + DoubleToStr(NormalizedBid,4);
            
            if(NormalizedBid <= OrderOpenPrice() - BreakEven*Point && OrderStopLoss() != OrderOpenPrice()){ //might as well put both conditions in the same one, won't hurt performance
               OrderModify(OrderTicket(),OrderOpenPrice(),OrderOpenPrice(),OrderTakeProfit(),0,Green);
            }
         }
      }
   }
}
Comment(comment);
   
//----
   return(0);
   }
 

First problematic thing I see is that you are using RefreshRates() but then you're using a previously assigned Ask/Bid value to NormalizedAsk/Bid. This makes RefreshRates() useless since you're not using the new Ask/Bid values. Second thing I see is actually something I don't see. For your SL, you are using actual prices to determine it and for takeprofit, you keep it at 0 so as to have none. This makes me unable to render a guess as to whether you are using a 4 or 5 digit broker. If you are using a 5 digit broker and using a breakeven of 20, that will be 20 points which is 2 pips, not 20 pips. This will be too close for most brokers at 2 pips difference and will cause errors which will make the breakeven always fail. Try putting this in:

int init()
{
   if(Digits == 3 || Digits == 5){ //This will turn your pip variables into the correct amount for 5-digit precision brokers
      BreakEven *= 10;
      TakeProfit *= 10;
   }
   
   return(0);
}

Then run it again and report if it still happens.

Jon

 
It still happens. The reason why I normalized the Ask/Bid was because of INVALID_PRICE error, but before, I got it with Ask/Bid with the same behavior. I'm testing only with 4 digits Broker, and TP=100
Reason: