Будут рассмотрены несколько ситуаций.
- Самая простая ситуация - пользователь выставил отложенные ордера. И через пол-часа хочет проверить какой именно ордер сработал. Причём проверка будет именно через историю ордеров.
- -
1 .2 - это продолжение предыдущий незаконченной темы?
где:
1. В момент открытия нового бара на High предыдущего бара размещается ордер BuyStop, а на Low предыдущего бара размещается ордер SellStop:
теперь продолжаем:
2. Через пол-часа проеряем какой именно ордер сработал. Причём проверка будет именно через историю ордеров.
3. -
- Самая простая ситуация - пользователь выставил отложенные ордера. И через пол-часа хочет проверить какой именно ордер сработал. Причём проверка будет именно через историю ордеров.
Обращаю внимание, что проверка идёт ИСТОРИИ ОРДЕРОВ - то есть, если отложенный ордер был выставлен, но ещё не сработал, то такой ордер в истории не появится. А вот когда отложенный ордер сработает, тогда он и появится истории ордеров.
Сам советник (просто выставляет два противоположных ордера и через определённое время проверяет историю ордеров. Если в истории ордеров есть ордера, то выводится такая информация:
//--- подготовим и выведм информацию об ордере printf("#ticket %d %s %G %s at %G was set up at %s => done at %s, order magic=%d, pos ID=%d", ticket, // тикет ордера type, // тип initial_volume, // выставленный объем symbol, // символ, по которому выставили open_price, // указанная цена открытия TimeToString(time_setup),// время установки ордера TimeToString(time_done), // время исполнения илм удаления order_magic, // магик positionID // ID позиции, в которую влилась сделка по ордеру );
Настройки тестирования (MetaEditor -> Настройки):
Рис. 1. Настройки тестирования
Тестирование проводить на истории (Ctrl + F5).
Советник стартует:
Рис. 2. Старт советника
А вот принты после срабатывания первого ордера:
2016.07.17 10:33:20.684 2016.01.04 10:30:00 #ticket 3 sell limit 0.01 EURUSD at 1.09212 was set up at 2016.01.04 00:00 => done at 2016.01.04 10:01, order magic=4134862, pos ID=3
...
и после срабатывания второго ордера:
Рис. 3. Оба ордера сработали
2016.07.17 10:36:56.861 2016.01.04 17:30:00 #ticket 3 sell limit 0.01 EURUSD at 1.09212 was set up at 2016.01.04 00:00 => done at 2016.01.04 10:01, order magic=4134862, pos ID=3 2016.07.17 10:36:56.861 2016.01.04 17:30:00 #ticket 2 buy limit 0.01 EURUSD at 1.08196 was set up at 2016.01.04 00:00 => done at 2016.01.04 17:13, order magic=4134862, pos ID=3
Итак из истории ордеров можно получить тикет ордера, магик советника - который разместил этот ордер, идентификатор позиции - в которой участвовал этот ордер.
Листинг советника:
//+------------------------------------------------------------------+ //| Pending Orders.mq5 | //| Copyright © 2016, Vladimir Karputov | //| http://wmua.ru/slesar/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2016, Vladimir Karputov" #property link "http://wmua.ru/slesar/" #property version "1.000" #property description "Размещение двух отложенных ордеров и периодическая" #property description "распринтовка истории ордеров и свойств ордеров:" #property description "тикет ордера, тип ордера, магик эксперта" #define MACD_MAGIC 4134862 //--- #include <Trade\Trade.mqh> #include <Trade\SymbolInfo.mqh> //--- input double InpLots=0.01; // Лоты input int InpIndent=50; // Отступ от текущей цены //--- int ExtTimeOut=1800; // Время (секунды) таймера double m_adjusted_point; // Значение точки с поправкой на 3 или 5 знака double m_indent; // отступ в ценах инструмента CTrade m_trade; // CTrade обьект CSymbolInfo m_symbol; // CSymbolInfo обьект bool ExtOrdersPlaced=false; // false -> ордера ещё не размещались datetime history_start; // переменная для использования в вызове HistorySelect() //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- create timer EventSetTimer(ExtTimeOut); //--- инициализия общей информации m_symbol.Name(Symbol()); // символ m_trade.SetExpertMagicNumber(MACD_MAGIC); // магик m_trade.SetMarginMode(); //--- настройка для 3 или 5 разрядов int digits_adjust=1; if(m_symbol.Digits()==3 || m_symbol.Digits()==5) digits_adjust=10; m_adjusted_point=m_symbol.Point()*digits_adjust; //--- m_indent=InpIndent*m_adjusted_point; //--- запомним время запуска эксперта для получения торговой истории history_start=TimeCurrent()-60; //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- destroy timer EventKillTimer(); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- if(!ExtOrdersPlaced) { if(!m_symbol.RefreshRates()) return; m_trade.BuyLimit(InpLots,m_symbol.Bid()-m_indent,m_symbol.Name(),0,0,0,0,"buy limit"); m_trade.SellLimit(InpLots,m_symbol.Ask()+m_indent,m_symbol.Name(),0,0,0,0,"sell limit"); ExtOrdersPlaced=true; } } //+------------------------------------------------------------------+ //| Timer function | //+------------------------------------------------------------------+ void OnTimer() { //--- запросим торговую историю ResetLastError(); bool update=HistorySelect(history_start,TimeCurrent()); if(!update) { Print("Ошибка HistorySelect с ",TimeToString(history_start,TIME_DATE|TIME_MINUTES|TIME_SECONDS), " по ",TimeToString(TimeCurrent(),TIME_DATE|TIME_MINUTES|TIME_SECONDS)); return; } //--- переменные для получения значений из свойств ордера ulong ticket; double open_price; double initial_volume; datetime time_setup; datetime time_done; string symbol; string type; long order_magic; long positionID; //--- количество текущих отложенных ордеров uint total=HistoryOrdersTotal(); //--- пройдем в цикле по всем ордерам for(uint i=0;i<total;i++) { //--- получим тикет ордера по его позиции в списке if((ticket=HistoryOrderGetTicket(i))>0) { //--- получим свойства ордера open_price= HistoryOrderGetDouble(ticket,ORDER_PRICE_OPEN); time_setup= (datetime)HistoryOrderGetInteger(ticket,ORDER_TIME_SETUP); time_done=(datetime)HistoryOrderGetInteger(ticket,ORDER_TIME_DONE); symbol=HistoryOrderGetString(ticket,ORDER_SYMBOL); order_magic= HistoryOrderGetInteger(ticket,ORDER_MAGIC); positionID = HistoryOrderGetInteger(ticket,ORDER_POSITION_ID); initial_volume=HistoryOrderGetDouble(ticket,ORDER_VOLUME_INITIAL); type=GetOrderType(HistoryOrderGetInteger(ticket,ORDER_TYPE)); //--- подготовим и выведм информацию об ордере printf("#ticket %d %s %G %s at %G was set up at %s => done at %s, order magic=%d, pos ID=%d", ticket, // тикет ордера type, // тип initial_volume, // выставленный объем symbol, // символ, по которому выставили open_price, // указанная цена открытия TimeToString(time_setup),// время установки ордера TimeToString(time_done), // время исполнения илм удаления order_magic, // магик positionID // ID позиции, в которую влилась сделка по ордеру ); } } //--- } //+------------------------------------------------------------------+ //| Возвращает строковое наименование типа ордера | //+------------------------------------------------------------------+ string GetOrderType(long type) { string str_type="unknown operation"; switch((int)type) { case (ORDER_TYPE_BUY): return("buy"); case (ORDER_TYPE_SELL): return("sell"); case (ORDER_TYPE_BUY_LIMIT): return("buy limit"); case (ORDER_TYPE_SELL_LIMIT): return("sell limit"); case (ORDER_TYPE_BUY_STOP): return("buy stop"); case (ORDER_TYPE_SELL_STOP): return("sell stop"); case (ORDER_TYPE_BUY_STOP_LIMIT): return("buy stop limit"); case (ORDER_TYPE_SELL_STOP_LIMIT):return("sell stop limit"); } return(str_type); } //+------------------------------------------------------------------+ //| TradeTransaction function | //+------------------------------------------------------------------+ void OnTradeTransaction(const MqlTradeTransaction &trans, const MqlTradeRequest &request, const MqlTradeResult &result) { //--- } //+------------------------------------------------------------------+
И что же все таки дальше? Будем ждать понедельника или когда ордер сработает?
Насчет понедельника.
В справке написано, что в конторах которые начисляют свопы путем переоткрытия позиций ID позиции изменяется и не будет совпадать с тикетом ордера открывшим ее.
В этом случае надо использовать для ордеров ORDER_POSITION_ID ,а для открытых позиций POSITION_IDENTIFIER который не изменяется в течение всей ее жизни.
Насчет понедельника.
В справке написано, что в конторах которые начисляют свопы путем переоткрытия позиций ID позиции изменяется и не будет совпадать с тикетом ордера открывшим ее.
В этом случае надо использовать для ордеров ORDER_POSITION_ID ,а для открытых позиций POSITION_IDENTIFIER который не изменяется в течение всей ее жизни.
Скрипт PositionIdentifier.mq5 поможет получать данные для ввода в следующие скрипты или советники: он распечатывает для всех позиций два параметра:
POSITION_TICKET | Тикет позиции. Уникальное число, которое присваивается каждой вновь открытой позиции. Как правило, соответствует тикету ордера, в результате которого она была открыта, за исключением случаев изменения тикета в результате служебных операций на сервере. Например, начисления свопов переоткрытием позиции. Для нахождения ордера, которым была открыта позиция, следует использовать свойство POSITION_IDENTIFIER. Значение POSITION_TICKET соответствует MqlTradeRequest::position. | long |
POSITION_IDENTIFIER | Идентификатор позиции - это уникальное число, которое присваивается каждой вновь открытой позиции и не изменяется в течение всей ее жизни. Соответствует тикету ордера, которым была открыта позиция.
Идентификатор позиции указывается в каждом ордере (ORDER_POSITION_ID) и сделке (DEAL_POSITION_ID), которая ее открыла, изменила или закрыла. Используйте это свойство для поиска ордеров и сделок, связанных с позицией.
Переворот позиции изменяет ее идентификатор на тикет ордера, в результате которого произошел переворот. | long |
Работает как на неттинговых, так и на хэдж счетах.
Листинг скрипта:
//+------------------------------------------------------------------+ //| PositionIdentifier.mq5 | //| Copyright 2016, MetaQuotes Software Corp. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2016, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property description "Print POSITION_IDENTIFIER and POSITION_TICKET" #property version "1.000" //+------------------------------------------------------------------+ //| Script program start function | //+------------------------------------------------------------------+ void OnStart() { //--- int pos=PositionsTotal(); for(int i=0;i<pos;i++) { ResetLastError(); string pos_symbol=PositionGetSymbol(i); if(pos_symbol==NULL) { Print("Error PositionGetSymbol #",GetLastError()); return; } long pos_ticket=PositionGetInteger(POSITION_TICKET); if(pos_ticket==0) { Print("Error PositionGetInteger(POSITION_TICKET)"); return; } long pos_identifier=PositionGetInteger(POSITION_IDENTIFIER); if(pos_ticket==0) { Print("Error PositionGetInteger(POSITION_IDENTIFIER)"); return; } PrintFormat("Symbol: %s, ticket: %I64d, identifier: %I64d",pos_symbol,pos_ticket,pos_identifier); } } //+------------------------------------------------------------------+
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Будут рассмотрены несколько ситуаций.