What is the correct way to set StopLoss and TakeProfit in OrderSend() in MetaTrader4 EA?
Asked Answered
P

2

6

I'm trying to figure out if there is a correct way to set the Stop Loss (SL) and Take Profit (TP) levels, when sending an order in an Expert Advisor, in MQL4 (Metatrader4). The functional template is:

OrderSend( symbol, cmd, volume, price, slippage, stoploss, takeprofit, comment, magic, expiration, arrow_color);

So naturally I've tried to do the following:

double dSL = Point*MM_SL;
double dTP = Point*MM_TP;

if (buy)  { cmd = OP_BUY;  price = Ask; SL = ND(Bid - dSL);  TP = ND(Ask + dTP); }
if (sell) { cmd = OP_SELL; price = Bid; SL = ND(Ask + dSL);  TP = ND(Bid - dTP); }

ticket = OrderSend(SYM, cmd, LOTS, price, SLIP, SL, TP, comment, magic, 0, Blue);

However, there are as many variations as there are scripts and EA's. So far I have come across these.

In the MQL4 Reference in the MetaEditor, the documentation say to use:

OrderSend(Symbol(),OP_BUY,Lots,Ask,3,
  NormalizeDouble(Bid - StopLoss*Point,Digits),
  NormalizeDouble(Ask + TakeProfit*Point,Digits), 
  "My order #2",3,D'2005.10.10 12:30',Red); 

While in the "same" documentation online, they use:

double stoploss = NormalizeDouble(Bid - minstoplevel*Point,Digits);
double takeprofit = NormalizeDouble(Bid + minstoplevel*Point,Digits);
int ticket=OrderSend(Symbol(),OP_BUY,1,price,3,stoploss,takeprofit,"My order",16384,0,clrGreen);

And so it goes on with various flavors, here, here and here...

Assuming we are interested in a OP_BUY and have the signs correct, we have the options for basing our SL and TP values on:

bid, bid 
bid, ask
ask, ask
ask, bid

So what is the correct way to set the SL and TP for a BUY?

(What are the advantages or disadvantages of using the various variations?)


EDIT: 2018-06-12

Apart a few details, the answer is actually quite simple, although not obvious. Perhaps because MT4 only show Bid prices on the chart (by default) and not both Ask and Bid.

So because: Ask > Bid and Ask - Bid = Slippage, it doesn't matter which we choose as long as we know about the slippage. Then depending on what price you are following on the chart, you may wish to decide on using one over the other, adding or subtracting the Slippage accordingly.

So when you use the measure tool to get the Pip difference of currently shown prices, vs your "exact" SL/TP settings, you need to keep this in mind.

So to avoid having to put the Slippage in my code above, I used the following for OP_BUY: TP = ND(Bid + dTP); (and the opposite for OP_SELL.)

Permeable answered 7/6, 2018 at 16:26 Comment(0)
U
3

If you buy, you OP_BUY at Ask and close (SL, TP) at Bid.
If you sell, OP_SELL operation is made at Bid price, and closes at Ask.

Both SL and TP should stay at least within STOP_LEVEL * Point() distance from the current price to close ( Bid for buy, Ask for sell).

It is possible that STOP_LEVEL is zero - in such cases ( while MT4 accepts the order ) the Broker may reject it, based on its own algorithms ( Terms and Conditions may call it a "floating Stoplevel" rule or some similar Marketing-wise "re-dressed" term ).

It is adviced to send an OrderSend() request with zero values of SL and TP and modify it after you see that the order was sent successfully. Sometimes it is not required, sometimes that is even mandatory.

There is no difference between the two links you gave us: you may compute SL and TP and then pass them into the function or compute them based on OrderOpenPrice() +/- distance * Point().

Unscathed answered 7/6, 2018 at 18:5 Comment(0)
A
2

So what is the correct way to set the SL and TP for a BUY ?

There is no such thing as "The Correct Way", there are rules to meet

Level 0: Syntax is to meet the call-signature ( the easiest one )
Level 1: all at Market XTO-s have to meet the right level of the current Price +/- slippage, make sure to repeat a RefreshRates()-test as close to the PriceDOMAIN-levels settings, otherwise they get rejected from the Broker side ( blocking one's trading engine at a non-deterministic add-on RTT-latency ) + GetLastError() == 129 | ERR_INVALID_PRICE

Level 2: yet another rules get set from Broker-side, in theire respective Service / Product definition in [ Trading Terms and Conditions ]. If one's OrderSend()-request fails to meet any one of these, again, the XTO will get rejected, having same adverse blocking effects, as noted in Level 1.

Some Brokers do not allow some XTO situations due to their T&C, so re-read such conditions with a due care. Any single of theirs rule, if violated, will lead to your XTO-instruction to get legally rejected, with all adverse effects, as noted above. Check all rules, as you will not like to see any of the following error-states + any of others, restricted by your Broker's T&C :

ERR_LONG_POSITIONS_ONLY_ALLOWED  Buy orders only allowed 
ERR_TRADE_TOO_MANY_ORDERS        The amount of open and pending orders has reached the limit set by the broker
ERR_TRADE_HEDGE_PROHIBITED       An attempt to open an order opposite to the existing one when hedging is disabled
ERR_TRADE_PROHIBITED_BY_FIFO     An attempt to close an order contravening the FIFO rule
ERR_INVALID_STOPS                Invalid stops
ERR_INVALID_TRADE_VOLUME         Invalid trade volume
...
..
.
#ASSUME NOTHING                ; Is the best & safest design-side (self)-directive
Actinism answered 7/6, 2018 at 17:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.