
Author Message:
This indicator combines a traditional Keltner Channel overlay with an oscillator, providing a comprehensive view of price action, trend, and momentum. The core of this indicator is its advanced ATR calculation, which uses statistical methods to provide a more robust measure of volatility.
Upper Study :
CSS:
#// Indicator For TOS
#// © MyTradingCoder
#indicator("Advanced Keltner Channel/Oscillator [MyTradingCoder]")
# Converted by Sam4Cok@Samer800 - 0/2024
input source = close; #, "Source", group = filter_group)
input length = 20; #, "Length", step = 0.5, minval = 2, group = filter_group)
input Q = 0.50;#, "Q", step = 0.125, minval = 0.125, group = filter_group)
input Multiplier = 2.0; #, "Multiplier", minval = 0, step = 0.25, group = atr_group)
input atrPeriod = 50; #, "Length", minval = 1, group = atr_group)
input atr_smoothing = yes; #(true, "Smoothing", group = atr_group) ? 2 : 1
def na = Double.NaN;
#-- Color
DefineGlobalColor("up", CreateColor(8, 153, 129));
DefineGlobalColor("dn", CreateColor(242, 54, 69));
#// filter {
script biquad_lpf {
input source = close;
input length = 10;
input Q = 0.5;
def na = Double.NaN;
def pi = Double.Pi;
def isfirst = BarNumber() <= 1;
def fc = Min(0.5, 1 / length);
def omega = 2 * pi * fc;
def cos_omega = Cos(omega);
def alpha = Sin(omega) / (2 * Q);
def a0 = 1 / (1 + alpha);
def b = 1 - cos_omega;
def a1;
def a2;
def b0;
def b1;
def b2;
if isfirst {
a1 = -2 * cos_omega * a0;
a2 = (1 - alpha) * a0;
b0 = b / 2 * a0;
b1 = b * a0;
b2 = b0;
} else {
a1 = if !a1[1] then na else a1[1];
a2 = if !a2[1] then na else a2[1];
b0 = if !b0[1] then na else b0[1];
b1 = if !b1[1] then na else b1[1];
b2 = if !b2[1] then na else b2[1];
}
def biquad;
def prQuad = CompoundValue(1, if !biquad[1] then source else biquad[1], source);
def x = if source then source else x[1];
def x1 = CompoundValue(1, if source[1] then source[1] else x, source);
def x2 = CompoundValue(1, if source[2] then source[2] else x1, x1);
def y1 = CompoundValue(1, if prQuad then prQuad else x, x);
def y2 = CompoundValue(1, if prQuad[1] then prQuad[1] else y1, y1);
biquad = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
plot out = if isfirst then source else biquad;
}
script advanced_atr {
input period = 50;
def tr = high - low;
def sumTr = Sum(Sqr(tr), period);
def rms = Sqrt(sumTr / Max(1, period -1));
def z = tr / rms;
def clamped_z = Min(z, 10);
def rounded_z = Round(clamped_z, 2);
def zidx = Floor(rounded_z * 100);
def z_idx = if isNaN(zidx) then 0 else zidx;
def lookback = 1001;
def rang_observations = if z_idx != 0 then z_idx else rang_observations[1];
def mode = (if period<=1 then 100 else 56) / 100 * rms;
def average = Average(rang_observations + 1, lookback) / 100 * rms;
plot avg = average;
plot mod = mode;
}
script smoothing {
input source = close;
input smoothing = yes;
def length = if smoothing then 2 else 1;
def wma = WMA(source, length);
def smooth = Average(wma, length);
plot out = smooth;
}
script normal_delta_scale {
input source = close;
input atr = 1;
input degree = 2;
def pi = Double.Pi;
def delta = (source - source[degree]) / atr;
def todegrees = ATan(delta) * 180 / pi;
def color_scale = (todegrees + 90) / 180;
plot out = color_scale;
}
def average = advanced_atr(atrPeriod).avg;
def mode = advanced_atr(atrPeriod).mod;
def biquad = biquad_lpf(source, length, Q);
def midline = smoothing(mode * Multiplier, atr_smoothing);
def maxline = smoothing(average * Multiplier, atr_smoothing);
def top_midline = biquad + midline;
def top_maxline = biquad + maxline;
def bottom_midline = biquad - midline;
def bottom_maxline = biquad - maxline;
def color_scale = normal_delta_scale(biquad, mode);
def delta_color = if IsNaN(color_scale) then 0 else
if color_scale > 1 then 255 else
if color_scale < 0 then 0 else color_scale * 255;
def top_mid_line = if top_midline then top_midline else na;
def bottom_mid_line = if bottom_midline then bottom_midline else na;
plot centerLine = if biquad then biquad else na;
plot top_max_line = if top_maxline then top_maxline else na;
plot bot_max_line = if bottom_maxline then bottom_maxline else na;
centerLine.SetLineWeight(2);
centerLine.AssignValueColor(CreateColor(255 - delta_color, delta_color, 72));
top_max_line.SetDefaultColor(GlobalColor("dn"));
bot_max_line.SetDefaultColor(GlobalColor("up"));
AddCloud(top_max_line, top_mid_line, Color.DARK_RED, Color.DARK_RED, yes);
AddCloud(bottom_mid_line, bot_max_line, Color.DARK_GREEN, Color.DARK_GREEN, yes);
#-- END of CODE
Lower Study:
CSS:
#// Indicator for TOS
#// © MyTradingCoder
#indicator("Advanced Keltner Channel/Oscillator [MyTradingCoder]")
# Converted by Sam4Cok@Samer800 - 08/2024
Declare lower;
input osc_source = close; #, "Source", group = osc_settings)
input SourceSmoothing = 3.0; #, "Source Smoothing", step = 0.5, minval = 0, group = osc_settings) + 1
input signalLinePeriod = 9; #, "Signal Period", minval = 1, group = osc_settings)
input NormalizeOscillator = yes; #(true, "Normalize Oscillator", group = osc_settings)
input source = close; #, "Source", group = filter_group)
input length = 20; #, "Length", step = 0.5, minval = 2, group = filter_group)
input Q = 0.50;#, "Q", step = 0.125, minval = 0.125, group = filter_group)
input Multiplier = 2.0; #, "Multiplier", minval = 0, step = 0.25, group = atr_group)
input atrPeriod = 50; #, "Length", minval = 1, group = atr_group)
input atr_smoothing = yes; #(true, "Smoothing", group = atr_group) ? 2 : 1
def na = Double.NaN;
def last = isNaN(close);
def osc_length = SourceSmoothing + 1;
#-- Color
DefineGlobalColor("up", CreateColor(8,153,129));
DefineGlobalColor("dn", CreateColor(242,54,69));
#// osc {
Script make_osc {
input source = close;
input min = low;
input max = high;
input center = hl2;
input normalize = yes;
def norm = -100 + (source - min) * 200 / (max - min);
def make_osc = if normalize then norm else source - center;
plot out = make_osc;
}
#// filter {
#// filter {
script biquad_lpf {
input source = close;
input length = 10;
input Q = 0.5;
def na = Double.NaN;
def pi = Double.Pi;
def isfirst = BarNumber() <= 1;
def fc = Min(0.5, 1 / length);
def omega = 2 * pi * fc;
def cos_omega = Cos(omega);
def alpha = Sin(omega) / (2 * Q);
def a0 = 1 / (1 + alpha);
def b = 1 - cos_omega;
def a1;
def a2;
def b0;
def b1;
def b2;
if isfirst {
a1 = -2 * cos_omega * a0;
a2 = (1 - alpha) * a0;
b0 = b / 2 * a0;
b1 = b * a0;
b2 = b0;
} else {
a1 = if !a1[1] then na else a1[1];
a2 = if !a2[1] then na else a2[1];
b0 = if !b0[1] then na else b0[1];
b1 = if !b1[1] then na else b1[1];
b2 = if !b2[1] then na else b2[1];
}
def biquad;
def prQuad = CompoundValue(1, if !biquad[1] then source else biquad[1], source);
def x = if source then source else x[1];
def x1 = CompoundValue(1, if source[1] then source[1] else x, source);
def x2 = CompoundValue(1, if source[2] then source[2] else x1, x1);
def y1 = CompoundValue(1, if prQuad then prQuad else x, x);
def y2 = CompoundValue(1, if prQuad[1] then prQuad[1] else y1, y1);
biquad = b0 * x + b1 * x1 + b2 * x2 - a1 * y1 - a2 * y2;
plot out = if isfirst then source else biquad;
}
Script ema {
input source = close;
input length = 9;
def bar = BarNumber();
def prefilter = if bar < 2 then source else Average(source, 2);
def alpha = 2 / (length + 1);
def smoothed = CompoundValue(1, alpha * prefilter + (1 - alpha) * smoothed[1],alpha * prefilter);
plot ema = if length > 1 then smoothed else source;
}
script advanced_atr {
input period = 50;
def tr = high - low;
def sumTr = Sum(Sqr(tr), period);
def rms = Sqrt(sumTr / Max(1, period -1));
def z = tr / rms;
def clamped_z = Min(z, 10);
def rounded_z = Round(clamped_z, 2);
def zidx = Floor(rounded_z * 100);
def z_idx = if isNaN(zidx) then 0 else zidx;
def lookback = 1001;
def rang_observations = if z_idx != 0 then z_idx else rang_observations[1];
def mode = (if period<=1 then 100 else 56) / 100 * rms;
def average = Average(rang_observations + 1, lookback) / 100 * rms;
plot avg = average;
plot mod = mode;
}
Script smoothing {
input source = close;
input smoothing = yes;
def length = if smoothing then 2 else 1;
def wma = wma(source, length);
def smooth = Average(wma, length);
plot out = smooth;
}
Script normal_delta_scale {
input source = close;
input atr = 1;
input degree = 2;
def pi = Double.Pi;
def delta = (source - source[degree]) / atr;
def todegrees = atan(delta) * 180 / pi;
def color_scale = (todegrees + 90) / 180;
plot out = color_scale;
}
def average = advanced_atr(atrPeriod).avg;
def mode = advanced_atr(atrPeriod).mod;
def biquad = biquad_lpf(source, length, Q);
def midline = smoothing(mode * Multiplier, atr_smoothing);
def maxline = smoothing(average * Multiplier, atr_smoothing);
def top_midline = biquad + midline;
def top_maxline = biquad + maxline;
def bottom_midline = biquad - midline;
def bottom_maxline = biquad - maxline;
def color_scale = normal_delta_scale(biquad, mode);
def delta_color = if isNaN(color_scale) then 0 else
if color_scale>1 then 255 else
if color_scale<0 then 0 else color_scale * 255;
#// osc {
def osc_midline_top = make_osc(top_midline, bottom_maxline, top_maxline, biquad, NormalizeOscillator);
def osc_midline_bottom = make_osc(bottom_midline, bottom_maxline, top_maxline, biquad, NormalizeOscillator);
def osc_max_top = make_osc(top_maxline, bottom_maxline, top_maxline, biquad, no);
def osc_max_bot = make_osc(bottom_maxline, bottom_maxline, top_maxline, biquad, no);
def osc_maxline_top = if last then na else if NormalizeOscillator then 100 else osc_max_top;
def osc_maxline_bottom = if last then na else if NormalizeOscillator then -100 else osc_max_bot;
def osc_normal = make_osc(osc_source, bottom_maxline, top_maxline, biquad, NormalizeOscillator);
def osc_line = ema(osc_normal, osc_length);
def osc_signal = ema(osc_line, signalLinePeriod);
def top_mid_line_osc = if osc_midline_top then osc_midline_top else na;
def bottom_mid_line_osc = if osc_midline_bottom then osc_midline_bottom else na;
plot Oscillator = if osc_line then osc_line else na;
plot Signal = if osc_signal then osc_signal else na;
plot top_max_line_osc = if osc_maxline_top then osc_maxline_top else na;
plot bottom_max_line_osc = if osc_maxline_bottom then osc_maxline_bottom else na;
plot zero = if last then na else 0;
Oscillator.SetDefaultColor(Color.CYAN);
Signal.SetDefaultColor(GetColor(8));
zero.AssignValueColor(CreateColor(255 - delta_color, delta_color, 72));
top_max_line_osc.SetDefaultColor(GlobalColor("dn"));
bottom_max_line_osc.SetDefaultColor(GlobalColor("up"));
AddCloud(top_max_line_osc, top_mid_line_osc, Color.DARK_RED, Color.DARK_RED, yes);
AddCloud(bottom_mid_line_osc, bottom_max_line_osc, Color.DARK_GREEN, Color.DARK_GREEN, yes);
#-- END of CODE