#// This source code is subject to the terms of the Mozilla Public License 2.0
#// © blackcat1402
#study("[blackcat] L2 Dual KDJ Indicator", overlay=false)
# Converted by Sam4Cok@Samer800 - 01/2024
declare lower;
#// inputs
input shortLength = 7;#, title="n1", type=input.integer, minval = 1)
input longLength = 17;#, title="n2", type=input.integer, minval = 1)
def na = Double.NaN;
def last = IsNaN(close);
#//functions
#xsa(src,len,wei) =>
script xsa {
input src = close;
input len = 0;
input wei = 0;
def srcLen = if isNaN(src[len]) then 0 else src[len];
def sumf = CompoundValue(1, sumf[1] - srcLen + src, 0);
def ma = if srcLen then sumf / len else 0;
def out = if out[1]==0 then ma else (src * wei + out[1] * (len - wei)) / len;
plot return = if isNaN(out) then Double.NaN else out;
}
#xbt(a, b, c) =>
Script xbt {
input a = close;
input b = 20;
input c = 60;
def out = if (a[1] >= b and a[1] <= c or a[1] >= c and a[1] <= b) then 1 else 0;
plot return = if isNaN(out) then 0 else out;
}
#//short term kdj
def hh1 = Highest(high, shortLength);
def ll1 = Lowest(low, shortLength);
def rsv = (close - ll1) / (hh1 - ll1) * 100;
def shortk1 = xsa(rsv, 3, 1);
def shortd1 = xsa(shortk1, 3, 1);
def shortk = shortk1;
def shortd = shortd1;
#//middle term kdj
def hh2 = Highest(high, longLength);
def ll2 = Lowest(low, longLength);
def rsv1 = (close - ll2) / (hh2 - ll2) * 100;
def midk = xsa(rsv1, 5, 1);
def midd = xsa(midk, 10, 1);
def midj = 3 * midk - 2 * midd;
def upSh= shortk>shortd;
def upMid = midk>midd;
#//plot short term KD candles
AddChart(high = if upSh then shortd else na, low = shortk , open = shortk, close = shortd,
type = ChartType.CANDLE, growcolor = Color.CYAN);
AddChart(high = if upSh then na else shortd , low = shortk , open = shortd, close = shortk,
type = ChartType.CANDLE, growcolor = Color.MAGENTA);
#//plot middle term KD candles
AddChart(high = if upMid then midd else na, low = midk , open = midk, close = midd,
type = ChartType.CANDLE, growcolor = CreateColor(38,166,154));
AddChart(high = if upMid then na else midd , low = midk , open = midd, close = midk,
type = ChartType.CANDLE, growcolor = CreateColor(239,83,80));
#---
def oversold = if(midj<0 and midd <50,30,0);
def bddd = lowest(midj,2)==lowest(midj,8);
def reentry = if((midj > midj[1]+0.01) and bddd and midj<20,20,-10);
def addmore = if((midj > midj[1]+0.01) and bddd and xbt(midj,20,60),10,0);
def overbought = highest(midj,2)==highest(midj,8) and midj>80;
def sellready = if((midj < midj[1]-0.01) and overbought[1] and midd>50,90,120);
plot os = oversold;#,color=color.yellow, linewidth=1,style=plot.style_area, transp=0)
plot ent = reentry;#,color=color.orange, linewidth=1,style=plot.style_area, transp=0)
plot add = addmore;#,color=color.lime, linewidth=1,style=plot.style_area, transp=0)
plot sell = sellready;#,color=color.red, linewidth=1,style=plot.style_line, transp=0)
os.SetDefaultColor(Color.YELLOW);
ent.SetDefaultColor(Color.CYAN);
add.SetDefaultColor(Color.GREEN);
sell.SetDefaultColor(Color.RED);
AddCloud(os, 0, Color.YELLOW);
AddCloud(add, 0, Color.GREEN);
AddCloud(ent, -10, Color.CYAN);
#//Oversold and overbought threshold
plot hline10 = if last then na else 10;
plot hline50 = if last then na else 50;
plot hline90 = if last then na else 90;
hline10.SetDefaultColor(Color.GRAY);
hline50.SetDefaultColor(Color.GRAY);
hline90.SetDefaultColor(Color.GRAY);
hline10.SetStyle(Curve.SHORT_DASH);
hline50.SetStyle(Curve.SHORT_DASH);
hline90.SetStyle(Curve.SHORT_DASH);
#-- END of CODE