Arnaud Legoux Moving Average (ALMA) -Multistage

Arnaud Legoux Moving Average (ALMA) -Multistage
# Triangles
# ─────────────────────────────────────────────
# │ MarketFragments.com | DNA & Market │
# │ info@marketfragments.com │
# │ www.marketfragments.com │
# ─────────────────────────────────────────────
# Time →
# │
# █ █ █│ █
# █ █ █ │ █ █
# █ █ █ │ █ █ █ ╭─╮
# █ █ █ │ █ █ █ █ ╭─╯ ╰─╮
# █ █ █ │ █ █ █ █ █ █ ╭─╯ ╰─╮
# █ █ █ │ █ █ █ █ █ █ █ █ ╭─╯ ╰─╮
# █ █ █ │ █ █ █ █ █ █ █ █ █ █╭─╯ ╰─╮
# █ █ █ │ █ █ █ █ █ █ █ █ ╰─╮ ╭─╯
# █ █ █ │ █ █ █ █ █ █ ╰─╮ ╭─╯
# █ █ █ │ █ █ █ █ ╰─╮ ╭─╯
# █ █ █ │ █ █ ╰─╮ ╭─╯
# █ █ █ │ █ ╰─────╯
# ──────┴──────────────────────────────────────────────────────────────
# T1 T2 T3 T4 T5 T6
#
# Custom Coding Agreement
# This Coding Agreement (the "Agreement") is entered into by and between MarketFragments and any person or subscriber who obtains a copy of the software code associated with this Agreement Triangle Patterns.
# 1. Ownership:
# a. The Author retains all intellectual property rights to the Code.
# b. User acknowledges and agrees that no ownership rights are transferred under this Agreement.
# 2. Usage:
# a. User is granted a non-exclusive, non-transferable license to use the Code for [specified purpose].
# b. User shall not distribute, sublicense, or make the Code publicly available without the explicit written consent of the Author.
# c. User shall not modify, reverse engineer, decompile, or disassemble the Code.
# 3. Sharing:
# a. Public Sharing: User shall not publicly share the Code without the prior written permission of the Author.
# b. Permission: User may share the Code with others only if the Author provides explicit written permission for such sharing.
# 4. Confidentiality:
# a. User shall treat the Code as confidential and take reasonable measures to prevent unauthorized disclosure.
# 5. No Warranty:
# a. The Code is provided "as is" without warranty of any kind, expressed or implied.
# b. The Author shall not be liable for any damages arising out of the use or inability to use the Code.
# 6. Termination:
# a. The Author may terminate this Agreement if User breaches any of its terms.
# b. Upon termination, User shall cease all use and distribution of the Code.
# 7. Governing Law:
# This Agreement shall be governed by and construed in accordance with the laws of [Jurisdiction].
# By using, copying, or distributing the Code, User agrees to be bound by the terms of this Agreement. If User does not agree to these terms, User should not use, copy, or distribute the Code.
# User input to select the ALMA type
input ALMA_Type = {"Standard", "Multi-Stage", "Non-Linear", "Trend-Filtered",
"Asymmetric", "Dynamic Sigma", "Adaptive Gaussian", "Momentum-Based",default "Gaussian Fold"};
# Base parameters for ALMA
input Data = close;
input Window = 9;
input Sigma = 6;
input Offset = 0.618;
input betaAdjustment = 0;
# Define ALMA Variants
script ALMA_GaussianFold {
input Data = close;
input Window = 20; # Window for ALMA
input Sigma = 10; # Similar to betaDev
input Offset = 0.85;
input betaAdjustment = 0;
# Mobius Gaussian parameters
def bd = CompoundValue(1,
if bd[1] + betaAdjustment < 2
then 2
else bd[1] + betaAdjustment,
Sigma);
def w = (2 * Double.Pi / Window);
def beta = (1 - Cos(w)) / (Power(1.414, 2.0 / bd) - 1);
def alpha = (-beta + Sqrt(beta * beta + 2 * beta));
# Offset and weighting calculations
def m = Offset * (Window - 1);
# Fold-based calculation with Gaussian math
def SumVectorData = fold y = 0 to Window with WS do
WS + Power(alpha, 4) * Exp(-Sqr(y - m) / (2 * Sqr(Window / Sigma))) * GetValue(Data, Window - 1 - y);
def SumVector = fold z = 0 to Window with CW do
CW + Power(alpha, 4) * Exp(-Sqr(z - m) / (2 * Sqr(Window / Sigma)));
plot ALMA = SumVectorData / SumVector;
}
# Standard ALMA
script ALMA_Standard {
input Data = close;
input Window = 9;
input Sigma = 6;
input Offset = 0.85;
def m = Offset * (Window - 1);
def s = Window / Sigma;
def ExpDenominator = 2 * Sqr(s);
def SumVectorData = fold y = 0 to Window with WS do WS + Exp(-Sqr(y - m) / ExpDenominator) * GetValue(Data, Window - 1 - y);
def SumVector = fold z = 0 to Window with CW do CW + Exp(-Sqr(z - m) / ExpDenominator);
plot ALMA = SumVectorData / SumVector;
}
# Multi-Stage ALMA
script ALMA_MultiStage {
input Data = close;
input Window = 9;
input Sigma = 6;
input Offset = 0.85;
def m = Offset * (Window - 1);
def s = Window / Sigma;
def ExpDenominator = 2 * Sqr(s);
def SumVectorData = fold y = 0 to Window with WS do WS + Exp(-Sqr(y - m) / ExpDenominator) * GetValue(Data, Window - 1 - y);
def SumVector = fold z = 0 to Window with CW do CW + Exp(-Sqr(z - m) / ExpDenominator);
def Stage1 = SumVectorData / SumVector;
def s2 = Window / (Sigma + 1);
def ExpDenominator2 = 2 * Sqr(s2);
def SumVectorData2 = fold y2 = 0 to Window with WS2 do WS2 + Exp(-Sqr(y2 - m) / ExpDenominator2) * GetValue(Stage1, Window - 1 - y2);
def SumVector2 = fold z2 = 0 to Window with CW2 do CW2 + Exp(-Sqr(z2 - m) / ExpDenominator2);
plot ALMA = SumVectorData2 / SumVector2;
}
# Non-Linear ALMA
script ALMA_NonLinear {
input Data = close;
input Window = 9;
input Sigma = 6;
input Offset = 0.85;
def nonLinearFactor = Power(AbsValue(close - GetValue(close, 1)), 0.5);
def m = Offset * (Window - 1);
def s = Window / Sigma;
def ExpDenominator = 2 * Sqr(s);
def SumVectorData = fold y = 0 to Window with WS do WS + nonLinearFactor * Exp(-Sqr(y - m) / ExpDenominator) * GetValue(Data, Window - 1 - y);
def SumVector = fold z = 0 to Window with CW do CW + nonLinearFactor * Exp(-Sqr(z - m) / ExpDenominator);
plot ALMA = SumVectorData / SumVector;
}
# Trend-Filtered ALMA
script ALMA_TrendFiltered {
input Data = close;
input Window = 9;
input Sigma = 6;
input Offset = 0.85;
def SMA_LongTerm = Average(Data, Window * 3);
def SlopeThreshold = 0.01;
def m = Offset * (Window - 1);
def s = Window / Sigma;
def ExpDenominator = 2 * Sqr(s);
def SumVectorData = fold y = 0 to Window with WS do WS + Exp(-Sqr(y - m) / ExpDenominator) * GetValue(Data, Window - 1 - y);
def SumVector = fold z = 0 to Window with CW do CW + Exp(-Sqr(z - m) / ExpDenominator);
def ALMA_Stage1 = SumVectorData / SumVector;
def Slope = ALMA_Stage1 - ALMA_Stage1[1];
def TrendConfirmed = close > SMA_LongTerm and AbsValue(Slope) > SlopeThreshold;
plot ALMA = if TrendConfirmed then ALMA_Stage1 else Double.NaN;
}
# Asymmetric ALMA
script ALMA_Asymmetric {
input Data = close;
input Window = 11;
input Sigma = 7;
input Offset = 0.8;
def m = Offset * (Window - 1);
def s_left = Window / (Sigma + 1.5);
def s_right = Window / (Sigma + 0.9);
def ExpDenominator = fold y1 = 0 to Window with ED do ED + if y1 < m then 2 * Sqr(s_left) else 2 * Sqr(s_right);
def SumVectorData = fold y = 0 to Window with WS do WS + Exp(-Sqr(y - m) / ExpDenominator) * GetValue(Data, Window - 1 - y);
def SumVector = fold z = 0 to Window with CW do CW + Exp(-Sqr(z - m) / ExpDenominator);
plot ALMA = SumVectorData / SumVector;
}
# Adaptive Gaussian ALMA
script ALMA_AdaptiveGaussian {
input Data = close;
input Window = 9;
input Sigma = 6;
input Offset = 0.85;
def m = Offset * (Window - 1);
def s = Window / Sigma;
def ExpDenominator = 2 * Sqr(s);
def threshold = 0.01;
def SumVectorData = fold y = 0 to Window with WS do
if Exp(-Sqr(y - m) / ExpDenominator) < threshold then WS
else WS + Exp(-Sqr(y - m) / ExpDenominator) * GetValue(Data, Window - 1 - y);
def SumVector = fold z = 0 to Window with CW do
if Exp(-Sqr(z - m) / ExpDenominator) < threshold then CW
else CW + Exp(-Sqr(z - m) / ExpDenominator);
plot ALMA = SumVectorData / SumVector;
}
# Momentum-Based ALMA
script ALMA_MomentumBased {
input Data = close;
input Window = 9;
input Sigma = 6;
input Offset = 0.85;
def momentum = (close - GetValue(close, 10)) / GetValue(close, 10);
def dynamicOffset = Offset + (momentum * 0.5);
def m = dynamicOffset * (Window - 1);
def s = Window / Sigma;
def ExpDenominator = 2 * Sqr(s);
def SumVectorData = fold y = 0 to Window with WS do WS + Exp(-Sqr(y - m) / ExpDenominator) * GetValue(Data, Window - 1 - y);
def SumVector = fold z = 0 to Window with CW do CW + Exp(-Sqr(z - m) / ExpDenominator);
plot ALMA = SumVectorData / SumVector;
}
# Dynamic Sigma ALMA
script ALMA_DynamicSigma {
input Data = close;
input Window = 9;
input Sigma = 6;
input Offset = 0.85;
def dynamicSigma = if AbsValue(Data - Data[1]) > Average(TrueRange(high, low, close), Window)
then Sigma / 2
else Sigma;
def m = Offset * (Window - 1);
def s = Window / dynamicSigma;
def ExpDenominator = 2 * Sqr(s);
def SumVectorData = fold y = 0 to Window with WS do WS + Exp(-Sqr(y - m) / ExpDenominator) * GetValue(Data, Window - 1 - y);
def SumVector = fold z = 0 to Window with CW do CW + Exp(-Sqr(z - m) / ExpDenominator);
plot ALMA = SumVectorData / SumVector;
}
# Plot the selected ALMA
plot SelectedALMA;
switch (ALMA_Type) {
case "Standard":
SelectedALMA = ALMA_Standard(Data, Window, Sigma, Offset);
case "Multi-Stage":
SelectedALMA = ALMA_MultiStage(Data, Window, Sigma, Offset);
case "Non-Linear":
SelectedALMA = ALMA_NonLinear(Data, Window, Sigma, Offset);
case "Trend-Filtered":
SelectedALMA = ALMA_TrendFiltered(Data, Window, Sigma, Offset);
case "Asymmetric":
SelectedALMA = ALMA_Asymmetric(Data, Window, Sigma, Offset);
case "Dynamic Sigma":
SelectedALMA = ALMA_DynamicSigma(Data, Window, Sigma, Offset);
case "Adaptive Gaussian":
SelectedALMA = ALMA_AdaptiveGaussian(Data, Window, Sigma, Offset);
case "Momentum-Based":
SelectedALMA = ALMA_MomentumBased(Data, Window, Sigma, Offset);
case "Gaussian Fold":
SelectedALMA = ALMA_GaussianFold(Data, Window, Sigma, Offset, betaAdjustment);
}
SelectedALMA.assignValueColor(
if SelectedALMA>SelectedALMA[1] then color.green else
color.red);
SelectedALMA.SetLineWeight(3);

