//+------------------------------------------------------------------+ //| iCorrelationTable.mq5 | //| Copyright 2023, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2023, MetaQuotes Ltd." #property link "https://www.mql5.com" #property version "1.00" #property indicator_separate_window #property indicator_buffers 0 #property indicator_plots 0 #define CHART_FLOAT_WIDTH 750 // Ширина открываемого графика символов #define CHART_FLOAT_HEIGHT 500 // Высота открываемого графика символов //+------------------------------------------------------------------+ //| Включаемые библиотеки | //+------------------------------------------------------------------+ #include "Controls\Controls.mqh" // Библиотека элементов управления //--- input parameters input(name="Bars Total (at least 10)") uint InpBarsTotal = 1000; // Количество баров данных для расчёта корреляции (не менее 10) input(name="Timeframe") ENUM_TIMEFRAMES InpTimeframe = PERIOD_CURRENT; // Таймфрейм данных для расчёта корреляции input(name="Symbols for Correlation") string InpSymbols = "EURUSD,GBPUSD,USDJPY,USDCHF,AUDUSD,NZDUSD,USDCAD"; // Символы для расчёта корреляции //--- global variables string ExtSymbolsArray[]; // Массив символов для расчёта корреляции matrix ExtPricesData; // Матрица данных символов (цены Close) uint ExtBarsTotal; // Количество баров данных для расчёта корреляции matrix ExtCorrelationMatrix; // Матрица рассчитанных парных корреляций между всеми символами bool ExtDataReady; // Флаг готовности данных по всем символам long ExtSymbolsChart; // Идентификатор нового графика для символов корреляции CTableControl *ExtTableCtrl; // Указатель на объект CTableControl CTableView *ExtTableView; // Указатель на объект визуального представления таблицы //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping //--- Идентификатор открываемого графика ExtSymbolsChart=0; //--- Ищем подокно графика int wnd=ChartWindowFind(); //--- Заполняем массив символов из указанных во входном параметре InpSymbols string sep=","; // разделитель в виде символа ushort u_sep; // код символа разделителя //--- получим код разделителя u_sep=StringGetCharacter(sep,0); //--- получим из строки InpSymbols подстроки по разделителю u_sep и запишем их в массив ExtSymbolsArray StringSplit(InpSymbols,u_sep,ExtSymbolsArray); //--- Распечатаем в журнале набор символов для расчёта корреляции Print("\nSymbols Array:"); ArrayPrint(ExtSymbolsArray); //--- Включаем все символы в обзор рынка SymbolsSelect(ExtSymbolsArray); //--- Получаем данные символов (не менее 10 баров) для расчёта корреляции ExtBarsTotal=(InpBarsTotal<10 ? 10 : InpBarsTotal); ExtDataReady=GetAndCalculateData(ExtBarsTotal); //--- Создаём графический элемент управления таблицами int w=500; int h=138; ExtTableCtrl=new CTableControl("TableControl0",0,wnd,8,8,w-0,h-0); if(ExtTableCtrl==NULL) { Print("Error. Failed to create TableControl object"); return INIT_FAILED; } //--- На графике обязательно должен быть один главный элемент ExtTableCtrl.SetAsMain(); //--- Можно установить параметры созданного элемента управления таблицами ExtTableCtrl.SetID(0); // Идентификатор ExtTableCtrl.SetName("Table Control 0"); // Наименование //--- Если данные символов и их корреляции успешно получены, //--- создаём объект таблицы 0 (компонент Model + View) внутри элемента управления таблицами //--- из вышесозданной матрицы ExtCorrelationMatrixSymmetric и //--- string-массива символов ExtSymbolsArray как заголовков столбцов if(ExtDataReady && !CreateTable(ExtTableCtrl)) return INIT_FAILED; //--- Всё успешно return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int32_t reason) { //--- Удаляем элемент управления таблицами и уничтожаем менеджер общих ресурсов библиотеки delete ExtTableCtrl; CCommonManager::DestroyInstance(); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int32_t rates_total, const int32_t prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int32_t &spread[]) { //--- Получаем данные пока не будут готовы ExtDataReady=GetAndCalculateData(ExtBarsTotal); if(!ExtDataReady) { Print("The symbol data and their correlations have not yet been obtained. Waiting for the next tick..."); return 0; } //--- Если таблица ещё не создана //--- создаём объект таблицы 0 (компонент Model + View) внутри элемента управления таблицами //--- из вышесозданной матрицы ExtCorrelationMatrixSymmetric и //--- string-массива символов ExtSymbolsArray как заголовков столбцов if(ExtTableView==NULL && !CreateTable(ExtTableCtrl)) return 0; //--- Обновляем данные в таблице с установкой цветов корреляции UpdateTableValuesAndColors(ExtTableCtrl.GetTableView(0),ExtCorrelationMatrix); //--- return value of prev_calculated for next call return(rates_total); } //+------------------------------------------------------------------+ //| Timer function | //+------------------------------------------------------------------+ void OnTimer() { //--- Раз в полторы минуты получаем данные по символам из массива static int count=0; count++; if(count>=3000) { double array[]; for(int i=0;i<(int)ExtSymbolsArray.Size();i++) CopyClose(ExtSymbolsArray[i],InpTimeframe,0,ExtBarsTotal,array); count=0; } //--- Вызываем обработчик OnTimer элемента управления таблицами ExtTableCtrl.OnTimer(); } //+------------------------------------------------------------------+ //| ChartEvent function | //+------------------------------------------------------------------+ void OnChartEvent(const int32_t id, const long &lparam, const double &dparam, const string &sparam) { //--- Вызываем обработчик OnChartEvent элемента управления таблицами ExtTableCtrl.OnChartEvent(id,lparam,dparam,sparam); if(id>=CHARTEVENT_CUSTOM) { //--- Преобразуем идентификатор полученного пользовательского события к значениям стандартных событий ENUM_CHART_EVENT chart_event=ENUM_CHART_EVENT(id-CHARTEVENT_CUSTOM); //--- Если событие щелчка по графическому объекту if(chart_event==CHARTEVENT_OBJECT_CLICK) { //--- Если в имени события (значение sparam) присутствует наименование строки таблицы (начинается с "TableCellView") if(StringFind(sparam,"TableCellView")==0) { //--- Получаем номер строки и столбца из параметров сорбытия int row=(int)lparam; int col=(int)dparam; string sep=";"; // разделитель в виде символа ushort u_sep; // код символа разделителя string result[]; // массив для получения строк //--- Получим код разделителя и разделим sparam на подстроки u_sep=StringGetCharacter(sep,0); int n=StringSplit(sparam,u_sep,result); //--- Должно быть три подстроки if(n==3) { //--- Получаем символ строки и символ столбца string row_symb=result[1]; string col_symb=result[2]; //--- Если график ещё не открыт - открываем его if(ExtSymbolsChart==0 || !IsExistChart(ExtSymbolsChart)) ExtSymbolsChart=OpenCharts(row_symb,col_symb); //--- Если график уже открыт if(ExtSymbolsChart!=0) { //--- Устанавливаем символы для двух объектов-графиков и перерисовываем график ObjectSetString(ExtSymbolsChart,"ChartRowSymbol",OBJPROP_SYMBOL,row_symb); ObjectSetString(ExtSymbolsChart,"ChartColSymbol",OBJPROP_SYMBOL,col_symb); ChartRedraw(ExtSymbolsChart); } } } } } } //+------------------------------------------------------------------+ //| Включает символы из массива в обзор рынка | //+------------------------------------------------------------------+ bool SymbolsSelect(string &array[]) { bool res=true; for(int i=0;i<(int)array.Size();i++) res &=SymbolSelect(array[i],true); return res; } //+------------------------------------------------------------------+ //| Возвращает символ по индексу массива | //+------------------------------------------------------------------+ string GetSymbolByIndex(const int index,string &array[]) { int total=(int)array.Size(); if(index<0 || index>total-1) return StringFormat("%s: Error. Invalid index (%d)",__FUNCTION__,index); return array[index]; } //+------------------------------------------------------------------+ //| Заполняет матрицу данных символов | //+------------------------------------------------------------------+ bool SymbolsDataMatrixFill(const ENUM_TIMEFRAMES timeframe,string &array[],matrix &data,const int data_count) { //--- В цикле по количеству символов в массиве array int total=(int)array.Size(); for(int i=0; i