Esta es una estrategia basada en el impulso que utiliza indicadores de osciladores como RSI, Stoch, MACD para generar señales comerciales. La idea principal es identificar la dirección de la tendencia cuando el precio oscila utilizando indicadores y entrar en operaciones basadas en señales de indicadores.
La estrategia primero llama a la función personalizada f_getOscilatorValues para obtener valores de diferentes indicadores de oscilador, incluidos RSI, Stoch, MACD, etc. Luego calcula los valores de supertendencia retrasados con f_getSupertrend para rastrear el stop loss.
Después de calcular los indicadores, la estrategia llama a f_getBuySellStops para calcular paradas de entrada y objetivos de ganancia basados en los valores del indicador. Específicamente, calcula ATR y utiliza ATR multiplicado por un coeficiente de stop loss como parada de entrada, y ATR multiplicado por un coeficiente de take profit como objetivo de ganancia. Las paradas y objetivos se ajustarán cuando la tendencia se invierta.
Luego, la estrategia determina la dirección de la vela. Las velas de tendencia al alza son de color verde y las de tendencia a la baja son de color rojo. Después de trazar velas e indicadores, la estrategia verifica si se cumplen las condiciones de entrada. Las condiciones de entrada son comprar cuando el indicador muestra sobrecompra y los precios se rompen por encima de la banda superior, y vender cuando el indicador muestra sobreventa y los precios se rompen por debajo de la banda inferior. También hay una condición de filtrado que requiere que el precio rompa el promedio móvil de marco de tiempo más alto.
Después de la entrada, el stop loss es seguido por la banda superior/inferior, lo que esté más cerca. Cuando se activa el stop loss, la posición se cierra. Cuando el precio alcanza el objetivo de ganancia, se obtiene un beneficio parcial.
Las ventajas de esta estrategia son:
El uso de osciladores para identificar la dirección de la tendencia puede capturar oportunamente las oportunidades de inversión a corto plazo.
La aplicación de un supertrend de stop loss retrasado puede detenerse antes de que las pérdidas aumenten, limitando las pérdidas de una sola operación.
El cálculo de la meta de stop loss y de beneficio basado en el ATR dinámico ayuda a ajustar el tamaño de las posiciones.
El filtrado con promedios móviles de mayor plazo evita quedar atrapado en las consolidaciones.
La obtención parcial de ganancias permite que las ganancias funcionen mientras se bloquea algo de ganancia.
La lógica es simple y fácil de entender para los principiantes en el comercio cuántico.
Algunos riesgos de esta estrategia incluyen:
Los osciladores pueden tener problemas de retraso, causando señales de entrada tardías y salida prematura.
El rango de stop loss se puede ampliar o se pueden usar paradas dinámicas como Chandelier.
La posición restante después de la obtención parcial de beneficios puede ser suspendida.
La estrategia debe validarse en diferentes mercados.
Fallo del filtro de la media móvil de los intervalos de tiempo superiores: los métodos de clasificación de tendencias deben utilizarse conjuntamente.
La estrategia se puede optimizar en los siguientes aspectos:
Prueba diferentes combinaciones de parámetros de los osciladores y encuentra los que proporcionan señales de calidad.
Intente reemplazar la obtención de ganancias parciales con la obtención de ganancias paradas basadas en ATR o promedios móviles.
Añadir algoritmos de aprendizaje automático para reemplazar la media móvil para el análisis de tendencias y mejorar la precisión.
Añadir indicadores de volumen como condiciones de filtración para evitar inversiones innecesarias.
Reunir y ponderar los indicadores para encontrar la combinación óptima para el activo.
Añadir módulos de control de riesgos de aprendizaje automático para optimizar dinámicamente las paradas, los objetivos y el tamaño de la posición.
Incorporar arbitraje triangular o señales de negociación de base utilizando diferenciales de precios entre futuros y spot.
En general, esta es una gran estrategia para los principiantes en el comercio de cantidades con una lógica clara centrada en los indicadores y la gestión de riesgos. Pero aún se necesitan optimización de parámetros y reducción de riesgos para el comercio en vivo. También se puede mejorar en aspectos como el análisis de tendencias, optimización de pérdidas de parada, modelos de conjunto, etc. para mejorar la robustez. Como plantilla de estrategia comercial, proporciona una referencia valiosa.
/*backtest start: 2023-08-26 00:00:00 end: 2023-09-25 00:00:00 period: 1h 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/ // © HeWhoMustNotBeNamed //@version=4 strategy("Oscilator candles - strategy", overlay=false, initial_capital = 1000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true) oscilatorType = input(title="Oscliator Type", defval="stoch", options=["rsi", "stoch", "cog", "macd", "tsi", "cci", "cmo", "mfi"]) length = input(3) shortlength = input(3) longlength = input(9) showSupertrend = input(true) AtrMAType = input(title="Moving Average Type", defval="rma", options=["ema", "sma", "hma", "rma", "vwma", "wma"]) AtrLength = input(30, step=10) stopMultiplier = input(4) targetMultiplier = input(3) wicks = input(true) considerWicksForDelayByStep = input(false) colorByPreviousClose = input(true) useHTFPivot = input(false) resolution = input("12M", type=input.resolution) HTFMultiplier = input(4, title="Higher Timeframe multiplier (Used when resolution is set to Same as Symbol)", minval=2, step=1) PivotLength = input(2, step=1) tradeDirection = input(title="Trade Direction", defval=strategy.direction.long, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short]) i_startTime = input(defval = timestamp("01 Jan 2010 00:00 +0000"), title = "Backtest Start Time", type = input.time) i_endTime = input(defval = timestamp("01 Jan 2099 00:00 +0000"), title = "Backtest End Time", type = input.time) inDateRange = true f_getOscilatorValues(oscilatorType, length, shortlength, longlength)=> oOpen = rsi(open, length) oClose = rsi(close, length) oHigh = rsi(high, length) oLow = rsi(low, length) if(oscilatorType == "tsi") oOpen := tsi(open, shortlength, longlength) oClose := tsi(close, shortlength, longlength) oHigh := tsi(high, shortlength, longlength) oLow := tsi(low, shortlength, longlength) if(oscilatorType == "stoch") oOpen := stoch(open, longlength, shortlength, length) oClose := stoch(close, longlength, shortlength, length) oHigh := stoch(high, longlength, shortlength, length) oLow := stoch(low, longlength, shortlength, length) if(oscilatorType == "cci") oOpen := cci(open, length) oClose := cci(close, length) oHigh := cci(high, length) oLow := cci(low, length) if(oscilatorType == "cog") oOpen := cog(open, length) oClose := cog(close, length) oHigh := cog(high, length) oLow := cog(low, length) if(oscilatorType == "cmo") oOpen := cmo(open, length) oClose := cmo(close, length) oHigh := cmo(high, length) oLow := cmo(low, length) if(oscilatorType == "mfi") oOpen := mfi(open, length) oClose := mfi(close, length) oHigh := mfi(high, length) oLow := mfi(low, length) if(oscilatorType == "macd") [macdLineOpen, signalLineOpen, histLineOpen] = macd(open, shortlength, longlength, length) [macdLineClose, signalLineClose, histLineClose] = macd(close, shortlength, longlength, length) [macdLineHigh, signalLineHigh, histLineHigh] = macd(high, shortlength, longlength, length) [macdLineLow, signalLineLow, histLineLow] = macd(low, shortlength, longlength, length) oOpen := macdLineOpen oClose := macdLineClose oHigh := macdLineHigh oLow := macdLineLow [oOpen, oClose, oHigh, oLow] f_getMovingAverage(source, MAType, length)=> ma = sma(source, length) if(MAType == "ema") ma := ema(source,length) if(MAType == "hma") ma := hma(source,length) if(MAType == "rma") ma := rma(source,length) if(MAType == "vwma") ma := vwma(source,length) if(MAType == "wma") ma := wma(source,length) ma f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)=> truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1]) averagetruerange = f_getMovingAverage(truerange, AtrMAType, AtrLength) atr = averagetruerange * stopMultiplier longStop = oClose - atr longStopPrev = nz(longStop[1], longStop) longStop := (wicks ? oLow[1] : oClose[1]) > longStopPrev ? max(longStop, longStopPrev) : longStop shortStop = oClose + atr shortStopPrev = nz(shortStop[1], shortStop) shortStop := (wicks ? oHigh[1] : oClose[1]) < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop dir = 1 dir := nz(dir[1], dir) dir := dir == -1 and (wicks ? oHigh : oClose) > shortStopPrev ? 1 : dir == 1 and (wicks ? oLow : oClose) < longStopPrev ? -1 : dir trailingStop = dir == 1? longStop : shortStop [dir, trailingStop] f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, considerWicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)=> barState = 0 source = oClose truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1]) atr = f_getMovingAverage(truerange, AtrMAType, AtrLength) buyStop = source - atr * stopMultiplier sellStop = source + atr * stopMultiplier buyStopDerived = buyStop sellStopDerived = sellStop highTarget = considerWicks ? oHigh : source lowTarget = considerWicks ? oLow : source highTargetDelayByStep = considerWicksForDelayByStep ? oHigh : source lowTargetDelayByStep = considerWicksForDelayByStep ? oLow : source barState := highTarget > sellStopDerived[1] ? 1 : lowTarget < buyStopDerived[1] ? -1 : nz(barState[1],0) buyMultiplier = (barState == 1)? stopMultiplier : targetMultiplier sellMultiplier = (barState == -1)? stopMultiplier : targetMultiplier buyStop := source - atr * buyMultiplier sellStop := source + atr * sellMultiplier buyStop := barState == 1? max(buyStop, buyStop[1]) : barState == -1? min(buyStop, buyStop[1]) : buyStop sellStop := barState == 1? max(sellStop, sellStop[1]) : barState == -1? min(sellStop, sellStop[1]) : sellStop buyStopDerived := buyStop sellStopDerived := sellStop buyStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? buyStopDerived[1] : buyStopDerived sellStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? sellStopDerived[1] : sellStopDerived [buyStopDerived, sellStopDerived, barState] f_secureSecurity(_symbol, _res, _src) => security(_symbol, _res, _src[1], lookahead = barmerge.lookahead_on, gaps=barmerge.gaps_off) f_multiple_resolution(HTFMultiplier) => target_Res_In_Min = timeframe.multiplier * HTFMultiplier * ( timeframe.isseconds ? 1. / 60. : timeframe.isminutes ? 1. : timeframe.isdaily ? 1440. : timeframe.isweekly ? 7. * 24. * 60. : timeframe.ismonthly ? 30.417 * 24. * 60. : na) target_Res_In_Min <= 0.0417 ? "1S" : target_Res_In_Min <= 0.167 ? "5S" : target_Res_In_Min <= 0.376 ? "15S" : target_Res_In_Min <= 0.751 ? "30S" : target_Res_In_Min <= 1440 ? tostring(round(target_Res_In_Min)) : tostring(round(min(target_Res_In_Min / 1440, 365))) + "D" f_getPivotHighLow(oOpen, oClose, oHigh, oLow, HTFMultiplier, resolution, PivotLength)=> derivedResolution = resolution == ""? f_multiple_resolution(HTFMultiplier) : resolution HTFHigh = f_secureSecurity(syminfo.tickerid, derivedResolution, oHigh) HTFLow = f_secureSecurity(syminfo.tickerid, derivedResolution, oLow) CLOSEprev = f_secureSecurity(syminfo.tickerid, derivedResolution, oClose) pivothi = pivothigh(HTFHigh, PivotLength, PivotLength) pivotlo = pivotlow(HTFLow, PivotLength, PivotLength) pivothi := na(pivothi)? nz(pivothi[1]) : pivothi pivotlo := na(pivotlo)? nz(pivotlo[1]) : pivotlo [pivothi, pivotlo] [oOpen, oClose, oHigh, oLow] = f_getOscilatorValues(oscilatorType, length, shortlength, longlength) [dir, trailingStop] = f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks) candleColor = colorByPreviousClose ? (oClose[1] < oClose ? color.green : oClose[1] > oClose ? color.red : color.silver) : (oOpen < oClose ? color.green : oOpen > oClose ? color.red : color.silver) plotcandle(oOpen, oHigh, oLow, oClose, 'Oscilator Candles', color = candleColor) [buyStopDerived, sellStopDerived, barState] = f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, wicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier) trailingStopDerived = barState == 1? buyStopDerived : sellStopDerived plot(showSupertrend?trailingStopDerived:na, title="TrailingStop", style=plot.style_linebr, linewidth=1, color= barState == 1 ? color.green : color.red) [pivotHigh, pivotLow] = f_getPivotHighLow(open, close, high, low, HTFMultiplier, resolution, PivotLength) buyCondition = (barState == 1) and (close > pivotHigh or not useHTFPivot) exitBuyConditin = (barState == -1) sellCondition = (barState == -1) and (close < pivotLow or not useHTFPivot) exitSellCondition = (barState == 1) // strategy.risk.allow_entry_in(tradeDirection) strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca") strategy.entry("Sell", strategy.short, when=sellCondition and inDateRange, oca_name="oca") strategy.close("Buy", when = exitBuyConditin) strategy.close( "Sell", when = exitSellCondition)