Estrategias comerciales flexibles de posiciones largas y cortas basadas en canales de Keltner

ATR EMA SMA MA TR
Fecha de creación: 2025-02-10 15:07:12 Última modificación: 2025-02-10 15:07:12
Copiar: 4 Número de Visitas: 448
1
Seguir
1617
Seguidores

Estrategias comerciales flexibles de posiciones largas y cortas basadas en canales de Keltner

Descripción general

Esta es una estrategia de negociación flexible basada en el canal de Keltner. La estrategia soporta el comercio bidireccional de múltiples espacios, que se realiza mediante la supervisión de la subida y bajada de los precios que atraviesan el canal. El núcleo de la estrategia consiste en la construcción de un canal de precios con una media móvil (MA) y la combinación de la amplitud de onda real (ATR) para ajustar dinámicamente el ancho del canal, lo que mantiene la adaptabilidad de la estrategia en diferentes entornos de mercado.

Principio de estrategia

La estrategia se basa principalmente en los siguientes principios centrales:

  1. Tendencia central en el cálculo de precios a través de EMA o SMA, formando el canal central
  2. Utiliza ATR, TR o Rango para calcular la fluctuación y construir el acceso y el descenso de la vía
  3. Cuando el precio se rompe en la vía de la subida, se activa una señal de más, cuando se rompe en la vía de la baja, se activa una señal de falta
  4. La adopción de un único mecanismo de cese de pérdidas para el ingreso y salida, para mejorar la fiabilidad de la ejecución de operaciones
  5. Opciones de modalidades de negociación flexibles: solo hacer más, solo hacer menos o negociar en dos sentidos

Ventajas estratégicas

  1. Adaptabilidad - Ajuste dinámico de la anchura del canal a través de ATR para que la estrategia se adapte a diferentes entornos de fluctuación del mercado
  2. Control de riesgo perfecto - El uso de un único mecanismo de cese de pérdidas para operar, control de riesgo eficaz
  3. Flexibilidad operativa: soporte para varios modos de negociación, adaptable a las características del mercado y las preferencias de negociación
  4. Validado - Ha tenido un buen desempeño en los mercados de criptomonedas y acciones, especialmente en mercados con mucha volatilidad
  5. Claridad de visualización - proporciona una visualización intuitiva de las señales de negociación y el estado de las posiciones

Riesgo estratégico

  1. Riesgo de mercado en movimiento - Falsa brecha frecuente en mercados en movimiento horizontal
  2. Riesgo de deslizamiento - en mercados con poca liquidez, los stop loss pueden tener un deslizamiento mayor
  3. Riesgo de reversión de la tendencia - puede sufrir mayores pérdidas en caso de reversión repentina de la tendencia
  4. Sensibilidad de parámetros: la elección de los parámetros de canal tiene un impacto importante en el rendimiento de la estrategia.

Dirección de optimización de la estrategia

  1. Introducción de filtros de tendencia - para reducir las falsas señales de ruptura mediante la adición de indicadores de tendencia
  2. Optimización de parámetros dinámicos - Ajuste dinámico de los parámetros de canal en función de las fluctuaciones del mercado
  3. Mecanismos de detención de pérdidas mejorados - Aumento de la función de detención de pérdidas móviles para proteger mejor los beneficios
  4. Aumento de la confirmación de tráfico - Indicadores de tráfico combinados para mejorar la fiabilidad de la señal
  5. Optimizar la gestión de las posiciones - Introducir la gestión de posiciones dinámicas para un mejor control de los riesgos

Resumir

La estrategia es un sistema de negociación perfectamente diseñado, con claridad lógica, que captura eficazmente las oportunidades de mercado mediante la aplicación flexible de los canales de Kettner y una variedad de indicadores técnicos. La estrategia es altamente personalizable y se adapta a los comerciantes con diferentes preferencias de riesgo.

Código Fuente de la Estrategia
/*backtest
start: 2022-02-11 00:00:00
end: 2025-02-08 08:00:00
period: 1d
basePeriod: 1d
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=6
strategy(title = "Jaakko's Keltner Strategy", overlay = true, initial_capital = 10000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100)

// ──────────────────────────────────────────────────────────────────────────────
// ─── USER INPUTS ─────────────────────────────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────────
length      = input.int(20,     minval=1,  title="Keltner MA Length")
mult        = input.float(2.0,             title="Multiplier")
src         = input(close,                 title="Keltner Source")
useEma      = input.bool(true,             title="Use Exponential MA")
BandsStyle  = input.string(title = "Bands Style", defval  = "Average True Range", options = ["Average True Range", "True Range", "Range"])
atrLength   = input.int(10,                title="ATR Length")

// Choose which side(s) to trade
tradeMode = input.string(title   = "Trade Mode", defval  = "Long Only", options = ["Long Only", "Short Only", "Both"])

// ──────────────────────────────────────────────────────────────────────────────
// ─── KELTNER MA & BANDS ───────────────────────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────────
f_ma(source, length, emaMode) =>
    maSma = ta.sma(source, length)
    maEma = ta.ema(source, length)
    emaMode ? maEma : maSma

ma    = f_ma(src, length, useEma)
rangeMa = BandsStyle == "True Range" ? ta.tr(true) : BandsStyle == "Average True Range" ? ta.atr(atrLength) : ta.rma(high - low, length)

upper = ma + rangeMa * mult
lower = ma - rangeMa * mult

// ──────────────────────────────────────────────────────────────────────────────
// ─── CROSS CONDITIONS ─────────────────────────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────────
crossUpper = ta.crossover(src, upper) // potential long signal
crossLower = ta.crossunder(src, lower) // potential short signal

// ──────────────────────────────────────────────────────────────────────────────
// ─── PRICE LEVELS FOR STOP ENTRY (LONG) & STOP ENTRY (SHORT) ─────────────────
// ──────────────────────────────────────────────────────────────────────────────
bprice = 0.0
bprice := crossUpper ? high + syminfo.mintick : nz(bprice[1])

sprice = 0.0
sprice := crossLower ? low - syminfo.mintick : nz(sprice[1])

// ──────────────────────────────────────────────────────────────────────────────
// ─── BOOLEAN FLAGS FOR PENDING LONG/SHORT ─────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────────
crossBcond = false
crossBcond := crossUpper ? true : crossBcond[1]

crossScond = false
crossScond := crossLower ? true : crossScond[1]

// Cancel logic for unfilled orders (same as original)
cancelBcond = crossBcond and (src < ma or high >= bprice)
cancelScond = crossScond and (src > ma or low <= sprice)

// ──────────────────────────────────────────────────────────────────────────────
// ─── LONG SIDE ────────────────────────────────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────────
if (tradeMode == "Long Only" or tradeMode == "Both")  // Only run if mode is long or both
    // Cancel unfilled long if invalid
    if cancelBcond
        strategy.cancel("KltChLE")

    // Place long entry
    if crossUpper
        strategy.entry("KltChLE", strategy.long, stop=bprice, comment="Long Entry")

    // If we are also using “Both,” we rely on short side to flatten the long.
    // But if “Long Only,” we can exit on crossLower or do nothing.
    // Let’s do a "stop exit" if in "Long Only" (like the improved version).
    if tradeMode == "Long Only"
        // Cancel unfilled exit
        if cancelScond
            strategy.cancel("KltChLX")

        // Place exit if crossLower
        if crossLower
            strategy.exit("KltChLX", from_entry="KltChLE", stop=sprice, comment="Long Exit")

// ──────────────────────────────────────────────────────────────────────────────
// ─── SHORT SIDE ───────────────────────────────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────────
if (tradeMode == "Short Only" or tradeMode == "Both") // Only run if mode is short or both
    // Cancel unfilled short if invalid
    if cancelScond
        strategy.cancel("KltChSE")

    // Place short entry
    if crossLower
        strategy.entry("KltChSE", strategy.short, stop=sprice, comment="Short Entry")

    // If “Short Only,” we might do a symmetrical exit approach for crossUpper
    // Or if "Both," going long automatically flattens the short in a no-hedge account.
    // Let's replicate "stop exit" for short side if "Short Only" is chosen:
    if tradeMode == "Short Only"
        // Cancel unfilled exit
        if cancelBcond
            strategy.cancel("KltChSX")

        // Place exit if crossUpper
        if crossUpper
            strategy.exit("KltChSX", from_entry="KltChSE", stop=bprice, comment="Short Exit")

// ──────────────────────────────────────────────────────────────────────────────
// ─── OPTIONAL VISUALS ─────────────────────────────────────────────────────────
// ──────────────────────────────────────────────────────────────────────────────
barcolor(strategy.position_size > 0 ? color.green : strategy.position_size < 0 ? color.red : na)

plotshape(    strategy.position_size > 0 and strategy.position_size[1] <= 0, title     = "BUY",  text      = '🚀',  style     = shape.labelup,    location  = location.belowbar,     color     = color.green,     textcolor = color.white,      size      = size.small)

plotshape(    strategy.position_size <= 0 and strategy.position_size[1] > 0,     title     = "SELL",     text      = '☄️',     style     = shape.labeldown,     location  = location.abovebar,     color     = color.red,       textcolor = color.white,     size      = size.small)

plotshape(crossLower, style=shape.triangledown, color=color.red, location=location.abovebar, title="CrossLower Trigger")