InteliTrend StableFX
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// Originally developed for MT4 by Mario Jemic. https://mario-jemic.com/ (If you are still using Windows 95 that is the version for you!)
// Recoded for the 21st century by d1g1talshad0w

//@version=5
indicator("InteliTrend StableFX", overlay = false)

// ≡≡≡≡≡≡≡≡ INPUTS & SETTINGS ≡≡≡≡≡≡≡≡

int cci_len = input.int(34, "CCI Length", group = "Commodity Channel Index")
cci_src = input(hlc3, "CCI Source", group = "Commodity Channel Index")

// weighting and smoothing
float c1 = input.float(0.5, title = "c1", group = "Weights & Smoothing")
float c2 = input.float(0.5, title = "c2", group = "Weights & Smoothing")
float c3 = input.float(0.5, title = "c3", group = "Weights & Smoothing")
int   p  = input.int(6, title = "Smoothing 'p'", group = "Weights & Smoothing")

// moving averages
int ma_len = input(61, title = "MA Length", group = "Moving Averages")

string ma_type = input.string("SMA"
  , title   = "MA Type"
  , options = ["SMA", "SMMA", "EMA", "HMA", "LVMA", "Alma"]
  , group   = "Moving Averages")

int lvma_wt = input.int(6
  , title   = "LVMA Weight"
  , group   = "Moving Averages"
  , tooltip = "Only used if LVMA is selected")

float alma_os = input.float(0.86
  , title   = "Alma Offset"
  , maxval  = 1
  , minval  = 0
  , group   = "Moving Averages"
  , tooltip = "Only used if Alma is selected. Lower is smoother, higher is more responsive.")

int alma_sig = input.int(6
  , title   = "Alma Sigma"
  , group   = "Moving Averages"
  , tooltip = "Only used if Alma is selected. Higher is smoother, lower is more responsive.")

// visual settings
color sfx_css = input.color(defval = color.new(color.orange, 0)
  , title  = "StableFX"
  , group  = "Visuals"
  , inline = "color")

color ma_css = input.color(defval = color.new(color.red, 0)
  , title  = "Moving Average"
  , group  = "Visuals"
  , inline = "color")


// ≡≡≡≡≡≡≡≡ FUNCTIONS ≡≡≡≡≡≡≡≡

// calculate linear weighted moving average
get_lwma(src, period, weight) =>
    price = src
    sub = weight / period - 1
    float per = na
    float wt = na
    float sum = 0
    float divider = 0
    for i = 0 to period - 1 by 1
        per := price[i] * (weight - i - sub)
        wt := weight - i - sub
        sum += per
        divider += wt
        divider
    sum / divider

// select moving average type
select_ma(src, len, ma_type) =>
    switch ma_type
        "SMA"  => ta.sma(src, len)
        "SMMA" => ta.rma(src, len)
        "EMA"  => ta.ema(src, len)
        "HMA"  => ta.hma(src, len)
        "LVMA" => get_lwma(src, len, lvma_wt)
        "Alma" => ta.alma(src, len, alma_os, alma_sig)


// ≡≡≡≡≡≡≡≡ CALCULATIONS ≡≡≡≡≡≡≡≡

// calculate commodity channel index
float cci_val = ta.cci(cci_src, cci_len)

// apply weights to the CCI and store to an array
wts = array.new_float(0, p)
for i = 0 to p - 1
    a = cci_val[i] * c1 + cci_val[i] * c2 - cci_val[i] * c3 + cci_val[i] * c2 - cci_val[i] * c3 + cci_val[i] * c2 - cci_val[i] * c3 + cci_val[i] * c2 - cci_val[i] * c3 + cci_val[i] * c2 - cci_val[i] * c3
    array.push(wts, a)

// sum the max and min values in the array
cci_wt = array.max(wts) + array.min(wts)

// calculate the moving average
ma = select_ma(cci_wt, ma_len, ma_type)

plot(cci_wt, title = "StableFX", color = sfx_css, editable = false)
plot(ma, title = "Moving Average", color = ma_css, editable = false)




