//+------------------------------------------------------------------+ //| Article-15026-MQL5-Trade-History-Visualizer.mq5 | //| Copyright 2026, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include "PositionsControl.mqh" #define KEY_LEFT 37 #define KEY_RIGHT 39 #define KEY_UP 38 #define KEY_DOWN 40 //--- global variables CPositionsControl ExtPositions; // Экземпляр класса исторических позиций bool ExtChartScroll; // Флаг прокрутки графика bool ExtChartHistory; // Флаг отображения торговой истории //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- Запоминаем флаг автопрокрутки графика и отключаем автопрокрутку ExtChartScroll=ChartGetInteger(ChartID(), CHART_AUTOSCROLL); ChartSetInteger(ChartID(), CHART_AUTOSCROLL, false); //--- Запоминаем флаг отображения торговой истории и отключаем показ истории ExtChartHistory=ChartGetInteger(ChartID(), CHART_SHOW_TRADE_HISTORY); ChartSetInteger(ChartID(), CHART_SHOW_TRADE_HISTORY, false); //--- Создаём список закрытых позиций и выводим в журнал время создания списка ulong start=GetTickCount64(); Print("Reading trade history and creating a list of historical positions"); ExtPositions.Refresh(); ulong msec=GetTickCount64()-start; PrintFormat("List of historical positions created in %I64u msec", msec); //ExtPositions.Print(); //--- Если это запуск после смены периода графика - отображаем текущую выбранную позицию if(UninitializeReason()==REASON_CHARTCHANGE) ExtPositions.ShowCurrent(true); //--- иначе - отображаем последнюю закрытую позицию else ExtPositions.ShowLast(true); //--- Успешно return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- Восстанавливаем начальное значение свойства автопрокрутки, торговой истории и удаляем комментарии на графике ChartSetInteger(ChartID(), CHART_AUTOSCROLL, ExtChartScroll); ChartSetInteger(ChartID(), CHART_SHOW_TRADE_HISTORY, ExtChartHistory); Comment(""); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //| TradeTransaction function | //+------------------------------------------------------------------+ void OnTradeTransaction(const MqlTradeTransaction& trans, const MqlTradeRequest& request, const MqlTradeResult& result) { //--- Если тип транзакции - добавление новой сделки if(trans.type==TRADE_TRANSACTION_DEAL_ADD) { //--- обновляем список позиций и их сделок ExtPositions.Refresh(); //--- Получаем тикет новой сделки ulong deal_ticket=trans.deal; //--- Если тикет не получен, или не удалось получить из свойств сделки способ изменения позиции - уходим long entry; if(deal_ticket==0 || !HistoryDealGetInteger(deal_ticket, DEAL_ENTRY, entry)) return; //--- Если это сделка выхода из позиции - отобразим на графике последнюю закрытую позицию if(entry==DEAL_ENTRY_OUT || entry==DEAL_ENTRY_OUT_BY) ExtPositions.ShowLast(true); } } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- Если идентификатор события - нажатие клавиши if(id==CHARTEVENT_KEYDOWN) { //--- Если удерживается клавиша Ctrl if(TerminalInfoInteger(TERMINAL_KEYSTATE_CONTROL)<0) { //--- Если прокрутка графика клавишами активна - выключим прокрутку графика клавишами if((bool)ChartGetInteger(0, CHART_KEYBOARD_CONTROL)) ChartSetInteger(0, CHART_KEYBOARD_CONTROL, false); //--- Если нажата клавиша "курсор влево" - отображаем предыдущую закрытую позицию if(lparam==KEY_LEFT) ExtPositions.ShowPrev(true); //--- Если нажата клавиша "курсор вправо" - отображаем следующую закрытую позицию if(lparam==KEY_RIGHT) ExtPositions.ShowNext(true); //--- Если нажата клавиша "курсор вверх" - отображаем первую закрытую позицию if(lparam==KEY_UP) ExtPositions.ShowFirst(true); //--- Если нажата клавиша "курсор вниз" - отображаем последнюю закрытую позицию if(lparam==KEY_DOWN) ExtPositions.ShowLast(true); } //--- Если клавиша Ctrl не нажата else { //--- Если прокрутка графика клавишами не активна - включим прокрутку графика клавишами if(!(bool)ChartGetInteger(0, CHART_KEYBOARD_CONTROL)) ChartSetInteger(0, CHART_KEYBOARD_CONTROL, true); } } //--- Если удерживается клавиша Shift - выводим в комментарии на график описание текущей позиции if(TerminalInfoInteger(TERMINAL_KEYSTATE_SHIFT)<0) Comment(ExtPositions.CurrentSelectedDescription()); //--- Если клавиша Shift не нажата - проверяем комментарий на графике и стираем, если он не пустой else { if(ChartGetString(ChartID(),CHART_COMMENT)!=NULL) Comment(""); } //--- Если изменился горизонтальный масштаб графика - отобразим текущую выбранную позицию static int scale=-1; if(id==CHARTEVENT_CHART_CHANGE) { int scale_curr=(int)ChartGetInteger(ChartID(), CHART_SCALE); if(scale!=scale_curr) { ExtPositions.ShowCurrent(true); scale=scale_curr; } } } //+------------------------------------------------------------------+