Ошибка 4756

 

Раньше я с такой ошибкой не сталкивался. Перешёл на терминал другого брокера и сразу столкнулся с этим вопросом.

У меня в библиотеках есть функция для получения типа заливки ордера. По сути, я это происходит вот так:

void SymbolInstance :: setOrderFillingType(void) {
//---
  int fillingMode = (int)SymbolInfoInteger(m_name, SYMBOL_FILLING_MODE);    // Получение возможного варианта заполнения ордера

  if ((SYMBOL_FILLING_FOK& fillingMode) == SYMBOL_FILLING_FOK) {
    m_orderFillingType = ORDER_FILLING_FOK;
  } else {
    if ((SYMBOL_FILLING_IOC& fillingMode) == SYMBOL_FILLING_IOC) {
      m_orderFillingType = ORDER_FILLING_IOC;
    } else {
      m_orderFillingType = ORDER_FILLING_RETURN;
    }
  }
}

В переменную m_orderFillingType присваивается значение типа заливки оредра.

// Возвращает тип ордера по исполнению(m_orderFillingType). ========================================================================================================================
ENUM_ORDER_TYPE_FILLING SymbolInstance :: getOrderFillingType(void) const {
//---
  return m_orderFillingType;
}

В справке я вижу это:

Все/Ничего

SYMBOL_FILLING_FOK

1

Данная политика исполнения означает, что ордер может быть исполнен исключительно в указанном объеме. Если на рынке в данный момент не присутствует достаточного объема финансового инструмента, то ордер не будет исполнен. Необходимый объем может быть составлен из нескольких предложений, доступных в данный момент на рынке.

Все/Частично

SYMBOL_FILLING_IOC

2

В данном случае трейдер соглашается совершить сделку по максимально доступному на рынке объему в пределах указанного в ордере. В случае невозможности полного исполнения ордер будет исполнен на доступный объем, а неисполненный объем ордера будет отменен. Возможность использования IOC ордеров определяется на торговом сервере.

Вернуть

Идентификатор отсутствует

 

Данный режим используется для рыночных (Buy и Sell), лимитных и стоп-лимитных ордеров и только в режимах "Исполнение по рынку" и "Биржевое исполнение". В случае частичного исполнения рыночный или лимитный ордер с остаточным объемом не снимается, а продолжает действовать.

Я принтанул в боте fillingType и вижу, что он равен 2 т.е. SYMBOL_FILLING_IOC

.

При заполнении структуры торгового запроса у меня прописано так:

m_request.type_filling = ptrSymbol.getOrderFillingType();

где m_request - экземпляр структуры MqlTradeRequest

По сути, в функцию открытия ордера попадает тип 2 т.е. SYMBOL_FILLING_IOC

Почему тогда возникает ошибка?

 
Когда устанете разбираться, сделайте #include <MT4Orders.mqh>
 
Andrey Khatimlianskii:
Когда устанете разбираться, сделайте #include <MT4Orders.mqh>

Вы сами понимате, как это работает? Я интересуюсь лишь как отличается отправка ордера с различной заливкой лота и всё..

А то, что этот инклюдник можно импортировать, я уже это видел. Но это форум, вроде бы, для обсуждения языка mql. Вот я и спрашиваю.

Я уже проверял с типами заливки ORDER_FILLING_FOK и ORDER_FILLING_IOC. Всё выдаёт ту же самую ошибку. С чего бы это вдруг?

Документация по MQL5: Торговые функции / OrderSend
Документация по MQL5: Торговые функции / OrderSend
  • www.mql5.com
OrderSend - Торговые функции - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Viktar Dzemikhau:

Вы сами понимате, как это работает? Я интересуюсь лишь как отличается отправка ордера с различной заливкой лота и всё..

А то, что этот инклюдник можно импортировать, я уже это видел. Но это форум, вроде бы, для обсуждения языка mql. Вот я и спрашиваю.

Я уже проверял с типами заливки ORDER_FILLING_FOK и ORDER_FILLING_IOC. Всё выдаёт ту же самую ошибку. С чего бы это вдруг?

Прежде, чем отправлять ордера, нужно (при инициализации советника) проверить какие режимы поддерживает Ваш брокер. 

Например:

//+------------------------------------------------------------------+
//| 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);
}
 
prostotrader:

Прежде, чем отправлять ордера, нужно (при инициализации советника) проверить какие режимы поддерживает Ваш брокер. 

Это понятно. У меня мои классы работают там,г где я проверял. Но здесь.. столкнулся с этим моментом. Вчера ночью спать хотел. Потому и спросил, что бы прояснилась ситуация. Оказалось, что быстрее посмотреть самому..))

Я щяс смотрю стандартный класс CTrade. Вот здесь вижу такое:

bool CTrade::SetTypeFillingBySymbol(const string symbol) {
//--- get possible filling policy types by symbol
  uint filling = (uint)SymbolInfoInteger(symbol, SYMBOL_FILLING_MODE);
  if ((filling&SYMBOL_FILLING_FOK) == SYMBOL_FILLING_FOK) {
    m_type_filling = ORDER_FILLING_FOK;
    return true;
  }
  if ((filling&SYMBOL_FILLING_IOC) == SYMBOL_FILLING_IOC) {
    m_type_filling = ORDER_FILLING_IOC;
    return true;
  }
//---
  return false;
}

Сразу возникает вопорс. А как же информация из справки?

Все/Ничего

SYMBOL_FILLING_FOK

1

Данная политика исполнения означает, что ордер может быть исполнен исключительно в указанном объеме. Если на рынке в данный момент не присутствует достаточного объема финансового инструмента, то ордер не будет исполнен. Необходимый объем может быть составлен из нескольких предложений, доступных в данный момент на рынке.

Все/Частично

SYMBOL_FILLING_IOC

2

В данном случае трейдер соглашается совершить сделку по максимально доступному на рынке объему в пределах указанного в ордере. В случае невозможности полного исполнения ордер будет исполнен на доступный объем, а неисполненный объем ордера будет отменен. Возможность использования IOC ордеров определяется на торговом сервере.

Вернуть

Идентификатор отсутствует

 

Данный режим используется для рыночных (Buy и Sell), лимитных и стоп-лимитных ордеров и только в режимах "Исполнение по рынку" и "Биржевое исполнение". В случае частичного исполнения рыночный или лимитный ордер с остаточным объемом не снимается, а продолжает действовать.


Т.е. там проверка исключает 3-ий вариант. Возникает вопрос попутный. А зачем тогда вариант без инентификатора? Его добавили, что бы исключить из возможности торговли с тикаим режимом заливки?

Документация по MQL5: Константы, перечисления и структуры / Состояние окружения / Информация об инструменте
Документация по MQL5: Константы, перечисления и структуры / Состояние окружения / Информация об инструменте
  • www.mql5.com
Информация об инструменте - Состояние окружения - Константы, перечисления и структуры - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Viktar Dzemikhau:

Я лишь сказал, что если вам нужно "ехать, а не шашечки", то можно не терять свое драгоценное время.

 
Andrey Khatimlianskii:

Я лишь сказал, что если вам нужно "ехать, а не шашечки", то можно не терять свое драгоценное время.

В таком случае, нужно было не терять своё драгоценное время и не писать такие бестолковые комментарии. Это разгоовр ни о чём. Я задал конкретный вопрос. Это не просьба дать мне готовый клас или функцию, а лишь пояснить как это работает. Соответственно, вопрос задан тем, кто понимает как это работает, а не тем, кто способен лишь добавить включаемый файл.

 
prostotrader:

Прежде, чем отправлять ордера, нужно (при инициализации советника) проверить какие режимы поддерживает Ваш брокер. 

Я в инициалзиацю торгового бота прописал проверку вашу как-то так:

  if (!checkMarketParam(_Symbol)) {
    Print(__FUNCTION__, " :: Initialization is invalid!");
    return INIT_FAILED;
  }


Сразу видно, что имеются несколько проверок, на которыз работа бота завершается ещё при инициализации. Первая проверка меня, на данный момент, не особо интересует, а вот вторая очень даже интересует. Вижу MessageBox следующего содержания:

Брокер не поддерживает биржевой расчёт маржи в режиме 'Неттинг'
Символ EURUSD не поддерживает filling FOK режим исполнения ордеров!

То что не поддерживается неттинг я уже понял. Но что с этим делать теперь? Я и не запрашивал неттинг. Изначально я задавал режим заливки лота в структуре торгового запроса в значение  SYMBOL_FILLING_FOK. Но этот вариант тоже не прокатывает. Такое ощущение, что оно вообще никак не работает.

У меня уже после всех проверок в переменную type_filling структуры торгового запроса присваивается режим исполнения SYMBOL_FILLING_FOK. Тем не менее, всё-равно при попытке открыть ордера возникает ошибка. Причём, не важно какой режим заполнения я задаю. Всегда та же самая ошибка.

Обрисую схему своей проверки. После всех присвоедений в структуру торгового запроса я вбиваю поочерёдно каждый из вариантов режима заливки. Например:

m_request.type_filling = SYMBOL_FILLING_IOK;

Далее с учётом всех проверок у меня отправляется ордер:

sent = OrderSend(m_request, m_result);

В самом конце функции, которая отправляется торговый запрос на открытие ордера у меня логирование ошибки, в случае её появления:

 if (m_result.order < 1) {
    writeLog(MESSAGE_ERROR, __FUNCTION__ + " { position wasn't sent! " + "m_result.retcode = '" + iToS(m_result.retcode) + "' | " +
                                                                         "orderType = '" + EnumToString(m_request.type) + "' | " +
                                                                         "orderPrice = '" + dToS(m_request.price) + "' | " +
                                                                         "sl = '" + dToS(m_request.sl) + "' | " +
                                                                         "tp = '" + dToS(m_request.tp) + "' | " +
                                                                         "typeFilling = '" + (string)ENUM_ORDER_TYPE_FILLING(m_request.type_filling) + "' | " +
                                                                         "spread = '" + dToS(m_symbol.spread()) + "' }");
    if (_LastError > 0)    //---- Контролируем возможные ошибки
      writeLog(MESSAGE_ERROR, __FUNCTION__ + " { _LastError = '" + iToS(_LastError) + "' }");
    return false;
  }

Самое главное, на что я хочу обратить внимание - это строка:

"typeFilling = '" + (string)ENUM_ORDER_TYPE_FILLING(m_request.type_filling) + "' | " +

Какой бы тип заполнения она не возвращала, при любом варианте ошибка.. Как так?

Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура торгового запроса
Документация по MQL5: Константы, перечисления и структуры / Структуры данных / Структура торгового запроса
  • www.mql5.com
Структура торгового запроса - Структуры данных - Константы, перечисления и структуры - Справочник MQL5 - Справочник по языку алгоритмического/автоматического трейдинга для MetaTrader 5
 
Viktar Dzemikhau:

Я щяс смотрю стандартный класс CTrade. Вот здесь вижу такое:

Сразу возникает вопорс. А как же информация из справки?

Т.е. там проверка исключает 3-ий вариант. Возникает вопрос попутный. А зачем тогда вариант без инентификатора? Его добавили, что бы исключить из возможности торговли с тикаим режимом заливки?

В CTrade  есть использование этого варианта. Смотрите метод FillingCheck.

Странно что вы его не нашли)

 
Aleksey Mavrin:

В CTrade  есть использование этого варианта. Смотрите метод FillingCheck.

Странно что вы его не нашли)

В том то и дело, что нашёл. И применил! А толку? Не работает эта функция как требуется у меня. Поэтому я и задал вопрос. Реально удивительно.

Мне интересно другое. Почему, если даже ничего не проверяя вбить в наглую режим заливки по данному инструменту это не работает? Ведь есть лишь 3 варианта. Вбиваешь поочерёдно их и какой-то ведь должен отработать. Но нет. Ни один не работает! С чего вдруг?
 
Viktar Dzemikhau:

В том то и дело, что нашёл. И применил! А толку? Не работает эта функция как требуется у меня. Поэтому я и задал вопрос. Реально удивительно.

Мне интересно другое. Почему, если даже ничего не проверяя вбить в наглую режим заливки по данному инструменту это не работает? Ведь есть лишь 3 варианта. Вбиваешь поочерёдно их и какой-то ведь должен отработать. Но нет. Ни один не работает! С чего вдруг?

Почему решили что именно тип исполнения по заливке вызвал ошибку? Может другие варианты тип по времени действия например?