MT5 CTrade - PositionOpen issue

 

Hi,

I'm willing to put  Sell Limit / Buy Limit with specified date on Exchange. I can do by the terminal manually but PositionOpen does not accept entering time.

https://www.mql5.com/en/docs/standardlibrary/tradeclasses/ctrade/ctradepositionopen


Only OrderOpen accepts entering time but it'll not be a position. It will be an "order" to be triggered by a price. It requires two prices as StopLimit price and execution price.

https://www.mql5.com/en/docs/standardlibrary/tradeclasses/ctrade/ctradeorderopen


I want to put a"postion" on exchange as limit with a specified end date.

Any way to overcome this?

Thanks.

Documentation on MQL5: Standard Library / Trade Classes / CTrade / PositionOpen
Documentation on MQL5: Standard Library / Trade Classes / CTrade / PositionOpen
  • www.mql5.com
Successful completion of the PositionOpen(...) method does not always mean successful execution of the trade operation. It is necessary to check the result of trade request (trade server return code) using ResultRetcode() and value returned by ResultDeal().
 
struct MqlTradeRequest 
  { 
   ENUM_TRADE_REQUEST_ACTIONS    action;           // Trade operation type 
   ulong                         magic;            // Expert Advisor ID (magic number) 
   ulong                         order;            // Order ticket 
   string                        symbol;           // Trade symbol 
   double                        volume;           // Requested volume for a deal in lots 
   double                        price;            // Price 
   double                        stoplimit;        // StopLimit level of the order 
   double                        sl;               // Stop Loss level of the order 
   double                        tp;               // Take Profit level of the order 
   ulong                         deviation;        // Maximal possible deviation from the requested price 
   ENUM_ORDER_TYPE               type;             // Order type 
   ENUM_ORDER_TYPE_FILLING       type_filling;     // Order execution type 
   ENUM_ORDER_TYPE_TIME          type_time;        // Order expiration type 
   datetime                      expiration;       // Order expiration time (for the orders of ORDER_TIME_SPECIFIED type) 
   string                        comment;          // Order comment 
   ulong                         position;         // Position ticket 
   ulong                         position_by;      // The ticket of an opposite position 
  };

Please see: https://www.mql5.com/en/docs/constants/structures/mqltraderequest

 

So it's not possible with CTrade, only possible with Trade Request Structure. I should say I cannot manage to use the Trade Request Structure, too complicated.

Thanks anyway.

Regards.

 

If you scroll down there are some examples.

#define EXPERT_MAGIC 123456   // MagicNumber of the expert
//+------------------------------------------------------------------+
//| Opening Buy position                                             |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- declare and initialize the trade request and result of trade request
   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
//--- parameters of request
   request.action   =TRADE_ACTION_DEAL;                     // type of trade operation
   request.symbol   =Symbol();                              // symbol
   request.volume   =0.1;                                   // volume of 0.1 lot
   request.type     =ORDER_TYPE_BUY;                        // order type
   request.price    =SymbolInfoDouble(Symbol(),SYMBOL_ASK); // price for opening
   request.deviation=5;                                     // allowed deviation from the price
   request.magic    =EXPERT_MAGIC;                          // MagicNumber of the order
//--- 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);
  }
//+------------------------------------------------------------------+

So you can modify these by changing and adding those fields in my previous post.


If you want you can also look here: https://www.mql5.com/en/docs/standardlibrary/tradeclasses/ctrade/ctradeorderopen

bool  OrderOpen( 
   const string          symbol,          // symbol 
   ENUM_ORDER_TYPE       order_type,      // order type 
   double                volume,          // order volume 
   double                limit_price,     // StopLimit price 
   double                price,           // execution price 
   double                sl,              // Stop Loss price 
   double                tp,              // Take Profit price 
   ENUM_ORDER_TYPE_TIME  type_time,       // type by expiration 
   datetime              expiration,      // expiration 
   const string          comment=""       // comment 
   )
Documentation on MQL5: Standard Library / Trade Classes / CTrade / OrderOpen
Documentation on MQL5: Standard Library / Trade Classes / CTrade / OrderOpen
  • www.mql5.com
Successful completion of the OrderSend(...) method does not always mean successful execution of the trade operation. It is necessary to check the result of a trade request (trade server return code) using ResultRetcode() and value returned by ResultOrder().
 

Hi again,

I'm planning to run this code on live tomorrow, a sell limit far away form ask for testing. Two questions:

1-) I'm confused to use request.type_time or request.experation. I guess for a specific date and time I should use experation.

2-) I'm not sure if I put the experiation date to request.experiation, do you think it will work?

Thanks.


#define EXPERT_MAGIC 123456



int OnInit()
  {

   MqlTradeRequest request={0};
   MqlTradeResult  result={0};
   
   //--- parameters of request
   request.action       =   TRADE_ACTION_PENDING;                        // type of trade operation
   request.symbol       =   Symbol();                                    // symbol
   request.volume       =   1;                                           // volume of 1 lot
   request.type         =   ORDER_TYPE_SELL_LIMIT;                       // order type
   request.price        =   9.80;                                        // price for opening
   request.deviation    =   0.05;                                        // allowed deviation from the price
   request.magic        =   EXPERT_MAGIC;                                // MagicNumber of the order
   request.type_filling =   ORDER_FILLING_RETURN;
   
   
   datetime date1=D'2019.02.08';
   MqlDateTime str1;
   TimeToStruct(date1,str1);
   
   
   //request.type_time    =   ORDER_TIME_GTC;
   request.expiration   =   StructToTime(str1);
   
   
   //--- 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);
   

   return(INIT_SUCCEEDED);
  }
 

ENUM_ORDER_PROPERTY_INTEGER

Identifier

Description

Type

ORDER_TICKET

Order ticket. Unique number assigned to each order

long

ORDER_TIME_SETUP

Order setup time

datetime

ORDER_TYPE

Order type

ENUM_ORDER_TYPE

ORDER_STATE

Order state

ENUM_ORDER_STATE

ORDER_TIME_EXPIRATION

Order expiration time

datetime

ORDER_TIME_DONE

Order execution or cancellation time

datetime

ORDER_TIME_SETUP_MSC

The time of placing an order for execution in milliseconds since 01.01.1970

long

ORDER_TIME_DONE_MSC

Order execution/cancellation time in milliseconds since 01.01.1970

long

ORDER_TYPE_FILLING

Order filling type

ENUM_ORDER_TYPE_FILLING

ORDER_TYPE_TIME

Order lifetime

ENUM_ORDER_TYPE_TIME

ORDER_MAGIC

ID of an Expert Advisor that has placed the order (designed to ensure that each Expert Advisor places its own unique number)

long

ORDER_REASON

The reason or source for placing an order

ENUM_ORDER_REASON

ORDER_POSITION_ID

Position identifier that is set to an order as soon as it is executed. Each executed order results in a dealthat opens or modifies an already existing position. The identifier of exactly this position is set to the executed order at this moment.

long

ORDER_POSITION_BY_ID

Identifier of an opposite position used for closing by order  ORDER_TYPE_CLOSE_BY

long


The order validity period can be set in the type_time field of the special structure MqlTradeRequest when sending a trade request using the OrderSend() function. Values of the ENUM_ORDER_TYPE_TIME enumeration are allowed. To obtain the value of this property use the function OrderGetInteger() or HistoryOrderGetInteger() with the ORDER_TYPE_TIME modifier.

ENUM_ORDER_TYPE_TIME

Identifier

Description

ORDER_TIME_GTC

Good till cancel order

ORDER_TIME_DAY

Good till current trade day order

ORDER_TIME_SPECIFIED

Good till expired order

ORDER_TIME_SPECIFIED_DAY

The order will be effective till 23:59:59 of the specified day. If this time is outside a trading session, the order expires in the nearest trading time.

 

You can do it.


 
Thanks again, appericated.
 

Unfortunaletly the code did not succed. It gives order send error 4756 and return code is 10022.


10022

TRADE_RETCODE_INVALID_EXPIRATION


I've disabled request.expiration (to test without expire time)  but still I got the same error. According to the link below, I should be able to place an limit order  (without expiration) but could not succeed.

https://www.mql5.com/en/docs/constants/structures/mqltraderequest


I could not undersand why I'm getting expiration error although I did not use it and as a next step what is the correct code for putting an expiration to a limit order? Could you please share an example code, I couln't find a correct one.

Thanks.

Documentation on MQL5: Constants, Enumerations and Structures / Data Structures / Trade Request Structure
Documentation on MQL5: Constants, Enumerations and Structures / Data Structures / Trade Request Structure
  • www.mql5.com
Interaction between the client terminal and a trade server for executing the order placing operation is performed by using trade requests. The trade request is represented by the special predefined structure of MqlTradeRequest type, which contain all the fields necessary to perform trade deals. The request processing result is represented by...
 

The Docs specify that these two fields, date/time of expiration and expiration type are required, but then goes on showing examples without these fields.

#property description "Example of placing pending orders"
#property script_show_inputs
#define EXPERT_MAGIC 123456                             // MagicNumber of the expert
input ENUM_ORDER_TYPE orderType=ORDER_TYPE_BUY_LIMIT;   // order type
input ENUM_ORDER_TYPE_TIME expiration_type=1;           // order expiration time type
input datetime expire=D'31.01.2019 00:00:01';           // order expiration YYYY.MM.DD HR:MN:SC
//+------------------------------------------------------------------+
//| Placing pending orders                                           |
//+------------------------------------------------------------------+
void OnStart()
  {
//--- declare and initialize the trade request and result of trade request
   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   =0.1;                                              // volume of 0.1 lot
   request.deviation=2;                                                // allowed deviation from the price
   request.magic    =EXPERT_MAGIC;                                     // MagicNumber of the order
   request.type_time=expiration_type;                                  // Expiration time type of the order  
   request.expiration=expire;                                          // Expiration of the order
   int offset = 50;                                                    // 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=(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS);           // number of decimal places (precision)
   //--- checking the type of operation
   if(orderType==ORDER_TYPE_BUY_LIMIT)
     {
      request.type     =ORDER_TYPE_BUY_LIMIT;                          // order type
      price=SymbolInfoDouble(Symbol(),SYMBOL_ASK)-offset*point;        // price for opening 
      request.price    =NormalizeDouble(price,digits);                 // normalized opening price 
     }
   else if(orderType==ORDER_TYPE_SELL_LIMIT)
     {
      request.type     =ORDER_TYPE_SELL_LIMIT;                          // order type
      price=SymbolInfoDouble(Symbol(),SYMBOL_BID)+offset*point;         // price for opening 
      request.price    =NormalizeDouble(price,digits);                  // normalized opening price 
     }
   else if(orderType==ORDER_TYPE_BUY_STOP)
     {
      request.type =ORDER_TYPE_BUY_STOP;                                // order type
      price        =SymbolInfoDouble(Symbol(),SYMBOL_ASK)+offset*point; // price for opening 
      request.price=NormalizeDouble(price,digits);                      // normalized opening price 
     }
   else if(orderType==ORDER_TYPE_SELL_STOP)
     {
      request.type     =ORDER_TYPE_SELL_STOP;                           // order type
      price=SymbolInfoDouble(Symbol(),SYMBOL_BID)-offset*point;         // price for opening 
      request.price    =NormalizeDouble(price,digits);                  // normalized opening price 
     }
   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);
  }
//+------------------------------------------------------------------+

This is a script that you can compile (as a script) and i have added these fields.

You can specify some things in the input parameters and see how it works.

You can check the pending order properties in the same way as when you want to modify them by a left click and 'modify'.


Here is the time_type again:

ENUM_ORDER_TYPE_TIME

Identifier

Description

ORDER_TIME_GTC

Good till cancel order

ORDER_TIME_DAY

Good till current trade day order

ORDER_TIME_SPECIFIED

Good till expired order

ORDER_TIME_SPECIFIED_DAY

The order will be effective till 23:59:59 of the specified day. If this time is outside a trading session, the order expires in the nearest trading time.

 

It worked well with parameter ORDER_TIME_SPECIFIED_DAY. The limit order is still open after market closed and it should expire on Monday, in the morning market session.

Thanks again.

Regards.

 
AED71:

It worked well with parameter ORDER_TIME_SPECIFIED_DAY. The limit order is still open after market closed and it should expire on Monday, in the morning market session.

Thanks again.

Regards.

Hi AED, 


Some people like to make things a lot more difficult than they need to be. The problem with your original code was that you were using the wrong methods. You should have been using CTrade::BuyLimit and CTrade::SellLimit instead. If I were you I wouldn't muck about with the low-level functions as others suggest and instead use the standard library classes as they were intended to be used.  Here is a working example you can run on history data with the debugger.

#include <trade/trade.mqh>
//+------------------------------------------------------------------+
int OnInit() {
   return(INIT_SUCCEEDED);
}

void OnTick() {
   if (OrdersTotal() <= 0) {
      CTrade trade;
      CSymbolInfo s;
      s.Name(_Symbol);
      s.RefreshRates();
      bool opened = trade.BuyLimit(
         0.1,
         s.Bid() - 1000 * s.Point(),
         NULL,
         0.0,
         0.0,
         ORDER_TIME_SPECIFIED,
         TimeCurrent() + PeriodSeconds(PERIOD_H1),
         "Limit order expire test"
      );
   }
}

Docs: https://www.mql5.com/en/docs/standardlibrary/tradeclasses/ctrade/ctradebuylimit

Documentation on MQL5: Standard Library / Trade Classes / CTrade / BuyLimit
Documentation on MQL5: Standard Library / Trade Classes / CTrade / BuyLimit
  • www.mql5.com
Successful completion of the BuyLimit(...) method does not always mean successful execution of the trade operation. It is necessary to check the result of trade request (trade server return code) using ResultRetcode() and value returned by ResultOrder().
Reason: