Страница 14 из 15
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, обрабатывающую событие щелчка мыши на графическом объекте индикатора:
#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);
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=rates_total-1;
if (calculated> rates_total) values_to_copy=rates_total;
else values_to_copy=calculated;
}
else
{
start=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);