Esta estrategia se llama RSI_OTT-TP/SL. Combina el indicador RSI y las bandas OTT para determinar las señales de negociación, pertenecientes a las estrategias de tendencia siguiente. La estrategia juzga la dirección de la tendencia del mercado a través del indicador RSI y utiliza las bandas OTT para localizar puntos de entrada específicos. También permite a los usuarios establecer ratios de toma de ganancias y stop loss para bloquear las ganancias o evitar las pérdidas automáticamente.
Esta estrategia utiliza indicadores RSI y OTT para determinar la tendencia y los puntos de entrada.
El RSI se utiliza para juzgar la dirección general de la tendencia. El RSI puede mostrar si el mercado está sobrecomprado o sobrevendido. Cruzar el RSI por encima del nivel de sobrecompra es una señal de compra, mientras que cruzar por debajo del nivel de sobreventa es una señal de venta. La longitud predeterminada del RSI es de 6, el nivel de sobrecompra es de 50 y el nivel de sobreventa también es de 50 en esta estrategia.
Las bandas OTT se utilizan para descubrir puntos de entrada. Son bandas formadas en base al indicador de tasa de cambio de volatilidad (VAR). Cuando el precio rompe la banda inferior hacia arriba, es una señal de compra. Cuando el precio rompe la banda superior hacia abajo, es una señal de venta.
Después de determinar la tendencia y confirmar el punto de entrada, esta estrategia abrirá posiciones largas o cortas cuando el precio rompa las bandas OTT.
La estrategia cerrará posiciones automáticamente cuando se toque el precio de toma de ganancias o stop loss.
La estrategia también permite el comercio sólo largo, sólo corto o en ambas direcciones.
La combinación de bandas RSI y OTT puede encontrar puntos de entrada de alta probabilidad bajo un juicio de tendencia preciso.
Las bandas OTT utilizan indicadores de impulso y son muy sensibles a las fluctuaciones de precios, lo que puede detectar los puntos de inflexión temprano.
Las funciones de toma de ganancias y stop loss ayudan a bloquear las ganancias y limitar las pérdidas antes de que se expandan, lo que beneficia el control de riesgos.
La estructura del código es clara con suficientes comentarios, fácil de entender y modificar.
Los parámetros de la estrategia se pueden ajustar de forma flexible a través de la interfaz para adaptarse a los diferentes entornos del mercado.
El RSI tiene una emisión rezagada y puede perder los puntos de inversión de tendencia, lo que lleva a pérdidas innecesarias.
Las bandas OTT también pueden generar señales falsas.
Los parámetros deben ajustarse para diferentes productos.
La estrategia solo se prueba en un solo producto. Los parámetros deben optimizarse por separado para diferentes productos en el comercio en vivo.
La ventana de tiempo de backtest es corta y puede no validar plenamente la eficacia de la estrategia.
Considere la posibilidad de añadir otros indicadores de filtración, como el MACD, el KD, etc., para reducir las entradas falsas.
Los rangos de toma de ganancias y de stop loss pueden ajustarse dinámicamente en función de la volatilidad.
Optimización de parámetros de investigación para diferentes productos para establecer criterios de selección de parámetros.
Prueba métodos de aprendizaje automático para optimizar dinámicamente los parámetros de estrategia.
Añadir confirmación de volumen para evitar fallas. Los indicadores de volumen también se pueden utilizar para determinar tendencias.
Considerar el uso de la penetración de MA como stop loss en lugar de un simple stop loss porcentual.
En resumen, esta es una estrategia típica de seguimiento de tendencias. Primero juzga la dirección de la tendencia a través del RSI, luego utiliza bandas OTT para ayudar a determinar puntos de entrada específicos, y finalmente establece tomar ganancias y detener pérdidas para bloquear las ganancias y controlar los riesgos. Las ventajas de esta estrategia son combinaciones de indicadores simples y efectivas y buenos resultados de pruebas de retroceso. Pero también hay algunos riesgos como el retraso del RSI y las señales falsas de la banda OTT. Esto requiere que optimizemos los parámetros cuidadosamente en el comercio en vivo y agregemos otros indicadores técnicos para la confirmación para mejorar la estabilidad de la estrategia. Con la optimización y verificación continuas, esta estrategia puede convertirse en una estrategia de seguimiento de tendencias muy práctica.
/*backtest start: 2023-09-08 00:00:00 end: 2023-10-08 00:00:00 period: 2h basePeriod: 15m 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="RSI_OTT-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) //----------- get the user inputs -------------- //---------- RSI ------------- price = input(close, title="Source") RSIlength = input.int(defval=6,title="RSI Length") RSIoverSold = input.int(defval=50, title="RSI OverSold", minval=1) RSIoverBought = input.int(defval=50, title="RSI OverBought", minval=1) //------- OTT Bands ---------------- src = close length=input.int(defval=1, title="OTT Period", minval=1) percent=input.float(defval=5, title="OTT Percent", step=0.1, minval=0.001) mav = input.string(title="OTT MA Type", defval="VAR", options=["SMA", "EMA", "WMA", "TMA", "VAR", "WWMA", "ZLEMA", "TSF"]) ottUpperPercent = input.float(title="OTT Upper Line Coeff", defval=0.01, minval = 0.001, step=0.001) ottLowerPercent = input.float(title="OTT Lower Line Coeff", defval=0.01, minval = 0.001, step=0.001) 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 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 ? math.max(longStop, longStopPrev) : longStop shortStop = MAvg + fark shortStopPrev = nz(shortStop[1], shortStop) shortStop := MAvg < shortStopPrev ? math.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 light_green=#08ff12 light_red=#fe0808 OTTupper = nz(OTT[2])*(1+ottUpperPercent) OTTlower = nz(OTT[2])*(1-ottLowerPercent) p1 = plot(OTTupper, color=light_green, linewidth=1, title="OTT UPPER") p2 = plot(nz(OTT[2]), color=color.new(color.yellow,0), linewidth=1, title="OTT MIDDLE") p3 = plot(OTTlower, color=light_red, linewidth=1, title="OTT LOWER") fill(plot1=p1, plot2=p3, title="OTT Background", color=color.new(color.aqua,90), fillgaps=false, editable=true) buyEntry = ta.crossover(src, OTTlower) sellEntry = ta.crossunder(src, OTTupper) //---------- input TP/SL --------------- 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 isEntryLong = input.bool(defval=true, title= 'Long Entry', inline="11") isEntryShort = 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() => true // create function "within window of time" //------- define the global variables ------ var bool long = true var bool stoppedOutLong = false var bool stoppedOutShort = false //--------- Colors --------------- //TrendColor = RSIoverBought and (price[1] > BBupper and price < BBupper) and BBbasis < BBbasis[1] ? color.red : RSIoverSold and (price[1] < BBlower and price > BBlower) and BBbasis > BBbasis[1] ? color.green : na //bgcolor(switch2?(color.new(TrendColor,50)):na) //--------- 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) //---------- RSI + Bollinger Bands Strategy ------------- vrsi = ta.rsi(price, RSIlength) rsiCrossOver = ta.crossover(vrsi, RSIoverSold) rsiCrossUnder = ta.crossunder(vrsi, RSIoverBought) OTTCrossOver = ta.crossover(src, OTTlower) OTTCrossUnder = ta.crossunder(src, OTTupper) if (not na(vrsi)) if rsiCrossOver and OTTCrossOver long := true if rsiCrossUnder and OTTCrossUnder long := false //------- define the global variables ------ buySignall = false sellSignall = false //------------------- determine buy and sell points --------------------- buySignall := window() and long and (not stoppedOutLong) sellSignall := window() and (not long) and (not stoppedOutShort) //---------- execute the strategy ----------------- if(isEntryLong and isEntryShort) 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(isEntryLong) strategy.entry("LONG", strategy.long, when = buySignall) strategy.close("LONG", when = sellSignall) if long stoppedOutLong := true else stoppedOutLong := false else if(isEntryShort) 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")