Stochastic OTT For ThinkOrSwim

sunnybabu

Member
Plus
The author states: Optimized Trend Tracker on Stochastic Oscillator is used to solve the fake signals of Stochastic Oscillator

The indicator is optomized for the 1 min chart. Parameters of the indicator might have to be optimized for other time frames and markets.

Optimized Trend Tracker OTT is an indicator used to find an existing trend
The uptrend where the prices are above OTT.
Downward trend, when prices are below OTT.

The first parameter in the OTT indicator set by the two parameters is the period/length.

OTT will be much sensitive to trend movements if it is smaller. And vice versa, will be less sensitive when it is longer.

As the period increases, it will become less sensitive to little trends and price actions.

In this way, your choice of period, will be closely related to which of the sort of trends you are interested in.

The OTT percent parameter in OTT is an optimization coefficient. Just like in the period
small values are better at capturing short term fluctuations, while large values
will be more suitable for long-term trends.

ajyVABb.png


Original code came from Tradingview: https://www.tradingview.com/script/BK45kYNB-Stochastic-OTT/
The new ThinkOrSwim code can be found in the next post.
 
Last edited by a moderator:
Hi @MerryDay & All Experts Here, I'm currently in the process of rewriting my trading bot due to the recent TOS acquisition by Schwab. Historically, I have relied on a combination of MACD and RSI indicators for trading signals, specifically when the value line is above the average and RSI is above 50. However, given that MACD can be a lagging indicator, it sometimes limits potential profits by not responding swiftly to trend reversals.

I came across this indicator on TradingView: Stochastic OTT,
https://www.tradingview.com/script/BK45kYNB-Stochastic-OTT/
and I'm curious if we have this written for thinkscript in this forum? If not, is there a similar non-lagging indicator that could be integrated with my current setup. Any guidance or recommendations for a MACD 2 line crossover alternative would be greatly appreciated.

Thank you for your time and expertise.
check the below:

CSS:
#// Indicator for TOS
#// © KivancOzbilgic
#//created by: @Anil_Ozeksi
#//developer: ANIL ÖZEK??
# study(title="Stochastic Optimized Trend Tracker", shorttitle="SOTT",
# Converted by Sam4Cok@Samer800    - 09/2024
declare lower;

input timeframe = AggregationPeriod.MIN;
input MovAvgType = {default VAR, SMA, EMA, WMA, DEMA, TMA, WWMA, ZLEMA, TSF, HULL};
input periodK = 500; #, title="%K Length", minval=1)
input smoothK = 200; #, title="%K Smoothing", minval=1)
input ottPeriod = 2; #, "OTT Period", minval=1)
input ottPercent= 0.5; #, "OTT Percent", type=input.float, step=0.1, minval=0)
input showSupportLine = no; # "Show Support Line?"
input showBubbles = no;    # "Show Support Line Crossing Signals?"

def na = Double.NaN;
def last = isNaN(close);
def current = GetAggregationPeriod();
def tf = Max(current, timeframe);
# theme #
DefineGlobalColor("Sky1" , Color.CYAN);  # >=90
DefineGlobalColor("Sky2" , CreateColor(0,137,137));  # >=80
DefineGlobalColor("Magenta1" , Color.MAGENTA);  # >=40
DefineGlobalColor("Magenta2" , Color.PLUM);  # >=30
DefineGlobalColor("movAvg", CreateColor(5,133,225));

# stoch(source, high, low, length) =>
script stoch {
    input src = close;
    input h = high;
    input l = low;
    input len = 14;
    def hh = Highest(h, len);
    def ll = Lowest(l, len);
    def c1 = src - ll;
    def c2 = hh - ll;
    def stoch = if c2 != 0 then c1 / c2 * 100 else 0;
    plot return = stoch;
}
#Var_Func(src, length) =>
script Var_Func {
    input src    = close;
    input length = 0;
    def valpha = 2 / (length + 1);
    def vud1 = if src > src[1] then src - src[1] else 0;
    def vdd1 = if src < src[1] then src[1] - src else 0;
    def vUD = Sum(vud1, 9);
    def vDD = Sum(vdd1, 9);
    def vCMO1 = ((vUD - vDD) / (vUD + vDD));
    def vCMO = if isNaN(vCMO1) then vCMO[1] else vCMO1;
    def VAR = CompoundValue(1, valpha * AbsValue(vCMO) * src + (1 - valpha * AbsValue(vCMO)) * (VAR[1]), src);
    plot result = if isNaN(close) then Double.NaN else VAR;
}
#Wwma_Func(src, length) =>
script Wwma_Func {
    input src = close;
    input length = 0;
    def wwalpha = 1 / length;
    def WWMA;
    WWMA = wwalpha * src + (1 - wwalpha) * (WWMA[1]);
    plot return = WWMA;
}
#Zlema_Func(src, length) =>
script Zlema_Func {
    input src = close;
    input length = 0;
    def zxLag = if length / 2 == Round(length / 2) then length / 2 else (length - 1) / 2;
    def zxEMAData = src + src - src[zxLag];
    def ZLEMA = ExpAverage(zxEMAData, length);
    plot return = ZLEMA;
}
#Tsf_Func(src, length) =>
script Tsf_Func {
    input src = close;
    input length = 0;
    def lrc = Inertia(src, length);
    def lrc1 = Inertia(src[1], length);
    def lrs = lrc - lrc1;
    def TSF = Inertia(src, length) + lrs;
    plot retur = TSF;
}
#Wwma_Funcl(srcl, length) =>
script Wwma_Funcl {
    input srcl = close;
    input length = 0;
    def wwalpha = 1 / length;
    def WWMA;
    WWMA = CompoundValue(1, wwalpha * srcl + (1 - wwalpha) * (WWMA[1]), srcl);
    plot return = WWMA;
}
#Zlema_Funcl(srcl, length) =>
script Zlema_Funcl {
    input srcl = close;
    input length = 0;
    def zxLag = if length / 2 == Round(length / 2,0) then length / 2 else (length - 1) / 2;
    def zxEMAData = srcl + srcl - srcl[zxLag];
    def ZLEMA = ExpAverage(zxEMAData, length);
    plot return = ZLEMA;
}
#Tsf_Funcl(srcl, length) =>
script Tsf_Funcl {
    input srcl = close;
    input length = 0;
    def lrc = Inertia(srcl, length);
    def lrc1 = Inertia(srcl[1], length);
    def lrs = lrc - lrc1;
    def TSF = Inertia(srcl, length) + lrs;
    plot retur = TSF;
}
#getMA(src, length, type) =>
script getMA {
    input src = close;
    input length = 100;
    input type   = "SMA";
    def ma = if type == "SMA" then Average(src, length) else
     if type == "EMA" then ExpAverage(src, length) else
     if type == "WMA" then WMA(src, length) else
     if type == "DEMA" then DEMA(src, length) else
     if type == "TMA" then Average(Average(src, Ceil(length / 2)), Floor(length / 2) + 1) else
     if type == "VAR" then Var_Func(src, length) else
     if type == "WWMA" then WWMA_Func(src, length) else
     if type == "ZLEMA" then Zlema_Func(src, length) else
     if type == "TSF" then Tsf_Func(src, length) else
     if type == "HULL" then HullMovingAvg(src, length) else Var_Func(src, length);
    plot result = ma;
}
def stoch = stoch(close(Period = tf), high(Period = tf), low(Period = tf), periodK);
def k = getMA(stoch, smoothK, MovAvgType);
def src = k + 1000;
def MAvg = getMA(src, ottPeriod, MovAvgType);
def fark = MAvg * ottPercent * 0.01;
def up = MAvg - fark;
def longStop;
def longStopPrev = CompoundValue(1, if longStop[1] then longStop[1] else up, up);
    longStop = if MAvg > longStopPrev then max(up, longStopPrev) else up;
def dn =  MAvg + fark;
def shortStop;
def shortStopPrev = CompoundValue(1, if shortStop[1] then shortStop[1] else dn, dn);
    shortStop = if MAvg < shortStopPrev then min(dn, shortStopPrev) else dn;
def dir; # = 1
def dir1 = compoundValue(1, if dir[1] then dir[1] else 1, 1);
    dir  = if dir1 == -1 and MAvg > shortStopPrev then 1 else
           if dir1 ==  1 and MAvg < longStopPrev then -1 else dir1;
def MT = if dir==1 then longStop else shortStop;
def OTT = if MAvg > MT then MT * (200 + ottPercent) / 200 else MT * (200 - ottPercent) / 200;
def buySignalc = (src Crosses Above OTT[2]);
def sellSignallc = (src Crosses Below OTT[2]);

plot kLine = src;
plot SupportLine = if !showSupportLine then na else MAvg;    # "Support Line"
plot ottLine = if !last and OTT[2] then OTT[2] else na;
ottLine.SetLineWeight(2);
SupportLine.SetDefaultColor(GlobalColor("movAvg"));
ottLine.SetDefaultColor(GlobalColor("Magenta1"));

plot h0 = if last then na else 1080;
plot md = if last then na else 1050;
plot h1 = if last then na else 1020;
md.SetDefaultColor(Color.GRAY);
h0.SetDefaultColor(Color.GRAY);
h1.SetDefaultColor(Color.GRAY);
md.SetStyle(Curve.SHORT_DASH);
AddCloud(h0, h1, Color.DARK_GRAY);
#--- sig

AddChartBubble(showBubbles and buySignalc, OTT, "B", Color.GREEN, no);
AddChartBubble(showBubbles and sellSignallc, OTT, "S", Color.RED);

### END of CODE
 
check the below:

CSS:
#// Indicator for TOS
#// © KivancOzbilgic
#//created by: @Anil_Ozeksi
#//developer: ANIL ÖZEK??
# study(title="Stochastic Optimized Trend Tracker", shorttitle="SOTT",
# Converted by Sam4Cok@Samer800    - 09/2024
declare lower;

input timeframe = AggregationPeriod.MIN;
input MovAvgType = {default VAR, SMA, EMA, WMA, DEMA, TMA, WWMA, ZLEMA, TSF, HULL};
input periodK = 500; #, title="%K Length", minval=1)
input smoothK = 200; #, title="%K Smoothing", minval=1)
input ottPeriod = 2; #, "OTT Period", minval=1)
input ottPercent= 0.5; #, "OTT Percent", type=input.float, step=0.1, minval=0)
input showSupportLine = no; # "Show Support Line?"
input showBubbles = no;    # "Show Support Line Crossing Signals?"

def na = Double.NaN;
def last = isNaN(close);
def current = GetAggregationPeriod();
def tf = Max(current, timeframe);
# theme #
DefineGlobalColor("Sky1" , Color.CYAN);  # >=90
DefineGlobalColor("Sky2" , CreateColor(0,137,137));  # >=80
DefineGlobalColor("Magenta1" , Color.MAGENTA);  # >=40
DefineGlobalColor("Magenta2" , Color.PLUM);  # >=30
DefineGlobalColor("movAvg", CreateColor(5,133,225));

# stoch(source, high, low, length) =>
script stoch {
    input src = close;
    input h = high;
    input l = low;
    input len = 14;
    def hh = Highest(h, len);
    def ll = Lowest(l, len);
    def c1 = src - ll;
    def c2 = hh - ll;
    def stoch = if c2 != 0 then c1 / c2 * 100 else 0;
    plot return = stoch;
}
#Var_Func(src, length) =>
script Var_Func {
    input src    = close;
    input length = 0;
    def valpha = 2 / (length + 1);
    def vud1 = if src > src[1] then src - src[1] else 0;
    def vdd1 = if src < src[1] then src[1] - src else 0;
    def vUD = Sum(vud1, 9);
    def vDD = Sum(vdd1, 9);
    def vCMO1 = ((vUD - vDD) / (vUD + vDD));
    def vCMO = if isNaN(vCMO1) then vCMO[1] else vCMO1;
    def VAR = CompoundValue(1, valpha * AbsValue(vCMO) * src + (1 - valpha * AbsValue(vCMO)) * (VAR[1]), src);
    plot result = if isNaN(close) then Double.NaN else VAR;
}
#Wwma_Func(src, length) =>
script Wwma_Func {
    input src = close;
    input length = 0;
    def wwalpha = 1 / length;
    def WWMA;
    WWMA = wwalpha * src + (1 - wwalpha) * (WWMA[1]);
    plot return = WWMA;
}
#Zlema_Func(src, length) =>
script Zlema_Func {
    input src = close;
    input length = 0;
    def zxLag = if length / 2 == Round(length / 2) then length / 2 else (length - 1) / 2;
    def zxEMAData = src + src - src[zxLag];
    def ZLEMA = ExpAverage(zxEMAData, length);
    plot return = ZLEMA;
}
#Tsf_Func(src, length) =>
script Tsf_Func {
    input src = close;
    input length = 0;
    def lrc = Inertia(src, length);
    def lrc1 = Inertia(src[1], length);
    def lrs = lrc - lrc1;
    def TSF = Inertia(src, length) + lrs;
    plot retur = TSF;
}
#Wwma_Funcl(srcl, length) =>
script Wwma_Funcl {
    input srcl = close;
    input length = 0;
    def wwalpha = 1 / length;
    def WWMA;
    WWMA = CompoundValue(1, wwalpha * srcl + (1 - wwalpha) * (WWMA[1]), srcl);
    plot return = WWMA;
}
#Zlema_Funcl(srcl, length) =>
script Zlema_Funcl {
    input srcl = close;
    input length = 0;
    def zxLag = if length / 2 == Round(length / 2,0) then length / 2 else (length - 1) / 2;
    def zxEMAData = srcl + srcl - srcl[zxLag];
    def ZLEMA = ExpAverage(zxEMAData, length);
    plot return = ZLEMA;
}
#Tsf_Funcl(srcl, length) =>
script Tsf_Funcl {
    input srcl = close;
    input length = 0;
    def lrc = Inertia(srcl, length);
    def lrc1 = Inertia(srcl[1], length);
    def lrs = lrc - lrc1;
    def TSF = Inertia(srcl, length) + lrs;
    plot retur = TSF;
}
#getMA(src, length, type) =>
script getMA {
    input src = close;
    input length = 100;
    input type   = "SMA";
    def ma = if type == "SMA" then Average(src, length) else
     if type == "EMA" then ExpAverage(src, length) else
     if type == "WMA" then WMA(src, length) else
     if type == "DEMA" then DEMA(src, length) else
     if type == "TMA" then Average(Average(src, Ceil(length / 2)), Floor(length / 2) + 1) else
     if type == "VAR" then Var_Func(src, length) else
     if type == "WWMA" then WWMA_Func(src, length) else
     if type == "ZLEMA" then Zlema_Func(src, length) else
     if type == "TSF" then Tsf_Func(src, length) else
     if type == "HULL" then HullMovingAvg(src, length) else Var_Func(src, length);
    plot result = ma;
}
def stoch = stoch(close(Period = tf), high(Period = tf), low(Period = tf), periodK);
def k = getMA(stoch, smoothK, MovAvgType);
def src = k + 1000;
def MAvg = getMA(src, ottPeriod, MovAvgType);
def fark = MAvg * ottPercent * 0.01;
def up = MAvg - fark;
def longStop;
def longStopPrev = CompoundValue(1, if longStop[1] then longStop[1] else up, up);
    longStop = if MAvg > longStopPrev then max(up, longStopPrev) else up;
def dn =  MAvg + fark;
def shortStop;
def shortStopPrev = CompoundValue(1, if shortStop[1] then shortStop[1] else dn, dn);
    shortStop = if MAvg < shortStopPrev then min(dn, shortStopPrev) else dn;
def dir; # = 1
def dir1 = compoundValue(1, if dir[1] then dir[1] else 1, 1);
    dir  = if dir1 == -1 and MAvg > shortStopPrev then 1 else
           if dir1 ==  1 and MAvg < longStopPrev then -1 else dir1;
def MT = if dir==1 then longStop else shortStop;
def OTT = if MAvg > MT then MT * (200 + ottPercent) / 200 else MT * (200 - ottPercent) / 200;
def buySignalc = (src Crosses Above OTT[2]);
def sellSignallc = (src Crosses Below OTT[2]);

plot kLine = src;
plot SupportLine = if !showSupportLine then na else MAvg;    # "Support Line"
plot ottLine = if !last and OTT[2] then OTT[2] else na;
ottLine.SetLineWeight(2);
SupportLine.SetDefaultColor(GlobalColor("movAvg"));
ottLine.SetDefaultColor(GlobalColor("Magenta1"));

plot h0 = if last then na else 1080;
plot md = if last then na else 1050;
plot h1 = if last then na else 1020;
md.SetDefaultColor(Color.GRAY);
h0.SetDefaultColor(Color.GRAY);
h1.SetDefaultColor(Color.GRAY);
md.SetStyle(Curve.SHORT_DASH);
AddCloud(h0, h1, Color.DARK_GRAY);
#--- sig

AddChartBubble(showBubbles and buySignalc, OTT, "B", Color.GREEN, no);
AddChartBubble(showBubbles and sellSignallc, OTT, "S", Color.RED);

### END of CODE
Thank you samer800.. you r a STAR
 
Nevermind i was able to convert this.. but the P&L is terrible


Code:
# ThinkScript: BOOTS with Buy and Sell Signals
# Author Msacs09

# Define VAR function
script Var_Func {
    input src = close;
    input length = 2;
    def valpha = 2 / (length + 1);
    def vud1 = if src > src[1] then src - src[1] else 0;
    def vdd1 = if src < src[1] then src[1] - src else 0;
    def vUD = Sum(vud1, 9);
    def vDD = Sum(vdd1, 9);
    def vCMO = ((vUD - vDD) / (vUD + vDD));
    def VAR = CompoundValue(1, valpha * AbsValue(vCMO) * src + (1 - valpha * AbsValue(vCMO)) * VAR[1], src);
    plot result = VAR;
}

# Parameters
input length = 2; # OTT Period
input percent = 10; # OTT Percent
input mult = 2; # Bollinger Bands multiplier

# Moving average and standard deviation
def MAvg = Var_Func(close, length);
def basis = MAvg;
def dev = mult * StDev(close, length);

# Calculate upper and lower Bollinger bands
def upper = basis + dev;
def lower = basis - dev;

# Fark and stops
def fark = MAvg * percent * 0.01;
def longStop = MAvg - fark;
def shortStop = MAvg + fark;

# BOOTS logic
def OTTl = lower; # BOOTSLow (purple line)
def OTT = upper;  # BOOTSHigh (cyan line)

# Buy and Sell Conditions
def buyCondition = close crosses above OTTl;
def sellCondition = close crosses below OTT;

# Stop (exit) conditions
#def stopBuyCondition = close crosses below OTTl;
#def stopSellCondition = close crosses above OTT;

# Plot Buy/Sell signals
AddChartBubble(buyCondition, low, "BUY", Color.GREEN, yes);
AddChartBubble(sellCondition, high, "SELL", Color.RED, no);

# Plot the BOOTSLow and BOOTSHigh lines
plot bootSlow = OTTl;
bootSlow.SetDefaultColor(Color.MAGENTA);

plot bootsHigh = OTT;
bootsHigh.SetDefaultColor(Color.CYAN);

# Exit positions plotting (optional)
#AddChartBubble(stopBuyCondition, high, "STOP", Color.YELLOW, no);
#AddChartBubble(stopSellCondition, low, "STOP", Color.YELLOW, yes);

# Place Orders
AddOrder(OrderType.BUY_AUTO, buyCondition, open[-1], 20);
AddOrder(OrderType.SELL_AUTO, sellCondition, open[-1], 20);
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
282 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top