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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Gennady Mazur
6436
Gennady Mazur  

Брокер БКС.
Из советника не могу выставить лимитный ордер, идет постоянная ошибка об экспирации,
хотя до нее еще более недели. Более того, я осуществляю проверку экспирации и если до нее менее 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]

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

Gennady Mazur
6436
Gennady Mazur  

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

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

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
Приказы на проведение торговых операций оформляются ордерами. Каждый ордер имеет множество свойств для чтения, информацию по ним можно получать с помощью функций Идентификатор позиции, который ставится на ордере при его исполнении. Каждый исполненный ордер порождает сделку, которая открывает новую или изменяет уже существующую позицию...
prostotrader
8579
prostotrader  
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);
}

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

Gennady Mazur
6436
Gennady Mazur  
lxa:

10022

TRADE_RETCODE_INVALID_EXPIRATION

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

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

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

prostotrader
8579
prostotrader  
Gennady Mazur:

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

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

Добавлено

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

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

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