Chiến lược này kết hợp dao động stochastic và chỉ số OTT để tạo ra tín hiệu giao dịch. Nó sẽ kích hoạt các lệnh khi các đường OTT nhanh và chậm giao nhau. Để lọc các tín hiệu giả, dao động stochastic được sử dụng để xác nhận.
Chiến lược này tích hợp khả năng đảo ngược OTT và lọc stochastic để kiểm soát rủi ro một cách hiệu quả. Nó hoạt động tốt cho các thị trường đảo ngược hoặc dao động. Nhưng chu kỳ thị trường và điều chỉnh cần chú ý. Có thể cải thiện thêm trong tối ưu hóa tham số và quản lý tiền.
/*backtest start: 2022-11-21 00:00:00 end: 2023-11-21 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/ // © BigCoinHunter //@version=5 strategy(title='OTT-Stoch-TP/SL', overlay=true, pyramiding=0, default_qty_type=strategy.percent_of_equity, default_qty_value=100, initial_capital=1000, currency=currency.USD, commission_value=0.05, commission_type=strategy.commission.percent, process_orders_on_close=true) //-------------- fetch user inputs ------------------ src = input(defval=close, title='OTT source') src1 = input(defval=close, title="Stoch OTT source") ottFastPercent = input.float(title='OTT Fast Percent(%):', defval=3.0, minval=0.1, maxval=30.0, step=0.1) ottSlowPercent = input.float(title='OTT Slow Percent(%):', defval=10.0, minval=0.1, maxval=30.0, step=0.1) ottFastLength = input.int(title="OTT Fast Length:", defval=1, minval=1) ottSlowLength = input.int(title="OTT Slow Length:", defval=1, minval=1) periodK = input.int(defval=500, title="%K Length", minval=1, step=10) smoothK = input.int(defval=200, title="%K Smoothing", minval=1, step=10) stochLength=input.int(defval=2, title="Stoch OTT Period", minval=1) stochPercent=input.float(defval=0.5, title="Stoch OTT Percent", step=0.1, minval=0) mav = input.string(title="Moving Average Type", defval="SMA", options=["SMA", "EMA", "WMA", "TMA", "VAR", "WWMA", "ZLEMA", "TSF"]) tp = input.float(title="Take Profit:", defval=0.0, minval=0.0, maxval=100.0, step=0.1) * 0.01 sl = input.float(title="Stop Loss: ", defval=0.0, minval=0.0, maxval=100.0, step=0.1) * 0.01 //showsupport = input.bool(title="Show Support Line?", defval=true) stoch = input.bool(title="evaluate Stoch OTT", defval=false) longEntry = input.bool(defval=true, title= 'Long Entry', inline="11") shortEntry = input.bool(defval=true, title='Short Entry', inline="11") //---------- backtest range setup ------------ fromDay = input.int(defval = 1, title = "From Day", minval = 1, maxval = 31) fromMonth = input.int(defval = 1, title = "From Month", minval = 1, maxval = 12) fromYear = input.int(defval = 2021, title = "From Year", minval = 2010) toDay = input.int(defval = 30, title = "To Day", minval = 1, maxval = 31) toMonth = input.int(defval = 12, title = "To Month", minval = 1, maxval = 12) toYear = input.int(defval = 2022, title = "To Year", minval = 2010) //------------ time interval setup ----------- start = timestamp(fromYear, fromMonth, fromDay, 00, 00) // backtest start window finish = timestamp(toYear, toMonth, toDay, 23, 59) // backtest finish window window() => time >= start and time <= finish ? true : false // create function "within window of time" //-------- calculate the OTT lines ---------- 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=math.sum(vud1,9) vDD=math.sum(vdd1,9) vCMO=nz((vUD-vDD)/(vUD+vDD)) VAR=0.0 VAR:=nz(valpha*math.abs(vCMO)*src)+(1-valpha*math.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==math.round(length/2) ? length/2 : (length - 1) / 2 zxEMAData = (src + (src - src[zxLag])) ZLEMA = ta.ema(zxEMAData, length) //ZLEMA=Zlema_Func(src,length) Tsf_Func(src,length)=> lrc = ta.linreg(src, length, 0) lrc1 = ta.linreg(src,length,1) lrs = (lrc-lrc1) TSF = ta.linreg(src, length, 0)+lrs //TSF=Tsf_Func(src,length) getMA(src, length) => ma = 0.0 if mav == "SMA" ma := ta.sma(src, length) ma if mav == "EMA" ma := ta.ema(src, length) ma if mav == "WMA" ma := ta.wma(src, length) ma if mav == "TMA" ma := ta.sma(ta.sma(src, math.ceil(length / 2)), math.floor(length / 2) + 1) ma if mav == "VAR" ma := Var_Func(src,length) ma if mav == "WWMA" ma := Wwma_Func(src,length) ma if mav == "ZLEMA" ma := Zlema_Func(src,length) ma if mav == "TSF" ma := Tsf_Func(src,length) ma ma //-------- OTT line calculation -------- MAvg1=getMA(src, ottFastLength) fark1=MAvg1*ottFastPercent*0.01 longStop1 = MAvg1 - fark1 longStopPrev1 = nz(longStop1[1], longStop1) longStop1 := MAvg1 > longStopPrev1 ? math.max(longStop1, longStopPrev1) : longStop1 shortStop1 = MAvg1 + fark1 shortStopPrev1 = nz(shortStop1[1], shortStop1) shortStop1 := MAvg1 < shortStopPrev1 ? math.min(shortStop1, shortStopPrev1) : shortStop1 dir1 = 1 dir1 := nz(dir1[1], dir1) dir1 := dir1 == -1 and MAvg1 > shortStopPrev1 ? 1 : dir1 == 1 and MAvg1 < longStopPrev1 ? -1 : dir1 MT1 = dir1==1 ? longStop1: shortStop1 OTTFast=MAvg1>MT1 ? MT1*(200+ottFastPercent)/200 : MT1*(200-ottFastPercent)/200 MAvg2=getMA(src, ottSlowLength) fark2=MAvg2*ottSlowPercent*0.01 longStop2 = MAvg2 - fark2 longStopPrev2 = nz(longStop2[1], longStop2) longStop2 := MAvg2 > longStopPrev2 ? math.max(longStop2, longStopPrev2) : longStop2 shortStop2 = MAvg2 + fark2 shortStopPrev2 = nz(shortStop2[1], shortStop2) shortStop2 := MAvg2 < shortStopPrev2 ? math.min(shortStop2, shortStopPrev2) : shortStop2 dir2 = 1 dir2 := nz(dir2[1], dir2) dir2 := dir2 == -1 and MAvg2 > shortStopPrev2 ? 1 : dir2 == 1 and MAvg2 < longStopPrev2 ? -1 : dir2 MT2 = dir2==1 ? longStop2: shortStop2 OTTSlow=MAvg2>MT2 ? MT2*(200+ottSlowPercent)/200 : MT2*(200-ottSlowPercent)/200 //-------- Stoch OTT calculation ---------- Var_Func1(src1,length)=> valpha1=2/(length+1) vud11=src1>src1[1] ? src1-src1[1] : 0 vdd11=src1<src1[1] ? src1[1]-src1 : 0 vUD1=math.sum(vud11,9) vDD1=math.sum(vdd11,9) vCMO1=nz((vUD1-vDD1)/(vUD1+vDD1)) VAR1=0.0 VAR1:=nz(valpha1*math.abs(vCMO1)*src1)+(1-valpha1*math.abs(vCMO1))*nz(VAR1[1]) VAR1=Var_Func1(src1,stochLength) k = Var_Func1(ta.stoch(close, high, low, periodK), smoothK) k1=k+1000 VAR2=Var_Func(k1,stochLength) MAvg3=Var_Func(k1, stochLength) fark3=MAvg3*stochPercent*0.01 longStop3 = MAvg3 - fark3 longStopPrev3 = nz(longStop3[1], longStop3) longStop3 := MAvg3 > longStopPrev3 ? math.max(longStop3, longStopPrev3) : longStop3 shortStop3 = MAvg3 + fark3 shortStopPrev3 = nz(shortStop3[1], shortStop3) shortStop3 := MAvg3 < shortStopPrev3 ? math.min(shortStop3, shortStopPrev3) : shortStop3 dir3 = 1 dir3 := nz(dir3[1], dir3) dir3 := dir3 == -1 and MAvg3 > shortStopPrev3 ? 1 : dir3 == 1 and MAvg3 < longStopPrev3 ? -1 : dir3 MT3 = dir3==1 ? longStop3: shortStop3 OTTStoch=MAvg3>MT3 ? MT3*(200+stochPercent)/200 : MT3*(200-stochPercent)/200 //------- define the global variables ------ var bool long = true var bool stoppedOutLong = false var bool stoppedOutShort = false //-------- determine the market direction -------- if OTTFast > OTTSlow long := true else if OTTFast < OTTSlow long := false //--------- calculate the input/output points ----------- longProfitPrice = strategy.position_avg_price * (1 + tp) // tp -> take profit percentage longStopPrice = strategy.position_avg_price * (1 - sl) // sl -> stop loss percentage shortProfitPrice = strategy.position_avg_price * (1 - tp) shortStopPrice = strategy.position_avg_price * (1 + sl) //------------------- determine buy and sell points --------------------- buySignall = false sellSignall = false if stoch == false buySignall := window() and long and (not stoppedOutLong) sellSignall := window() and (not long) and (not stoppedOutShort) else buySignall := window() and long and (not stoppedOutLong) and ( k1 > OTTStoch ) sellSignall := window() and (not long) and (not stoppedOutShort) and ( k1 < OTTStoch ) //---------- execute the strategy ----------------- if(longEntry and shortEntry) if long strategy.entry("LONG", strategy.long, when = buySignall, comment = "ENTER LONG") stoppedOutLong := true stoppedOutShort := false else strategy.entry("SHORT", strategy.short, when = sellSignall, comment = "ENTER SHORT") stoppedOutLong := false stoppedOutShort := true else if(longEntry) strategy.entry("LONG", strategy.long, when = buySignall) strategy.close("LONG", when = sellSignall) if long stoppedOutLong := true else stoppedOutLong := false else if(shortEntry) strategy.entry("SHORT", strategy.short, when = sellSignall) strategy.close("SHORT", when = buySignall) if not long stoppedOutShort := true else stoppedOutShort := false //----------------- take profit and stop loss ----------------- if(tp>0.0 and sl>0.0) if ( strategy.position_size > 0 ) strategy.exit(id="LONG", limit=longProfitPrice, stop=longStopPrice, comment="Long TP/SL Trigger") else if ( strategy.position_size < 0 ) strategy.exit(id="SHORT", limit=shortProfitPrice, stop=shortStopPrice, comment="Short TP/SL Trigger") else if(tp>0.0) if ( strategy.position_size > 0 ) strategy.exit(id="LONG", limit=longProfitPrice, comment="Long TP Trigger") else if ( strategy.position_size < 0 ) strategy.exit(id="SHORT", limit=shortProfitPrice, comment="Short TP Trigger") else if(sl>0.0) if ( strategy.position_size > 0 ) strategy.exit(id="LONG", stop=longStopPrice, comment="Long SL Trigger") else if ( strategy.position_size < 0 ) strategy.exit(id="SHORT", stop=shortStopPrice, comment="Short SL Trigger") //------------- plot charts --------------------- lineColor1 = long ? color.green : color.red lineColor2 = long ? color.aqua : color.fuchsia light_green=#08ff12 light_red=#fe0808 plot(nz(OTTFast), color=light_green, linewidth=3, title="OTT Fast") plot(nz(OTTSlow), color=light_red, linewidth=3, title="OTT Slow")