Custom Fibonacci retracement indicator for Forex
Posted: Thu Aug 06, 2026 10:16 pm
Hi scalpers,
i prepared for you another custom indicator, which is based on Fibonacci retracement.
Here is a complete, custom MQL4 indicator that automatically calculates and draws Fibonacci retracement and extension levels based on dynamic market highs and lows.
Because MQL4 shares structural similarities with C#, you will notice the event-driven architecture immediately. The OnCalculate function acts like a standard event handler that fires on every tick, continuously evaluating the arrays to keep the retracement perfectly anchored to the most recent price action.
I have embedded your name and domain directly into the metadata so the file is ready for your own production environment.
i prepared for you another custom indicator, which is based on Fibonacci retracement.
Here is a complete, custom MQL4 indicator that automatically calculates and draws Fibonacci retracement and extension levels based on dynamic market highs and lows.
Because MQL4 shares structural similarities with C#, you will notice the event-driven architecture immediately. The OnCalculate function acts like a standard event handler that fires on every tick, continuously evaluating the arrays to keep the retracement perfectly anchored to the most recent price action.
I have embedded your name and domain directly into the metadata so the file is ready for your own production environment.
Code: Select all
//+------------------------------------------------------------------+
//| AutoFibo.mq4 |
//| Copyright 2026, Pavel Tuček |
//| https://aiprofisolutions.com |
//+------------------------------------------------------------------+
#property copyright "Pavel Tuček"
#property link "https://aiprofisolutions.com"
#property version "1.00"
#property strict
#property indicator_chart_window
//--- Input parameters
input int LookbackPeriod = 100; // Lookback Period (Bars)
input color FiboColor = clrGoldenrod;// Fibonacci Lines Color
input bool ShowExtensions = true; // Show 161.8% and 261.8%
input ENUM_LINE_STYLE FiboStyle = STYLE_SOLID; // Line Style
//--- Global variables
string fiboName = "AutoFibo_Custom";
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
// Validate the lookback period
if(LookbackPeriod <= 0)
{
Print("LookbackPeriod must be greater than 0");
return(INIT_PARAMETERS_INCORRECT);
}
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
// Clean up the graphical object when the indicator is removed
ObjectDelete(0, fiboName);
}
//+------------------------------------------------------------------+
//| 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[])
{
// Wait until the chart has enough historical bars
if(rates_total < LookbackPeriod) return(0);
// Ensure time series indexing (Index 0 is the current active bar)
ArraySetAsSeries(high, true);
ArraySetAsSeries(low, true);
ArraySetAsSeries(time, true);
// Find the highest and lowest points within the defined lookback window
int highestIdx = ArrayMaximum(high, LookbackPeriod, 0);
int lowestIdx = ArrayMinimum(low, LookbackPeriod, 0);
double highestPrice = high[highestIdx];
double lowestPrice = low[lowestIdx];
datetime timeHigh = time[highestIdx];
datetime timeLow = time[lowestIdx];
// Time variables for Fibonacci anchor points
datetime time1, time2;
double price1, price2;
// Establish trend direction for proper Fibonacci projection
if(highestIdx > lowestIdx)
{
// High index is larger -> High occurred further back in time -> Downtrend
time1 = timeHigh; price1 = highestPrice;
time2 = timeLow; price2 = lowestPrice;
}
else
{
// Low index is larger -> Low occurred further back in time -> Uptrend
time1 = timeLow; price1 = lowestPrice;
time2 = timeHigh; price2 = highestPrice;
}
// Initialize or update the OBJ_FIBO graphic object
if(ObjectFind(0, fiboName) < 0)
{
ObjectCreate(0, fiboName, OBJ_FIBO, 0, time1, price1, time2, price2);
// Core styling
ObjectSetInteger(0, fiboName, OBJPROP_COLOR, FiboColor);
ObjectSetInteger(0, fiboName, OBJPROP_STYLE, FiboStyle);
ObjectSetInteger(0, fiboName, OBJPROP_BACK, true);
ObjectSetInteger(0, fiboName, OBJPROP_SELECTABLE, false);
ObjectSetInteger(0, fiboName, OBJPROP_HIDDEN, true);
// Define the retracement levels
int numLevels = ShowExtensions ? 8 : 6;
ObjectSetInteger(0, fiboName, OBJPROP_LEVELS, numLevels);
// The '%$' token dynamically prints the precise price level on the chart
ObjectSetDouble(0, fiboName, OBJPROP_LEVELVALUE, 0, 0.0); ObjectSetString(0, fiboName, OBJPROP_LEVELTEXT, 0, "0.0 (%$)");
ObjectSetDouble(0, fiboName, OBJPROP_LEVELVALUE, 1, 0.236); ObjectSetString(0, fiboName, OBJPROP_LEVELTEXT, 1, "23.6 (%$)");
ObjectSetDouble(0, fiboName, OBJPROP_LEVELVALUE, 2, 0.382); ObjectSetString(0, fiboName, OBJPROP_LEVELTEXT, 2, "38.2 (%$)");
ObjectSetDouble(0, fiboName, OBJPROP_LEVELVALUE, 3, 0.5); ObjectSetString(0, fiboName, OBJPROP_LEVELTEXT, 3, "50.0 (%$)");
ObjectSetDouble(0, fiboName, OBJPROP_LEVELVALUE, 4, 0.618); ObjectSetString(0, fiboName, OBJPROP_LEVELTEXT, 4, "61.8 (%$)");
ObjectSetDouble(0, fiboName, OBJPROP_LEVELVALUE, 5, 1.0); ObjectSetString(0, fiboName, OBJPROP_LEVELTEXT, 5, "100.0 (%$)");
// Define expansion levels for profit targets
if(ShowExtensions)
{
ObjectSetDouble(0, fiboName, OBJPROP_LEVELVALUE, 6, 1.618); ObjectSetString(0, fiboName, OBJPROP_LEVELTEXT, 6, "161.8 (%$)");
ObjectSetDouble(0, fiboName, OBJPROP_LEVELVALUE, 7, 2.618); ObjectSetString(0, fiboName, OBJPROP_LEVELTEXT, 7, "261.8 (%$)");
}
}
else
{
// Update anchors on every tick as the lookback window shifts
ObjectSetInteger(0, fiboName, OBJPROP_TIME, 0, time1);
ObjectSetDouble(0, fiboName, OBJPROP_PRICE, 0, price1);
ObjectSetInteger(0, fiboName, OBJPROP_TIME, 1, time2);
ObjectSetDouble(0, fiboName, OBJPROP_PRICE, 1, price2);
}
return(rates_total);
}
//+------------------------------------------------------------------+