Что я делаю не так? Ошибка по экспирации.

 

Брокер БКС.
Из советника не могу выставить лимитный ордер, идет постоянная ошибка об экспирации,
хотя до нее еще более недели. Более того, я осуществляю проверку экспирации и если до нее менее 3 дней,
то я не выставляю ордер. Уже что только не перепробовал.
Вот код.

bool My_Expert::SetPendingOrder(string symbol,ENUM_ORDER_TYPE type,double price,double volume,datetime expiration,string comment="",ulong deviation=10,ENUM_ORDER_TYPE_FILLING filling=ORDER_FILLING_FOK)
{
  MqlTradeRequest Request;
  MqlTradeResult Results;
  ZeroMemory(Request);
  ZeroMemory(Results);
  Request.action=TRADE_ACTION_PENDING;
  Request.symbol=symbol;
  Request.type=type;
  Request.price=price;
  Request.volume=volume;      
  Request.deviation=deviation; 
  Request.comment=comment;  
  Request.type_filling=filling;
//  Request.type_time=ORDER_TIME_SPECIFIED;
//  Request.type_time=ORDER_TIME_GTC;
  Request.expiration=expiration;
  bool res=false;
  res=OrderSend(Request,Results);
      int answer=Results.retcode;
      GetLastError();
      Print("Ошибка!!! Код ",answer);
      Print("Ошибка!!! Запрос ",TimeToString(Request.expiration));
  if(res)
  {
    if(Results.order>0) return(true);
    else return(false);
  }
  return(false);
}
bool My_Expert::Check_Expiration()
{
  data_Expiration=(datetime)SymbolInfoInteger(m_symbol,SYMBOL_EXPIRATION_TIME);
  MqlDateTime data_exp;
  MqlDateTime data_cur;
  TimeToStruct(data_Expiration,data_exp);
  TimeToStruct(TimeCurrent(),data_cur);
  if(data_cur.mon==data_exp.mon && data_cur.day+3>data_exp.day)
  {
    Print(m_symbol," Contract Expiration ",data_exp.day,".",data_exp.mon);
    return(true);
  }
  return(false);
}

а в результате при проверке в тестере на визуале получаю вот такие записи.

2020.05.20 15:21:32.865 2020.04.20 11:14:20   Ошибка!!! Код 10022
2020.05.20 15:21:32.865 2020.04.20 11:14:20   Ошибка!!! Запрос 2020.06.01 18:45
2020.05.20 15:21:32.865 2020.04.20 11:14:20   failed buy limit 1.00 BR-6.20 at 28.77 [Invalid expiration]

Подскажите как устранить эту проблему.

 

Сам  запрос выглядит так

    res=SetPendingOrder(m_symbol,type_order,price_order,m_volume,data_Expiration,comment_EA,slippage,order_filling);
 

10022

TRADE_RETCODE_INVALID_EXPIRATION

Неверная дата истечения ордера в запросе

https://www.mql5.com/ru/docs/constants/errorswarnings/enum_trade_return_codes

Например, ORDER_TIME_DAY у меня работает. Другие варианты не знаю.

Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Свойства ордеров
Документация по MQL5: Константы, перечисления и структуры / Торговые константы / Свойства ордеров
  • www.mql5.com
Приказы на проведение торговых операций оформляются ордерами. Каждый ордер имеет множество свойств для чтения, информацию по ним можно получать с помощью функций Идентификатор позиции, который ставится на ордере при его исполнении. Каждый исполненный ордер порождает сделку, которая открывает новую или изменяет уже существующую позицию...
 
Gennady Mazur:

Сам  запрос выглядит так

void SetOrder(const string aSymbol, uint &order_id, const double price, const double volume, const bool buy_sell)
{
  MqlTradeRequest request = {0};
  MqlTradeResult  result  = {0};
  main_order_ticket = 0;
  main_order_symbol = aSymbol;
 /* main_mem_magic = magic_storage + 1;
//---  
  if(main_mem_magic >= (magic_number + 254)) main_mem_magic = magic_number;*/
  
  main_mem_magic = magic_storage + 1;
  if(main_mem_magic >= (magic_number + 254))
  {
    main_mem_magic = magic_number;
    magic_storage = magic_number;
  }
//--- Fill structure
  request.magic = main_mem_magic;
  request.symbol = aSymbol;
  request.volume = volume; 
  request.type_filling = ORDER_FILLING_IOC;
  request.type_time = ORDER_TIME_DAY;
  if(price == 0)
  {
    request.action = TRADE_ACTION_DEAL;
    request.comment = "Рыночный ордер...";
    if(buy_sell == true)
    {
      request.type = ORDER_TYPE_BUY;
    }
    else
    {
      request.type = ORDER_TYPE_SELL;
    }
  }
  else
  { 
    request.action = TRADE_ACTION_PENDING;
    request.price = price;
    request.comment = "Лимитный ордер...";
    if (buy_sell)
    {
      request.type = ORDER_TYPE_BUY_LIMIT;
    }
    else
    {
      request.type = ORDER_TYPE_SELL_LIMIT;
    }   
  }  
//--- Send order
  if(OrderSendAsync(request, result) == true)
  {
    if((result.retcode == TRADE_RETCODE_PLACED) || (result.retcode == TRADE_RETCODE_DONE))
    {
      order_id = result.request_id;
      magic_storage = main_mem_magic;
      main_state = ORD_DO_SET;
      main_mem_time = GetMicrosecondCount();
      main_start_time = TimeCurrent();
      SetTransCount();
    }
    else
    {
      order_id = 0;
      main_mem_magic = 0;
      main_order_symbol = "";
      main_state = ORD_NO_STATE;
      main_mem_time = 0;
      main_start_time = 0;
      CheckError(result.retcode, "SetOrder: Ордер не установлен! Причина: ", MAIN_ORDER, main_order_ticket);
    }
  }
  else
  {
    order_id = 0;
    main_mem_magic = 0;
    main_order_symbol = "";
    main_state = ORD_NO_STATE;
    main_mem_time = 0;
    main_start_time = 0;
    CheckError(result.retcode, "SetOrder: Ордер не отправлен! Причина: ", MAIN_ORDER, main_order_ticket);
  }
}

И прежде чем отправлять ордера, хорошо бы проверить какие параметры поддерживает брокер

//+------------------------------------------------------------------+
//| Expert Check Market Parameters function                          |
//+------------------------------------------------------------------+
bool CheckMarketParam(const string a_symbol)
{
//--- Check real accaunt
  ENUM_ACCOUNT_TRADE_MODE acc_trade_mode = ENUM_ACCOUNT_TRADE_MODE(AccountInfoInteger(ACCOUNT_TRADE_MODE));
#ifdef DEBUG
  if(acc_trade_mode != ACCOUNT_TRADE_MODE_DEMO)
  {
    MessageBox("Эксперт запущен не на демо-счёте!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
#else
  if(acc_trade_mode != ACCOUNT_TRADE_MODE_REAL)
  {
    MessageBox("Эксперт запущен не на реальном счёте!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
#endif  
//--- Check margine mode
  ENUM_ACCOUNT_MARGIN_MODE margin_mode = ENUM_ACCOUNT_MARGIN_MODE(AccountInfoInteger(ACCOUNT_MARGIN_MODE));
  if(margin_mode != ACCOUNT_MARGIN_MODE_RETAIL_NETTING)
  {
    MessageBox("Брокер не поддерживает биржевой расчёт маржи в режиме 'Неттинг'!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
//--- Check symbol calc mode 
  ENUM_SYMBOL_CALC_MODE calc_mode = ENUM_SYMBOL_CALC_MODE(SymbolInfoInteger(a_symbol, SYMBOL_TRADE_CALC_MODE));
  
  if((calc_mode != SYMBOL_CALC_MODE_EXCH_FUTURES_FORTS) && (calc_mode != SYMBOL_CALC_MODE_EXCH_OPTIONS_MARGIN))
  {
    MessageBox("Символ " + a_symbol + " не поддерживает расчёт фьючерсов для FORTS!", "Ошибка", MB_OK | MB_ICONHAND);
    Print("Текуший расчёт: ", EnumToString(calc_mode));
    return( false );
  } 
//--- Check for full mode
  ENUM_SYMBOL_TRADE_MODE trade_mode = ENUM_SYMBOL_TRADE_MODE(SymbolInfoInteger(a_symbol, SYMBOL_TRADE_MODE));
  
  if(trade_mode != SYMBOL_TRADE_MODE_FULL)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает полную торговлю!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
//--- Check trade execution mode
  ENUM_SYMBOL_TRADE_EXECUTION market_info = ENUM_SYMBOL_TRADE_EXECUTION( SymbolInfoInteger(a_symbol, SYMBOL_TRADE_EXEMODE));
    
  if((market_info & SYMBOL_TRADE_EXECUTION_EXCHANGE) != SYMBOL_TRADE_EXECUTION_EXCHANGE)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает TRADE EXECUTION EXCHANGE режим!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
//--- Check orders mode
  int order_mode = int(SymbolInfoInteger(a_symbol, SYMBOL_ORDER_MODE));
  
  if((SYMBOL_ORDER_MARKET & order_mode) != SYMBOL_ORDER_MARKET)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает Market Execution режим установки ордеров!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
  
  if((SYMBOL_ORDER_LIMIT & order_mode) != SYMBOL_ORDER_LIMIT)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает Limit режим установки ордеров!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
  
  if((SYMBOL_ORDER_STOP_LIMIT & order_mode) != SYMBOL_ORDER_STOP_LIMIT)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает Stop Limit режим установки ордеров!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
  
  if((SYMBOL_ORDER_STOP & order_mode) != SYMBOL_ORDER_STOP)
  {
    MessageBox( "Символ " + a_symbol + " не поддерживает Stop режим установки ордеров!", "Ошибка", MB_OK | MB_ICONHAND );
    return(false);
  }
  
  if((SYMBOL_ORDER_SL & order_mode) != SYMBOL_ORDER_SL)
  {
    MessageBox( "Символ " + a_symbol + " не поддерживает Stop Loss режим установки ордеров!", "Ошибка", MB_OK | MB_ICONHAND );
    return(false);
  }
  
  if((SYMBOL_ORDER_TP & order_mode) != SYMBOL_ORDER_TP)
  {
    MessageBox( "Символ " + a_symbol + " не поддерживает Take Profit режим установки ордеров!", "Ошибка", MB_OK | MB_ICONHAND );
    return(false);
  }
//---Filing mode
  int filling_mode = int(SymbolInfoInteger(a_symbol, SYMBOL_FILLING_MODE));
  
  if((SYMBOL_FILLING_IOC & filling_mode) != SYMBOL_FILLING_IOC)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает filling IOC режим исполнения ордеров!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
  
  if((SYMBOL_FILLING_FOK & filling_mode) != SYMBOL_FILLING_FOK)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает filling FOK режим исполнения ордеров!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
//---Ckeck expiration
  int symbol_exp_type = int( SymbolInfoInteger(a_symbol, SYMBOL_EXPIRATION_MODE));
//---  
  if((symbol_exp_type & SYMBOL_EXPIRATION_DAY) != SYMBOL_EXPIRATION_DAY)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает экспирацию DAY!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
  if((symbol_exp_type & SYMBOL_EXPIRATION_SPECIFIED_DAY) != SYMBOL_EXPIRATION_SPECIFIED_DAY)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает экспирацию SPECIFIED DAY!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
  return(true);
}

И если Вы торгуете на ФОРТС, то лучше пишите в Биржевой раздел

 
lxa:

10022

TRADE_RETCODE_INVALID_EXPIRATION

Неверная дата истечения ордера в запросе

Например, ORDER_TIME_DAY у меня работает. Другие варианты не знаю.

Применил ORDER_TIME_SPECIFIED_DAY ... помогло
конечно это не совсем точно то что надо, но как выход из критической ситуации подходит.
Большое спасибо.

 
Gennady Mazur:

Применил ORDER_TIME_SPECIFIED_DAY ... помогло
конечно это не совсем точно то что надо, но как выход из критической ситуации подходит.
Большое спасибо.

Нужно не подбирать параметры, а сначала проверить их и потом устанавливать.

Добавлено

На ФОРТС  Request.deviation=deviation; не работает

И не нужжно использовать FOK, когда торгуете BR, никогда не наберете позицию 

 
Спасибо всем ... пока тема закрыта ...
временное решение найдено, а позже разберусь досконально.
 

@prostotrader, подскажите пожалуйста в какую часть советника вставить вашу часть кода, чтобы он работал. 

Что я делаю не так? Ошибка по экспирации.
Что я делаю не так? Ошибка по экспирации.
  • www.mql5.com
Брокер БКС. Из советника не могу выставить лимитный ордер, идет постоянная ошибка об экспирации, хотя до нее еще более недели...
 
sergofortrsh #:

@prostotrader, подскажите пожалуйста в какую часть советника вставить вашу часть кода, чтобы он работал. 

Добрый день!

Эта проверка делается один раз, при инициализации советника.

OnInit() 

 
prostotrader #:

Добрый день!

Эта проверка делается один раз, при инициализации советника.

OnInit() 

Спасибо за ответ. Но все равно не понял. При вставлении кода внутрь  OnInit()  выдает ошибку: 'CheckMarketParam'  - function declarations are allowed on global, namespace or class scope only. 

 
sergofortrsh #:

Спасибо за ответ. Но все равно не понял. При вставлении кода внутрь  OnInit()  выдает ошибку: 'CheckMarketParam'  - function declarations are allowed on global, namespace or class scope only. 

Вот так надо

//+------------------------------------------------------------------+
//|                                                         4_aa.mq5 |
//|                                      Copyright 2021 prostotrader |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021 prostotrader"
#property link      "https://www.mql5.com"
#property version   "1.00"

//+------------------------------------------------------------------+
//| Expert Check Market Parameters function                          |
//+------------------------------------------------------------------+
bool CheckMarketParam(const string a_symbol)
{
//--- Check real accaunt
  ENUM_ACCOUNT_TRADE_MODE acc_trade_mode = ENUM_ACCOUNT_TRADE_MODE(AccountInfoInteger(ACCOUNT_TRADE_MODE));
#ifdef DEBUG
  if(acc_trade_mode != ACCOUNT_TRADE_MODE_DEMO)
  {
    MessageBox("Эксперт запущен не на демо-счёте!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
#else
  if(acc_trade_mode != ACCOUNT_TRADE_MODE_REAL)
  {
    MessageBox("Эксперт запущен не на реальном счёте!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
#endif  
//--- Check margine mode
  ENUM_ACCOUNT_MARGIN_MODE margin_mode = ENUM_ACCOUNT_MARGIN_MODE(AccountInfoInteger(ACCOUNT_MARGIN_MODE));
  if(margin_mode != ACCOUNT_MARGIN_MODE_RETAIL_NETTING)
  {
    MessageBox("Брокер не поддерживает биржевой расчёт маржи в режиме 'Неттинг'!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
//--- Check symbol calc mode 
  ENUM_SYMBOL_CALC_MODE calc_mode = ENUM_SYMBOL_CALC_MODE(SymbolInfoInteger(a_symbol, SYMBOL_TRADE_CALC_MODE));
  
  if((calc_mode != SYMBOL_CALC_MODE_EXCH_FUTURES_FORTS) && (calc_mode != SYMBOL_CALC_MODE_EXCH_OPTIONS_MARGIN))
  {
    MessageBox("Символ " + a_symbol + " не поддерживает расчёт фьючерсов для FORTS!", "Ошибка", MB_OK | MB_ICONHAND);
    Print("Текуший расчёт: ", EnumToString(calc_mode));
    return( false );
  } 
//--- Check for full mode
  ENUM_SYMBOL_TRADE_MODE trade_mode = ENUM_SYMBOL_TRADE_MODE(SymbolInfoInteger(a_symbol, SYMBOL_TRADE_MODE));
  
  if(trade_mode != SYMBOL_TRADE_MODE_FULL)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает полную торговлю!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
//--- Check trade execution mode
  ENUM_SYMBOL_TRADE_EXECUTION market_info = ENUM_SYMBOL_TRADE_EXECUTION( SymbolInfoInteger(a_symbol, SYMBOL_TRADE_EXEMODE));
    
  if((market_info & SYMBOL_TRADE_EXECUTION_EXCHANGE) != SYMBOL_TRADE_EXECUTION_EXCHANGE)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает TRADE EXECUTION EXCHANGE режим!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
//--- Check orders mode
  int order_mode = int(SymbolInfoInteger(a_symbol, SYMBOL_ORDER_MODE));
  
  if((SYMBOL_ORDER_MARKET & order_mode) != SYMBOL_ORDER_MARKET)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает Market Execution режим установки ордеров!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
  
  if((SYMBOL_ORDER_LIMIT & order_mode) != SYMBOL_ORDER_LIMIT)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает Limit режим установки ордеров!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
  
  if((SYMBOL_ORDER_STOP_LIMIT & order_mode) != SYMBOL_ORDER_STOP_LIMIT)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает Stop Limit режим установки ордеров!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
  
  if((SYMBOL_ORDER_STOP & order_mode) != SYMBOL_ORDER_STOP)
  {
    MessageBox( "Символ " + a_symbol + " не поддерживает Stop режим установки ордеров!", "Ошибка", MB_OK | MB_ICONHAND );
    return(false);
  }
  
  if((SYMBOL_ORDER_SL & order_mode) != SYMBOL_ORDER_SL)
  {
    MessageBox( "Символ " + a_symbol + " не поддерживает Stop Loss режим установки ордеров!", "Ошибка", MB_OK | MB_ICONHAND );
    return(false);
  }
  
  if((SYMBOL_ORDER_TP & order_mode) != SYMBOL_ORDER_TP)
  {
    MessageBox( "Символ " + a_symbol + " не поддерживает Take Profit режим установки ордеров!", "Ошибка", MB_OK | MB_ICONHAND );
    return(false);
  }
//---Filing mode
  int filling_mode = int(SymbolInfoInteger(a_symbol, SYMBOL_FILLING_MODE));
  
  if((SYMBOL_FILLING_IOC & filling_mode) != SYMBOL_FILLING_IOC)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает filling IOC режим исполнения ордеров!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
  
  if((SYMBOL_FILLING_FOK & filling_mode) != SYMBOL_FILLING_FOK)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает filling FOK режим исполнения ордеров!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
//---Ckeck expiration
  int symbol_exp_type = int( SymbolInfoInteger(a_symbol, SYMBOL_EXPIRATION_MODE));
//---  
  if((symbol_exp_type & SYMBOL_EXPIRATION_DAY) != SYMBOL_EXPIRATION_DAY)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает экспирацию DAY!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
  if((symbol_exp_type & SYMBOL_EXPIRATION_SPECIFIED_DAY) != SYMBOL_EXPIRATION_SPECIFIED_DAY)
  {
    MessageBox("Символ " + a_symbol + " не поддерживает экспирацию SPECIFIED DAY!", "Ошибка", MB_OK | MB_ICONHAND);
    return(false);
  }
  return(true);
}

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
     if(CheckMarketParam(Symbol()) == false) return(INIT_FAILED);   
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   
  }
//+------------------------------------------------------------------+
Причина обращения: