I'm trying to ADD a stop loss to my open market orders in MetaTrader 4 when a position gets 100 pips "to the good" which is to be equal to the Order Open Price;
OrderStopLoss() == OrderOpenPrice()
But this isn't happening.
I've added Print()
& GetLastError()
functions and nothing is coming up in the journal, so it must be something in my coding - but cannot see what would be wrong.
OK this is what I have so far, one for loop for the buy, one for the sell. I've also Normalized the "doubles" as I have been advised to do & have also declared the BuyMod & SellMod to "true" at the very top. This should ensure that the default won't resort to false. I also thought it might be helpful if I told you I have the MetaEditor version 5 build 1241:)
The following code I have is the following;
/*Breakeven Order Modification*/
bool BuyMod = true;
bool SellMod = true;
for(int b = OrdersTotal()-1;b>=0;b--)
{
if(OrderSelect(b,SELECT_BY_POS,MODE_TRADES))
{
double aBidPrice = MarketInfo(Symbol(),MODE_BID);
double anOpenPrice = OrderOpenPrice();
double aNewTpPrice = OrderTakeProfit();
double aCurrentSL = OrderStopLoss();
double aNewSLPrice = anOpenPrice;
double pnlPoints = (aBidPrice - anOpenPrice)/_Point;
double stopPoints = (aBidPrice - aNewSLPrice)/_Point;
int stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL));
int aTicket = OrderTicket();
if(OrderType() == OP_BUY)
if(stopPoints >= stopLevel)
if(aTicket > 0)
if(pnlPoints >= breakeven)
if(aNewSLPrice != aCurrentSL)
{
BuyMod = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(aNewSLPrice,Digits),NormalizeDouble(aNewTpPrice,Digits),0,buycolor);
SendMail("Notification of Order Modification for Ticket#"+IntegerToString(OrderTicket(),10),"Good news! Order Ticket#"+IntegerToString(OrderTicket(),10)+"has been changed to breakeven");
}
}
}
for(int s = OrdersTotal()-1; s>=0; s--)
{
if(OrderSelect(s,SELECT_BY_POS,MODE_TRADES))
{
double anAskPrice = MarketInfo(Symbol(),MODE_ASK);
double anOpenPrice = OrderOpenPrice();
double aNewTpPrice = OrderTakeProfit();
double aCurrentSL = OrderStopLoss();
double aNewSLPrice = anOpenPrice;
double pnlPoints = (anOpenPrice - anAskPrice)/_Point;
double stopPoints = (aNewSLPrice - anAskPrice)/_Point;
int stopLevel = int(MarketInfo(Symbol(),MODE_STOPLEVEL));
int aTicket = OrderTicket();
if(OrderType()== OP_SELL)
if(stopPoints >= stopLevel)
if(pnlPoints >= breakeven)
if(aNewSLPrice != aCurrentSL)
if(aTicket > 0)
{
SellMod = OrderModify(OrderTicket(),OrderOpenPrice(),NormalizeDouble(aNewSLPrice,Digits),NormalizeDouble(aNewTpPrice,Digits),0,sellcolor);
SendMail("Notification of Order Modification for Ticket#"+IntegerToString(OrderTicket(),10),"Good news! Order Ticket#"+IntegerToString(OrderTicket(),10)+"has been changed to breakeven");
}
}
}
trading algorithmic-trading mql4 metatrader4
shareeditdeleteflag
edited just now
asked 2 days ago
Todd Gilbey 264
You might want to know, StackOverflow does not promote duplicate questions. ( see the
The problem is in your call to a built-in
OrderModify()
function.OrderStopLoss() == OrderModify()
will evaluate asfalse
which in turn will evaluate as 0 since==
is a comparison operator.An
OrderStopLoss()
is a call to another built-in function (not a variable), you can't save anything to it soOrderStopLoss() = 4
wouldn't work either.In your case that would be the following, assuming
ModBuy
is already defined somewhere in the code:Or you could just use any other valid value instead of the second
OrderOpenPrice()
to set a new stoploss.Besides meeting an
MQL4
syntax-rules,there are more conditions:
A first hidden trouble is in number rounding issues.
MetaQuotes, Inc., recommends wherever possible, to normalise float values into a proper price-representation.
Thus,
wherever a price goes into a server-side instruction
{ OrderSend(), OrderModify(), ... }
one shall always prepare suchaPriceDOMAIN
valueby a call to
NormalizeDouble( ... , _Digits )
, before a normalised price hits any server-side instruction call.May sound rather naive, but this saves you issues with server-side rejections.
Add
NormalizeDouble()
calls into your code on a regular base as your life-saving vest.A second, even a better hidden trouble is in
STOP_ZONE
-s andFREEZE_ZONE
-sWhile not visible directly, any Broker set's in their respective Terms & Conditions these parameters.
In practice,
this means, if you instruct
{ OrderSend() | OrderModify() }
to set / moveaPriceDOMAIN
level to be setup too close to current actualAsk
/Bid
( violating a Broker-forbiddenSTOP_ZONE
)or
to delete / modify
aPriceDOMAIN
level of TP or SL, that are already set and is right now, within a Broker-forbiddenFREEZE_ZONE
distance from actualAsk
/Bid
,such instruction will not be successfully accepted and executed.
So besides calls to the
NormalizeDouble()
, always wait a bit longer as the price moves "far" enough and regularly check for not violating forbiddenSTOP_
+FREEZE_
zones before ordering any modifications in your order-management part of your algotrading projects.Anyway, Welcome to Wild Worlds of
MQL4
Update:
while StackOverflow is not a Do-a-Homework site, let me propose a few directions for the solution:I'm really sorry, I'm new to Stackoverflow, this is the revised code I now have based on everyone's comments & recommendation's below