Reputation: 173
I have trouble with modifying the stoploss of a running trade using MQL5. Selecting the order works out for me. But if I try to access the variables ( for instance OrderTicket()
& OrderOpenPrice()
), it always returns 0.00000:
2017.06.01 00:06:32.114 2016.04.08 00:00:00 failed modify buy 0.00 sl: 0.00000, tp: 0.00000 -> sl: 1.41594, tp: 0.00000 [Invalid request]
Here's my stoploss modyfing void:
void modifyStops() {
int total = OrdersTotal(); // total number of placed pending orders
Print( total + " Orders on the line!!!" );
//--- Over all placed pending orders
for ( int i = 0; i < total; i++ )
{ bool isOrderSelected = OrderSelect( i, SELECT_BY_POS, MODE_TRADES );
if ( isOrderSelected )
{ // TODO: Check the Trades to contain the correct Order Number
Print( "Symbol & Magicnumber matching" );
double newStopLoss;
// Update the stop loss
if ( OrderType() == OP_BUY )
{
newStopLoss = addTolerance( SL );
}
else if ( OrderType() == OP_SELL )
{
newStopLoss = minusTolerance( SL );
}
newStopLoss = NormalizeDouble( newStopLoss, Digits );
Print( "NEW STOP LOSS::::=====> ", Symbol(), " at ", newStopLoss );
if ( !OrderModify( OrderTicket(), OrderOpenPrice(), newStopLoss, OrderTakeProfit(), 0, Green ) )
{
Print( "OrderModify returned the error of ", GetLastError() );
}
}
}
The CTrade class isn't working properly for me. I tried to implement the code you've posted - however: It still doesn't seem to work out.
Unfortunately I implemented that in my EA and the OrderGetTicket(i) returns zero when the trade is live. So my void looks like this:
void modifyStops() {
for(int i=0; i<PositionsTotal();i++)
{
ulong ticket;
if((ticket=PositionGetTicket(i))>0)
{
//--- return order properties
double open_price =PositionGetDouble(POSITION_PRICE_OPEN);
datetime time_open =(datetime)PositionGetInteger(POSITION_TIME);
string symbol =PositionGetString(POSITION_SYMBOL);
int order_magic =PositionGetInteger(POSITION_MAGIC);
double volume =PositionGetDouble(POSITION_VOLUME);
double stoploss =PositionGetDouble(POSITION_SL);
double takeprofit =PositionGetDouble(POSITION_TP);
ENUM_ORDER_TYPE type =EnumToString(ENUM_ORDER_TYPE(PositionGetInteger(POSITION_TYPE)));
//--- prepare and show information about the order
printf("#ticket %d %s %G %s at %G, with sl: %G tp: %G was set up at %s",
ticket, // order ticket
type, // type
volume, // placed volume
symbol, // symbol
open_price, // specified open price
stoploss, //
takeprofit, //
TimeToString(time_open) // time of order placing
);
}
}
}
And the printf function returns nothing:
2017.06.02 01:42:26.910 2016.04.07 00:00:00 #ticket 1 (non-string passed) 0 at 0, with sl: 0 tp: 0 was set up at 1970.01.01 00:00
I can't believe it's that hard to simply modify an SL in MQL5. That's horribly. However I need to get through it to test my strategy over several pairs...
Do you have another idea? I set up trades with the following code:
void createPendingOrder(ENUM_ORDER_TYPE orderType, double lots, double stopLoss) {
MqlTradeRequest request={0};
MqlTradeResult result={0};
//--- parameters to place a pending order
request.action =TRADE_ACTION_PENDING; // type of trade operation
request.symbol =Symbol(); // symbol
request.volume =lots; // volume of 0.1 lot
//request.deviation=2; // allowed deviation from the price
request.magic =224466 ; // MagicNumber of the order
//int offset = 3; // offset from the current price to place the order, in points
double price; // order triggering price
double point=SymbolInfoDouble(_Symbol,SYMBOL_POINT); // value of point
int digits=SymbolInfoInteger(_Symbol,SYMBOL_DIGITS); // number of decimal places (precision)
//--- checking the type of operation
if(orderType==ORDER_TYPE_BUY_STOP)
{
request.type =ORDER_TYPE_BUY_STOP; // order type
price =entryPrice;
request.price =NormalizeDouble(price,digits); // normalized opening price
request.sl =stopLoss;
}
else if(orderType==ORDER_TYPE_SELL_STOP)
{
request.type =ORDER_TYPE_SELL_STOP; // order type
price =entryPrice;
request.price =NormalizeDouble(price,digits); // normalized opening price
request.sl =stopLoss;
}
else Alert("This example is only for placing pending orders"); // if not pending order is selected
//--- send the request
if(!OrderSend(request,result))
PrintFormat("OrderSend error %d",GetLastError()); // if unable to send the request, output the error code
//--- information about the operation
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
}
Would it for instance be possible to save the result object in a Array and then access the running trade through that object?
Upvotes: 2
Views: 11029
Reputation: 568
Your problem is you are trying to run MQL4 code in MQL5.
There are no OrderModify()
, OrderOpenPrice()
, OrderTicket()
in MQL5!!!
See the documentation here on how to select, query values and modify trades.
you will need to be using OrderGetDouble()
, OrderGetInteger()
and OrderGetString()
to query open price, stop loss etc.
e.g.
if((ticket=OrderGetTicket(i))>0)
{
//--- return order properties
open_price =OrderGetDouble(ORDER_PRICE_OPEN);
time_setup =(datetime)OrderGetInteger(ORDER_TIME_SETUP);
symbol =OrderGetString(ORDER_SYMBOL);
order_magic =OrderGetInteger(ORDER_MAGIC);
positionID =OrderGetInteger(ORDER_POSITION_ID);
initial_volume=OrderGetDouble(ORDER_VOLUME_INITIAL);
type =EnumToString(ENUM_ORDER_TYPE(OrderGetInteger(ORDER_TYPE)));
//--- prepare and show information about the order
printf("#ticket %d %s %G %s at %G was set up at %s",
ticket, // order ticket
type, // type
initial_volume, // placed volume
symbol, // symbol
open_price, // specified open price
TimeToString(time_setup)// time of order placing
);
}
Orders are modified using the OrderSend()
function https://www.mql5.com/en/docs/trading/ordersend
MQL5 uses a much more complex system of Orders, Positions, Deals and historyOrders. An MQL5 community article attempts to explain how they all relate to one another.
To loop through and look at pending Orders:
for(int i=0; i<OrdersTotal();i++)
{
if((ticket=OrderGetTicket(i))>0)
{
//--- return order properties
open_price =OrderGetDouble(ORDER_PRICE_OPEN);
time_setup =(datetime)OrderGetInteger(ORDER_TIME_SETUP);
symbol =OrderGetString(ORDER_SYMBOL);
order_magic =OrderGetInteger(ORDER_MAGIC);
positionID =OrderGetInteger(ORDER_POSITION_ID);
initial_volume=OrderGetDouble(ORDER_VOLUME_INITIAL);
type =EnumToString(ENUM_ORDER_TYPE(OrderGetInteger(ORDER_TYPE)));
//--- prepare and show information about the order
printf("#ticket %d %s %G %s at %G was set up at %s",
ticket, // order ticket
type, // type
initial_volume, // placed volume
symbol, // symbol
open_price, // specified open price
TimeToString(time_setup)// time of order placing
);
}
}
To loop through and look at open trades:
for(int i=0; i<PositionsTotal();i++)
{
if((ticket= PositionGetTicket(i))>0)
{
//--- return order properties
open_price =PositionGetDouble(POSITION_PRICE_OPEN);
time_open =(datetime)PositionGetInteger(POSITION_TIME);
symbol =PositionGetString(POSITION_SYMBOL);
order_magic =PositionGetInteger(POSITION_MAGIC);
volume =PositionGetDouble(POSITION_VOLUME);
stoploss =PositionGetDouble(POSITION_SL);
takeprofit =PositionGetDouble(POSITION_TP);
type =EnumToString(ENUM_ORDER_TYPE(PositionGetInteger(POSITION_TYPE)));
//--- prepare and show information about the order
printf("#ticket %d %s %G %s at %G, with sl: %G tp: %G was set up at %s",
ticket, // order ticket
type, // type
volume, // placed volume
symbol, // symbol
open_price, // specified open price
stoploss, //
takeprofit, //
TimeToString(time_open) // time of order placing
);
}
}
Hopefully, someone else will be able to provide a better explanation of Orders, Positions, Deals, history Orders as they still give me a headache.
To make it simpler I usually just create an instance of the CTrade Class
Minimal example of trailSL for buy Positions using standard trade functions and Ctrade class
Ctrade *m_trade;
CSymbolInfo *m_symbol;
Void OnInit()
{
m_trade = new Ctrade();
m_trade.SetExpertMagicNumber(100);
m_symbol = new CSymbolInfo();
m_symbol.Name(Symbol());
}
void OnTick()
{
m_symbol.RefreshRates();
}
void modifysl()
{
ulong ticket;
MqlTradeRequest request = {0};
MqlTradeResult result = {0};
double newsl;
for(int i=0; i<PositionsTotal();i++)
{
ticket=PositionGetTicket(i);
if(ticket>0)
{
request.action = TRADE_ACTION_SLTP; // type of trade operation
request.position = ticket; // ticket of the position
request.symbol = PositionGetString(POSITION_SYMBOL); // symbol
request.sl = PositionGetDouble(POSITION_SL); // Stop Loss of the position
request.tp = PositionGetDouble(POSITION_TP); // Take Profit of the position
request.magic = 100; // MagicNumber of the position
newsl = NormalizeDouble(m_symbol.Bid()-100*m_symbol.Point(),
m_symbol.Digits());
if(newsl>request.sl)
{
request.sl = newsl;
if(!OrderSend(request,result))
{
PrintFormat("OrderSend error %d",GetLastError()); // if unable to send the request, output the error code
}
//--- information about the operation
PrintFormat("retcode=%u deal=%I64u order=%I64u",result.retcode,result.deal,result.order);
}
}
}
}
void modifyslCtrade()
{
ulong ticket;
MqlTradeRequest request= {0};
MqlTradeResult response ={0};
double newsl;
for(int i=0; i<PositionsTotal();i++)
{
ticket=PositionGetTicket(i);
if(ticket>0)
{
newsl = NormalizeDouble(m_symbol.Bid()-100*m_symbol.Point(),
m_symbol.Digits());
if(newsl>PositionGetDouble(POSITION_SL))
{
m_trade.PositionModify(ticket,
newsl,
PositionGetDouble(POSITION_TP));
}
}
}
}
Upvotes: 6