Обсуждение статьи "Библиотека для простого и быстрого создания программ для MetaTrader (Часть X): Совместимость с MQL4 - События открытия позиции и активации отложенных ордеров" - страница 3
Артём, скажи пожалуйста какую роль играет выделенный участок кода
Как может выполняться этот код, если таймер не включен?
Но если этот участок кода удалить, то сообщения о событии не печатаются. А с ним всё работает.
И хотелось-бы вместе с сообщением о событии была возможность получить тикет, цены и возможно какие-то ещё свойства позиций и ордеров.
Мне кажется, что ты поменял комментарий. В OnTimer() советника проверяется работа не в тестере:
/************************Expert tick function************************/voidOnTick()
{
//--- Инициализация последнего торгового событияstatic ENUM_TRADE_EVENT last_event=WRONG_VALUE;
//--- Если работа в тестереif(MQLInfoInteger(MQL_TESTER))
{
engine.OnTimer();
}//--- Если последнее торговое событие изменилосьif(engine.LastTradeEvent()!=last_event)
{
last_event=engine.LastTradeEvent();
Comment("last_event: ",EnumToString(last_event));
Print(__FUNCTION__, " last_event: ",EnumToString(last_event));
//engine.ResetLastTradeEvent();//Print("last_event: ",EnumToString(last_event));
}
}
/***************************Timer function***************************/voidOnTimer()
{
//--- Инициализация последнего торгового событияstatic ENUM_TRADE_EVENT last_event=WRONG_VALUE;
//--- Если работа не в тестереif(!MQLInfoInteger(MQL_TESTER))
{
engine.OnTimer();
}
}
/*******************************************************************/
И сравни два обработчика: в OnTick() таймер библиотеки запускается только в тестере, а в OnTimer() таймер библиотеки запускается только не в тестере - ведь в MQL4 таймер в тестере не работает, и работаем по тикам в тестере.
Просто копировал в одном месте, а вставлял в разные и не обратил внимания. Но потом поставил отрицание в виде ! а не важное не трогал.
Но вопрос остался без ответа: Если в OnInit() таймер не запускается, то какой смысл вообще в обработчике OnTimer() и почему код в нём выполняется как минимум один раз.
В принципе я получил сообщения в журнал. Осталось получить свойства позиций. Тип, тикет, цены и время открытия, закрытия, модификации.
И хотелось-бы вместе с сообщением о событии была возможность получить тикет, цены и возможно какие-то ещё свойства позиций и ордеров.
Не в тестере ты можешь получить тикет ордера последнего события в OnChartEvent() - параметр lparam. В dparam хранится цена. В sparam - символ.
Чтобы получать данные в тестере, нужно на данный момент использовать код события, который получаешь при помощи engine.LastTradeEvent() - ведь всё зависит от события - если это модификация, то нужно получать список модификаций, а если это изменение количества ордеров, то нужно получать списки этих новых ордеров.
Нужно добавить в CEngine возврат нужных значений в программу. Я же ещё не дошёл до отправки в программу сведений - пока идёт описание подготовки необходимых данных. В последующих статьях дойдём до класса, дающего простой доступ ко всем нужным данным. А сейчас - если нужно прям срочно, то надо добавить в CEngine возврат списка из класса-коллекции событий - в самом классе есть получение этого списка, вот они - все списки в публичной секции CEventCollection:
public:
//--- Выбирает события из коллекции со временем в диапазоне от begin_time до end_time
CArrayObj *GetListByTime(const datetime begin_time=0,const datetime end_time=0);
//--- Возвращает полный список-коллекцию событий "как есть"
CArrayObj *GetList(void) { return &this.m_list_events; }
//--- Возвращает список по выбранному (1) целочисленному, (2) вещественному и (3) строковому свойству, удовлетворяющему сравниваемому критерию
CArrayObj *GetList(ENUM_EVENT_PROP_INTEGER property,longvalue,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByEventProperty(this.GetList(),property,value,mode); }
CArrayObj *GetList(ENUM_EVENT_PROP_DOUBLE property,doublevalue,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByEventProperty(this.GetList(),property,value,mode); }
CArrayObj *GetList(ENUM_EVENT_PROP_STRING property,stringvalue,ENUM_COMPARER_TYPE mode=EQUAL) { return CSelect::ByEventProperty(this.GetList(),property,value,mode); }
Все события хранятся в списке m_list_events, а эти методы возвращают либо полный список, либо отфильтрованный по заданному критерию.
Для получения последнего события достаточно создать в CEngine возврат этого списка в программу, а в программе уже брать из списка нужное событие.
Всё это скоро будет автоматизировано - пока до этого не дошла очерёдность.
Если тебе нужно всё же сделать костыль, то его обсуждение - в личку. Здесь не стоит - это не относится к библиотеке, так как она на стадии разработки, и далее будет сделана нормальная и правильная работа по получению всех и любых требуемых событий в программе.
Просто копировал в одном месте, а вставлял в разные и не обратил внимания. Но потом поставил отрицание в виде ! а не важное не трогал.
Но вопрос остался без ответа: Если в OnInit() таймер не запускается, то какой смысл вообще в обработчике OnTimer() и почему код в нём выполняется как минимум один раз.
В принципе я получил сообщения в журнал. Осталось получить свойства позиций. Тип, тикет, цены и время открытия, закрытия, модификации.
Поясни что имеешь в виду? Ты говоришь о создании таймера? Он создаётся в конструкторе CEngine:
//+------------------------------------------------------------------+//| CEngine конструктор |//+------------------------------------------------------------------+
CEngine::CEngine() : m_first_start(true),m_last_trade_event(TRADE_EVENT_NO_EVENT)
{
this.m_list_counters.Sort();
this.m_list_counters.Clear();
this.CreateCounter(COLLECTION_COUNTER_ID,COLLECTION_COUNTER_STEP,COLLECTION_PAUSE);
this.m_is_hedge=#ifdef __MQL4__ true#else bool(::AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING) #endif;
this.m_is_tester=::MQLInfoInteger(MQL_TESTER);
::ResetLastError();
#ifdef __MQL5__if(!::EventSetMillisecondTimer(TIMER_FREQUENCY))
::Print(DFUN,"Не удалось создать таймер. Ошибка: ","Could not create timer. Error: ",(string)::GetLastError());
//---__MQL4__#else
if(!this.IsTester() && !::EventSetMillisecondTimer(TIMER_FREQUENCY))
::Print(DFUN,"Не удалось создать таймер. Ошибка: ","Could not create timer. Error: ",(string)::GetLastError());
#endif }
//+------------------------------------------------------------------+
Не в тестере ты можешь получить тикет ордера последнего события в OnChartEvent() - параметр lparam. В dparam хранится цена. В sparam - символ.
Это я уже нашёл, спасибо. А получив тикет можно получить всё что надо. За исключением с какой цены была модификация. Или делать действительно костыль чтобы знать цену до модификации. В принципе не очень пока надо.
Это я уже нашёл, спасибо. А получив тикет можно получить всё что надо. За исключением с какой цены была модификация. Или делать действительно костыль чтобы знать цену до модификации. В принципе не очень пока надо.
Я тебе уже дал код - там есть всё, и цена до модификации тоже.
И вдруг при очередном издевательстве был модифицирована одна позиция, одна открыта и закрыта. Но вот откуда появилась запись об удалении давно удалённого ордера?
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
Артём, скажи пожалуйста какую роль играет выделенный участок кода
Как может выполняться этот код, если таймер не включен?
Но если этот участок кода удалить, то сообщения о событии не печатаются. А с ним всё работает.
И хотелось-бы вместе с сообщением о событии была возможность получить тикет, цены и возможно какие-то ещё свойства позиций и ордеров.
Мне кажется, что ты поменял комментарий. В OnTimer() советника проверяется работа не в тестере:
И сравни два обработчика: в OnTick() таймер библиотеки запускается только в тестере, а в OnTimer() таймер библиотеки запускается только не в тестере - ведь в MQL4 таймер в тестере не работает, и работаем по тикам в тестере.
Сейчас пример сделаю.
Мне кажется, что ты поменял комментарий.
Комментарий сам поменялся, я не трогал.)))
Просто копировал в одном месте, а вставлял в разные и не обратил внимания. Но потом поставил отрицание в виде ! а не важное не трогал.
Но вопрос остался без ответа: Если в OnInit() таймер не запускается, то какой смысл вообще в обработчике OnTimer() и почему код в нём выполняется как минимум один раз.
В принципе я получил сообщения в журнал. Осталось получить свойства позиций. Тип, тикет, цены и время открытия, закрытия, модификации.
И хотелось-бы вместе с сообщением о событии была возможность получить тикет, цены и возможно какие-то ещё свойства позиций и ордеров.
Не в тестере ты можешь получить тикет ордера последнего события в OnChartEvent() - параметр lparam. В dparam хранится цена. В sparam - символ.
Чтобы получать данные в тестере, нужно на данный момент использовать код события, который получаешь при помощи engine.LastTradeEvent() - ведь всё зависит от события - если это модификация, то нужно получать список модификаций, а если это изменение количества ордеров, то нужно получать списки этих новых ордеров.
Нужно добавить в CEngine возврат нужных значений в программу. Я же ещё не дошёл до отправки в программу сведений - пока идёт описание подготовки необходимых данных. В последующих статьях дойдём до класса, дающего простой доступ ко всем нужным данным. А сейчас - если нужно прям срочно, то надо добавить в CEngine возврат списка из класса-коллекции событий - в самом классе есть получение этого списка, вот они - все списки в публичной секции CEventCollection:
Все события хранятся в списке m_list_events, а эти методы возвращают либо полный список, либо отфильтрованный по заданному критерию.
Для получения последнего события достаточно создать в CEngine возврат этого списка в программу, а в программе уже брать из списка нужное событие.
Всё это скоро будет автоматизировано - пока до этого не дошла очерёдность.
Если тебе нужно всё же сделать костыль, то его обсуждение - в личку. Здесь не стоит - это не относится к библиотеке, так как она на стадии разработки, и далее будет сделана нормальная и правильная работа по получению всех и любых требуемых событий в программе.
Комментарий сам поменялся, я не трогал.)))
Просто копировал в одном месте, а вставлял в разные и не обратил внимания. Но потом поставил отрицание в виде ! а не важное не трогал.
Но вопрос остался без ответа: Если в OnInit() таймер не запускается, то какой смысл вообще в обработчике OnTimer() и почему код в нём выполняется как минимум один раз.
В принципе я получил сообщения в журнал. Осталось получить свойства позиций. Тип, тикет, цены и время открытия, закрытия, модификации.
Поясни что имеешь в виду? Ты говоришь о создании таймера? Он создаётся в конструкторе CEngine:
Не в тестере ты можешь получить тикет ордера последнего события в OnChartEvent() - параметр lparam. В dparam хранится цена. В sparam - символ.
Это я уже нашёл, спасибо. А получив тикет можно получить всё что надо. За исключением с какой цены была модификация. Или делать действительно костыль чтобы знать цену до модификации. В принципе не очень пока надо.
В принципе я получил сообщения в журнал. Осталось получить свойства позиций. Тип, тикет, цены и время открытия, закрытия, модификации.
Впрочем, для быстрого решения, добавь в публичную секцию CEngine возврат списка событий:
В советнике добавь этот код:
И последнее событие распечатается в журнале
Поясни что имеешь в виду? Ты говоришь о создании таймера? Он создаётся в конструкторе CEngine:
Ну, так для этого-же надо было всю библиотеку проштудировать. )))
Это я уже нашёл, спасибо. А получив тикет можно получить всё что надо. За исключением с какой цены была модификация. Или делать действительно костыль чтобы знать цену до модификации. В принципе не очень пока надо.
Я тебе уже дал код - там есть всё, и цена до модификации тоже.
Ну, так для этого-же надо было всю библиотеку проштудировать. )))
Нет. Просто прочитать статьи
И вот такая непонятка случилась:
Пока я гонял этот код на демке был установлен и удалён лимитный ордер
И вдруг при очередном издевательстве был модифицирована одна позиция, одна открыта и закрыта. Но вот откуда появилась запись об удалении давно удалённого ордера?