Files
xMQL4/Docs/Samples/Simple.indicator.md
T
2024-01-25 04:03:36 +03:30

6.2 KiB

Indicator

usually indicators is visualized some additional data on chart, and drwn on candle charts by default. specially works on prices.

#property indicator_buffers numOfBuffers

for example:

#property indicator_buffers 2

here we define 2 buffer to system for processing in each candle ...

then we have to define arrays ...

double BufferFast[]; double BufferSlow[];

usually for each indicator buffers we can define a constant to hold it's index on chart queue.

#define FastIndicator 0
#define SlowIndicator 1

each buffer holds data to use in candle calculation time and then draw things on chart.

we have to define Indexes for Buffers to draw themon chart. this happens on OnInit() event handler method.

int OnInit() {
    //
    // Fast Indicator ...
    SetIndexStyle(FastIndicator, DRAW_LINE, STYLE_DOT, 1, clrFireBrick);
    SetIndexBuffer(FastIndicator, BufferFast);
    SetIndexLabel(FastIndicator, "Fast");
 
    //
    // Slow Indicator ...
    SetIndexStyle(SlowIndicator, DRAW_LINE, STYLE_DOT, 1, clrGreen);
    SetIndexBuffer(SlowIndicator, BufferSlow);
    SetIndexLabel(SlowIndicator, "Slow");

    //
    return INIT_SUCCEEDED;
}

after define styling of indicators parts, we have to fill buffers by required data's, in OnCalculate() event handler. since at initialization time, there is no data in Buffers to use them.

in OnCalculate event handler, also some usefull args and params to use them for calculation steps or implement our business logic.

if you need to know them completely, see proppered documentation file.

int OnCalculate(
    const int rates_total,      // size of input time series
    const int prev_calculated,  // bars handled in previous call
    const datetime& time[],     // Time
    const double& open[],       // Open
    const double& high[],       // High
    const double& low[],        // Low
    const double& close[],      // Close
    const long& tick_volume[],  // Tick Volume
    const long& volume[],       // Real Volume
    const int& spread[]         // Spread
) {
    //
    // Here we defined some variables to use them ...
    int limit;
    double  signalMa,
            fastMa,
            slowMa;
    
    //
    // in this example, SlowMAPeriod is an input for
    // using in Calculations ...
    // so as we don't reach to this input candle, we cant calculate
    // anything ...
    // for this reasin we check rates_total param, and if not reach to our
    // input variable, we return 0 means nothing passed ...
    if (rates_total <= SlowMAPeriod) {
        return 0;
    }

    //
    // found which candles calculated before ...
    limit = rates_total - prev_calculated;
    if (prev_calculated>0) {
        limit++;
    }

    //
    // Do Calculation ...
    // Symbol() => retrieve current chart window symbol ...
    // Period() => retrieve current period ...
    for (int i = limit - 1; i>0; i--) {
        // 
        signalMa = iMa(Symbol(), Period(), SignalMaPeriod, 0, MAMethod, PRICE_CLOSE, i);

        //
        fastMa = iMa(Symbol(), Period(), FastMaPeriod, 0, MAMethod, PRICE_CLOSE, i);

        //
        slowMa = iMa(Symbol(), Period(), SlowMaPeriod, 0, MAMethod, PRICE_CLOSE, i);

        //
        // Here we have to do some calculation, and check some conditions, then
        // fill up buffers based on conditions ...
        // Trending Up Condition ...
        if (signalMa > fastMa && fastMa < slowMa) {
            //
            BufferFast[i] = fastMa;
            BufferSlow[i] = slowMa;
        //
        // Trending Down Condition ...
        } else if (signalMa < fastMa && fastMa < slowMa>) {
            //
            BufferFast[i] = fastMa;
            BufferSlow[i] = slowMa;
        }
        //
        // NOTE: it could be possible to combine above two condition, but 
        // we separate them for learning purposed ...
    }

    //
    // this tells meta trader how many candles we used ...
    return rate_total;
} 

in above example we just show two line, and there is no histogram. in mt4 for drawing histogram we have to do some unusual works ...

we are going to complete the example to support histogram.

for showing histogram, we need two more buffers.

//
// Increase System Defined Buffers ...
#property indicator_buffers 4

//
// Next we have to define two more Buffer ...
double BufferUp[];
double BufferDown[];

//
// then we have to change definition of indexes of buffers for supporting histograms ...
// wen MT draws Histogram, it's used area between next indicator and selected one ...
#define UpIndicator 0
#define DownIndicator 2
#define FastIndicator 3
#define SlowIndicator 1

//
// Then we have to define Styling for histogram ...
int OnInit() {
    //
    // Fast Indicator ...
    SetIndexStyle(FastIndicator, DRAW_LINE, STYLE_DOT, 1, clrFireBrick);
    SetIndexBuffer(FastIndicator, BufferFast);
    SetIndexLabel(FastIndicator, "Fast");
 
    //
    // Slow Indicator ...
    SetIndexStyle(SlowIndicator, DRAW_LINE, STYLE_DOT, 1, clrGreen);
    SetIndexBuffer(SlowIndicator, BufferSlow);
    SetIndexLabel(SlowIndicator, "Slow");
 
    //
    // Up Indicator ...
    SetIndexStyle(UpIndicator, DRAW_HISTOGRAM, STYLE_DOT, 1, clrGreen);
    SetIndexBuffer(UpIndicator, BufferUp);
    SetIndexEmptyValue(UpIndicator, 0.0);
 
    //
    // Down Indicator ...
    SetIndexStyle(DownIndicator, DRAW_HISTOGRAM, STYLE_DOT, 1, clrFireBrick);
    SetIndexBuffer(DownIndicator, BufferDown);
    SetIndexEmptyValue(DownIndicator, 0.0);

    //
    return INIT_SUCCEEDED;
}

//
// then we have to change calculation for filling bufferup and bufferdown ...
//
// the reason which we separate this conditions, for drawing histograms ... 
// Trending Up Condition ...
if (signalMa > fastMa && fastMa < slowMa) {
    //
    BufferFast[i] = fastMa;
    BufferSlow[i] = slowMa;

    //
    // the histogram drawn between fast line and slow line ...
    // so up indicator draws between itself and slow ...
    BufferUp[i] = fastMa;
//
// Trending Down Condition ...
} else if (signalMa < fastMa && fastMa < slowMa>) {
    //
    BufferFast[i] = fastMa;
    BufferSlow[i] = slowMa;

    //
    // the histogram drawn between slow line and fast line ...
    // so up indicator draws between itself and fast  ...
    BufferDown[i] = slowMa;
}