Estratégias flexíveis de negociação longa e curta baseadas em canais Keltner

ATR EMA SMA MA TR
Data de criação: 2025-02-10 15:07:12 última modificação: 2025-02-10 15:07:12
cópia: 4 Cliques: 448
1
focar em
1617
Seguidores

Estratégias flexíveis de negociação longa e curta baseadas em canais Keltner

Visão geral

Esta é uma estratégia de negociação flexível baseada no Keltner Channel. A estratégia suporta negociação bidirecional em múltiplos espaços, com a monitorização do aumento e diminuição do preço através da ruptura do canal. O núcleo da estratégia é construir um canal de preços usando a média móvel (MA) e ajustar dinamicamente a largura do canal em combinação com a amplitude real (ATR) para manter a adaptabilidade da estratégia em diferentes ambientes de mercado.

Princípio da estratégia

A estratégia baseia-se nos seguintes princípios:

  1. A tendência central do preço calculado através da EMA ou SMA, formando a trajectória central do canal
  2. Utilize ATR, TR ou Range para calcular a taxa de flutuação e construir um canal de subida e descida
  3. Quando o preço se eleva, um sinal de multiplicação é acionado, e quando ele baixa, um sinal de ruptura é acionado
  4. Adotar um mecanismo de entrada e saída de stop loss para aumentar a confiabilidade da execução de transações
  5. Opções de modalidades de negociação flexíveis: apenas fazer mais, apenas fazer menos ou negociação bidirecional

Vantagens estratégicas

  1. Adaptabilidade - ajuste dinâmico da largura do canal através do ATR, permitindo que a estratégia se adapte a diferentes ambientes de flutuação do mercado
  2. Controle de Risco Perfeito - Controlo de Risco eficiente com o uso de um mecanismo único de stop loss
  3. Flexibilidade de operação - Suporte a vários modos de negociação, que podem ser ajustados de acordo com as características do mercado e preferências de negociação
  4. Verificação de eficácia - bom desempenho nos mercados de criptomoedas e ações, especialmente em mercados com maior volatilidade
  5. Visualização clara - fornece sinais de negociação e visualizações intuitivas de posições

Risco estratégico

  1. Risco de mercado em choque - Falso sinal de ruptura pode ser frequente em mercados em choque horizontal
  2. Risco de deslizamento - em mercados com pouca liquidez, os contratos de stop loss podem ter um deslizamento maior
  3. Risco de reversão de tendência - pode sofrer grandes perdas em caso de reversão súbita da tendência
  4. Sensibilidade de parâmetros - a escolha de parâmetros de canal tem um impacto importante na performance da estratégia

Direção de otimização da estratégia

  1. Introdução de filtros de tendência - para reduzir os falsos sinais de ruptura adicionando indicadores de julgamento de tendência
  2. Otimização de parâmetros dinâmicos - Ajuste dinâmico de parâmetros de canal de acordo com a volatilidade do mercado
  3. Melhorar o mecanismo de parada de prejuízos - adicionar a função de parada de prejuízos móvel para melhor proteger os lucros
  4. Aumento da confirmação de volume de transação - combinação de indicadores de volume de transação para aumentar a confiabilidade do sinal
  5. Otimização da gestão de posições - introdução de gestão de posições dinâmicas para um melhor controlo do risco

Resumir

A estratégia é um sistema de negociação perfeitamente concebido e logicamente claro, que permite a captura eficaz de oportunidades de mercado através da utilização flexível do canal de Kettner e de vários indicadores tecnológicos. A estratégia é altamente personalizável e adequada para o uso de comerciantes com diferentes preferências de risco. Através de otimização e melhoria contínua, a estratégia deve manter um desempenho estável em todos os tipos de ambientes de mercado.

Código-fonte da estratégia
/*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")