OrderSend Error 2400

 

I'm trying to finish up an EA and I just can't for the life of me figure out why it wont place trades.

Below is my function for placing orders. I am aware it's probably a little lackluster. This is my first EA and I'm learning.

void PlaceOrder(){
   if(CurBias == 0 && OrdersTotal() == 0){   
      int openbuy=OrderSend(_Symbol,OP_BUY,Lots,Ask,1000,NormalizeDouble(Ask-StopLoss, Digits),NormalizeDouble(Ask+GetATR(1),Digits),"Phoenix Trade",MagicNumber,0,Blue);
      Alert("Order Fired!");      
   }else{
      int opensell=OrderSend(_Symbol,OP_SELL,Lots,Bid,1000,NormalizeDouble(Bid-StopLoss, Digits),NormalizeDouble(Bid+GetATR(1),Digits),"Phoenix Trade",MagicNumber,0,Blue);
      
   }   
}

Any assistance would be great!

Thanks!


EDIT: Played with things a bit, and now it says "invalid stoploss."
 
Tristen Shaw:

I'm trying to finish up an EA and I just can't for the life of me figure out why it wont place trades.

Below is my function for placing orders. I am aware it's probably a little lackluster. This is my first EA and I'm learning.

Any assistance would be great!

Thanks!

Any errors?

Because this doesn't look good:


OP_SELL,Lots,Bid,1000,NormalizeDouble(Bid-StopLoss, Digits)
 
Daniel Cioca #:

Any errors?

Because this doesn't look good:


At first it was just a 2400 error. Now it says invalid stop loss.

It's my first EA, so I was copying what I saw on tutorials.

 
Tristen Shaw #:

 Now it says invalid stop loss.


on this OP_SELL, stop loss is below openorder price...you should have something like OpenOrderPrice() + StopLoss

 
but what is this error 2400 ? cannot find this error code
 
Daniel Cioca #:
but what is this error 2400 ? cannot find this error code

I looked it up and it said something like "object already exists" or something like that. I think it might have been an error in my print function showing me an error for a different function.

I changed the Stoploss, however, it's still saying invalid stoploss.

void PlaceOrder(){
   if(CurBias == 0 && OrdersTotal() == 0 && GetSpread()<MaxSpread){//Note to self: Replace conditions with a "IsTradeAllowed" function   
      int openbuy=OrderSend(_Symbol,OP_BUY,Lots,Ask,1000,NormalizeDouble(Ask-StopLoss-GetSpread(), Digits),NormalizeDouble(Ask+GetATR(1)+GetSpread(),Digits),"Phoenix Trade",MagicNumber,0,Blue);
      Alert("Order Fired!");      
   }else{
      int opensell=OrderSend(_Symbol,OP_SELL,Lots,Bid,1000,NormalizeDouble(Bid+StopLoss+GetSpread(), Digits),NormalizeDouble(Bid-GetATR(1)-GetSpread(),Digits),"Phoenix Trade",MagicNumber,0,Blue);
      
   }   
}
 
Tristen Shaw #:

I looked it up and it said something like "object already exists" or something like that. I think it might have been an error in my print function showing me an error for a different function.

I changed the Stoploss, however, it's still saying invalid stoploss.

Is this a price?

NormalizeDouble(Bid+StopLoss+GetSpread()
 
Daniel Cioca #:

Is this a price?


They are formatted as points.

 
Tristen Shaw #: They are formatted as points.
There are several problems with your code, but here are some to get you started with correcting it. There are more.
  1. There is no such error code 2400 in MQL4. There is however code 4200 "Object already exists", but it has nothing to do with the code you have shown.
  2. For your code to work correctly, the variable "StopLoss" and the functions "GetSpread()" or "GetATR()" should be in price changes and not in "points". If it is in "points" then you should scale it by multiplying it with "_Point" for example.
  3. All prices should not be normalised by the number of "digits". It should be rounded according to the tick size (see below).
  4. You are not checking if your stops are acceptable according to the symbols contract specifications. You must check for the Stops Level condition for example. Read the Requirements and Limitations in Making Trades.
  5. As an extra note, you should also be checking the volume (lots) properly in accordance with the contract specifications (min, max and step values).

Forum on trading, automated trading systems and testing trading strategies

Tick size vs Point(), can be a little tricky in Multicurrency EA

Fernando Carreiro, 2022.03.09 12:11

Tick Size and Point Size can be very different especially on stocks and other symbols besides forex.

Always use Tick Size to adjust and align your prices, not the point size. In essence, make sure that your price quotes, are properly aligned to the Tick size (see following examples).

...
double tickSize = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_SIZE );
...
double normalised_price = round( price / tick_size ) * tick_size;
...
// Or use a function
double Round2Ticksize( double price )
{
   double tick_size = SymbolInfoDouble( _Symbol, SYMBOL_TRADE_TICK_SIZE );
   return( round( price / tick_size ) * tick_size );
};
 
Fernando Carreiro #:
There are several problems with your code, but here are some to get you started with correcting it. There are more.
  1. There is no such error code 2400 in MQL4. There is however code 4200 "Object already exists", but it has nothing to do with the code you have shown.
  2. For your code to work correctly, the variable "StopLoss" and the functions "GetSpread()" or "GetATR()" should be in price changes and not in "points". If it is in "points" then you should scale it by multiplying it with "_Point" for example.
  3. All prices should not be normalised by the number of "digits". It should be rounded according to the tick size (see below).
  4. You are not checking if your stops are acceptable according to the symbols contract specifications. You must check for the Stops Level condition for example. Read the Requirements and Limitations in Making Trades.
  5. As an extra note, you should also be checking the volume (lots) properly in accordance with the contract specifications (min, max and step values).

OK, first I would like to thank you guys for your time. :)

Second, I have attempted to put your fixes into practice. However, being very new to this, I'm sure I have probably butchered it. I'm struggling to understand some things and am doing my best to try and bumble my way through it. Please don't crucify me lol. I'm currently watching my EA to see what happens when it hits a buy trigger.

void PlaceOrder(){
   int SLpips = MarketInfo(Symbol(), MODE_STOPLEVEL);
   int TPpips = MarketInfo(Symbol(), MODE_STOPLEVEL);
   
   //Buy Order Variables
   if(SLpips>0) double BuyStopLoss = NormalizeDouble((Ask-StopLoss-GetSpread())*_Point, Digits);
   BuyStopLoss = round(BuyStopLoss / TickSize) * TickSize;
   
   if(TPpips>0)double BuyTakeProfit = NormalizeDouble(Ask+(GetATR(1)+GetSpread())*_Point, Digits);
   BuyTakeProfit = round(BuyTakeProfit / TickSize) * TickSize;
   
   //Sell Order Variables
   if(SLpips>0)double SellStopLoss = NormalizeDouble(Bid+(StopLoss+GetSpread())*_Point, Digits);
   SellStopLoss = round(SellStopLoss / TickSize) * TickSize;
   
   if(TPpips>0)double SellTakeProfit = NormalizeDouble(Bid-(GetATR(1)-GetSpread())*_Point,Digits);
   SellTakeProfit = round(SellTakeProfit / TickSize) * TickSize;
   
   if(CurBias == 0 && OrdersTotal() == 0 && GetSpread()<MaxSpread){//Note to self: Replace conditions with a "IsTradeAllowed" function   
      int openbuy=OrderSend(_Symbol,OP_BUY,Lots,Ask,1000,BuyStopLoss,BuyTakeProfit,"Phoenix Trade",MagicNumber,0,Blue);
      Alert("Order Fired!");      
   }else{
      int opensell=OrderSend(_Symbol,OP_SELL,Lots,Bid,1000,SellStopLoss,SellTakeProfit,"Phoenix Trade",MagicNumber,0,Blue);
      
   }   
}
Edit: As far as the stop loss. I'm eventually trying to use the ZigZag idicator to set the stoploss at a particular low/high. Haven't figured that part out yet.
 
Tristen Shaw #:


They are formatted as points.

That is why you have this invalid stop... OrderSend() function is expecting a price...StopLoss , takeProfit should be normalized prices.

Using Fernando's functions:

int StopLoss  =300 ; // Point
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Round2Ticksize(double price)
  {
   double tick_size = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
   return(round(price / tick_size) * tick_size);
  }

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double tickstoprice(int ticks)
  {
   double tickstoPrice= ticks * SymbolInfoDouble(_Symbol,SYMBOL_TRADE_TICK_SIZE);
   return(tickstoPrice);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

//StopLoss Price for OP_BUY
double stoploss = Round2Ticksize(Ask - tickstoprice(StopLoss));
Reason: