2026-03-23 12:55:37 +07:00 | | | //+------------------------------------------------------------------+
|
2026-03-23 12:49:42 +07:00 | | | //| Article-15026-MQL5-Trade-History-Visualizer.mq5 |
|
| | | //| Copyright 2026, MetaQuotes Ltd. |
|
| | | //| https://www.mql5.com |
|
| | | //+------------------------------------------------------------------+
|
2026-03-23 12:55:37 +07:00 | | | #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; // Флаг отображения торговой истории
|
| | |
|
2026-03-23 12:49:42 +07:00 | | | //+------------------------------------------------------------------+
|
| | | //| Expert initialization function |
|
| | | //+------------------------------------------------------------------+
|
| | | int OnInit()
|
| | | {
|
2026-03-23 12:55:37 +07:00 | | | //--- Запоминаем флаг автопрокрутки графика и отключаем автопрокрутку
|
| | | ExtChartScroll=ChartGetInteger(ChartID(), CHART_AUTOSCROLL);
|
| | | ChartSetInteger(ChartID(), CHART_AUTOSCROLL, false);
|
2026-03-23 12:49:42 +07:00 | | |
|
2026-03-23 12:55:37 +07:00 | | | //--- Запоминаем флаг отображения торговой истории и отключаем показ истории
|
| | | 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);
|
| | |
|
| | | //--- Успешно
|
2026-03-23 12:49:42 +07:00 | | | return(INIT_SUCCEEDED);
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| Expert deinitialization function |
|
| | | //+------------------------------------------------------------------+
|
| | | void OnDeinit(const int reason)
|
| | | {
|
2026-03-23 12:55:37 +07:00 | | | //--- Восстанавливаем начальное значение свойства автопрокрутки, торговой истории и удаляем комментарии на графике
|
| | | ChartSetInteger(ChartID(), CHART_AUTOSCROLL, ExtChartScroll);
|
| | | ChartSetInteger(ChartID(), CHART_SHOW_TRADE_HISTORY, ExtChartHistory);
|
| | | Comment("");
|
2026-03-23 12:49:42 +07:00 | | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| Expert tick function |
|
| | | //+------------------------------------------------------------------+
|
| | | void OnTick()
|
| | | {
|
| | | //---
|
| | |
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| TradeTransaction function |
|
| | | //+------------------------------------------------------------------+
|
| | | void OnTradeTransaction(const MqlTradeTransaction& trans,
|
| | | const MqlTradeRequest& request,
|
| | | const MqlTradeResult& result)
|
| | | {
|
2026-03-23 12:55:37 +07:00 | | | //--- Если тип транзакции - добавление новой сделки
|
| | | 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);
|
| | | }
|
2026-03-23 12:49:42 +07:00 | | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| ChartEvent function |
|
| | | //+------------------------------------------------------------------+
|
2026-03-23 12:55:37 +07:00 | | | void OnChartEvent(const int id,
|
2026-03-23 12:49:42 +07:00 | | | const long &lparam,
|
| | | const double &dparam,
|
| | | const string &sparam)
|
| | | {
|
2026-03-23 12:55:37 +07:00 | | | //--- Если идентификатор события - нажатие клавиши
|
| | | 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;
|
| | | }
|
| | | }
|
2026-03-23 12:49:42 +07:00 | | | }
|
| | | //+------------------------------------------------------------------+
|
2026-03-23 12:55:37 +07:00 | | |
|