Esta estrategia combina los indicadores de promedio móvil y el indicador de supertrend para implementar una estrategia de seguimiento de tendencia con stop loss de seguimiento.
La estrategia utiliza dos medias móviles FRAMA para señales de negociación y el indicador SuperTrend para filtrar.
Específicamente, cuando la línea rápida cruza por encima de la línea lenta, se genera una señal de compra. Cuando la línea rápida cruza por debajo de la línea lenta, se genera una señal de venta. Para evitar roturas falsas, la estrategia agrega un filtro que requiere que el indicador SuperTrend se alinee. Las operaciones solo se realizan cuando SuperTrend está de acuerdo con la dirección de la señal.
Para la gestión de posiciones, la estrategia utiliza el cambio de dirección de SuperTrend como una señal de stop loss.
Además, se puede habilitar el trailing stop loss como una opción.
Estos riesgos pueden reducirse ajustando los parámetros de la media móvil, optimizando los ajustes de SuperTrend y utilizando el stop loss de seguimiento de manera adecuada.
La estrategia se puede optimizar en los siguientes aspectos:
Se pueden probar diferentes combinaciones de períodos para encontrar el equilibrio óptimo de suavidad y sensibilidad.
Se pueden probar diferentes períodos y multiplicadores de ATR para optimizar el efecto de stop loss.
Se pueden probar filtros adicionales como el canal de Donchian, el indicador de volatilidad.
Se pueden probar diferentes anchuras de arrastramiento para maximizar las ganancias y controlar el riesgo.
Se pueden probar combinaciones con parada fija, parada de volatilidad y parada adaptativa.
La estrategia integra el análisis de tendencias de los promedios móviles y la gestión de parada de SuperTrends en una estrategia completa de seguimiento de tendencias con stop loss de seguimiento.
/*backtest start: 2023-10-01 00:00:00 end: 2023-10-13 00:00:00 period: 30m 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/ // © 03.freeman //@version=4 // strategy("FRAMA strategy", overlay=true,precision=6, initial_capital=1000,calc_on_every_tick=true, pyramiding=0, default_qty_type=strategy.fixed, default_qty_value=10000, currency=currency.EUR) ma_src = input(title="MA FRAMA Source", type=input.source, defval=close) ma_frama_len = input(title="MA FRAMA Length", type=input.integer, defval=12) res = input(title="Resolution", type=input.resolution, defval="1W") frama_FC = input(defval=1,minval=1, title="* Fractal Adjusted (FRAMA) Only - FC") frama_SC = input(defval=200,minval=1, title="* Fractal Adjusted (FRAMA) Only - SC") High = security(syminfo.tickerid, res, high) Low = security(syminfo.tickerid, res, low) source = security(syminfo.tickerid, res, ma_src) enterRule = input(false,title = "Use supertrend for enter") exitRule = input(false,title = "Use supertrend for exit") ma(src, len) => float result = 0 int len1 = len/2 e = 2.7182818284590452353602874713527 w = log(2/(frama_SC+1)) / log(e) // Natural logarithm (ln(2/(SC+1))) workaround H1 = highest(High,len1) L1 = lowest(Low,len1) N1 = (H1-L1)/len1 H2_ = highest(High,len1) H2 = H2_[len1] L2_ = lowest(Low,len1) L2 = L2_[len1] N2 = (H2-L2)/len1 H3 = highest(High,len) L3 = lowest(Low,len) N3 = (H3-L3)/len dimen1 = (log(N1+N2)-log(N3))/log(2) dimen = iff(N1>0 and N2>0 and N3>0,dimen1,nz(dimen1[1])) alpha1 = exp(w*(dimen-1)) oldalpha = alpha1>1?1:(alpha1<0.01?0.01:alpha1) oldN = (2-oldalpha)/oldalpha N = (((frama_SC-frama_FC)*(oldN-1))/(frama_SC-1))+frama_FC alpha_ = 2/(N+1) alpha = alpha_<2/(frama_SC+1)?2/(frama_SC+1):(alpha_>1?1:alpha_) frama = 0.0 frama :=(1-alpha)*nz(frama[1]) + alpha*src result := frama result frama = ma(sma(source,1),ma_frama_len) signal = ma(frama,ma_frama_len) plot(frama, color=color.red) plot(signal, color=color.green) longCondition = crossover(frama,signal) shortCondition = crossunder(frama,signal) Factor=input(3, minval=1,maxval = 100) Pd=input(7, minval=1,maxval = 100) Up=hl2-(Factor*atr(Pd)) Dn=hl2+(Factor*atr(Pd)) TrendUp = 0.0 TrendDown = 0.0 Trend = 0.0 Tsl = 0.0 TrendUp :=close[1]>TrendUp[1]? max(Up,TrendUp[1]) : Up TrendDown :=close[1]<TrendDown[1]? min(Dn,TrendDown[1]) : Dn Trend := close > TrendDown[1] ? 1: close< TrendUp[1]? -1: nz(Trend[1],1) Tsl := Trend==1? TrendUp: TrendDown linecolor = Trend == 1 ? color.green : color.red //plot(Tsl, color = linecolor , style = plot.style_line , linewidth = 2,title = "SuperTrend") plotshape(cross(close,Tsl) and close>Tsl , "Up Arrow", shape.triangleup,location.belowbar,color.green,0,0) plotshape(cross(Tsl,close) and close<Tsl , "Down Arrow", shape.triangledown , location.abovebar, color.red,0,0) plotarrow(Trend == 1 and Trend[1] == -1 ? Trend : na, title="Up Entry Arrow", colorup=color.lime, maxheight=60, minheight=50, transp=0) plotarrow(Trend == -1 and Trend[1] == 1 ? Trend : na, title="Down Entry Arrow", colordown=color.red, maxheight=60, minheight=50, transp=0) // Strategy: (Thanks to JayRogers) // === STRATEGY RELATED INPUTS === //tradeInvert = input(defval = false, title = "Invert Trade Direction?") // the risk management inputs inpTakeProfit = input(defval = 0, title = "Take Profit Points", minval = 0) inpStopLoss = input(defval = 0, title = "Stop Loss Points", minval = 0) inpTrailStop = input(defval = 0, title = "Trailing Stop Loss Points", minval = 0) inpTrailOffset = input(defval = 0, title = "Trailing Stop Loss Offset Points", minval = 0) // === RISK MANAGEMENT VALUE PREP === // if an input is less than 1, assuming not wanted so we assign 'na' value to disable it. useTakeProfit = inpTakeProfit >= 1 ? inpTakeProfit : na useStopLoss = inpStopLoss >= 1 ? inpStopLoss : na useTrailStop = inpTrailStop >= 1 ? inpTrailStop : na useTrailOffset = inpTrailOffset >= 1 ? inpTrailOffset : na // === STRATEGY - LONG POSITION EXECUTION === enterLong() => enterRule? (longCondition and Trend ==1):longCondition // functions can be used to wrap up and work out complex conditions exitLong() => exitRule and Trend == -1 strategy.entry(id = "Buy", long = true, when = enterLong() ) // use function or simple condition to decide when to get in strategy.close(id = "Buy", when = exitLong() ) // ...and when to get out // === STRATEGY - SHORT POSITION EXECUTION === enterShort() => enterRule? (shortCondition and Trend ==-1):shortCondition exitShort() => exitRule and Trend == 1 strategy.entry(id = "Sell", long = false, when = enterShort()) strategy.close(id = "Sell", when = exitShort() ) // === STRATEGY RISK MANAGEMENT EXECUTION === // finally, make use of all the earlier values we got prepped strategy.exit("Exit Buy", from_entry = "Buy", profit = useTakeProfit, loss = useStopLoss, trail_points = useTrailStop, trail_offset = useTrailOffset) strategy.exit("Exit Sell", from_entry = "Sell", profit = useTakeProfit, loss = useStopLoss, trail_points = useTrailStop, trail_offset = useTrailOffset) // === Backtesting Dates === thanks to Trost testPeriodSwitch = input(false, "Custom Backtesting Dates") testStartYear = input(2020, "Backtest Start Year") testStartMonth = input(1, "Backtest Start Month") testStartDay = input(1, "Backtest Start Day") testStartHour = input(0, "Backtest Start Hour") testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,testStartHour,0) testStopYear = input(2020, "Backtest Stop Year") testStopMonth = input(12, "Backtest Stop Month") testStopDay = input(31, "Backtest Stop Day") testStopHour = input(23, "Backtest Stop Hour") testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,testStopHour,0) testPeriod() => time >= testPeriodStart and time <= testPeriodStop ? true : false isPeriod = true // === /END if not isPeriod strategy.cancel_all() strategy.close_all()