#// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
#// © QuantraSystems
#indicator("Cosine Kernel Regressions [QuantraSystems]", "CKR [QuantraSystems]" , overlay = false, max_labels_count = 500)
# Converted by Sam4Cok@Samer800 - 06/2024
declare lower;
#// Indicator Calibrations
input ColorType = {"None", default "Fast Trend", "Slow Trend"}; # "Choose Mode"
input CosineKernelRegressionType = {default "Tuneable", "Stepped"}; # "Cosine Kernel Regression Type"
input Source = close; # "Source"
input RegressionLookback = 60; # "Regression Lookback"
input TuningCoefficient = 15.0; # "Tuning Coefficient"
input useStoch = yes; # "STOCH"
input StochasticLength = 14; # "Stochastic Length"
input useRsi = yes; # "RSI"
input rsiLength = 14; # "RSI Length"
input useBollinger = yes; # "BBPCT"
input bbLength = 20; # "BBPCT Length"
input useCmo = yes; # "CMO"
input ChandeMomentumLength = 14; # "Chande Momentum Length"
input useCci = yes; # "CCI"
input cciLength = 20; # "CCI Length"
input useFisher = yes; # "FISH"
input FisherTransformLength = 9; # "Fisher Transform Length"
input useVzo = yes; # "VZO"
input vzoLength = 21; # "VZO Length"
def na = Double.NaN;
def last = IsNaN(close);
def tune = CosineKernelRegressionType == CosineKernelRegressionType."Tuneable";
#// Define a kernel that utilizes the cosine function
#// Kernel Regression //
script kernelRegression {
input src = close;
input lookback = 60;
input tuning = 15;
# def bar_index = BarNumber();
def pi = Double.Pi;
def toFold = lookback - 1; #Min(lookback, bar_index);
def currentWeight = fold i = 0 to toFold with p do
p + GetValue(src, i) * (if AbsValue(i / lookback) <= pi / (2 * tuning) then AbsValue(Cos((i / lookback) * tuning)) else 0);
def totalWeight = fold j = 0 to toFold with q do
q + (if AbsValue(j / lookback) <= pi / (2 * tuning) then AbsValue(Cos((j / lookback) * tuning)) else 0);
def kernelRegression = currentWeight / totalWeight;
plot out = if !IsNaN(close) and !isNaN(kernelRegression) then kernelRegression else Double.NaN;
}
#// Multi Cosine
script multicosine {
input src = close;
input lookback = 60;
input steps = 15;
def pi = Double.Pi;
def toFold = lookback - 1;
def regression = fold k = 1 to steps-1 with r do
r + ((fold i = 0 to toFold with p do
p + (if AbsValue(i / lookback) <= pi / (2 * k) then AbsValue(Cos((i / lookback) * k)) else 0) * src[i]) /
(fold j = 0 to toFold with q do
q + (if AbsValue(j / lookback) <= pi / (2 * k) then AbsValue(Cos((j / lookback) * k)) else 0)));
def multicosine = regression / steps;
plot out = if !IsNaN(close) and !isNaN(multicosine) then multicosine else Double.NaN;
}
script ALMA {
input src = close;
input len = 9;
input offset = 0;
input sigma = 6;
def m = Floor(offset * (len - 1));
def s = len / sigma;
def alm = fold i = 0 to len with p do
if !IsNaN(src[i]) then p + src[i] * Exp(-1 * Power(i - m, 2) / (2 * Power(s, 2))) else p;
def norm = fold j = 0 to len with q do
if !IsNaN(src[j]) then q + Exp(-1 * Power(j - m, 2) / (2 * Power(s, 2))) else q;
def ALMA = if norm > 0 then alm / norm else Double.NaN;
plot out = if !IsNaN(close) and !isNaN(ALMA) then ALMA else Double.NaN;
}
#// ║ RELATIVE STRENGTH INDEX ║ //
script DynamicRSI {
input src = close;
input length = 14;
def nRSI = RSI(Price = src, Length = length);
def RSI_ReScale = (nRSI - 50) * 2.8;
plot out = RSI_ReScale;
}
#/ ║ STOCHASTIC OSCILLATOR ║ //
script DynamicSTOCH {
input source = close;
input hi = high;
input lo = low;
input length = 14;
def lowestLow = Lowest(lo, length);
def highestHigh = Highest(hi, length);
def stochastic = 100 * (source - lowestLow) / (highestHigh - lowestLow);
def STOCH_ReScale = (stochastic - 50) * 2;
plot out = STOCH_ReScale;
}
#// ║ BOLLINGER BAND PERCENT ║ //
script DynamicBBPCT {
input src = close;
input length = 20;
input multi = 1;
def basis = Average(src, length);
def dev = multi * StDev(src, length);
def upper = basis + dev;
def lower = basis - dev;
def bbpct = (src - lower) / (upper - lower);
def BBPCT_ReScale = (bbpct - 0.5) * 120;
plot out = BBPCT_ReScale;
}
#// ║ CHANDE MOMENTUM ║ //
script DynamicCMO {
input src = close;
input length = 20;
def momm = (src - src[1]);
def m1 = if momm >= 0 then momm else 0.0;
def m2 = if momm < 0 then -momm else 0.0;
def sm1 = Sum(m1, length);
def sm2 = Sum(m2, length);
def div = sm1 + sm2;
def chandeMO = if div != 0 then 100 * (sm1 - sm2) / div else 0;
def CMO_ReScale = (chandeMO * 1.15);
plot out = CMO_ReScale;
}
#// ║ COMMODITY CHANNEL INDEX ║ //
script DynamicCCI {
input src = close;
input len = 20;
def ma = Average(src, len);
def Dev = LinDev(src, len);
def cci = (src - ma) / (0.015 * Dev);
def CCI_ReScale = if Dev == 0 then 0 else (cci / 2);
plot out = CCI_ReScale;
}
#// ║ FISHER TRANSFORM ║ //
script DynamicFisher {
input len = 10;
def fish = FisherTransform(Length = len);
def FISH_ReScale = (fish * 30);
plot out = FISH_ReScale;
}
#// ║ VOLUME ZONE OSCILLATOR ║ //
script DynamicVZO {
input length = 14;
def mom = hlc3 - hlc3[1];
def sig = Sign(mom);
def VP = ExpAverage(sig * volume, length / 3);
def TV = ExpAverage(volume, length / 3);
def VZO_ReScale = (VP / TV) * 110;
plot out = VZO_ReScale;
}
#//║ CORE CALCULATIONS
#// Function to count active indicators
script countCondition {
input condition = close;
def count = if !IsNaN(condition) then 1 else 0;
plot out = count;
}
script nz {
input val = close;
def count = if !IsNaN(val) then val else 0;
plot out = count;
}
def f_rsi = DynamicRSI(Source, rsiLength);
def f_sto = DynamicSTOCH(Source, high, low, StochasticLength);
def f_bbc = DynamicBBPCT(Source, bbLength, 2);
def f_cmo = DynamicCMO(Source, ChandeMomentumLength);
def f_cci = DynamicCCI(Source, cciLength);
def f_fis = DynamicFisher(FisherTransformLength);
def f_vzo = DynamicVZO(vzoLength);
#// Pull all standardized base indicator values
def val_RSI = if useRsi then f_rsi else na;
def val_STOCH = if useStoch then f_sto else na;
def val_BBPCT = if useBollinger then f_bbc else na;
def val_CMO = if useCmo then f_cmo else na;
def val_CCI = if useCci then f_cci else na;
def val_FISH = if useFisher then f_fis else na;
def val_VZO = if useVzo then f_vzo else na;
#// Count the number of active indicators
def activeIndicators =
countCondition(useRsi ) +
countCondition(useStoch) +
countCondition(useBollinger) +
countCondition(useCmo ) +
countCondition(useCci ) +
countCondition(useFisher ) +
countCondition(useVzo );
#// Calculate the average only with active indicators
def value1 = if activeIndicators > 0 then (
nz(val_RSI) +
nz(val_STOCH) +
nz(val_BBPCT) +
nz(val_CMO) +
nz(val_CCI) +
nz(val_FISH) +
nz(val_VZO)) / activeIndicators else na;
#// Gentle ALMA smoothing
def value = ALMA(value1, 9, 0, 6);
#// Calulate the Output - Depending on the method of Cosine Regression Selected
def rLen = Round(TuningCoefficient / 5, 0);
def kernelReg1 = kernelRegression(value, RegressionLookback, TuningCoefficient);
def multCosin1 = multicosine(value, RegressionLookback, TuningCoefficient);
def kernelReg2 = kernelRegression(value, RegressionLookback, rLen);
def multCosin2 = multicosine(value, RegressionLookback, rLen);
def out1 = if tune then kernelReg1 else multCosin1;
def out2 = if tune then kernelReg2 else multCosin2;
#// Define Alert Conditions
def fastTrend_up = out1 > out1[1] and !(out1[1] > out1[2]);
def fastTrend_dn = out1 < out1[1] and !(out1[1] < out1[2]);
#//║ VISUALIZATION ║//
def col;
switch (ColorType) {
case "None" :
col = 0;
case "Slow Trend" :
col = if out2 > 0 then 1 else -1;
default :
col = if out1 > out1[1] then 1 else -1;
}
def col1 = if !col then if out1 > out1[1] then 1 else -1 else col;
def col2 = if out2 > 0 then 1 else 0;
#-- plots
plot shapeDn = if fastTrend_dn then out1 else na;
plot shapeUp = if fastTrend_up then out1 else na;
plot sig = out1; #, "Fast Signal"
plot sig2 = out2;
shapeDn.SetLineWeight(3);
shapeUp.SetLineWeight(3);
shapeDn.SetPaintingStrategy(PaintingStrategy.SQUARES);
shapeUp.SetPaintingStrategy(PaintingStrategy.SQUARES);
shapeDn.SetDefaultColor(Color.RED);
shapeUp.SetDefaultColor(Color.GREEN);
sig.SetLineWeight(2);
sig.AssignValueColor(if col1>0 then Color.CYAN else if col1<0 then Color.MAGENTA else Color.LIGHT_GRAY);
sig2.AssignValueColor(if col2 then Color.DARK_GREEN else Color.DARK_RED);
AssignPriceColor(if !col then Color.CURRENT else if col>0 then Color.CYAN else Color.MAGENTA);
AddCloud(sig2, 0, Color.DARK_GREEN, Color.DARK_RED);
AddCloud(if last then na else 100, 50, Color.PLUM);
AddCloud(if last then na else 100, 75, Color.PLUM);
AddCloud(if last then na else -50, -100, CreateColor(0, 118, 118));
AddCloud(if last then na else -75, -100, CreateColor(0, 118, 118));
#-- END of CODE