Esta estrategia utiliza una combinación de señales de varios indicadores técnicos para realizar operaciones dinámicas de activos como acciones, monedas digitales, etc. La estrategia identifica automáticamente las tendencias del mercado y realiza un seguimiento de tendencias.
Esta estrategia utiliza principalmente varios indicadores como la media móvil, el indicador de fuerza y de debilidad relativa (RSI), el ancho de onda verdadero medio (ATR) y el indicador de movimiento direccional (ADX) para generar señales comerciales a través de una combinación de indicadores.
Concretamente, la estrategia utiliza dos medias móviles para generar una señal de doble horquilla; una línea rápida tiene 10 días de duración y una línea lenta tiene 50 días de duración; una línea rápida genera una señal de compra cuando rompe la línea lenta desde abajo; una línea rápida genera una señal de venta cuando rompe la línea lenta desde arriba. El sistema de medias móviles puede identificar eficazmente el cambio de tendencia de la línea larga en el mercado.
Sobre la base de dos medias móviles, la estrategia también introduce indicadores del RSI para identificar señales de tendencia y evitar falsos breaks. El RSI determina la fuerza del mercado a través de los valores negativos de líneas rápidas y lentas, con un Length de 14.
Además, la estrategia utiliza el indicador ATR para ajustar automáticamente el nivel de stop loss. El indicador ATR refleja eficazmente el grado de volatilidad del mercado. Cuando la volatilidad del mercado aumenta, la estrategia establece el nivel de stop loss más ancho, lo que reduce la posibilidad de que se produzca un stop loss.
Finalmente, la estrategia determina la intensidad de la tendencia con el indicador ADX. ADX determina la intensidad de la tendencia con el valor negativo del indicador DI + y el valor negativo del indicador DI-.
La combinación de varios indicadores puede hacer que la estrategia sea más cautelosa al enviar señales de negociación para evitar ser engañada por falsas señales en el mercado y obtener una mayor probabilidad de ganar.
La estrategia tiene las siguientes ventajas:
La combinación de múltiples indicadores, como el promedio, el RSI, el ATR, el ADX, etc., puede mejorar la precisión de las decisiones de negociación y evitar los errores causados por un solo indicador.
El nivel de stop loss se ajusta automáticamente según la volatilidad del mercado, lo que reduce la probabilidad de que se desencadene un stop loss y controla eficazmente el riesgo comercial.
El comercio real después de determinar la intensidad de la tendencia con el indicador ADX puede reducir las pérdidas de operaciones inversas.
Los parámetros de la estrategia, como la longitud de la línea media, la longitud del RSI, el ciclo ATR, el ciclo ADX, etc., se pueden optimizar para adaptarse a diferentes mercados.
Mediante un sistema de media rápida que determina la tendencia de la línea larga y reduce el impacto del ruido de la línea corta con indicadores como el RSI, se puede mantener la línea larga en la tendencia para obtener mayores ganancias.
La estrategia también presenta algunos riesgos, los principales incluyen:
La combinación de múltiples parámetros aumenta la dificultad de la optimización, y la combinación inadecuada de parámetros puede causar un deterioro de los efectos de la estrategia. Este riesgo se puede mitigar con una revisión y un ajuste de parámetros más completos.
Los indicadores técnicos tienen su estado de mercado aplicable. Cuando el mercado entra en un estado especial, los indicadores involucrados en la estrategia pueden fallar al mismo tiempo. Los riesgos que conlleva este evento BLACK SWAN requieren atención.
Las estrategias permiten el uso de operaciones en blanco. Las operaciones en blanco tienen un riesgo de pérdida ilimitada. Este riesgo puede reducirse mediante la configuración de un stop loss.
Cuando la tendencia se invierte, las señales del indicador no pueden reaccionar rápidamente, lo que puede generar pérdidas inversas. Se pueden reducir adecuadamente algunos parámetros del indicador para mejorar la sensibilidad.
La estrategia también tiene espacio para una mayor optimización, y las ideas principales incluyen:
Al analizar la relevancia de los diferentes indicadores y el estado del mercado, se pueden diseñar mecanismos para ajustar dinámicamente los pesos de cada indicador para mejorar la eficacia de la decisión en diferentes entornos de mercado.
El uso de modelos como el aprendizaje profundo para predecir la dirección de los cambios en los precios, ayuda a diseñar las reglas de la decisión artificialmente y mejora la precisión de la decisión estratégica.
El diseño de módulos de optimización automática de parámetros para datos históricos de ventanas deslizantes permite ajustar dinámicamente los parámetros de los indicadores para que las estrategias se adapten mejor a los cambios en el mercado.
Incorporar métodos de análisis del ciclo de crecimiento, como la teoría de las ondas, para ayudar a juzgar la tendencia de tendencia media y larga y mejorar la probabilidad de obtener ganancias.
La estrategia utiliza en conjunto varios indicadores como la línea media móvil, RSI, ATR, ADX, etc. para diseñar un conjunto más completo de reglas de decisión, tanto para determinar la tendencia de la línea media a través del sistema como para reducir la interferencia de ruido a través de indicadores de ciclo corto como RSI. Al mismo tiempo, la estrategia tiene un mayor margen de optimización y se espera obtener mejores resultados. En general, la estrategia utiliza una combinación de indicadores para mejorar la eficacia de la decisión, controlar el riesgo y merecer más investigación y aplicación.
/*backtest start: 2023-01-28 00:00:00 end: 2024-02-03 00:00:00 period: 1d basePeriod: 1h exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ // This source code to my testing // © sgb //@version=5 strategy(title='Soren test 2', overlay=true, initial_capital=100, pyramiding=1, calc_on_order_fills=true, calc_on_every_tick=true, default_qty_type=strategy.percent_of_equity, default_qty_value=50, commission_value=0.04) //SOURCE ============================================================================================================================================================================================================================================================================================================= src = input(open) // INPUTS ============================================================================================================================================================================================================================================================================================================ //ADX -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ADX_options = input.string('MASANAKAMURA', title='Adx Type', options=['CLASSIC', 'MASANAKAMURA'], group='ADX') ADX_len = input.int(38, title='Adx lenght', minval=1, group='ADX') th = input.float(23, title='Adx Treshold', minval=0, step=0.5, group='ADX') // Volume ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ volume_f = input.float(1.2, title='Volume mult.', minval=0, step=0.1, group='Volume') sma_length = input.int(35, title='Volume lenght', minval=1, group='Volume') //RSI---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- len_3 = input.int(25, title='RSI lenght', group='Relative Strenght Indeks') src_3 = input.source(low, title='RSI Source', group='Relative Strenght Indeks') RSI_VWAP_length = input(25, title='Rsi vwap lenght') // Range Filter --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- per_ = input.int(26, title='SAMPLING PERIOD', minval=1, group='Range Filter') mult = input.float(2.3, title='RANGE MULTIPLIER', minval=0.1, step=0.1, group='Range Filter') // Cloud -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- len = input.int(1, title='Cloud Length', group='Cloud') //RMI ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- RMI_len = input.int(26, title='Rmi Lenght', minval=1, group='Relative Momentum Index') mom = input.int(17, title='Rmi Momentum', minval=1, group='Relative Momentum Index') RMI_os = input.int(33, title='Rmi oversold', minval=0, group='Relative Momentum Index') RMI_ob = input.int(68, title='Rmi overbought', minval=0, group='Relative Momentum Index') // Indicators Calculations ======================================================================================================================================================================================================================================================================================================== // Range Filter ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- var bool L_RF = na var bool S_RF = na Range_filter(_src, _per_, _mult) => var float _upward = 0.0 var float _downward = 0.0 wper = _per_ * 2 - 1 avrng = ta.ema(math.abs(_src - _src[1]), _per_) _smoothrng = ta.ema(avrng, wper) * _mult _filt = _src _filt := _src > nz(_filt[1]) ? _src - _smoothrng < nz(_filt[1]) ? nz(_filt[1]) : _src - _smoothrng : _src + _smoothrng > nz(_filt[1]) ? nz(_filt[1]) : _src + _smoothrng _upward := _filt > _filt[1] ? nz(_upward[1]) + 1 : _filt < _filt[1] ? 0 : nz(_upward[1]) _downward := _filt < _filt[1] ? nz(_downward[1]) + 1 : _filt > _filt[1] ? 0 : nz(_downward[1]) [_smoothrng, _filt, _upward, _downward] [smoothrng, filt, upward, downward] = Range_filter(src, per_, mult) hband = filt + smoothrng lband = filt - smoothrng L_RF := high > hband and upward > 0 S_RF := low < lband and downward > 0 //ADX------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- calcADX(_len) => up = ta.change(high) down = -ta.change(low) plusDM = na(up) ? na : up > down and up > 0 ? up : 0 minusDM = na(down) ? na : down > up and down > 0 ? down : 0 truerange = ta.rma(ta.tr, _len) _plus = fixnan(100 * ta.rma(plusDM, _len) / truerange) _minus = fixnan(100 * ta.rma(minusDM, _len) / truerange) sum = _plus + _minus _adx = 100 * ta.rma(math.abs(_plus - _minus) / (sum == 0 ? 1 : sum), _len) [_plus, _minus, _adx] calcADX_Masanakamura(_len) => SmoothedTrueRange = 0.0 SmoothedDirectionalMovementPlus = 0.0 SmoothedDirectionalMovementMinus = 0.0 TrueRange = math.max(math.max(high - low, math.abs(high - nz(close[1]))), math.abs(low - nz(close[1]))) DirectionalMovementPlus = high - nz(high[1]) > nz(low[1]) - low ? math.max(high - nz(high[1]), 0) : 0 DirectionalMovementMinus = nz(low[1]) - low > high - nz(high[1]) ? math.max(nz(low[1]) - low, 0) : 0 SmoothedTrueRange := nz(SmoothedTrueRange[1]) - nz(SmoothedTrueRange[1]) / _len + TrueRange SmoothedDirectionalMovementPlus := nz(SmoothedDirectionalMovementPlus[1]) - nz(SmoothedDirectionalMovementPlus[1]) / _len + DirectionalMovementPlus SmoothedDirectionalMovementMinus := nz(SmoothedDirectionalMovementMinus[1]) - nz(SmoothedDirectionalMovementMinus[1]) / _len + DirectionalMovementMinus DIP = SmoothedDirectionalMovementPlus / SmoothedTrueRange * 100 DIM = SmoothedDirectionalMovementMinus / SmoothedTrueRange * 100 DX = math.abs(DIP - DIM) / (DIP + DIM) * 100 adx = ta.sma(DX, _len) [DIP, DIM, adx] [DIPlusC, DIMinusC, ADXC] = calcADX(ADX_len) [DIPlusM, DIMinusM, ADXM] = calcADX_Masanakamura(ADX_len) DIPlus = ADX_options == 'CLASSIC' ? DIPlusC : DIPlusM DIMinus = ADX_options == 'CLASSIC' ? DIMinusC : DIMinusM ADX = ADX_options == 'CLASSIC' ? ADXC : ADXM L_adx = DIPlus > DIMinus and ADX > th S_adx = DIPlus < DIMinus and ADX > th // Volume ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Volume_condt = volume > ta.sma(volume, sma_length) * volume_f //RSI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ up_3 = ta.rma(math.max(ta.change(src_3), 0), len_3) down_3 = ta.rma(-math.min(ta.change(src_3), 0), len_3) rsi_3 = down_3 == 0 ? 100 : up_3 == 0 ? 0 : 100 - 100 / (1 + up_3 / down_3) L_rsi = rsi_3 < 70 S_rsi = rsi_3 > 30 RSI_VWAP = ta.rsi(ta.vwap(close), RSI_VWAP_length) RSI_VWAP_overSold = 13 RSI_VWAP_overBought = 68 L_VAP = ta.crossover(RSI_VWAP, RSI_VWAP_overSold) S_VAP = ta.crossunder(RSI_VWAP, RSI_VWAP_overBought) //Cloud -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- PI = 2 * math.asin(1) hilbertTransform(src) => 0.0962 * src + 0.5769 * nz(src[2]) - 0.5769 * nz(src[4]) - 0.0962 * nz(src[6]) computeComponent(src, mesaPeriodMult) => hilbertTransform(src) * mesaPeriodMult computeAlpha(src, fastLimit, slowLimit) => mesaPeriod = 0.0 mesaPeriodMult = 0.075 * nz(mesaPeriod[1]) + 0.54 smooth = 0.0 smooth := (4 * src + 3 * nz(src[1]) + 2 * nz(src[2]) + nz(src[3])) / 10 detrender = 0.0 detrender := computeComponent(smooth, mesaPeriodMult) I1 = nz(detrender[3]) Q1 = computeComponent(detrender, mesaPeriodMult) jI = computeComponent(I1, mesaPeriodMult) jQ = computeComponent(Q1, mesaPeriodMult) I2 = 0.0 Q2 = 0.0 I2 := I1 - jQ Q2 := Q1 + jI I2 := 0.2 * I2 + 0.8 * nz(I2[1]) Q2 := 0.2 * Q2 + 0.8 * nz(Q2[1]) Re = I2 * nz(I2[1]) + Q2 * nz(Q2[1]) Im = I2 * nz(Q2[1]) - Q2 * nz(I2[1]) Re := 0.2 * Re + 0.8 * nz(Re[1]) Im := 0.2 * Im + 0.8 * nz(Im[1]) if Re != 0 and Im != 0 mesaPeriod := 2 * PI / math.atan(Im / Re) mesaPeriod if mesaPeriod > 1.5 * nz(mesaPeriod[1]) mesaPeriod := 1.5 * nz(mesaPeriod[1]) mesaPeriod if mesaPeriod < 0.67 * nz(mesaPeriod[1]) mesaPeriod := 0.67 * nz(mesaPeriod[1]) mesaPeriod if mesaPeriod < 6 mesaPeriod := 6 mesaPeriod if mesaPeriod > 50 mesaPeriod := 50 mesaPeriod mesaPeriod := 0.2 * mesaPeriod + 0.8 * nz(mesaPeriod[1]) phase = 0.0 if I1 != 0 phase := 180 / PI * math.atan(Q1 / I1) phase deltaPhase = nz(phase[1]) - phase if deltaPhase < 1 deltaPhase := 1 deltaPhase alpha = fastLimit / deltaPhase if alpha < slowLimit alpha := slowLimit alpha [alpha, alpha / 2.0] er = math.abs(ta.change(src, len)) / math.sum(math.abs(ta.change(src)), len) [a, b] = computeAlpha(src, er, er * 0.1) mama = 0.0 mama := a * src + (1 - a) * nz(mama[1]) fama = 0.0 fama := b * mama + (1 - b) * nz(fama[1]) alpha = math.pow(er * (b - a) + a, 2) kama = 0.0 kama := alpha * src + (1 - alpha) * nz(kama[1]) L_cloud = kama > kama[1] S_cloud = kama < kama[1] // RMI ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- RMI(len, m) => up = ta.ema(math.max(close - close[m], 0), len) dn = ta.ema(math.max(close[m] - close, 0), len) RMI = dn == 0 ? 0 : 100 - 100 / (1 + up / dn) RMI L_rmi = ta.crossover(RMI(RMI_len, mom), RMI_os) S_rmi = ta.crossunder(RMI(RMI_len, mom), RMI_ob) //STRATEGY ========================================================================================================================================================================================================================================================================================================== L_1 = L_VAP and L_RF and not S_adx S_1 = S_VAP and S_RF and not L_adx L_2 = L_adx and Volume_condt and L_rsi and L_cloud S_2 = S_adx and Volume_condt and S_rsi and S_cloud L_3 = L_rmi and L_RF and not S_adx S_3 = S_rmi and S_RF and not L_adx L_basic_condt = L_1 or L_2 or L_3 S_basic_condt = S_1 or S_2 or S_3 var bool longCondition = na var bool shortCondition = na var float last_open_longCondition = na var float last_open_shortCondition = na var int last_longCondition = 0 var int last_shortCondition = 0 longCondition := L_basic_condt shortCondition := S_basic_condt last_open_longCondition := longCondition ? close : nz(last_open_longCondition[1]) last_open_shortCondition := shortCondition ? close : nz(last_open_shortCondition[1]) last_longCondition := longCondition ? time : nz(last_longCondition[1]) last_shortCondition := shortCondition ? time : nz(last_shortCondition[1]) in_longCondition = last_longCondition > last_shortCondition in_shortCondition = last_shortCondition > last_longCondition // SWAP-SL --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- var int last_long_sl = na var int last_short_sl = na sl = input.float(2, 'Swap % period', minval=0, step=0.1, group='strategy settings') long_sl = ta.crossunder(low, (1 - sl / 100) * last_open_longCondition) and in_longCondition and not longCondition short_sl = ta.crossover(high, (1 + sl / 100) * last_open_shortCondition) and in_shortCondition and not shortCondition last_long_sl := long_sl ? time : nz(last_long_sl[1]) last_short_sl := short_sl ? time : nz(last_short_sl[1]) var bool CondIni_long_sl = 0 CondIni_long_sl := long_sl ? 1 : longCondition ? -1 : nz(CondIni_long_sl[1]) var bool CondIni_short_sl = 0 CondIni_short_sl := short_sl ? 1 : shortCondition ? -1 : nz(CondIni_short_sl[1]) Final_Long_sl = long_sl and nz(CondIni_long_sl[1]) == -1 and in_longCondition and not longCondition Final_Short_sl = short_sl and nz(CondIni_short_sl[1]) == -1 and in_shortCondition and not shortCondition var int sectionLongs = 0 sectionLongs := nz(sectionLongs[1]) var int sectionShorts = 0 sectionShorts := nz(sectionShorts[1]) // RE-ENTRY --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- if longCondition or Final_Long_sl sectionLongs += 1 sectionShorts := 0 sectionShorts if shortCondition or Final_Short_sl sectionLongs := 0 sectionShorts += 1 sectionShorts var float sum_long = 0.0 var float sum_short = 0.0 if longCondition sum_long := nz(last_open_longCondition) + nz(sum_long[1]) sum_short := 0.0 sum_short if Final_Long_sl sum_long := (1 - sl / 100) * last_open_longCondition + nz(sum_long[1]) sum_short := 0.0 sum_short if shortCondition sum_short := nz(last_open_shortCondition) + nz(sum_short[1]) sum_long := 0.0 sum_long if Final_Short_sl sum_long := 0.0 sum_short := (1 + sl / 100) * last_open_shortCondition + nz(sum_short[1]) sum_short var float Position_Price = 0.0 Position_Price := nz(Position_Price[1]) Position_Price := longCondition or Final_Long_sl ? sum_long / sectionLongs : shortCondition or Final_Short_sl ? sum_short / sectionShorts : na //TP_1 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- tp = input.float(1.2, 'Tp-1 ', minval=0, step=0.1, group='strategy settings') long_tp = ta.crossover(high, (1 + tp / 100) * fixnan(Position_Price)) and in_longCondition and not longCondition short_tp = ta.crossunder(low, (1 - tp / 100) * fixnan(Position_Price)) and in_shortCondition and not shortCondition var int last_long_tp = na var int last_short_tp = na last_long_tp := long_tp ? time : nz(last_long_tp[1]) last_short_tp := short_tp ? time : nz(last_short_tp[1]) Final_Long_tp = long_tp and last_longCondition > nz(last_long_tp[1]) Final_Short_tp = short_tp and last_shortCondition > nz(last_short_tp[1]) fixnan_1 = fixnan(Position_Price) ltp = Final_Long_tp ? fixnan_1 * (1 + tp / 100) : na fixnan_2 = fixnan(Position_Price) stp = Final_Short_tp ? fixnan_2 * (1 - tp / 100) : na if Final_Short_tp or Final_Long_tp sum_long := 0.0 sum_short := 0.0 sectionLongs := 0 sectionShorts := 0 sectionShorts if Final_Long_tp CondIni_long_sl == 1 if Final_Short_tp CondIni_short_sl == 1 // COLORS & PLOTS -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ADX_COLOR = L_adx ? color.lime : S_adx ? color.red : color.orange barcolor(color=ADX_COLOR) hbandplot = plot(hband, title='RF HT', color=ADX_COLOR, transp=50) lbandplot = plot(lband, title='RF LT', color=ADX_COLOR, transp=50) fill(hbandplot, lbandplot, title='RF TR', color=ADX_COLOR, transp=90) plotshape(longCondition, title='Long', style=shape.triangleup, location=location.belowbar, color=color.new(color.blue, 0), size=size.tiny) plotshape(shortCondition, title='Short', style=shape.triangledown, location=location.abovebar, color=color.new(color.red, 0), size=size.tiny) plot(ltp, style=plot.style_circles, linewidth=5, color=color.new(color.fuchsia, 0), editable=false) plot(stp, style=plot.style_circles, linewidth=5, color=color.new(color.fuchsia, 0), editable=false) //BACKTESTING-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Q = 50 SL = input.float(0.4, 'StopLoss ', minval=0, step=0.1) strategy.entry('long', strategy.long, when=longCondition) strategy.entry('short', strategy.short, when=shortCondition) strategy.exit('TP', 'long', qty_percent=Q, limit=fixnan(Position_Price) * (1 + tp / 100)) strategy.exit('TP', 'short', qty_percent=Q, limit=fixnan(Position_Price) * (1 - tp / 100)) strategy.exit('SL', 'long', stop=fixnan(Position_Price) * (1 - SL / 100)) strategy.exit('SL', 'short', stop=fixnan(Position_Price) * (1 + SL / 100)) // // // // // // // By SGB