Need Help with Error #130 invalid stoploss - page 2

 

The best way to get the stoploss correct is to think properly about the spread. The spread is the distance between the Ask and the Bid. So when you add a stoploss to a buy order using Bid - SL automatically includes the spread and you will not need to code for it and you are able to effectively totally ignore spread. For a sell trade using Ask + SL has the same effect. However, BEWARE --- at times of low trading volume the spread gets larger and you may well end up with a SL well away from the place you expect it to be --- therefore you may want to add some code to prevent the addition of the SL above a set Spread size.

Now the question of the Spread is out of the way the next main causes of error 130s is that the prices have changed while your EA is still executing. This can be caused by an EA that takes a long time to execute or the server is very busy servicing trades which delay your EA execution. The result is that one tick has caused your EA to start executing but another tick has come before the execution has finished and the prices are now invalid.

In either case you need to refresh the prices using RefreshRates: while (RefrshRates() == 1) Sleep(5); ------ or whatever you want as a wait time.

 
BigAl:


In either case you need to refresh the prices using RefreshRates: while (RefrshRates() == 1) Sleep(5); ------ or whatever you want as a wait time.

That's only correct if the code uses Predefined variables https://docs.mql4.com/predefined/variables if the code uses MarketInfo for Bid and Ask then RefreshRates will have no bearing . . .
 
qjol:
AFAIK RefreshRates() has nothing to do with error 130

Point taken RaptorUK and I agree that using MODE_ASK etc would eliminate the necessity for RefreshRates() but I assumed that as in shinobi's code example ....

I send an order with for example:

int ticket = OrderSend(Symbol(), OP_BUY, position_size, Ask, SLIPPAGE, initial_stop, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);

the predefined variable ASK is being used and therefore the ask/bid as well as the spread value may have changed giving the error 130. In such a case then RefreshRates() could be used immediately prior to the OrderSend

 
BigAl:

Point taken RaptorUK and I agree that using MODE_ASK etc would eliminate the necessity for RefreshRates() but I assumed that as in shinobi's code example ....

I send an order with for example:

int ticket = OrderSend(Symbol(), OP_BUY, position_size, Ask, SLIPPAGE, initial_stop, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);

the predefined variable ASK is being used and therefore the ask/bid as well as the spread value may have changed giving the error 130. In such a case then RefreshRates() could be used immediately prior to the OrderSend

Thanks to all for your great advice!
I am a bit busy at the moment, but once I got the chance, I'll try all your suggestions and then write a summarizing post for anyone who might stumble across this thread with the same problem.

Thanks, and take care!

shinobi
 
BigAl:I send an order with for example:

int ticket = OrderSend(Symbol(), OP_BUY, position_size, Ask, SLIPPAGE, initial_stop, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);

doesn't say everything. How are you computing initial_stop - using Bid?

How are you computing SLIPPAGE - adjusting for 4/5 digit brokers?

 
Hey guys!

I had to take a break for a while (moving to a new city, new job).
But now I'd like to take up on this thread, and finally find a solution for this cursed #130 stoploss error.

I am grateful for all of your advice and tried to incorporate all of it:

1: Spread.
to eliminate the spread as possible cause for the error, I set stoploss as
Bid-stoploss (Long)
Ask+stoploss (Short)

2: Changing Market Rates
to eliminate the possible cause of market rates changing before the order is send,
I changed my code and replaced all occurrences of Ask and Bid with
MarketInfo(Symbol(), MODE_ASK) and MarketInfo(Symbol(), MODE_BID)

3: 4-5 Digits-Broker
to eliminate the possible cause of invalid number of digits, I rounded the stoploss according to WHRoeders code:
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)

//init digit adjustment
if (Digits % 2 == 1) {      // DE30=1/JPY=3/EURUSD=5 forum.mql4.com/43064#515262
    pips2dbl    = Point*10; pips2points = 10;   Digits.pips = 1;
} else {
    pips2dbl    = Point;    pips2points =  1;   Digits.pips = 0; 
}

OrderSend(Symbol(), OP_BUY, position_size, MarketInfo(Symbol(), MODE_ASK), SLIPPAGE, (MarketInfo(Symbol(), MODE_BID) - stoploss) * pips2dbl, TAKEPROFIT, NULL, EXPERT_ID, 0, Green);
As mentioned earlier, the variables SLIPPAGE and TAKEPROFIT in my case are always 0. So they shoudln't cause a problem as well.

So I incorporated all suggestions, but the error still persists. As far as I can tell it occurs just as often as before, so there has to be another cause for it.
Here's a recent log:

tickvalue: 12.50000000
pos size: 37.00000000
Ask/Bid 1262.00000000/1261.75000000
stoploss:12.59610000
position_size: 37
Spread 0.25000000

Error could not take long position. Error is: #130 invalid stops

The above OrderSend code line was used with the logged values to try and take a long position.
Do you have any more ideas, what could be the cause?

Thanks!
shinobi
 

Is this an ECN Broker ?

WHRoeder 2011.09.15 20:36

On ECN brokers you must open and THEN set stops.

 
shinobi:
to eliminate the possible cause of invalid number of digits, I rounded the stoploss according to WHRoeders code:
  1. There was no rounding in the code I posted
  2. On ECN brokers you must open and THEN set stops.
  3. On metals (where TICKSIZE != Point) the opening price for pending orders must be rounded
    double TS=MarketInfo(pair, MODE_TICKSIZE);
    OOP = MathRound(OOP/TS)*TS;
    I don't know about stops.
  4. Stop telling us what the values are and what you think you did. Post the code.
 

Just do

extern double StopLoss = 50;

extern double TakeProfit = 50;

then for buys:

double SL=Bid - StopLoss* Point;

double TP=Bid + TakeProfit*Point;

int Ticket=OrderSend(Symbol(),0,1,Ask,2,SL,TP,"",12345);

if( Ticket<0) print("error="GetLastError());

for sells:

double SL=Ask + StopLoss* Point;

double TP=Ask - TakeProfit*Point;

int Ticket=OrderSend(Symbol(),1,1,Bid,2,SL,TP,"",12345);

if( Ticket<0) print("error="GetLastError());

then post the log file if it doesnt work.

 
Thanks Raptor, WHRoeder and SDC for your replies.

SDC:
I tried your code like this:
   int result_ticket = -1;
   double stoploss            = 50;
   double takeprofit          = 50;
   double SL = 0.0;
   double TP = 0.0;
   if(long) {   //take long position
      SL = MarketInfo(Symbol(), MODE_BID) - stoploss * MarketInfo(Symbol(), MODE_POINT));
      TP = MarketInfo(Symbol(), MODE_BID) + takeprofit * MarketInfo(Symbol(), MODE_POINT));
      result_ticket = OrderSend(Symbol(), 0, 1, MarketInfo(Symbol(), MODE_ASK), 2, SL, TP, "", 12345);
   } else {     //take short position
      SL = MarketInfo(Symbol(), MODE_ASK) + stoploss * MarketInfo(Symbol(), MODE_POINT));
      TP = MarketInfo(Symbol(), MODE_ASK) - takeprofit * MarketInfo(Symbol(), MODE_POINT));
      result_ticket = OrderSend(Symbol(), 1, 1, MarketInfo(Symbol(), MODE_BID), 2, SL, TP, "", 12345);
   }

   //check for errors
   if(result_ticket == -1) {
      Log("error="+GetLastError());
      return(-1);
   }
The only difference is, that I replaced Point, Ask and Bid with MarketInfo to avoid the RefreshRates problem mentioned by Raptor and BigAI.
The problem persists with this simple example. I still get

#ESZ1,M5: Opening Position
#ESZ1,M5: tickvalue: 12.50000000
#ESZ1,M5: pos size: 1.00000000
#ESZ1,M5: Ask/Bid 1244.50000000/1244.25000000
#ESZ1,M5: Spread 0.25000000
#ESZ1,M5: SL: 1244.00000000
#ESZ1,M5: TP: 1245.00000000
#ESZ1,M5: error=130

Raptor:
I currently use UWC-Trader with a demo account for testing.
Like mentioned earlier I am trading Futures. E.g. ESZ1 and FDXZ1.

WHRoeder:
Sorry I don't round either. Replace "round" with "adjust for 4/5-Digit Brokers. I.E. I just applied your code.
I also posted the OrderSend just as I use it in my previous reply. And the values of all the variables involved. I am not sure what other part of the code would be interesting.
As the mini-example, suggested by SDC, showed, the error can be broken down to this simple code. So it must be more fundamental.

I am not trading Metals, so rounding shouldn't be important.

I will try next:
opening (no stoploss) and then modifying (setting stoploss) later.

thanks again for your thoughts,

shinobi