The Twin Optimized Trend Tracker Strategy is an enhanced version of the OTT strategy that combines dual OTT lines and a coefficient to better handle false signals during sideways market. This strategy was developed by Turkish trader Anıl Özekşi, who explained the design philosophy in his video tutorials.
The core of the Twin OTT strategy is to determine the trend direction using two optimized trend tracking lines - OTT. It first calculates the moving average MAvg, then obtains the long stop loss line longStop and short stop loss line shortStop based on a percentage of the MAvg value. When the price crosses above the longStop line, it is a long signal, and when it crosses below the shortStop line, it is a short signal.
To handle false signals during sideways market, the strategy improves the following two aspects:
Two vertically displaced OTT lines, OTTup and OTTdn, are added. They are slight upward and downward shifts of the original OTT. Only when the price breaks through these two displaced lines, valid trading signals are generated.
A small coefficient coef is introduced to fine tune the two displaced OTT lines for better precision.
With this twin OTT design, most noise from sideways market can be filtered to avoid wrong signals. It helps capture trend turning points and switch positions in a timely manner. This is the biggest advantage of the Twin OTT strategy.
Counter measures:
In summary, the Twin OTT strategy fully utilizes Anıl Özekşi’s OTT experience and makes innovations. It has the potential to become a reliable, customizable trend tracking framework. But continuous optimization and testing are still needed to adapt to changing markets.
The Twin OTT strategy effectively handles false signals during sideways markets using dual optimized trend tracking lines and a fine tuning coefficient. It makes sensible use of moving average concepts and dynamic stop loss lines to track trends. This concise and practical strategy stems from a renowned trader’s first-hand experience, making it worth in-depth research and application. But we should also be aware of its limitations and avoid complacency. Only through continuous optimizations and rigorous testing can it become a robust trend tracking strategy.
/*backtest start: 2023-09-07 00:00:00 end: 2023-10-07 00:00:00 period: 4h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © KivancOzbilgic //created by: @Anil_Ozeksi //developer: ANIL ÖZEKŞİ //author: @kivancozbilgic strategy("Twin Optimized Trend Tracker","TOTT", overlay=true) src = input(close, title="Source") length=input(40, "OTT Period", minval=1) percent=input(1, "Optimization Constant", type=input.float, step=0.1, minval=0) coeff=input(0.001, "Twin OTT Coefficient", type=input.float, step=0.001, minval=0) showsupport = input(title="Show Support Line?", type=input.bool, defval=true) showsignalsk = input(title="Show Signals?", type=input.bool, defval=true) mav = input(title="Moving Average Type", defval="VAR", options=["SMA", "EMA", "WMA", "TMA", "VAR", "WWMA", "ZLEMA", "TSF"]) highlighting = input(title="Highlighter On/Off ?", type=input.bool, defval=true) Var_Func(src,length)=> valpha=2/(length+1) vud1=src>src[1] ? src-src[1] : 0 vdd1=src<src[1] ? src[1]-src : 0 vUD=sum(vud1,9) vDD=sum(vdd1,9) vCMO=nz((vUD-vDD)/(vUD+vDD)) VAR=0.0 VAR:=nz(valpha*abs(vCMO)*src)+(1-valpha*abs(vCMO))*nz(VAR[1]) VAR=Var_Func(src,length) Wwma_Func(src,length)=> wwalpha = 1/ length WWMA = 0.0 WWMA := wwalpha*src + (1-wwalpha)*nz(WWMA[1]) WWMA=Wwma_Func(src,length) Zlema_Func(src,length)=> zxLag = length/2==round(length/2) ? length/2 : (length - 1) / 2 zxEMAData = (src + (src - src[zxLag])) ZLEMA = ema(zxEMAData, length) ZLEMA=Zlema_Func(src,length) Tsf_Func(src,length)=> lrc = linreg(src, length, 0) lrc1 = linreg(src,length,1) lrs = (lrc-lrc1) TSF = linreg(src, length, 0)+lrs TSF=Tsf_Func(src,length) getMA(src, length) => ma = 0.0 if mav == "SMA" ma := sma(src, length) ma if mav == "EMA" ma := ema(src, length) ma if mav == "WMA" ma := wma(src, length) ma if mav == "TMA" ma := sma(sma(src, ceil(length / 2)), floor(length / 2) + 1) ma if mav == "VAR" ma := VAR ma if mav == "WWMA" ma := WWMA ma if mav == "ZLEMA" ma := ZLEMA ma if mav == "TSF" ma := TSF ma ma MAvg=getMA(src, length) fark=MAvg*percent*0.01 longStop = MAvg - fark longStopPrev = nz(longStop[1], longStop) longStop := MAvg > longStopPrev ? max(longStop, longStopPrev) : longStop shortStop = MAvg + fark shortStopPrev = nz(shortStop[1], shortStop) shortStop := MAvg < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop dir = 1 dir := nz(dir[1], dir) dir := dir == -1 and MAvg > shortStopPrev ? 1 : dir == 1 and MAvg < longStopPrev ? -1 : dir MT = dir==1 ? longStop: shortStop OTT=MAvg>MT ? MT*(200+percent)/200 : MT*(200-percent)/200 OTTup=OTT*(1+coeff) OTTdn=OTT*(1-coeff) PPLOT=plot(showsupport ? MAvg : na, color=#0585E1, linewidth=2, title="Support Line") pALLup=plot(nz(OTTup[2]), color=color.green, linewidth=2, title="OTTup", transp=0) pALLdn=plot(nz(OTTdn[2]), color=color.red, linewidth=2, title="OTTdown", transp=0) buySignalk = crossover(MAvg, OTTup[2]) sellSignalk = crossunder(MAvg, OTTdn[2]) K1=barssince(buySignalk) K2=barssince(sellSignalk) O1=barssince(buySignalk[1]) O2=barssince(sellSignalk[1]) plotshape(buySignalk and showsignalsk and O1>K2 ? min(low-abs(roc(low,1)),OTTdn-abs(roc(low,1))) : na, title="Buy", text="Buy", location=location.absolute, style=shape.labelup, size=size.tiny, color=color.green, textcolor=color.white, transp=0) plotshape(sellSignalk and showsignalsk and O2>K1 ? max(high+abs(roc(high,1)),OTTup+abs(roc(high,1))) : na, title="Sell", text="Sell", location=location.absolute, style=shape.labeldown, size=size.tiny, color=color.red, textcolor=color.white, transp=0) mPlot = plot(ohlc4, title="", style=plot.style_circles, linewidth=0,display=display.none) longFillColor = highlighting ? (O2>K1 ? color.green : na) : na shortFillColor = highlighting ? (O1>K2 ? color.red : na) : na fill(mPlot, PPLOT, title="UpTrend Highligter", color=longFillColor,transp=90) fill(mPlot, PPLOT, title="DownTrend Highligter", color=shortFillColor,transp=90) fill(pALLup, pALLdn, title="Flat Zone Highligter", color=color.blue,transp=90) dummy0 = input(true, title = "=Backtest Inputs=") FromDay = input(defval = 1, title = "From Day", minval = 1, maxval = 31) FromMonth = input(defval = 1, title = "From Month", minval = 1, maxval = 12) FromYear = input(defval = 2005, title = "From Year", minval = 2005) ToDay = input(defval = 1, title = "To Day", minval = 1, maxval = 31) ToMonth = input(defval = 1, title = "To Month", minval = 1, maxval = 12) ToYear = input(defval = 9999, title = "To Year", minval = 2006) Start = timestamp(FromYear, FromMonth, FromDay, 00, 00) Finish = timestamp(ToYear, ToMonth, ToDay, 23, 59) Timerange() => time >= Start and time <= Finish ? true : false if buySignalk strategy.entry("Long", strategy.long) if sellSignalk strategy.entry("Short", strategy.short)