Article-13179-MQL5-InfoPane.../Article-13179-MQL5-InfoPanel-Ind-EAs.mq5

254 lines
14 KiB
MQL5
Raw Permalink Normal View History

2026-03-19 00:45:49 +07:00
//+------------------------------------------------------------------+
2026-03-19 00:39:42 +07:00
//| Article-13179-MQL5-InfoPanel-Ind-EAs.mq5 |
//| Copyright 2026, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
2026-03-19 00:45:49 +07:00
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
//--- plot MA
#property indicator_label1 "MA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrRed
#property indicator_style1 STYLE_SOLID
#property indicator_width1 1
//--- includes
#include "Dashboard.mqh"
//--- input variables
input int InpPeriodMA = 10; /* MA Period */ // Период расчёта скользящей средней
input ENUM_MA_METHOD InpMethodMA = MODE_SMA; /* MA Method */ // Метод расчёта скользящей средней
input ENUM_APPLIED_PRICE InpPriceMA = PRICE_CLOSE; /* MA Price */ // Цена расчёта скользящей средней
input int InpPanelX = 20; /* Dashboard X */ // Координата X панели
input int InpPanelY = 20; /* Dashboard Y */ // Координата Y панели
input int InpUniqID = 0; /* Unique ID */ // Уникальный идентификатор для объекта-панели
//--- indicator buffers
double BufferMA[];
//--- global variables
CDashboard *dashboard=NULL;
int handle_ma; // Хэндл индикатора Moving Average
int period_ma; // Период расчёта Moving Average
int mouse_bar_index; // Индекс бара, с которого берутся данные
string plot_label; // Имя индикаторной графической серии для отображения в окне DataWindow
2026-03-19 00:39:42 +07:00
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
2026-03-19 00:45:49 +07:00
SetIndexBuffer(0,BufferMA,INDICATOR_DATA);
//--- Создаём хэндл индикатора
period_ma=(InpPeriodMA<1 ? 1 : InpPeriodMA);
ResetLastError();
handle_ma=iMA(Symbol(),PERIOD_CURRENT,period_ma,0,InpMethodMA,InpPriceMA);
if(handle_ma==INVALID_HANDLE)
{
PrintFormat("%s Failed to create MA indicator handle. Error %lu",__FUNCTION__,GetLastError());
return INIT_FAILED;
}
//--- Устанавливаем параметры индикатора
IndicatorSetInteger(INDICATOR_DIGITS,Digits());
IndicatorSetString(INDICATOR_SHORTNAME,"Test Dashboard");
2026-03-19 00:39:42 +07:00
2026-03-19 00:45:49 +07:00
//--- Устанавливаем параметры рисуемого буфера
plot_label="MA("+(string)period_ma+","+StringSubstr(EnumToString(Period()),7)+")";
PlotIndexSetString(0,PLOT_LABEL,plot_label);
ArraySetAsSeries(BufferMA,true);
//--- Создаём объект панели
dashboard=new CDashboard(InpUniqID,InpPanelX,InpPanelY,200,250);
if(dashboard==NULL)
{
Print("Error. Failed to create dashboard object");
return INIT_FAILED;
}
//--- Отображаем панель с текстом в заголовке "Символ, Описание таймфрейма"
dashboard.View(Symbol()+", "+StringSubstr(EnumToString(Period()),7));
//--- Рисуем табличку на фоне панели
dashboard.DrawGridAutoFill(2,12,2);
//dashboard.DrawGrid(2,1,12,2,19,97);
//--- Выводим в журнал табличные данные
dashboard.GridPrint(2);
//--- Инициализируем переменную с индексом бара указателя мышки
mouse_bar_index=0;
//--- Успешная инициализация
2026-03-19 00:39:42 +07:00
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
2026-03-19 00:45:49 +07:00
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- Если объект панели существует - удаляем
if(dashboard!=NULL)
delete dashboard;
//--- Освобождаем хэндл индикатора МА
ResetLastError();
if(!IndicatorRelease(handle_ma))
PrintFormat("%s: IndicatorRelease failed. Error %ld",__FUNCTION__,GetLastError());
//--- Стираем все комментарии
Comment("");
}
//+------------------------------------------------------------------+
2026-03-19 00:39:42 +07:00
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
2026-03-19 00:45:49 +07:00
int OnCalculate(const int rates_total,
const int prev_calculated,
2026-03-19 00:39:42 +07:00
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
2026-03-19 00:45:49 +07:00
const int &spread[])
2026-03-19 00:39:42 +07:00
{
2026-03-19 00:45:49 +07:00
//--- Устанавливаем массивам индексацию как в таймсерии
ArraySetAsSeries(time,true);
ArraySetAsSeries(open,true);
ArraySetAsSeries(high,true);
ArraySetAsSeries(low,true);
ArraySetAsSeries(close,true);
ArraySetAsSeries(tick_volume,true);
ArraySetAsSeries(volume,true);
ArraySetAsSeries(spread,true);
//--- Проверка на минимальное количество баров для расчёта
if(rates_total<period_ma) return 0;
//--- Проверка и расчёт количества просчитываемых баров
int limit=rates_total-prev_calculated;
//--- Если limit равен 0, то просчитывается только текущий бар
//--- Если limit равен 1 (открытие нового бара), то просчитываются два бара - текущий вновь открытый и предыдущий
//--- Если limit более 1, то это либо первый запуск индикатора, либо какие-то изменения в истории - индикатор полностью пересчитывается
if(limit>1)
{
limit=rates_total-period_ma-1;
ArrayInitialize(BufferMA,EMPTY_VALUE);
}
//--- Расчёт количества копируемых данных из хэндла индикатора в рисуемый буфер
int count=(limit>1 ? rates_total : 1),copied=0;
//--- Подготовка данных (получение данных в буфер скользящей средней по хэндлу)
copied=CopyBuffer(handle_ma,0,0,count,BufferMA);
if(copied!=count) return 0;
//--- Цикл расчёта индикатора по данным скользящей средней
for(int i=limit; i>=0 && !IsStopped(); i--)
{
// Здесь рассчитываем некий индикатор по данным стандартного Moving Average
}
//--- Получаем данные цен и таймсерии и выводим на панель
//--- При первом запуске выводим на панель данные текущего бара
static bool first=true;
if(first)
{
DrawData(0,TimeCurrent());
first=false;
}
//--- Объявляем структуру цен и получаем текущие цены
MqlTick tick={0};
if(!SymbolInfoTick(Symbol(),tick))
return 0;
//--- Если курсор находится на текущем баре - выводим на панель все данные текущего бара
if(mouse_bar_index==0)
DrawData(0,time[0]);
//--- Иначе - выводим на панель только цены Bid и Ask (обновляем цены на панели на каждом тике)
else
{
dashboard.DrawText("Bid",dashboard.CellX(0,0)+2,dashboard.CellY(0,0)+2); dashboard.DrawText(DoubleToString(tick.bid,Digits()),dashboard.CellX(0,1)+2,dashboard.CellY(0,1)+2,90);
dashboard.DrawText("Ask",dashboard.CellX(1,0)+2,dashboard.CellY(1,0)+2); dashboard.DrawText(DoubleToString(tick.ask,Digits()),dashboard.CellX(1,1)+2,dashboard.CellY(1,1)+2,90);
}
2026-03-19 00:39:42 +07:00
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Timer function |
//+------------------------------------------------------------------+
void OnTimer()
{
//---
}
//+------------------------------------------------------------------+
//| ChartEvent function |
//+------------------------------------------------------------------+
2026-03-19 00:45:49 +07:00
void OnChartEvent(const int id,
2026-03-19 00:39:42 +07:00
const long &lparam,
const double &dparam,
const string &sparam)
{
2026-03-19 00:45:49 +07:00
//--- Вызываем обработчик событий панели
dashboard.OnChartEvent(id,lparam,dparam,sparam);
//--- Если курсор перемещается или щелчок по графику
if(id==CHARTEVENT_MOUSE_MOVE || id==CHARTEVENT_CLICK)
{
//--- Объявляем переменные для записи в них координат времени и цены
datetime time=0;
double price=0;
int wnd=0;
//--- Если координаты курсора преобразованы в дату и время
if(ChartXYToTimePrice(ChartID(),(int)lparam,(int)dparam,wnd,time,price))
{
//--- записываем индекс бара, где расположен курсор в глобальную переменную
mouse_bar_index=iBarShift(Symbol(),PERIOD_CURRENT,time);
//--- Выводим данные бара под курсором на панель
DrawData(mouse_bar_index,time);
}
}
//--- Если получили пользовательское событие - выводим об этом сообщение в журнал
if(id>CHARTEVENT_CUSTOM)
{
//--- Здесь может быть обработка щелчка по кнопке закрытия на панели
PrintFormat("%s: Event id=%ld, object id (lparam): %lu, event message (sparam): %s",__FUNCTION__,id,lparam,sparam);
}
}
//+------------------------------------------------------------------+
//| Выводит данные с указанного индекса таймсерии на панель |
//+------------------------------------------------------------------+
void DrawData(const int index,const datetime time)
{
//--- Объявляем переменные для получения в них данных
MqlTick tick={0};
MqlRates rates[1];
//--- Если текущие цены получить не удалось - уходим
if(!SymbolInfoTick(Symbol(),tick))
return;
//--- Если данные бара по указанному индексу получить не удалось - уходим
if(CopyRates(Symbol(),PERIOD_CURRENT,index,1,rates)!=1)
return;
//--- Выводим на панель текущие цены и данные указанного бара
dashboard.DrawText("Bid", dashboard.CellX(0,0)+2, dashboard.CellY(0,0)+2); dashboard.DrawText(DoubleToString(tick.bid,Digits()), dashboard.CellX(0,1)+2, dashboard.CellY(0,1)+2,90);
dashboard.DrawText("Ask", dashboard.CellX(1,0)+2, dashboard.CellY(1,0)+2); dashboard.DrawText(DoubleToString(tick.ask,Digits()), dashboard.CellX(1,1)+2, dashboard.CellY(1,1)+2,90);
dashboard.DrawText("Date", dashboard.CellX(2,0)+2, dashboard.CellY(2,0)+2); dashboard.DrawText(TimeToString(rates[0].time,TIME_DATE), dashboard.CellX(2,1)+2, dashboard.CellY(2,1)+2,90);
dashboard.DrawText("Time", dashboard.CellX(3,0)+2, dashboard.CellY(3,0)+2); dashboard.DrawText(TimeToString(rates[0].time,TIME_MINUTES),dashboard.CellX(3,1)+2, dashboard.CellY(3,1)+2,90);
dashboard.DrawText("Open", dashboard.CellX(4,0)+2, dashboard.CellY(4,0)+2); dashboard.DrawText(DoubleToString(rates[0].open,Digits()), dashboard.CellX(4,1)+2, dashboard.CellY(4,1)+2,90);
dashboard.DrawText("High", dashboard.CellX(5,0)+2, dashboard.CellY(5,0)+2); dashboard.DrawText(DoubleToString(rates[0].high,Digits()), dashboard.CellX(5,1)+2, dashboard.CellY(5,1)+2,90);
dashboard.DrawText("Low", dashboard.CellX(6,0)+2, dashboard.CellY(6,0)+2); dashboard.DrawText(DoubleToString(rates[0].low,Digits()), dashboard.CellX(6,1)+2, dashboard.CellY(6,1)+2,90);
dashboard.DrawText("Close", dashboard.CellX(7,0)+2, dashboard.CellY(7,0)+2); dashboard.DrawText(DoubleToString(rates[0].close,Digits()), dashboard.CellX(7,1)+2, dashboard.CellY(7,1)+2,90);
2026-03-19 00:39:42 +07:00
2026-03-19 00:45:49 +07:00
dashboard.DrawText("Volume", dashboard.CellX(8,0)+2, dashboard.CellY(8,0)+2); dashboard.DrawText((string)rates[0].real_volume, dashboard.CellX(8,1)+2, dashboard.CellY(8,1)+2,90);
dashboard.DrawText("Tick Volume",dashboard.CellX(9,0)+2, dashboard.CellY(9,0)+2); dashboard.DrawText((string)rates[0].tick_volume, dashboard.CellX(9,1)+2, dashboard.CellY(9,1)+2,90);
dashboard.DrawText("Spread", dashboard.CellX(10,0)+2, dashboard.CellY(10,0)+2); dashboard.DrawText((string)rates[0].spread, dashboard.CellX(10,1)+2, dashboard.CellY(10,1)+2,90);
dashboard.DrawText(plot_label, dashboard.CellX(11,0)+2, dashboard.CellY(11,0)+2); dashboard.DrawText(DoubleToString(BufferMA[index],Digits()),dashboard.CellX(11,1)+2, dashboard.CellY(11,1)+2,90);
//--- Перерисовываем график для немедленного отображения всех изменений на панели
ChartRedraw(ChartID());
2026-03-19 00:39:42 +07:00
}
//+------------------------------------------------------------------+