Custom Indicator Development for MT4/MT5: From Concept to Code
Off-the-shelf indicators often don't capture your exact trading idea. Here's how to build custom indicators from scratch. .

Custom Indicator Development for MT4/MT5
Off-the-shelf indicators often don't capture your exact trading idea. Here's how to build custom indicators from scratch.
Indicator Architecture Basics
MT5 Indicator Structure:
//+------------------------------------------------------------------+
//| Indicator Properties |
//+------------------------------------------------------------------+
#property indicator_chart_window // Draw on main chart
//#property indicator_separate_window // Draw in separate window
#property indicator_buffers 2 // Number of data buffers
#property indicator_plots 2 // Number of visual plots
//--- Plot settings
#property indicator_label1 "Signal Line"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
//--- Input parameters
input int InpPeriod = 14; // Period
input double InpDeviation = 2.0; // Deviation
input ENUM_APPLIED_PRICE InpPrice = PRICE_CLOSE;
//--- Indicator buffers
double SignalBuffer[];
double HistogramBuffer[];
//+------------------------------------------------------------------+
int OnInit() {
// Initialize buffers
SetIndexBuffer(0, SignalBuffer, INDICATOR_DATA);
SetIndexBuffer(1, HistogramBuffer, INDICATOR_DATA);
// Set draw begin
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, InpPeriod);
// Set indicator name
IndicatorSetString(INDICATOR_SHORTNAME, "MyIndicator(" + 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[]) {
int start;
if(prev_calculated == 0) {
start = InpPeriod;
ArrayInitialize(SignalBuffer, EMPTY_VALUE);
} else {
start = prev_calculated - 1;
}
for(int i = start; i < rates_total; i++) {
// Your calculation logic here
SignalBuffer[i] = CalculateSignal(close, i, InpPeriod);
}
return(rates_total);
}
Building a Custom RSI Divergence Indicator
Complete Example:
#property indicator_separate_window
#property indicator_buffers 5
#property indicator_plots 3
#property indicator_label1 "RSI"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrDodgerBlue
#property indicator_width1 2
#property indicator_label2 "Bullish Divergence"
#property indicator_type2 DRAW_ARROW
#property indicator_color2 clrGreen
#property indicator_label3 "Bearish Divergence"
#property indicator_type3 DRAW_ARROW
#property indicator_color3 clrRed
//--- Inputs
input int RSI_Period = 14;
input int Divergence_Lookback = 20;
input double RSI_Oversold = 30;
input double RSI_Overbought = 70;
//--- Buffers
double RSI_Buffer[];
double BullDiv_Buffer[];
double BearDiv_Buffer[];
double Price_Highs[];
double Price_Lows[];
int OnInit() {
SetIndexBuffer(0, RSI_Buffer, INDICATOR_DATA);
SetIndexBuffer(1, BullDiv_Buffer, INDICATOR_DATA);
SetIndexBuffer(2, BearDiv_Buffer, INDICATOR_DATA);
SetIndexBuffer(3, Price_Highs, INDICATOR_CALCULATIONS);
SetIndexBuffer(4, Price_Lows, INDICATOR_CALCULATIONS);
PlotIndexSetInteger(1, PLOT_ARROW, 233); // Up arrow
PlotIndexSetInteger(2, PLOT_ARROW, 234); // Down arrow
IndicatorSetDouble(INDICATOR_LEVELVALUE, 0, RSI_Overbought);
IndicatorSetDouble(INDICATOR_LEVELVALUE, 1, RSI_Oversold);
IndicatorSetInteger(INDICATOR_LEVELS, 2);
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[]) {
// Calculate RSI
int handle = iRSI(_Symbol, PERIOD_CURRENT, RSI_Period, PRICE_CLOSE);
CopyBuffer(handle, 0, 0, rates_total, RSI_Buffer);
// Initialize divergence buffers
if(prev_calculated == 0) {
ArrayInitialize(BullDiv_Buffer, EMPTY_VALUE);
ArrayInitialize(BearDiv_Buffer, EMPTY_VALUE);
}
int start = MathMax(prev_calculated - 1, Divergence_Lookback);
for(int i = start; i < rates_total - 1; i++) {
// Check for bullish divergence
if(IsBullishDivergence(close, RSI_Buffer, i, Divergence_Lookback)) {
BullDiv_Buffer[i] = RSI_Buffer[i];
} else {
BullDiv_Buffer[i] = EMPTY_VALUE;
}
// Check for bearish divergence
if(IsBearishDivergence(close, RSI_Buffer, i, Divergence_Lookback)) {
BearDiv_Buffer[i] = RSI_Buffer[i];
} else {
BearDiv_Buffer[i] = EMPTY_VALUE;
}
}
return(rates_total);
}
bool IsBullishDivergence(const double &price[], const double &rsi[],
int bar, int lookback) {
// Find previous swing low in price
int prev_low_bar = FindPreviousSwingLow(price, bar, lookback);
if(prev_low_bar < 0) return false;
// Price making lower low, RSI making higher low
if(price[bar] < price[prev_low_bar] &&
rsi[bar] > rsi[prev_low_bar] &&
rsi[bar] < RSI_Oversold) {
return true;
}
return false;
}
bool IsBearishDivergence(const double &price[], const double &rsi[],
int bar, int lookback) {
// Find previous swing high in price
int prev_high_bar = FindPreviousSwingHigh(price, bar, lookback);
if(prev_high_bar < 0) return false;
// Price making higher high, RSI making lower high
if(price[bar] > price[prev_high_bar] &&
rsi[bar] < rsi[prev_high_bar] &&
rsi[bar] > RSI_Overbought) {
return true;
}
return false;
}
int FindPreviousSwingLow(const double &price[], int current_bar, int lookback) {
int min_bar = -1;
double min_price = DBL_MAX;
for(int i = current_bar - 3; i >= current_bar - lookback && i >= 0; i--) {
if(price[i] < min_price && IsSwingLow(price, i)) {
min_price = price[i];
min_bar = i;
}
}
return min_bar;
}
bool IsSwingLow(const double &price[], int bar) {
if(bar < 2 || bar >= ArraySize(price) - 2) return false;
return (price[bar] < price[bar-1] &&
price[bar] < price[bar-2] &&
price[bar] < price[bar+1] &&
price[bar] < price[bar+2]);
}
๐ค Can This Strategy Be Automated?
In 2026, top traders run custom EAs โ not manual charts. We build MT4/MT5 Expert Advisors that execute your exact strategy 24/7, pass prop firm challenges, and eliminate emotional decisions.
- Runs 24/7 โ no screen time, no missed entries
- Prop-firm compliant (FTMO, MFF, TFT drawdown rules)
- MyFXBook-verified backtest results included
- From strategy brief to live EA in 2โ4 weeks
Multi-Timeframe Indicators
Access Higher Timeframe Data:
#property indicator_chart_window
#property indicator_buffers 2
input ENUM_TIMEFRAMES HTF = PERIOD_H4; // Higher timeframe
input int MA_Period = 20;
double HTF_MA_Buffer[];
double Current_MA_Buffer[];
int htf_ma_handle;
int current_ma_handle;
int OnInit() {
htf_ma_handle = iMA(_Symbol, HTF, MA_Period, 0, MODE_SMA, PRICE_CLOSE);
current_ma_handle = iMA(_Symbol, PERIOD_CURRENT, MA_Period, 0, MODE_SMA, PRICE_CLOSE);
SetIndexBuffer(0, HTF_MA_Buffer, INDICATOR_DATA);
SetIndexBuffer(1, Current_MA_Buffer, INDICATOR_DATA);
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[]) {
// Copy current timeframe MA
CopyBuffer(current_ma_handle, 0, 0, rates_total, Current_MA_Buffer);
// Copy and expand HTF MA
double htf_temp[];
int htf_bars = Bars(_Symbol, HTF);
ArrayResize(htf_temp, htf_bars);
CopyBuffer(htf_ma_handle, 0, 0, htf_bars, htf_temp);
// Map HTF values to current timeframe
for(int i = 0; i < rates_total; i++) {
datetime bar_time = time[i];
int htf_shift = iBarShift(_Symbol, HTF, bar_time);
if(htf_shift >= 0 && htf_shift < htf_bars) {
HTF_MA_Buffer[i] = htf_temp[htf_shift];
}
}
return(rates_total);
}
Performance Optimization
Efficient Calculation:
// Bad: Recalculates entire history every tick
for(int i = 0; i < rates_total; i++) {
Buffer[i] = HeavyCalculation(close, i);
}
// Good: Only calculate new bars
int limit;
if(prev_calculated == 0) {
limit = 0;
} else {
limit = prev_calculated - 1;
}
for(int i = limit; i < rates_total; i++) {
Buffer[i] = HeavyCalculation(close, i);
}
Caching Expensive Operations:
static double cached_value = 0;
static datetime last_calc_time = 0;
double GetExpensiveValue() {
if(TimeCurrent() - last_calc_time < 60) { // Cache for 60 seconds
return cached_value;
}
cached_value = ExpensiveCalculation();
last_calc_time = TimeCurrent();
return cached_value;
}
๐ Stop Trading Manually โ Let AI Do It
While you sleep, your EA keeps working. Viprasol builds prop-firm-compliant Expert Advisors with strict risk management, real backtests, and live deployment support.
- No rule violations โ daily drawdown, max drawdown, consistency rules built in
- Covers MT4, MT5, cTrader, and Python-based algos
- 5.0โ Upwork record โ 100% job success rate
- Free strategy consultation before we write a single line
Testing Your Indicator
Visual Testing Checklist:
- โ Correct values compared to manual calculation
- โ No repaint issues
- โ Handles missing data gracefully
- โ Works on different timeframes
- โ Works on different symbols
- โ Efficient (doesn't lag)
Debug Output:
#ifdef _DEBUG
Print("Bar: ", i, " Value: ", SignalBuffer[i]);
#endif
Our Custom Indicator Services
Viprasol develops professional custom indicators:
- Proprietary algorithms
- Multi-timeframe analysis
- Divergence detection
- Pattern recognition
- Alert systems
Need a custom indicator? Contact us with your specifications.
About the Author
Viprasol Tech Team
Custom Software Development Specialists
The Viprasol Tech team specialises in algorithmic trading software, AI agent systems, and SaaS development. With 100+ projects delivered across MT4/MT5 EAs, fintech platforms, and production AI systems, the team brings deep technical experience to every engagement. Based in India, serving clients globally.
Ready to Automate Your Trading?
Get a custom Expert Advisor built by professionals with verified MyFXBook results.
Free consultation โข No commitment โข Response within 24 hours
Need a custom EA or trading bot built?
We specialise in MT4/MT5 Expert Advisor development โ prop-firm compliant, forward-tested before live, MyFXBook verifiable. 5.0โ Upwork, 100% Job Success, 100+ projects shipped.