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

PlotIndexSetInteger (0,PLOT_ARROW,233);

PlotIndexSetDouble (0,PLOT_EMPTY_VALUE,0);

PlotIndexSetInteger (0,PLOT_ARROW_SHIFT, -10);

Для второго графического построения определим тип стрелки – стрелка вниз, пустое значение и сдвиг:

PlotIndexSetInteger (1,PLOT_ARROW,234);

PlotIndexSetDouble (1,PLOT_EMPTY_VALUE,0);

PlotIndexSetInteger (1,PLOT_ARROW_SHIFT,10);

Свяжем массивы с буферами индикатора:

SetIndexBuffer (0,IKBuyBuffer, INDICATOR_DATA);

SetIndexBuffer (1,ColorIKBuyBuffer, INDICATOR_COLOR_INDEX);

SetIndexBuffer (2,IKSellBuffer, INDICATOR_DATA);

SetIndexBuffer (3,ColorIKSellBuffer, INDICATOR_COLOR_INDEX);

SetIndexBuffer (4,EMA34HBuffer, INDICATOR_CALCULATIONS);

SetIndexBuffer (5,EMA34LBuffer, INDICATOR_CALCULATIONS);

SetIndexBuffer (6,EMA125Buffer, INDICATOR_CALCULATIONS);

SetIndexBuffer (7,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);

В функции OnCalculate () произведем проверку размера доступной истории для расчета используемых индикаторов, определим количество копируемых значений используемых индикаторов и определим стартовую позицию расчета индикатора:

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;

}

Переменную bars_calculated определим как глобальную int bars_calculated=0; в свойствах индикатора.

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

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);

Здесь FillArrayFromMABuffer и FillArrayFromPSARBuffer – пользовательские функции, определенные вне функции OnCalculate ():

//+ – — – — – — – — – — – — – — – — – — – — – — – — – — – — – — – — – +

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);

}

Далее в функции OnCalculate () заполним буфера индикатора данными и цветом:

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

{

IKBuyBuffer [i-1] =0;

ColorIKBuyBuffer [i-1] =1;

IKSellBuffer [i-1] =0;

ColorIKSellBuffer [i-1] =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]) {

IKBuyBuffer [i-1] =high [i-1];

ColorIKBuyBuffer [i-1] =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]) {

IKSellBuffer [i-1] =low [i-1];

ColorIKSellBuffer [i-1] =0;

}

}

bars_calculated=calculated;

// – - return value of prev_calculated for next call

return (rates_total);

}

Здесь мы рассчитываем индикатор на предыдущем баре, так как на текущем баре цена close – это текущая цена тика.

Откомпилируем код и присоединим индикатор к графику:

Рис.39 Язык программирования MQL5: Продвинутое использование торговой платформы MetaTrader 5
Рис.40 Язык программирования MQL5: Продвинутое использование торговой платформы MetaTrader 5

Мы увидим, что, в общем и целом, индикатор дает верные сигналы на продажу и покупку, хотя в некоторых случаях он запаздывает и дает ложные сигналы:

Рис.41 Язык программирования MQL5: Продвинутое использование торговой платформы MetaTrader 5
Рис.42 Язык программирования MQL5: Продвинутое использование торговой платформы MetaTrader 5

Как мы видим, происходит это из-за трендовой линии EMA125.

Попробуем отвязать ее от текущего периода и попробуем определять тренд, скажем по дневному графику:

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

При этом запаздывание, конечно, сократится, но количество ложных сигналов увеличится:

Рис.43 Язык программирования MQL5: Продвинутое использование торговой платформы MetaTrader 5
Рис.44 Язык программирования MQL5: Продвинутое использование торговой платформы MetaTrader 5

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

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

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

#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;

В функции OnInit () соответственно оставим только привязку массивов к буферам промежуточных расчетов и получение хэндлов используемых индикаторов:

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);

}

В функции OnCalculate () определим создание объектов на графике символа:

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 (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);

}

Здесь функцией ObjectCreate создаются объекты стрелка, привязанные ко времени и максимальной или минимальной цене.

Функцией ObjectSetInteger со свойством OBJPROP_COLOR определяется цвет стрелки.

Функцией ObjectSetInteger со свойством OBJPROP_ARROWCODE определяется направление стрелки вверх или вниз.

Функцией ObjectSetInteger со свойством OBJPROP_WIDTH определяется размер объекта.

Функцией ObjectSetInteger со свойством OBJPROP_ANCHOR определяется привязка к цене сверху или снизу по центру.

Функцией ObjectSetInteger со свойством OBJPROP_HIDDEN – true определяется отсутствие созданных объектов в списке объектов графика символа.

Функцией ObjectSetString со свойством OBJPROP_TOOLTIP определяется содержание всплывающей подсказки при наведении указателя на объект.

Страницы: «« 12345678 »»

Читать бесплатно другие книги:

«Здравствуйте, мой дорогой друг! Это уже третье издание книги «7 профессий для быстрого заработка в ...
Центральная Азия в глазах большинства жителей развитых стран – это несколько Богом забытых бедных го...
Семнадцатый век представляется каким-то потерянным временем, когда страна топталась на месте, но в и...
Оказаться во власти злейшего врага – такое только на сцене бывает. Так я считала, пока меня не прико...
Каждый вложенный в рекламу рубль должен приносить доход – вот главное требование бизнеса к интернет-...
В книгу известного детского писателя входит повесть о детях, об их родителях, о школе. Ее главный ге...