# Custom Indicators 101: How to code a simple custom indicator for Metatrader

4.8
(16)

Today I am going to teach you how to code a simple indicator in MQL4 that plots a buy arrow when the high of the last bar is broken, and a sell arrow when the low of the last bar is broken. This indicator is the simplest of indicators that can be coded in Metatrader4.

## Creating a new file

Let’s begin using the MetaEditor Wizard to create a new  source code file with the basic structure already laid out for us. Using the wizard makes sure the structure of our indicator is correct.

1. Create a new Indicator
2. Select “Custom Indicator” from the wizard
3. Set “Indicators\Indicator101” as name
4. Select “OnCalculate(…,open, high, low, close)” and click [Next >]
5. Ignore the next screen and click on [Finish]

The Metaeditor is opened and we are ready to code. The complete source code of our project is below. Feel free to copy and paste the code into the Editor, replacing all the generated code. The basic structure is the same as the generated one.

//---- File Properties
#property description "Sample indicator that plots breakout arrows."
#property version     "1.0"
#property strict

//---- Indicator drawing and buffers
#property indicator_chart_window
#property indicator_buffers 2

//---- Colors and sizes for buffers
#property indicator_color1 clrDodgerBlue
#property indicator_color2 clrTomato
#property indicator_width1 2
#property indicator_width2 2

//---- Buffer Arrays
double ExtMapBuffer1[];
double ExtMapBuffer2[];

//+------------------------------------------
//| Custom indicator initialization function
//+------------------------------------------
int init()
{
// First buffer
SetIndexBuffer(0, ExtMapBuffer1);  // Assign buffer array
SetIndexStyle(0, DRAW_ARROW);      // Style to arrow
SetIndexArrow(0, 233);             // Arrow code

//Second buffer
SetIndexBuffer(1, ExtMapBuffer2);  // Assign buffer array
SetIndexStyle(1, DRAW_ARROW);      // Style to arrow
SetIndexArrow(1, 234);             // Arrow code

// Exit
return(0);
}

//+-------------------------------------
//| 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[],
{
// Start and limit
int start = 1;
int limit;

// Bars counted so far
int counted_bars = IndicatorCounted();

// No more bars?
if(counted_bars < 0)
return(-1);

// Do not check repeated bars
limit = Bars - 1 - counted_bars;

// Iterate bars from past to present
for(int i = limit; i >= start; i--)
{
// If not enough data...
if(i > Bars-2) continue;

if(Close[i] > High[i+1])
{
ExtMapBuffer1[i] = Low[i];
}

// Sell check signal
if(Close[i] < Low[i+1])
{
ExtMapBuffer2[i] = High[i];
}
}

// Exit
return(rates_total);
}

Now save the file and click on compile in MetaEditor. The compilation process will generate the indicator binary which we can load to the chart. Make sure the compilation raises no errors.

Now we are ready to load the indicator to the chart. The indicator will be listed in the Indicators menu in the Navigator. If the Navigator is hidden, go to View -> Navigator -> Indicators.

Load the Indicator101 Indicator to the chart, et voilà.

## Understanding the indicator

The anatomy of our custom indicator is the following:

• The initial properties describe author, website, indicator description and indicator version, which are displayed in the indicator loading window.
• The buffer properties describe buffer number, colors and sizes.
• The OnInit()  function is executed when the indicator loads. In this function, we define our buffer arrays and styles, which are later used to plot arrows on the chart.
• The OnCalculate() function is executed every tick. It iterates the bars in the chart and evaluates the entry strategy. If our conditions are met, it saves the signal on the buffer array, which causes the indicator to draw an arrow on the chart.
• Inside OnCalculate(), our code iterates bars from past to present and purposely ignores the unclosed bar to avoid repainting. The shift of the current bar is zero, and our loop ends at 1.
• A buffer is always linked to a previously defined array.
• The HLOC data is available in the OnCalculate() function as four arrays: High[…], Low[…], Open[…] and Close[…]. Other information is available to us such as Volume[…] and Time[…].

## Making changes

Once the indicator is working, we can edit the buy/sell conditions to meet other, more complex criteria. For example, we can filter out breakouts which are preceded by a previous breakout in the same direction changing the OnCalculate(…) function like follows.

//+-------------------------------------
//| 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[],
{
// Start and limit
int start = 1;
int limit;

// Bars counted so far
int counted_bars = IndicatorCounted();

// No more bars?
if(counted_bars < 0)
return(-1);

// Do not check repeated bars
limit = Bars - 1 - counted_bars;

// Iterate bars from past to present
for(int i = limit; i >= start; i--)
{
// If not enough data...
if(i > Bars-3) continue;

// Check buy signal and apply filter
if(Close[i] > High[i+1] && !(Close[i+1] > High[i+2]))
{
ExtMapBuffer1[i] = Low[i];
}

// Sell check signal and apply filter
if(Close[i] < Low[i+1] && !(Close[i+1] < Low[i+2]))
{
ExtMapBuffer2[i] = High[i];
}
}

// Exit
return(rates_total);
}

Once edited, save the file, compile it again and load the indicator to the chart.

As you can see the result is very different: consecutive breakouts are no longer displayed and the trading frequency has decreased. We could keep adding conditions using HLOC data to find a particular price pattern that we’d like to trade, or read from custom indicators to apply a filter to our trades. The possibilities are almost endless.

I hope this served as an useful introduction to coding your own custom indicators. In the next post, I’ll teach you how to implement filters using native indicators applied to any timeframe.

9,556 total views,  27 views today

Average rating 4.8 / 5. Vote count: 16

Thanks for rating!

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

### Arthur Lopez

Private investor and speculator, software engineer and founder of PZ Trading Solutions.

## 7 thoughts on “Custom Indicators 101: How to code a simple custom indicator for Metatrader”

1. Arun says:

This is great initiative sir. Waiting for more. Thank you.

2. Luke says:

OMG. This is very helpful! Thank you for this!

3. Anthony says:

WOW this is great Arthur. Thank you!

4. Glad to see you writing tutorials 🙂 Well done!

1. Thanks Rimantas. You are the boss at that 😉 I wanted to do a larger post but let’s start small.