Skip to content
NEXORA Money & AI

How to Build Your First MT5 Indicator: A Beginner’s Guide to MQL5

September 30, 2026 · OYIN ADESOLA · 5 min read · Updated October 12, 2026
Cover graphic for the article: How to Build Your First MT5 Indicator: A Beginner's Guide to MQL5

Last checked: 12 October 2026. This guide draws on the MetaQuotes MQL5 reference for SetIndexBuffer and the custom indicator functions. Code is written from the documentation; compile it in MetaEditor and test it on a demo account before relying on it.

Your first MetaTrader 5 indicator does not need to be clever. It needs to compile, draw something on the chart and recalculate correctly when a new bar arrives. This guide builds a simple moving average line from scratch in MQL5, and uses it to explain the three ideas that trip up almost every beginner: indicator buffers, the OnCalculate function and the prev_calculated value.

What you need before you start

Install MetaTrader 5 from your broker and open MetaEditor by pressing F4 inside the terminal. In MetaEditor choose File, then New, then Custom Indicator. Give it a name such as MyFirstMA and finish the wizard. MetaEditor creates a file in the MQL5/Indicators folder with an empty skeleton. Everything below goes into that file.

Indicator buffers in plain language

A buffer is an array of numbers that the terminal keeps lined up with the bars on your chart. If your indicator has a buffer, then element 0 of that array belongs to the first bar in history, and the last element belongs to the newest bar. The MQL5 reference explains that SetIndexBuffer binds one of your arrays to an indicator buffer, and that you cannot change the size of that array yourself, because the terminal manages the resizing.

The reference also says a buffer can be one of two types. INDICATOR_DATA holds values that are drawn on the chart. INDICATOR_CALCULATIONS holds working values that you need for your maths but do not want to draw. Beginners often put everything in a drawn buffer and then wonder why stray lines appear.

Summary graphic listing the main sections of: How to Build Your First MT5 Indicator: A Beginner's Guide to MQL5

The complete first indicator

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   1
#property indicator_label1  "MyFirstMA"
#property indicator_type1   DRAW_LINE
#property indicator_color1  clrDodgerBlue
#property indicator_width1  2

input int InpPeriod = 20;   // Moving average period

double MaBuffer[];

int OnInit()
  {
   SetIndexBuffer(0, MaBuffer, INDICATOR_DATA);
   PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, InpPeriod - 1);
   IndicatorSetString(INDICATOR_SHORTNAME, "MyFirstMA(" + IntegerToString(InpPeriod) + ")");
   return(INIT_SUCCEEDED);
  }

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[])
  {
   if(rates_total < InpPeriod)
      return(0);

   int start;
   if(prev_calculated == 0)
     {
      start = InpPeriod - 1;
      for(int i = 0; i < start; i++)
         MaBuffer[i] = EMPTY_VALUE;
     }
   else
      start = prev_calculated - 1;

   for(int i = start; i < rates_total; i++)
     {
      double sum = 0.0;
      for(int k = 0; k < InpPeriod; k++)
         sum += close[i - k];
      MaBuffer[i] = sum / InpPeriod;
     }
   return(rates_total);
  }

How the code works, line by line

The #property lines tell the terminal how to draw the indicator: on the main chart, with one buffer, as a blue line two pixels wide. The input line creates a setting that appears in the indicator’s properties window, so you can change the period without editing code.

OnInit runs once when the indicator loads. It binds the array MaBuffer to buffer number 0. PLOT_DRAW_BEGIN tells the terminal not to draw the first few bars, where there are not yet enough prices to average.

OnCalculate runs on every new tick. The terminal passes in rates_total, the number of bars available, and prev_calculated, the value your function returned last time. On the first call prev_calculated is 0, so you calculate the full history. On later calls you only need to recalculate from the last bar you already did, which is why the code starts at prev_calculated minus one. This keeps the indicator fast on charts with many thousands of bars. Returning rates_total at the end is how you tell the terminal the work is finished.

In this code the arrays close[] and MaBuffer[] use the default indexing, where index 0 is the oldest bar. That is the opposite of how many beginners think about a chart, and it is the single biggest source of confusion when copying code from MQL4 tutorials. If you want index 0 to mean the newest bar, call ArraySetAsSeries on the arrays, but then you must be consistent everywhere.

Compile, attach and check

  1. Press F7 in MetaEditor to compile. Fix any errors listed at the bottom.
  2. Return to the terminal, open the Navigator panel and find MyFirstMA under Indicators. Refresh the list if it is missing.
  3. Drag it onto a chart. A blue line should appear.
  4. Add the built-in Moving Average with the same period and the Simple method on top. The two lines should sit on each other.

That last comparison is the most useful habit you can learn: always check a new indicator against a trusted built-in one.

Common beginner mistakes

  • Looping from zero every tick. This works but wastes processing time. Use prev_calculated.
  • Reading past the start of an array. Starting the loop below InpPeriod minus one gives an “array out of range” error.
  • Forgetting to return rates_total. The indicator may stop updating.
  • Mixing MQL4 and MQL5 habits. MQL5 uses OnCalculate and buffers, not start() and IndicatorCounted().

What we could not confirm

  • How your own broker’s build behaves on very old history, which depends on how much data it supplies.
  • That the code compiles without warnings on every MetaEditor build. Compile it yourself and read the messages.

Frequently asked questions

Do I need to know C++? No, but MQL5 is similar to C++, so prior programming experience helps.

Where are my files saved? In the MQL5/Indicators folder inside the terminal’s data folder, which you can open from File, Open Data Folder.

Can I use the built-in iMA instead? Yes. For learning, writing your own is useful. For production, calling a built-in indicator through its handle is often shorter.

Key takeaways

An indicator is a function that fills arrays aligned with chart bars. Bind the array with SetIndexBuffer, calculate only new bars using prev_calculated, return rates_total and verify your results against a built-in indicator.

Sources checked

  • MQL5 Reference, “SetIndexBuffer”, mql5.com
  • MQL4 Reference, “Custom Indicators” (what’s new in MQL5 section), docs.mql4.com

Educational content only — not financial advice. Income and savings results vary and are never guaranteed. How we write

Enjoyed this story?

Get the best stories delivered weekly.

Leave a Reply

Your email address will not be published. Required fields are marked *

Share with