Page 1 of 2
ALMA in Forex Scalping: Precision Without the Lag
Posted: Mon Aug 10, 2026 3:14 pm
by PTScalper
Hi traders,
today i would like to share with you little more information about one of special indicator, which is not so well known,
but it can have interesting potencial for you.
Its called
ALMA.
In the fast-paced arena of forex scalping, standard moving averages force a frustrating compromise: you either get rapid signals full of false breakouts (EMA) or smooth lines that lag terribly (SMA). The
Arnaud Legoux Moving Average (ALMA) engineers a highly effective way out of this trap.
Developed by Arnaud Legoux and Dimitris Kouzis-Loukas, ALMA borrows signal-processing techniques to apply a Gaussian (bell curve) weight distribution to price data. It essentially filters price action from left to right and right to left, virtually eliminating the phase shift (lag) while ironing out the micro-noise that whipsaws short-term traders. For M1 or M5 scalpers, ALMA acts as an exceptionally clean dynamic support and resistance level. Its behavior is governed by three primary parameters:Window: The lookback period (e.g., 9 for rapid scalping). Offset: Dictates responsiveness on a scale of 0 to 1. Pushing it to 0.85 heavily weights the curve toward the most recent prices, allowing the line to tightly hug the trend. Sigma: Controls the Gaussian curve's width. A standard setting of 6 (inspired by the Six Sigma process) keeps the distribution crisp.
When the ALMA line slopes sharply, it confirms pure momentum. When price pulls back to the ALMA during an established micro-trend, it often presents a high-probability entry point. By stripping out market noise without delaying the signal, ALMA gives scalpers one of the clearest reads on immediate price action.
Custom ALMA Indicator for MT4 (MQL4)
Here is a lightweight, optimized MQL4 custom indicator script. You can compile this directly in MetaEditor and drop it into your platform's Indicators folder.
Code: Select all
//+------------------------------------------------------------------+
//| ALMA.mq4 |
//| Arnaud Legoux Moving Average |
//+------------------------------------------------------------------+
#property copyright "Custom Indicator"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 clrDodgerBlue
#property indicator_width1 2
input int Window = 9; // Window size
input double Offset = 0.85; // Gaussian Offset (0 to 1)
input double Sigma = 6.0; // Curve width
double ALMABuffer[];
int OnInit() {
SetIndexBuffer(0, ALMABuffer);
SetIndexStyle(0, DRAW_LINE);
IndicatorShortName("ALMA(" + IntegerToString(Window) + ")");
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 < Window) return(0);
int limit;
// Determine how many bars to calculate
if (prev_calculated == 0) {
limit = rates_total - Window + 1;
} else {
limit = rates_total - prev_calculated + 1; // Always recalculate the current active bar
}
double m = Offset * (Window - 1);
double s = Window / Sigma;
// Safeguard against division by zero
if (s == 0) s = 0.000001;
// Loop through chart bars
for (int i = 0; i < limit; i++) {
double wtdSum = 0.0;
double cumWt = 0.0;
// Apply Gaussian weighting over the Window
for (int k = 0; k < Window; k++) {
double wtd = MathExp(-MathPow(k - m, 2) / (2 * s * s));
// Close[] is an MT4 predefined timeseries array (0 is the current bar)
wtdSum += wtd * Close[i + Window - 1 - k];
cumWt += wtd;
}
if (cumWt > 0) {
ALMABuffer[i] = wtdSum / cumWt;
}
}
return(rates_total);
}
//+------------------------------------------------------------------+
Re: ALMA in Forex Scalping: Precision Without the Lag
Posted: Mon Aug 10, 2026 3:15 pm
by PTScalper
Here are the custom ALMA (Arnaud Legoux Moving Average) indicator implementations for both MetaTrader 5 (MQL5) and cTrader (C#).
Both implementations pre-calculate the Gaussian weight distribution upon initialization to maximize execution speed during live tick processing.
1. MetaTrader 5 Implementation (MQL5)
Save this file as ALMA.mq5 inside your MT5 MQL5/Indicators directory and compile it using MetaEditor 5.
Code: Select all
//+------------------------------------------------------------------+
//| ALMA.mq5 |
//| Arnaud Legoux Moving Average |
//+------------------------------------------------------------------+
#property copyright "Custom Indicator"
#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots 1
#property indicator_label1 "ALMA"
#property indicator_type1 DRAW_LINE
#property indicator_color1 clrDodgerBlue
#property indicator_style1 STYLE_SOLID
#property indicator_width1 2
// Inputs
input int InpWindow = 9; // Window size
input double InpOffset = 0.85; // Gaussian Offset (0 to 1)
input double InpSigma = 6.0; // Curve width
// Indicator Buffers
double ALMABuffer[];
// Dynamic weight cache
double weights[];
double weightSum;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
SetIndexBuffer(0, ALMABuffer, INDICATOR_DATA);
PlotIndexSetString(0, PLOT_LABEL, "ALMA(" + IntegerToString(InpWindow) + ")");
// Pre-calculate Gaussian weights for maximum runtime performance
ArrayResize(weights, InpWindow);
weightSum = 0.0;
double m = InpOffset * (InpWindow - 1);
double s = InpWindow / (InpSigma > 0 ? InpSigma : 1.0);
for(int k = 0; k < InpWindow; k++)
{
weights[k] = MathExp(-MathPow(k - m, 2.0) / (2.0 * s * s));
weightSum += weights[k];
}
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[])
{
if(rates_total < InpWindow) return(0);
int start = prev_calculated - 1;
if(start < InpWindow - 1) start = InpWindow - 1;
for(int i = start; i < rates_total; i++)
{
double sum = 0.0;
for(int k = 0; k < InpWindow; k++)
{
sum += close[i - (InpWindow - 1 - k)] * weights[k];
}
if(weightSum > 0)
ALMABuffer[i] = sum / weightSum;
}
return(rates_total);
}
//+------------------------------------------------------------------+
Re: ALMA in Forex Scalping: Precision Without the Lag
Posted: Mon Aug 10, 2026 3:17 pm
by PTScalper
And here i prepared for Ic traders:
cTrader Implementation (C#)
In cTrader, navigate to Automate > Indicators > New, paste the C# code below, and press Ctrl + B to build.
Code: Select all
using System;
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class ArnaudLegouxMovingAverage : Indicator
{
[Parameter("Source")]
public DataSeries Source { get; set; }
[Parameter("Window Size", DefaultValue = 9, MinValue = 1)]
public int Window { get; set; }
[Parameter("Offset", DefaultValue = 0.85, MinValue = 0, MaxValue = 1)]
public double Offset { get; set; }
[Parameter("Sigma", DefaultValue = 6.0, MinValue = 0.1)]
public double Sigma { get; set; }
[Output("ALMA", LineColor = "DodgerBlue", PlotType = PlotType.Line, Thickness = 2)]
public IndicatorDataSeries Result { get; set; }
private double[] _weights;
private double _weightSum;
protected override void Initialize()
{
_weights = new double[Window];
_weightSum = 0;
double m = Offset * (Window - 1);
double s = Window / Sigma;
for (int k = 0; k < Window; k++)
{
_weights[k] = Math.Exp(-Math.Pow(k - m, 2) / (2 * s * s));
_weightSum += _weights[k];
}
}
public override void Calculate(int index)
{
if (index < Window - 1)
{
Result[index] = double.NaN;
return;
}
double sum = 0;
for (int k = 0; k < Window; k++)
{
int sourceIndex = index - (Window - 1 - k);
sum += Source[sourceIndex] * _weights[k];
}
Result[index] = _weightSum > 0 ? sum / _weightSum : Source[index];
}
}
}
Parameter Setup
Window (9): Standard period length for M1/M5 scalping.
Offset (0.85): Places the Gaussian bell peak closer to current price action for maximum responsiveness.
Sigma (6.0): Standard deviation parameter ensuring sharp weight distribution across the lookback period.
I hope, you will like it and please let me know, if it was usefull for you
Take a care and lot of good trades.
Re: ALMA in Forex Scalping: Precision Without the Lag
Posted: Fri Sep 04, 2026 8:40 pm
by FTtrader
Here is the conversion of the cTrader (C#) Arnaud Legoux Moving Average (ALMA) into TradingView's Pine Script v5.
Because ALMA is a standard indicator, Pine Script actually has a highly optimized built-in function (ta.alma) that does exactly what your C# calculation loop does.
Here is the cleanest and most efficient way to write it in Pine Script:
Code: Select all
//@version=5
indicator("Arnaud Legoux Moving Average", shorttitle="ALMA", overlay=true)
// Inputs mapping directly to your C# Parameters
src = input.source(close, title="Source")
window = input.int(9, title="Window Size", minval=1)
offset = input.float(0.85, title="Offset", minval=0.0, maxval=1.0, step=0.05)
sigma = input.float(6.0, title="Sigma", minval=0.1, step=0.5)
// Calculation using Pine Script's built-in ALMA function
alma_result = ta.alma(src, window, offset, sigma)
// Plotting the output with Dodger Blue (#1E90FF) and Thickness = 2
plot(alma_result, color=color.new(#1E90FF, 0), linewidth=2, title="ALMA")
Re: ALMA in Forex Scalping: Precision Without the Lag
Posted: Fri Sep 04, 2026 8:40 pm
by FTtrader
Manual Loop Version (Exact C# Translation)
If you are learning Pine Script and want to see exactly how your C# Initialize() and Calculate() logic translates into Pine Script's array/loop mechanics, here is the manual calculation.
(Note: Pine Script executes on every bar, so we run a lookback loop on historical bars instead of managing a separate index variable).
Code: Select all
//@version=5
indicator("Arnaud Legoux Moving Average (Manual)", shorttitle="ALMA Custom", overlay=true)
src = input.source(close, title="Source")
window = input.int(9, title="Window Size", minval=1)
offset = input.float(0.85, title="Offset", minval=0.0, maxval=1.0)
sigma = input.float(6.0, title="Sigma", minval=0.1)
// Manual Calculation Function mirroring the C# logic
calc_alma(source, len, off, sig) =>
if bar_index < len - 1
na // Returns NaN until we have enough bars (matches: if index < Window - 1)
else
m = off * (len - 1)
s = len / sig
sum = 0.0
weightSum = 0.0
// Loop through the lookback window
for k = 0 to len - 1
weight = math.exp(-math.pow(k - m, 2) / (2 * s * s))
// In Pine, source[x] looks back 'x' bars ago
// len - 1 - k perfectly mirrors: index - (Window - 1 - k)
sum += source[len - 1 - k] * weight
weightSum += weight
weightSum > 0 ? (sum / weightSum) : source
// Execute function and plot
alma_result = calc_alma(src, window, offset, sigma)
plot(alma_result, color=color.new(#1E90FF, 0), linewidth=2, title="ALMA")
Re: ALMA in Forex Scalping: Precision Without the Lag
Posted: Fri Sep 04, 2026 8:41 pm
by FTtrader
Key Differences to Note:
Indexing: In C#, you access historical data by doing index - offset. In Pine Script, the [] operator handles historical lookbacks automatically relative to the current bar (e.g., close[1] is yesterday's close).
Colors: Pine Script doesn't have a named DodgerBlue constant, so I used its exact hex color equivalent (#1E90FF).
Re: ALMA in Forex Scalping: Precision Without the Lag
Posted: Fri Sep 04, 2026 8:42 pm
by FTtrader
To write a truly "professional" Pine Script, the focus shifts from just getting the math right to optimizing performance, enhancing the user experience (UX), and integrating seamlessly with TradingView's alert system.
In Pine Script v5, a professional-grade indicator relies on built-in functions (which execute much faster than manual loops), uses grouped inputs with tooltips for a clean settings menu, provides dynamic visual feedback, and includes ready-to-use alert conditions.
Here is the professional, fully-featured version of your ALMA indicator:
Code: Select all
//@version=5
indicator("Arnaud Legoux Moving Average [Pro]", shorttitle="ALMA Pro", overlay=true, timeframe="", timeframe_gaps=true)
// =====================================================================
// 1. INPUTS (Organized with Groups, Inlines, and Tooltips)
// =====================================================================
var string GRP_ALMA = "ALMA Parameters"
var string GRP_VISUAL = "Visuals & Alerts"
src = input.source(close, title="Source", group=GRP_ALMA)
window = input.int(9, title="Window Size", minval=1, group=GRP_ALMA, tooltip="Number of bars used in the calculation.")
offset = input.float(0.85, title="Offset", minval=0.0, maxval=1.0, step=0.05, group=GRP_ALMA, tooltip="Shifts the focus of the ALMA. 1 = Current bar, 0 = Oldest bar.")
sigma = input.float(6.0, title="Sigma", minval=0.1, step=0.5, group=GRP_ALMA, tooltip="Standard deviation applied to the curve. Larger values = smoother line.")
colUp = input.color(#2962FF, title="Rising Color", group=GRP_VISUAL, inline="Colors")
colDn = input.color(#F23645, title="Falling Color", group=GRP_VISUAL, inline="Colors")
// =====================================================================
// 2. CALCULATION
// =====================================================================
// Using the highly optimized built-in function instead of manual loops
float alma = ta.alma(src, window, offset, sigma)
// =====================================================================
// 3. LOGIC & VISUALS
// =====================================================================
// Determine if the ALMA is rising or falling for dynamic coloring
bool isRising = ta.rising(alma, 1)
color almaCol = isRising ? colUp : colDn
// Plotting the line with conditional colors
plot(alma, title="ALMA", color=almaCol, linewidth=2, style=plot.style_line)
// =====================================================================
// 4. ALERTS
// =====================================================================
bool crossUp = ta.crossover(src, alma)
bool crossDn = ta.crossunder(src, alma)
alertcondition(crossUp, title="Price Crossed Above ALMA", message="Bullish Signal: Price closed above ALMA.")
alertcondition(crossDn, title="Price Crossed Below ALMA", message="Bearish Signal: Price closed below ALMA.")
Re: ALMA in Forex Scalping: Precision Without the Lag
Posted: Fri Sep 04, 2026 8:43 pm
by FTtrader
What makes this version professional?
Optimized Execution: It relies entirely on ta.alma. In Pine Script, built-in functions are compiled in C++ under the hood and will execute exponentially faster than looping over historical bars manually.
Clean UI (Groups & Inlines): The settings menu is divided into logically named groups (ALMA Parameters and Visuals & Alerts). Related items, like the up/down colors, are placed on the same row using inline.
Tooltips: Adding tooltip arguments explains the math to the end-user (e.g., explaining what Sigma actually does) without cluttering the screen.
Dynamic Visuals: Instead of a static blue line, the indicator calculates momentum (ta.rising) and paints the line green when moving up and red when moving down, allowing for instant visual trend recognition.
Multi-Timeframe Support: Adding timeframe="" to the indicator() declaration natively allows users to apply this indicator from a higher timeframe directly onto their current chart via the settings menu.
Integrated Alerts: alertcondition functions are built in, allowing users to hook up TradingView webhook alerts or push notifications instantly when the price crosses the moving average.
Re: ALMA in Forex Scalping: Precision Without the Lag
Posted: Fri Sep 04, 2026 8:43 pm
by FTtrader
And here i prepared the updated professional version with visual Buy and Sell shape markers integrated.
I added a toggle switch in the settings so you can easily turn the shapes on or off to keep your chart clean, and the shapes will automatically match the colors you choose for the ALMA line.
Code: Select all
//@version=5
indicator("Arnaud Legoux Moving Average [Pro]", shorttitle="ALMA Pro", overlay=true, timeframe="", timeframe_gaps=true)
// =====================================================================
// 1. INPUTS
// =====================================================================
var string GRP_ALMA = "ALMA Parameters"
var string GRP_VISUAL = "Visuals, Shapes & Alerts"
src = input.source(close, title="Source", group=GRP_ALMA)
window = input.int(9, title="Window Size", minval=1, group=GRP_ALMA, tooltip="Number of bars used in the calculation.")
offset = input.float(0.85, title="Offset", minval=0.0, maxval=1.0, step=0.05, group=GRP_ALMA, tooltip="Shifts the focus of the ALMA. 1 = Current bar, 0 = Oldest bar.")
sigma = input.float(6.0, title="Sigma", minval=0.1, step=0.5, group=GRP_ALMA, tooltip="Standard deviation applied to the curve. Larger values = smoother line.")
colUp = input.color(#2962FF, title="Rising Color", group=GRP_VISUAL, inline="Colors")
colDn = input.color(#F23645, title="Falling Color", group=GRP_VISUAL, inline="Colors")
showShapes = input.bool(true, title="Show Buy/Sell Crossover Shapes", group=GRP_VISUAL)
// =====================================================================
// 2. CALCULATION
// =====================================================================
float alma = ta.alma(src, window, offset, sigma)
// =====================================================================
// 3. LOGIC & LINE PLOTTING
// =====================================================================
// Determine if the ALMA is rising or falling
bool isRising = ta.rising(alma, 1)
color almaCol = isRising ? colUp : colDn
plot(alma, title="ALMA", color=almaCol, linewidth=2, style=plot.style_line)
// =====================================================================
// 4. CROSSOVER SIGNALS & SHAPES
// =====================================================================
bool crossUp = ta.crossover(src, alma)
bool crossDn = ta.crossunder(src, alma)
// Plot Up Triangle below the bar when price crosses above ALMA
plotshape(showShapes and crossUp ? true : na, title="Buy Signal", style=shape.triangleup, location=location.belowbar, color=colUp, size=size.small)
// Plot Down Triangle above the bar when price crosses below ALMA
plotshape(showShapes and crossDn ? true : na, title="Sell Signal", style=shape.triangledown, location=location.abovebar, color=colDn, size=size.small)
// =====================================================================
// 5. ALERTS
// =====================================================================
alertcondition(crossUp, title="Price Crossed Above ALMA", message="Bullish Signal: Price closed above ALMA.")
alertcondition(crossDn, title="Price Crossed Below ALMA", message="Bearish Signal: Price closed below ALMA.")
Re: ALMA in Forex Scalping: Precision Without the Lag
Posted: Fri Sep 04, 2026 8:44 pm
by FTtrader
What was added:
showShapes Toggle: A checkbox in the settings menu allowing you to show or hide the markers instantly.
plotshape() Functions:
When the price crosses above the ALMA, a small upward-pointing triangle appears below the candle.
When the price crosses below the ALMA, a small downward-pointing triangle appears above the candle.
Color Syncing: The shapes automatically inherit the colUp and colDn colors you pick for the moving average line, ensuring your chart's theme remains consistent.