🚀 AI One-Click Generation of mql4 Strategy Code

Building Your First Mql4 Custom Indicator: A Step-by-Step Guide

mql4 | Published on: 2025/12/11
The following content is generated by EasyQuant .

Problem Description

I want to create my own simple indicator. Can you show me the basic structure and explain how to draw a line on the chart?

Solution

Here is the complete code for a basic MQL4 indicator. This example creates a Median Price Indicator, which draws a line representing the average of the High and Low prices (High + Low) / 2 for each bar.

MQL4 Indicator Structure

//+------------------------------------------------------------------+
//|                                          SimpleLineIndicator.mq4 |
//|                        Copyright 2023, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2023, Your Name"
#property link      "https://www.yourwebsite.com"
#property version   "1.00"
#property strict

//--- 1. INDICATOR PROPERTIES
// Display the indicator in the main chart window (overlay on price)
#property indicator_chart_window 
// We need 1 buffer to store the data for our line
#property indicator_buffers 1 
// Define the color of the line (Index 0)
#property indicator_color1 clrDodgerBlue 
// Define the width of the line
#property indicator_width1 2

//--- 2. INPUT PARAMETERS
// Allow the user to shift the line forward/backward
input int InputShift = 0; 

//--- 3. GLOBAL VARIABLES (BUFFERS)
// This dynamic array will hold the calculated values to be drawn
double LineBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
{
   //--- 4. MAPPING BUFFERS
   // Associate the dynamic array 'LineBuffer' with indicator buffer index 0
   SetIndexBuffer(0, LineBuffer);
   
   //--- 5. STYLING
   // Set the drawing style to a Line
   SetIndexStyle(0, DRAW_LINE);
   // Apply the shift defined in inputs
   SetIndexShift(0, InputShift);
   // Set the label that appears in the Data Window
   SetIndexLabel(0, "Median Price");
   
   // Return initialization success
   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[])
{
   //--- 6. OPTIMIZATION (Do not recalculate all bars every tick)
   int limit;
   
   // If prev_calculated is 0, it means it's the first run. Calculate all bars.
   if(prev_calculated == 0) 
      limit = rates_total - 1;
   else 
      // Otherwise, only calculate the new bars (and re-calculate the current open bar)
      limit = rates_total - prev_calculated;

   //--- 7. CALCULATION LOOP
   // Iterate from the oldest necessary bar to the current bar (0)
   for(int i = 0; i <= limit; i++)
   {
      // Calculate the Median Price: (High + Low) / 2
      double medianPrice = (High[i] + Low[i]) / 2.0;
      
      // Store the result in the buffer. 
      // The terminal automatically draws whatever is in this array.
      LineBuffer[i] = medianPrice;
   }

   // Return the total number of bars to be used as 'prev_calculated' in the next tick
   return(rates_total);
}
//+------------------------------------------------------------------+

Explanation of the Structure

1. Properties (#property)

These directives tell the MetaTrader terminal how to handle the indicator before the code even runs.

  • indicator_chart_window: Draws the line directly over the candlesticks. If you wanted a separate window (like RSI or MACD), you would use indicator_separate_window.
  • indicator_buffers: Allocates memory for the data arrays. We used 1 because we are drawing one line.
  • indicator_color1: Sets the default color for the first buffer.

2. Input Parameters (input)

Variables declared with input appear in the "Inputs" tab when you attach the indicator to a chart. This allows users to change settings without editing the code.

3. Global Variables (Buffers)

We declared double LineBuffer[]. This is a dynamic array. However, we do not set its size manually using ArrayResize. The terminal handles the size automatically because we link it as an indicator buffer in OnInit.

4. OnInit() Function

This runs once when you attach the indicator.

  • SetIndexBuffer(0, LineBuffer): This is the most critical line. It links the array LineBuffer to the chart's drawing engine. Any value you put into LineBuffer will be drawn on the screen.
  • SetIndexStyle: Defines that we want to draw a Line (as opposed to a Histogram, Arrow, or Section).

5. OnCalculate() Function

This function runs every time a new price tick is received.

  • rates_total: The total number of bars on the chart.
  • prev_calculated: The number of bars the indicator has already calculated in previous ticks.
  • The Optimization Logic: We calculate limit. If the indicator has already run, we don't want to loop through 100,000 history bars again. We only want to calculate the newest bar (index 0) and perhaps the one just closed.
  • The Loop: We iterate through the bars. In MQL4, High[0] is the current bar, and High[10] is 10 bars ago.
  • The Assignment: LineBuffer[i] = ... assigns the math result to the array. The visual line on the chart updates automatically based on these values.

How to Install and Run

  1. Open MetaTrader 4.
  2. Press F4 to open the MetaEditor.
  3. Click New -> Custom Indicator -> Next.
  4. Name it SimpleLineIndicator and click Finish.
  5. Paste the code above into the file (replace everything).
  6. Press F7 to Compile.
  7. Go back to the main MetaTrader 4 window.
  8. Find SimpleLineIndicator in the Navigator panel (under Indicators) and drag it onto a chart.

Q&A

Q: How do I make the line appear in a separate window below the chart?
A: Change #property indicator_chart_window to #property indicator_separate_window.

Q: How do I draw a Moving Average instead of Median Price?
A: Inside the for loop, replace the math with the built-in MA function:
LineBuffer[i] = iMA(NULL, 0, 14, 0, MODE_SMA, PRICE_CLOSE, i);

Q: Why does the loop use rates_total - prev_calculated?
A: This is for performance. Calculating thousands of bars on every single tick (millisecond) would freeze the computer. This logic ensures we only calculate new data as it arrives.