521 lines
26 KiB
MQL5
521 lines
26 KiB
MQL5
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| 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<total; i++)
|
||
|
|
{
|
||
|
|
//--- получаем цены закрытия в количестве data_count
|
||
|
|
double close[];
|
||
|
|
int copied=CopyClose(array[i], timeframe, 0, data_count, close);
|
||
|
|
if(copied!=data_count)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
//--- Записываем цены в строку матрицы так, чтобы 0 ячейка строки соответствовала 0 бару
|
||
|
|
for(int j=0; j<data_count; j++)
|
||
|
|
{
|
||
|
|
string symbol=GetSymbolByIndex(i,array);
|
||
|
|
int digits=(int)SymbolInfoInteger(symbol,SYMBOL_DIGITS);
|
||
|
|
data[i][data_count-1-j]=NormalizeDouble(close[j],digits);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//|Рассчитывает симметричную матрицу корреляций между всеми символами|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool SymbolsCorrelationMatrixSymmetric(const matrix &data, matrix &correlation)
|
||
|
|
{
|
||
|
|
int symb_total=(int)data.Rows(); // количество символов
|
||
|
|
|
||
|
|
//--- Устанавливаем размер матрицы корреляций
|
||
|
|
if(!correlation.Resize(symb_total,symb_total))
|
||
|
|
return false;
|
||
|
|
|
||
|
|
//--- Внешний цикл по всем символам (строкам)
|
||
|
|
for(int i=0;i<symb_total;i++)
|
||
|
|
{
|
||
|
|
//--- Получаем временной ряд цен для символа i
|
||
|
|
vector vi=data.Row(i);
|
||
|
|
//--- Внутренний цикл по всем символам (столбцам)
|
||
|
|
for(int j=0;j<symb_total;j++)
|
||
|
|
{
|
||
|
|
//--- Если символы в строке и столбце одинаковы, то это корреляция с собой
|
||
|
|
if(i==j)
|
||
|
|
correlation[i][j]=1.0;
|
||
|
|
|
||
|
|
//--- Символы в строке и столбце различаются
|
||
|
|
else
|
||
|
|
{
|
||
|
|
//--- Получаем временной ряд цен для символа j и считаем корреляцию между символами i и j
|
||
|
|
vector vj=data.Row(j);
|
||
|
|
correlation[i][j]=vi.CorrCoef(vj);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//--- Всё успешно
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Распечатывает в журнале симметричную матрицу корреляций |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void SymbolsCorrelationMatrixSymmetricPrint(const string &symb_array[],matrix &correlation)
|
||
|
|
{
|
||
|
|
//--- Создаём и распечатываем заголовок
|
||
|
|
Print("Correlation matrix:");
|
||
|
|
string header=" ";
|
||
|
|
for(int j=0;j<(int)symb_array.Size();j++)
|
||
|
|
header+=symb_array[j]+" ";
|
||
|
|
Print(header);
|
||
|
|
|
||
|
|
//--- Распечатываем данные корреляции символов
|
||
|
|
for(int i=0;i<(int)symb_array.Size();i++)
|
||
|
|
{
|
||
|
|
string row=symb_array[i]+" ";
|
||
|
|
for(int j=0;j<(int)symb_array.Size();j++)
|
||
|
|
row+=DoubleToString(correlation[i][j],2)+" ";
|
||
|
|
Print(row);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Получает и рассчитывает все необходимые данные |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool GetAndCalculateData(uint bars_total)
|
||
|
|
{
|
||
|
|
//--- Получаем значения для данных по символам
|
||
|
|
const int symb_total=(int)ExtSymbolsArray.Size(); // количество символов
|
||
|
|
|
||
|
|
//--- Изменяем размер матрицы: строки - символы, столбцы - бары
|
||
|
|
if(!ExtPricesData.Resize(symb_total,bars_total))
|
||
|
|
{
|
||
|
|
Print("Error. Failed to resize the symbol data matrix");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- Заполняем матрицу ценами закрытия символов и присваиваем значение флагу готовности данных
|
||
|
|
ExtDataReady=SymbolsDataMatrixFill(InpTimeframe,ExtSymbolsArray,ExtPricesData,bars_total);
|
||
|
|
if(!ExtDataReady)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
//--- Рассчитываем симметричную матрицу корреляций
|
||
|
|
if(!SymbolsCorrelationMatrixSymmetric(ExtPricesData,ExtCorrelationMatrix))
|
||
|
|
{
|
||
|
|
Print("Error calculating correlation matrix");
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Создаёт на панели таблицу символов с данными их корреляций |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool CreateTable(CTableControl *table_ctrl)
|
||
|
|
{
|
||
|
|
//--- создаём объект таблицы 0 (компонент Model + View) внутри элемента управления таблицами
|
||
|
|
//--- из вышесозданной матрицы ExtCorrelationMatrixSymmetric и
|
||
|
|
//--- string-массива символов ExtSymbolsArray как заголовков столбцов
|
||
|
|
ExtTableView=table_ctrl.TableCreate(ExtCorrelationMatrix,ExtSymbolsArray,ExtSymbolsArray);
|
||
|
|
if(ExtTableView==NULL)
|
||
|
|
return false;
|
||
|
|
|
||
|
|
//--- Установим для столбцов вывод текста по центру ячейки
|
||
|
|
int total=(int)table_ctrl.RowsTotal(0);
|
||
|
|
for(int i=0;i<total;i++)
|
||
|
|
{
|
||
|
|
table_ctrl.ColumnSetTextAnchor(0,i,ANCHOR_CENTER,true,false);
|
||
|
|
}
|
||
|
|
|
||
|
|
//--- Установим режим подсветки строк таблицы для отдельных ячеек
|
||
|
|
table_ctrl.SetRowsHighlightMode(0,ROWS_HIGHLIGHT_MODE_CELLS);
|
||
|
|
//--- и сделаем таблицу несортируемой
|
||
|
|
table_ctrl.SetSortable(0,false);
|
||
|
|
|
||
|
|
//--- Нарисуем и раскрасим таблицу в цвета корреляции символов
|
||
|
|
table_ctrl.Draw(false);
|
||
|
|
UpdateTableValuesAndColors(table_ctrl.GetTableView(0),ExtCorrelationMatrix);
|
||
|
|
|
||
|
|
//--- Получим модель таблицы с индексом 0 и распечатаем в журнале
|
||
|
|
CTable *table_model=table_ctrl.GetTableModel(0);
|
||
|
|
table_model.Print(7);
|
||
|
|
|
||
|
|
//--- Всё успешно
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Обновляет значения и цвета ячеек таблицы по матрице корреляций |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
void UpdateTableValuesAndColors(CTableView *table_view, matrix &corr_matrix)
|
||
|
|
{
|
||
|
|
//--- Проверим валидность указателя на таблицу
|
||
|
|
if(table_view==NULL)
|
||
|
|
return;
|
||
|
|
|
||
|
|
//--- Количество строк и столбцов таблицы
|
||
|
|
int total_row=table_view.RowsTotal();
|
||
|
|
int total_col=table_view.CellsInRow(0);
|
||
|
|
|
||
|
|
//--- В цикле по строкам таблицы
|
||
|
|
for(int r=0; r<total_row; r++)
|
||
|
|
{
|
||
|
|
//--- получаем очередной объект визуального представления строки
|
||
|
|
CTableRowView *row_obj=table_view.GetRowView(r);
|
||
|
|
if(row_obj==NULL)
|
||
|
|
continue;
|
||
|
|
//--- Получаем элемент управления цветом
|
||
|
|
CColorElement *ce=row_obj.GetBackColorControl();
|
||
|
|
if(ce==NULL)
|
||
|
|
continue;
|
||
|
|
|
||
|
|
//--- В цикле по количеству ячеек в строке
|
||
|
|
for(int c=0; c<total_col; c++)
|
||
|
|
{
|
||
|
|
//--- получаем очередной объект визуального представления ячейки
|
||
|
|
CTableCellView *cell=table_view.GetCellView(r,c);
|
||
|
|
if(cell==NULL)
|
||
|
|
continue;
|
||
|
|
|
||
|
|
//--- Берём значение корреляции из матрицы
|
||
|
|
double val=corr_matrix[r][c];
|
||
|
|
//--- Обновляем текст ячейки,
|
||
|
|
cell.SetText(DoubleToString(val,2));
|
||
|
|
//--- обновляем цвет ячейки
|
||
|
|
color new_color=ce.InterpolateColorByCoeff(clrRed,clrYellow,clrGreen,val);
|
||
|
|
cell.SetBackColor(new_color);
|
||
|
|
|
||
|
|
//--- Перерисовываем ячейку (график обновляем на последней ячейке таблицы)
|
||
|
|
bool flag=(r==total_row-1 && c==total_col-1 ? true : false);
|
||
|
|
cell.Draw(flag);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Возвращает флаг существования графика с указанным идентификатором|
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool IsExistChart(const long id)
|
||
|
|
{
|
||
|
|
//--- Переменные для идентификаторов графиков
|
||
|
|
long curr_chart=0, prev_chart=0;
|
||
|
|
int i=0;
|
||
|
|
|
||
|
|
//--- Проходим по всем графикам
|
||
|
|
while(!IsStopped() && i<CHARTS_MAX)
|
||
|
|
{
|
||
|
|
//--- На основании предыдущего получим новый график
|
||
|
|
curr_chart=ChartNext(prev_chart); // prev_chart==0 - получить первый график
|
||
|
|
//--- Если достигли конца списка графиков - выходим из цикла
|
||
|
|
if(curr_chart<0)
|
||
|
|
break;
|
||
|
|
//--- Если идентификатор графика совпадает с искомым - такой график есть
|
||
|
|
if(curr_chart==id)
|
||
|
|
return true;
|
||
|
|
//--- Запомним идентификатор текущего графика для следующего ChartNext()
|
||
|
|
prev_chart=curr_chart;
|
||
|
|
//--- увеличиваем счетчик
|
||
|
|
i++;
|
||
|
|
}
|
||
|
|
//--- Нет искомого графика
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Открывает графики символов |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
long OpenCharts(const string row_symb,const string col_symb)
|
||
|
|
{
|
||
|
|
//--- устанавливаем символ и таймфрейм для нового графика
|
||
|
|
string symbol=row_symb;
|
||
|
|
if(symbol==NULL || symbol=="")
|
||
|
|
symbol=Symbol();
|
||
|
|
|
||
|
|
//--- открываем новый график с заданными символом и периодом
|
||
|
|
long id=ChartOpen(symbol,PERIOD_CURRENT);
|
||
|
|
if(id==0)
|
||
|
|
{
|
||
|
|
Print("ChartOpen() failed. Error ", GetLastError());
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
//--- Открепляем график и делаем его пустым
|
||
|
|
ChartSetInteger(id,CHART_IS_DOCKED,false);
|
||
|
|
ChartSetInteger(id,CHART_SHOW,false);
|
||
|
|
|
||
|
|
//--- Получаем координаты сторон откреплённого графика
|
||
|
|
int top=(int)ChartGetInteger(id,CHART_FLOAT_TOP);
|
||
|
|
int bottom=(int)ChartGetInteger(id,CHART_FLOAT_BOTTOM);
|
||
|
|
int left=(int)ChartGetInteger(id,CHART_FLOAT_LEFT);
|
||
|
|
int right=(int)ChartGetInteger(id,CHART_FLOAT_RIGHT);
|
||
|
|
|
||
|
|
//--- Устанавливаем новые ширину и высоту графика
|
||
|
|
ChartSetInteger(id,CHART_FLOAT_RIGHT,left+CHART_FLOAT_WIDTH);
|
||
|
|
ChartSetInteger(id,CHART_FLOAT_BOTTOM,top+CHART_FLOAT_HEIGHT);
|
||
|
|
|
||
|
|
//--- Получаем размеры графика в пикселях
|
||
|
|
int cw=(int)ChartGetInteger(id,CHART_WIDTH_IN_PIXELS);
|
||
|
|
int ch=(int)ChartGetInteger(id,CHART_HEIGHT_IN_PIXELS);
|
||
|
|
|
||
|
|
//--- Задаём высоту для верхнего и нижнего объектов-графиков
|
||
|
|
int h0=(int)round(ch/2);
|
||
|
|
int h1=ch-h0;
|
||
|
|
|
||
|
|
//--- Создаём на откреплённом графике два объекта-графика с символами строки и столбца
|
||
|
|
if(!CreateChartObject(id,"ChartRowSymbol",row_symb,PERIOD_CURRENT,0,0,cw,h0))
|
||
|
|
return 0;
|
||
|
|
if(!CreateChartObject(id,"ChartColSymbol",col_symb,PERIOD_CURRENT,0,h0-1,cw,h1+1))
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
//--- Обновляем открытый график и возвращаем его идентификатор
|
||
|
|
ChartRedraw(id);
|
||
|
|
return id;
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
//| Создаёт объект-график указанного символа |
|
||
|
|
//+------------------------------------------------------------------+
|
||
|
|
bool CreateChartObject(const long chart_id,const string name,const string symbol,const ENUM_TIMEFRAMES timeframe,const int x,const int y,const int w,const int h)
|
||
|
|
{
|
||
|
|
//--- Создаём объект-график с указанными координатами и размерами
|
||
|
|
//--- и устанавливаем его свойства - символ, период, координаты и размеры
|
||
|
|
if(ObjectCreate(chart_id,name,OBJ_CHART,0,x,y,w,h))
|
||
|
|
{
|
||
|
|
ObjectSetString(chart_id,name,OBJPROP_SYMBOL,symbol);
|
||
|
|
ObjectSetInteger(chart_id,name,OBJPROP_PERIOD,timeframe);
|
||
|
|
ObjectSetInteger(chart_id,name,OBJPROP_XDISTANCE,x);
|
||
|
|
ObjectSetInteger(chart_id,name,OBJPROP_YDISTANCE,y);
|
||
|
|
ObjectSetInteger(chart_id,name,OBJPROP_XSIZE,w);
|
||
|
|
ObjectSetInteger(chart_id,name,OBJPROP_YSIZE,h);
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
//--- Ошибка создания объекта-графика
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
//+------------------------------------------------------------------+
|