Язык программирования MQL5: Продвинутое использование торговой платформы MetaTrader 5 - Тимур Сергеевич Машнин 9 стр.


ResourceReadImage("::Images\\image.bmp», ExtImg, width, height);

TextOut («Text», 10,10,TA_LEFT|TA_TOP, ExtImg,100,100,0xffffff, COLOR_FORMAT_XRGB_NOALPHA);

ResourceCreate (»:: IMG», ExtImg,100,100,0,0,0,COLOR_FORMAT_XRGB_NOALPHA);

ChartRedraw ();

//  - return value of prev_calculated for next call

return (rates_total);

}

//+                                  +

void OnDeinit (const int reason) {

ObjectsDeleteAll (0, -1, -1);

}

В качестве примера использования графических объектов, рассмотрим создание индикатора, который выводит в небольшое окно на графике символа тот же график, но с другим временным периодом.

Для этого используем графический объект OBJ_CHART.

В качестве входных параметров индикатора используем символ графика и его период:

#property indicator_chart_window


input string InpSymbol=«EURUSD»; // Символ

input ENUM_TIMEFRAMES InpPeriod=PERIOD_CURRENT; // Период

В функции OnInit () создадим графический объект График:

int OnInit ()

{

if (!ObjectCreate (0,«Chart», OBJ_CHART,0,0,0))

{

return (false);

}

По умолчанию точка привязки этого объекта  левый верхний угол графика.

Определим отступ точки привязки объекта, его размеры, символ и период графика, отображение шкалы времени, размер точки привязки, с помощью которой можно перемещать объект, отображение ценовой шкалы, режим перемещения мышкой, цвет рамки графика:

ObjectSetInteger (0,«Chart», OBJPROP_XDISTANCE,10);

ObjectSetInteger (0,«Chart», OBJPROP_YDISTANCE,20);

ObjectSetInteger (0,«Chart», OBJPROP_XSIZE,300);

ObjectSetInteger (0,«Chart», OBJPROP_YSIZE,200);

ObjectSetString (0,«Chart», OBJPROP_SYMBOL, InpSymbol);

ObjectSetInteger (0,«Chart», OBJPROP_PERIOD, InpPeriod);

ObjectSetInteger (0,«Chart», OBJPROP_DATE_SCALE, true);

ObjectSetInteger (0,«Chart», OBJPROP_WIDTH,1);

ObjectSetInteger (0,«Chart», OBJPROP_PRICE_SCALE, true);

ObjectSetInteger (0,«Chart», OBJPROP_SELECTABLE, true);

ObjectSetInteger (0,«Chart», OBJPROP_SELECTED, true);

ObjectSetInteger (0,«Chart», OBJPROP_COLOR, clrBlue);

С помощью свойства объектов OBJPROP_CHART_ID функции ObjectGetInteger получим идентификатор графика, используя который мы теперь можем применять функции работы с графиками (https://www.mql5.com/ru/docs/chart_operations) и свойства графиков (https://www.mql5.com/ru/docs/constants/chartconstants/enum_chart_property):

long chartId=ObjectGetInteger (0,«Chart», OBJPROP_CHART_ID);

Откроем наш график символа, к которому мы хотим присоединить индикатор, и нажав правой кнопкой мышки, выберем пункт в контекстном меню Шаблоны и Сохранить шаблон.

Теперь мы можем перенести на наш графический объект все настройки и индикаторы графика символа:

ChartApplyTemplate(chartId,"my.tpl»);

ChartRedraw (chartId);

//  

return (INIT_SUCCEEDED);

}

Присоединив индикатор к графику символа, мы можем нажать на нем правой кнопкой мышки и изменить его свойства, включая его период, размеры и др.

Функция PlaySound

Функция PlaySound воспроизводит звуковой файл. Например, это можно делать при появлении сигнала индикатора для напоминания:

bool PlaySound (

string filename // имя WAV-файла

);

В качестве примера добавим звуковой сигнал в наш индикатор Impulse keeper при появлении первого сигнала на покупку или продажу.

Скачаем какой-нибудь WAV-сигнал из Интернета и поместим его файл в папку Sounds терминала.

Добавим код в индикатор Impulse keeper:

#property indicator_chart_window

#property indicator_buffers 4


double EMA34HBuffer [];

double EMA34LBuffer [];

double EMA125Buffer [];

double PSARBuffer [];


int EMA34HHandle;

int EMA34LHandle;

int EMA125Handle;

int PSARHandle;


int bars_calculated=0;

int countBuy=0

int countSell=0;

//+                                  +

//| Custom indicator initialization function |

//+                                  +

int OnInit ()

{

//  - indicator buffers mapping

SetIndexBuffer (0,EMA34HBuffer, INDICATOR_CALCULATIONS);

КОНЕЦ ОЗНАКОМИТЕЛЬНОГО ОТРЫВКА

int OnInit ()

{

//  - indicator buffers mapping

SetIndexBuffer (0,EMA34HBuffer, INDICATOR_CALCULATIONS);

SetIndexBuffer (1,EMA34LBuffer, INDICATOR_CALCULATIONS);

SetIndexBuffer (2,EMA125Buffer, INDICATOR_CALCULATIONS);

SetIndexBuffer (3,PSARBuffer, INDICATOR_CALCULATIONS);


EMA34HHandle=iMA (NULL,0,34,0,MODE_EMA, PRICE_HIGH);

EMA34LHandle=iMA (NULL,0,34,0,MODE_EMA, PRICE_LOW);

EMA125Handle=iMA (NULL,0,125,0,MODE_EMA, PRICE_CLOSE);

PSARHandle=iSAR (NULL,0,0.02, 0.2);


//  

return (INIT_SUCCEEDED);

}

//+                                  +

//| Custom indicator iteration function |

//+                                  +

int OnCalculate (const int rates_total,

const int 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 int &spread [])

{

//  

int values_to_copy;

int start;


int calculated=BarsCalculated (EMA34HHandle);

if (calculated <=0)

{

return (0);

}


if (prev_calculated==0 || calculated!=bars_calculated)

{

start=1;

if (calculated> rates_total) values_to_copy=rates_total;

else values_to_copy=calculated;

}

else

{

start=rates_total-1;

values_to_copy=1;

}

if (!FillArrayFromMABuffer (EMA34HBuffer,0,EMA34HHandle, values_to_copy)) return (0); if (!FillArrayFromMABuffer (EMA34LBuffer,0,EMA34LHandle, values_to_copy)) return (0); if (!FillArrayFromMABuffer (EMA125Buffer,0,EMA125Handle, values_to_copy)) return (0);

if (!FillArrayFromPSARBuffer (PSARBuffer, PSARHandle, values_to_copy)) return (0);


for (int i=start; i <rates_total &&!IsStopped ();i++)

{


if (close [i-1]> open [i-1] &&close [i-1]> EMA34HBuffer [i-1] &&close [i-1]> EMA34LBuffer [i-1] &&low [i-1]> EMA125Buffer [i-1] &&low [i-1]> PSARBuffer [i-1] &&EMA125Buffer [i-1] <EMA34LBuffer [i-1] &&EMA125Buffer [i-1] <EMA34HBuffer [i-1]) {

if (!ObjectCreate (0,«Buy»+i, OBJ_ARROW,0,time [i-1],high [i-1]))

{

return (false);

}

ObjectSetInteger (0,«Buy»+i, OBJPROP_COLOR, clrGreen);

ObjectSetInteger (0,«Buy»+i, OBJPROP_ARROWCODE,233);

ObjectSetInteger (0,«Buy»+i, OBJPROP_WIDTH,2);

ObjectSetInteger (0,«Buy»+i, OBJPROP_ANCHOR, ANCHOR_UPPER);

ObjectSetInteger (0,«Buy»+i, OBJPROP_HIDDEN, true);

ObjectSetString (0,«Buy»+i, OBJPROP_TOOLTIP, close [i-1]);

}


if (start!=1) {

if (close [i-1]> open [i-1] &&close [i-1]> EMA34HBuffer [i-1] &&close [i-1]> EMA34LBuffer [i-1] &&low [i-1]> EMA125Buffer [i-1] &&low [i-1]> PSARBuffer [i-1] &&EMA125Buffer [i-1] <EMA34LBuffer [i-1] &&EMA125Buffer [i-1] <EMA34HBuffer [i-1]) {

countBuy++;

if (countBuy==1) PlaySound («chime. wav»)

} else {

countBuy=0;

}


if (close [i-1] <open [i-1] &&close [i-1] <EMA34HBuffer [i-1] &&close [i-1] <EMA34LBuffer [i-1] &&high [i-1] <EMA125Buffer [i-1] &&high [i-1] <PSARBuffer [i-1] &&EMA125Buffer [i-1]> EMA34LBuffer [i-1] &&EMA125Buffer [i-1]> EMA34HBuffer [i-1]) {

countSell++;

if (countSell==1) PlaySound («chime. wav»);

} else {

countSell=0;

}

}


if (close [i-1] <open [i-1] &&close [i-1] <EMA34HBuffer [i-1] &&close [i-1] <EMA34LBuffer [i-1] &&high [i-1] <EMA125Buffer [i-1] &&high [i-1] <PSARBuffer [i-1] &&EMA125Buffer [i-1]> EMA34LBuffer [i-1] &&EMA125Buffer [i-1]> EMA34HBuffer [i-1]) {

if (!ObjectCreate (0,«Sell»+i, OBJ_ARROW,0,time [i-1],low [i-1]))

{

return (false);

}

ObjectSetInteger (0,«Sell»+i, OBJPROP_COLOR, clrRed);

ObjectSetInteger (0,«Sell»+i, OBJPROP_ARROWCODE,234);

ObjectSetInteger (0,«Sell»+i, OBJPROP_WIDTH,2);

ObjectSetInteger (0,«Sell»+i, OBJPROP_ANCHOR, ANCHOR_LOWER);

ObjectSetInteger (0,«Sell»+i, OBJPROP_HIDDEN, true);

ObjectSetString (0,«Sell»+i, OBJPROP_TOOLTIP, close [i-1]);

}

}


bars_calculated=calculated;

//  - return value of prev_calculated for next call

return (rates_total);

}

//+                                  +

bool FillArrayFromPSARBuffer (double &sar_buffer [], // индикаторный буфер значений Parabolic SAR

int ind_handle, // хэндл индикатора iSAR

int amount // количество копируемых значений

)

{

ResetLastError ();

if (CopyBuffer (ind_handle,0,0,amount, sar_buffer) <0)

{

return (false);

}

return (true);

}

//+                                  +

bool FillArrayFromMABuffer (double &values [], // индикаторный буфер значений Moving Average

int shift, // смещение

int ind_handle, // хэндл индикатора iMA

int amount // количество копируемых значений

)

{

ResetLastError ();

if (CopyBuffer (ind_handle,0, -shift, amount, values) <0)

{

return (false);

}

return (true);

}


void OnDeinit (const int reason) {

ObjectsDeleteAll (0, -1, -1);

}

Здесь добавлены счетчики сигналов на продажу и покупку countBuy, countSell, для того, чтобы сигнал звучал только при появлении первого сигнала.

Функция OnChartEvent

Функция OnChartEvent является функцией обратного вызова, которая вызывается при взаимодействии пользователя с графиком символа и событиях, связанных с графическими объектами графика символа.

void OnChartEvent (const int id, // идентификатор события

const long& lparam, // параметр события типа long

const double& dparam, // параметр события типа double

const string& sparam // параметр события типа string

);

В качестве примера использования функции OnChartEvent рассмотрим наш индикатор Impulse keeper и добавим в него функциональность, позволяющую посмотреть значения используемых индикаторов при клике на сигнале покупки или продажи индикатора.

Для этого добавим в код индикатора функцию OnChartEvent, обрабатывающую событие щелчка мыши на графическом объекте индикатора:

КОНЕЦ ОЗНАКОМИТЕЛЬНОГО ОТРЫВКА

Для этого добавим в код индикатора функцию OnChartEvent, обрабатывающую событие щелчка мыши на графическом объекте индикатора:

#property indicator_chart_window

#property indicator_buffers 4

double EMA34HBuffer [];

double EMA34LBuffer [];

double EMA125Buffer [];

double PSARBuffer [];

int EMA34HHandle;

int EMA34LHandle;

int EMA125Handle;

int PSARHandle;


int bars_calculated=0;

//+                                  +

//| Custom indicator initialization function |

//+                                  +

int OnInit ()

{

//  - indicator buffers mapping

SetIndexBuffer (0,EMA34HBuffer, INDICATOR_CALCULATIONS);

SetIndexBuffer (1,EMA34LBuffer, INDICATOR_CALCULATIONS);

SetIndexBuffer (2,EMA125Buffer, INDICATOR_CALCULATIONS);

Назад