Help converting KDJ from pinescript to thinkscript


New member
I'd love if someone with more experience could convert this script for me, I'd even be willing to pay a bit. KDJ indicator.

study("KDJ Indicator")
// KDJ Indicator, Rev 03
// Rewrite for Tradingview "Pine Script" by Kocurekc, April 2014
// Code is provided as public domain, no warranty
lenL = input(title="Lookback Period, Long", type=integer, defval=14, minval=2)
lenS = input(title="Lookback Period, Short", type=integer, defval=5, minval=2)
bE = input(title="Use EMA?", type=bool, defval=true)
bJ = input(title="Smooth the %J?", type=bool, defval=false)
lenJ = input(title="%J Smoothing", type=integer, defval=5, minval=1)
s = stoch(close, high, low, lenL)
pK = bE ? ema(s,5) : sma(s,5)
pD = bE ? ema(pK, lenS) : sma(pK, lenS)
pJ = (3 * pD) - (2 * pK)
plot(pK, color=blue)
plot(pD, color=red)
plot(bJ ? sma(pJ,lenJ) : pJ, color=green)
Last edited:


Active member
This should do it. Muted some of the code that would just add noise and clutter up the chart. Also put the default settings at 9,3,3 to match what was on the chart you sent. 14,5,5 would be the more common stochastic settings though.

# TD Ameritrade IP Company, Inc. (c) 2008-2020
# Rewrite for Tradingview "Pine Script" by Kocurekc, April 2014
# mods for TOS by WTF_Dude

declare lower;

input KPeriod = 14;
input DPeriod = 5;
input J_smoothPeriod = 7;
input AverageType = AverageType.EXPONENTIAL;
input Smooth_J = no;
input J_Average = AverageType.SIMPLE;
input priceH = high;
input priceL = low;
input priceC = close;
input over_bought = 80;
input over_sold = 20;
#input showBreakoutSignals = {default "No", "On SlowK", "On SlowD", "On SlowK & SlowD"};

plot K = reference StochasticFull(over_bought,over_sold,KPeriod,DPeriod,priceH,priceL,priceC,3,averageType).FullK;
plot D = reference StochasticFull(over_bought,over_sold,KPeriod,DPeriod,priceH,priceL,priceC,3,averageType).FullD;
def SLOWJ = (3*k) - (2*d); 

plot J;
J = MovingAverage(J_average,SLOWJ,J_smoothperiod);
} else {

plot OverBought = over_bought;
plot OverSold = over_sold;

#plot SmoothJ = movingaverage(Averagetype, SLOWJ, 5);

def upK = K crosses above OverSold;
def upD = D crosses above OverSold;
def downK = K crosses below OverBought;
def downD = D crosses below OverBought;

#plot UpSignal;
#plot DownSignal;
#switch (showBreakoutSignals) {
#case "No":
#    UpSignal = Double.NaN;
#    DownSignal = Double.NaN;
#case "On SlowK":
#    UpSignal = if upK then OverSold else Double.NaN;
#    DownSignal = if downK then OverBought else Double.NaN;
#case "On SlowD":
#    UpSignal = if upD then OverSold else Double.NaN;
#    DownSignal = if downD then OverBought else Double.NaN;
#case "On SlowK & SlowD":
#    UpSignal = if upK or upD then OverSold else Double.NaN;
#    DownSignal = if downK or downD then OverBought else Double.NaN;

#UpSignal.setHiding(showBreakoutSignals == showBreakoutSignals."No");
#DownSignal.setHiding(showBreakoutSignals == showBreakoutSignals."No");


Last edited:


New member
You're such a swell fellow! Thanks so much, the settings i have on tradingview (where i used it) are 14 5 7. The only thing that seems to me isn't quite right is the "J" heres the discrepancy. It seems to be moving too "fast." Both of these images are on the daily time frame. I could try to mess with the values just like i did with the original but i thought i'd just update you with my findings.



It seems when i change the value for "J" it does nothing to change the indicator
Last edited by a moderator:


New member
I've been attempting to fix it myself, unfortunately, I don't think i can with my lack of knowledge on the subject... I appreciate you taking the time to help though! Out of all the KDJ scripts I used (which is about all of them) this was my favorite. I'm sure a ton of people would be able to make use of it given that, as far as i can tell, there isn't any KDJ indicator written for ToS.


Active member
Ok, so if this is the script you have been using. It's completely backwards lol The formula for J is backwards. I should be 3*K - 2*d and your script has it the other way around. So the super fast way that youre looking at with this script IS the correct one. Essentially what you're seeing is the difference between the K and D suped up on crack and stacked on top of the K. This makes not only a moving average ribbon effect, but can point in the direction of the trend change a bit faster. What you want is for the green to cross over the blue and magenta IN the overbought or oversold areas. With the exponential averages, you'll get cleaner signals but there's going to be alot more swinging. The J period is only the length of the moving average to SMOOTH out the suped up k-d difference. So if you elect not to smooth J, then adjusting the J period won't matter. The J formula is a constant otherwise. Let me know if this all makes sense. fixed the code in original post

Notice how theres an up and down J wave that seems to go opposite of where the stochastic is in the tradingview version? That's not the KDJ indicator basically unless you reverse the equation and smooth the J waaaaaaaaay down... but then you aren't getting the signals you're supposed to. It would make the indicator lag like CRAZY.

Also note on your trading view chart, there is not a SINGLE KDJ convergence lol

If you want to see the difference, replace this line in the code:

def SLOWJ = (3*k) - (2*d);

with this

def SLOWJ = (3*d) - (2*k);
Last edited:


New member
If you take a look at this post it says that there are many different ways people have gone about calculating the J value. I've found 3 ways when searching. I'll see how it looks and give you another update later. Just don't want to leave you hanging... I could always edit the formula part myself but i'm really grateful for the work you've put in to help. This was the other KDJ i used for a while, but i ended up liking the one i originally posted more, probably because of the different way of calculating J, not sure it was a while back. The one i like better was also a bit more clean looking. Now I'm pretty confident that, anyone searching for a KDJ indicator for think or swim will be able to find this post and find what they're after thanks to you! That's definitely a great find with the equation, i'll have to do some more experimenting, maybe another equation is better after all.
Last edited:


Active member
@Chaomane No problem at all! I'm still learning to code myself so this was good practice. Can you tell me how you're using the other formula with the reversed J wave? It basically makes a delayed reverse sine wave so I don't really see how you're getting your signal other than the normal KD?


Well-known member
@Chaomane This is most likely similiar to your trading view one. Thought I had seen it before and had it in my records.


declare lower;

input overBot       = 80;
input overSld       = 20;
input kPeriod       = 9;
input dPeriod       = 3;
input slowingPeriod = 3;
input averageType   = AverageType.SIMPLE;

def rsv             = StochasticFull( overBot, overSld, kPeriod, dPeriod, high, low, close, slowingPeriod, averageType ).FastK;

plot K              = MovingAverage( averageType, rsv, slowingPeriod );
plot D              = MovingAverage( averageType, K, dPeriod );
plot J              = ( 3 * D ) - ( 2 * K );

plot OverBought     = overBot;
plot OverSold       = overSld;

K.SetDefaultColor( GetColor( 1 ) );
D.SetDefaultColor( GetColor( 6 ) );
J.SetDefaultColor( GetColor( 5 ) );

OverBought.SetDefaultColor( Color.BLACK );
OverSold.SetDefaultColor( Color.BLACK );


New member
No problem at all! I'm still learning to code myself so this was good practice. Can you tell me how you're using the other formula with the reversed J wave? It basically makes a delayed reverse sine wave so I don't really see how you're getting your signal other than the normal KD?
I was mainly using it in a way that if the RSI is low and the K and D are about ready to cross up over the J, then its a good buy signal. But like I said there's 3 different ways of doing the J equation.

(3*d) - (2*k) , (3*k) - (2*d), and 3 * pK - 2 * pD;

I'll have to do some more studying and find out which is best. On the bright side, the code works exactly how i wanted it to, as far as i can tell!
For information sake, someone else took a crack at it and it seems to be working well (reddit) I posted your code at first on accident, lol... This is the code he wrote FYI @wtf_dude


declare lower;

input KPeriod = 9;
input DPeriod = 3;
input priceH = high;
input priceL = low;
input priceC = close;
input slowing_period = 3;
input averageType = AverageType.Exponential;

def lowest_k = Lowest(priceL, KPeriod);
def c1 = priceC - lowest_k;
def c2 = Highest(priceH, KPeriod) - lowest_k;
def FastK = if c2 != 0 then c1 / c2 * 100 else 0;

plot FullK = MovingAverage(averageType, FastK, slowing_period);
plot FullD = MovingAverage(averageType, FullK, DPeriod);
plot FullJ = (3 * FullD) - (2 * FullK);

Your code was the only one i was able to get to replicate what it looks like on trading view @wtf_dude nice job!
Last edited:


Well-known member
2019 Donor
interesting thanks, share your testing results and approach.

I ported this version - might want to test and compare:



#KDJ V1.0
# 2020.04.29 V1.0 @diazlaz Initial Port/interpretation
input ilong = 9;
input isig = 3;
input overBought = 80;
input overSold = 20;
input showColorBars = yes;

DefineGlobalColor("cpK", CreateColor(30, 136, 229));
DefineGlobalColor("cPD", CreateColor(255, 111, 0));
DefineGlobalColor("cPJ", Color.YELLOW);

def c = close;
def h = Highest(high, ilong);
def l = Lowest(low, ilong);

def RSV = 100 * ((c - l) / (h - l));
def pK = ( 1 * RSV + (isig - 1) * pK[1]) / isig;
def pD = (1 * pK + (isig - 1) * pD[1]) / isig;
def pJ = 3 * pK - 2 * pD;

AddLabel (1, "KDJ Indicator", COLOR.ORANGE);

plot ppK = pK;

plot ppD = pD;

plot ppJ = pJ;

plot pOverBought = overBought;
plot pOverSold = overSold;

def cR = If(pJ >= pD,Double.NaN,0);
AddCloud(data1 = 1, data2 = 100, color1 = Color.UPTICK, color2 = Color.UPTICK);
AddCloud(cR, 100,  Color.DOWNTICK, Color.DOWNTICK);

AssignPriceColor(if showcolorBars then if pJ > pD then Color.GREEN else Color.RED else COLOR.CURRENT);

#END of KDJ for ThinkOrSwim V1.0


New member
I would like to add KDJ indicator on the ThinkorSwim platform, and have no clue how to do it at all. Please so kindly help.
The existing "StochasticFull" indicator has the K and D line. If I could add a J line in the StochasticFull indicator, then it became the KDJ indicator.
I do not know anything about coding, and wish someone could help coding the script and advise the installation steps, and I am willing to offer payment for it.


New member
Hi @wtf_dude. First off, a big thank you for you having shared this KDJ script.

I’m reaching out as I am curious to know if you have any experience / interest in developing a TOS script for something similar but where the indicator is overplayed over the main chart in ribbon form. If you do I am absolutely open to paying for the work.

I came across this post on another forum and found it really interesting. Take a look if you are curious / interested.


New member
Can you please make this indicator Crossover type I mean it give signal if (PPJ) the yellow line cross the level 20 above and signal if it cross 80 below similar to the RSI Crossover indicator in Thinkorswim


Well-known member
Is this what you are looking for:


# To Add CrossOver Signals to KDJ indicator
# paste the following code into the end of your study:

plot ppJ_crossUP = if ppJ crosses above OverSold then OverSold else double.NaN ;
plot ppJ_crossDN = if ppJ crosses below OverBought then OverBought else double.NaN ;

ppJ_crossUP.SetDefaultColor( ;
ppJ_crossDN.SetDefaultColor( ;

Similar threads