Tendência intradiária Seguindo a estratégia com stop loss múltiplos

Autora:ChaoZhang, Data: 23 de dezembro de 2023
Tags:

img

Resumo

Esta estratégia incorpora múltiplas paradas de trail ATR e um ladrilho Renko melhorado para capturar os movimentos de tendências intradiárias.

Estratégia lógica

O núcleo desta estratégia reside no mecanismo de stop loss múltiplo ATR. Ele define 3 grupos de paradas ATR - 5 ATR, 10 ATR e 15 ATR. Quando o preço quebra essas 3 paradas para baixo, ele indica uma inversão de tendência, provocando a saída da posição. Tal configuração de stop triplo efetivamente filtra sinais falsos de ruídos de curto prazo.

Outro componente chave são os tijolos Renko melhorados. Eles são particionados com base nos valores ATR e incorporam SMA para determinar o viés da tendência. É mais sensível do que os tijolos Renko regulares na captura de mudanças iniciais da tendência.

O sinal de entrada é acionado quando o preço ultrapassa 3 paradas ATR. Sair quando o preço atinge qualquer paragem ATR ou mudança de cor do tijolo Renko.

Vantagens

  • As três paragens controlam eficazmente os riscos
  • Os tijolos Renko melhorados permitem paradas mais cedo.
  • A combinação de tendências e gráficos simples garante a captação das tendências
  • A análise de quadros de tempo múltiplos torna a identificação de tendências mais fiável
  • Parâmetros ajustáveis adequados a diferentes regimes de mercado

Riscos e melhorias

O principal risco é a penetração de stop loss causando perdas prolongadas.

  • Ajustar múltiplos de parada ATR - relaxar em tendências fortes e apertar em tendências fracas
  • Períodos ATR de tijolo Renko para equilibrar sensibilidade e estabilidade
  • Adicionar outros indicadores de parada, por exemplo, canal de Donchian para confiabilidade
  • Implementar filtros para evitar problemas durante a consolidação

Conclusão

Esta estratégia funciona bem para fortes tendências intradiárias. Seu mecanismo de stop loss científico e a detecção precoce de mudança de tendência por tijolos Renko aprimorados são dignos de nota. Parâmetros ajustados podem adaptá-lo a diferentes condições de mercado. Vale a pena testar ao vivo como um sistema de tendência.


/*backtest
start: 2022-12-20 00:00:00
end: 2023-12-26 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("Lancelot vstop intraday strategy", overlay=true, currency=currency.NONE, initial_capital = 100, commission_type=strategy.commission.percent, 
     commission_value=0.075, default_qty_type = strategy.percent_of_equity, default_qty_value = 100)

///Volatility Stop///
lengtha = input(title="Vstop length", type=input.integer, defval=26, minval=1)
mult1a = 5

atr_a = atr(lengtha)
max1a = 0.0
min1a = 0.0
is_uptrend_preva = false
stopa = 0.0
vstop_preva = 0.0
vstop1a = 0.0
is_uptrenda = false
is_trend_changeda = false
max_a = 0.0
min_a = 0.0
vstopa = 0.0
max1a := max(nz(max_a[1]), ohlc4)
min1a := min(nz(min_a[1]), ohlc4)
is_uptrend_preva := nz(is_uptrenda[1], true)
stopa := is_uptrend_preva ? max1a - mult1a * atr_a : min1a + mult1a * atr_a
vstop_preva := nz(vstopa[1])
vstop1a := is_uptrend_preva ? max(vstop_preva, stopa) : min(vstop_preva, stopa)
is_uptrenda := ohlc4 - vstop1a >= 0
is_trend_changeda := is_uptrenda != is_uptrend_preva
max_a := is_trend_changeda ? ohlc4 : max1a
min_a := is_trend_changeda ? ohlc4 : min1a
vstopa := is_trend_changeda ? is_uptrenda ? max_a - mult1a * atr_a : min_a + mult1a * atr_a : 
   vstop1a

///Volatility Stop///
lengthb = input(title="Vstop length", type=input.integer, defval=26, minval=1)
mult1b = 10

atr_b = atr(lengthb)
max1b = 0.0
min1b = 0.0
is_uptrend_prevb = false
stopb = 0.0
vstop_prevb = 0.0
vstop1b = 0.0
is_uptrendb = false
is_trend_changedb = false
max_b = 0.0
min_b = 0.0
vstopb = 0.0
max1b := max(nz(max_b[1]), ohlc4)
min1b := min(nz(min_b[1]), ohlc4)
is_uptrend_prevb := nz(is_uptrendb[1], true)
stopb := is_uptrend_prevb ? max1b - mult1b * atr_b : min1b + mult1b * atr_b
vstop_prevb := nz(vstopb[1])
vstop1b := is_uptrend_prevb ? max(vstop_prevb, stopb) : min(vstop_prevb, stopb)
is_uptrendb := ohlc4 - vstop1b >= 0
is_trend_changedb := is_uptrendb != is_uptrend_prevb
max_b := is_trend_changedb ? ohlc4 : max1b
min_b := is_trend_changedb ? ohlc4 : min1b
vstopb := is_trend_changedb ? is_uptrendb ? max_b - mult1b * atr_b : min_b + mult1b * atr_b : 
   vstop1b
   
///Volatility Stop///
lengthc = input(title="Vstop length", type=input.integer, defval=26, minval=1)
mult1c = 15

atr_c = atr(lengthc)
max1c = 0.0
min1c = 0.0
is_uptrend_prevc = false
stopc = 0.0
vstop_prevc = 0.0
vstop1c = 0.0
is_uptrendc = false
is_trend_changedc = false
max_c = 0.0
min_c = 0.0
vstopc = 0.0
max1c := max(nz(max_c[1]), ohlc4)
min1c := min(nz(min_c[1]), ohlc4)
is_uptrend_prevc := nz(is_uptrendc[1], true)
stopc := is_uptrend_prevc ? max1c - mult1c * atr_c : min1c + mult1c * atr_c
vstop_prevc := nz(vstopc[1])
vstop1c := is_uptrend_prevc ? max(vstop_prevc, stopc) : min(vstop_prevc, stopc)
is_uptrendc := ohlc4 - vstop1c >= 0
is_trend_changedc := is_uptrendc != is_uptrend_prevc
max_c := is_trend_changedc ? ohlc4 : max1c
min_c := is_trend_changedc ? ohlc4 : min1c
vstopc := is_trend_changedc ? is_uptrendc ? max_c - mult1c * atr_c : min_c + mult1c * atr_c : 
   vstop1c

plot(vstopa, color=is_uptrenda ? color.green : color.red, style=plot.style_line, linewidth=1)
plot(vstopb, color=is_uptrendb ? color.green : color.red, style=plot.style_line, linewidth=1)
plot(vstopc, color=is_uptrendc ? color.green : color.red, style=plot.style_line, linewidth=1)

vstoplongcondition = close > vstopa and close > vstopb and close > vstopc and vstopa > vstopb and vstopa > vstopc and vstopb > vstopc
vstoplongclosecondition = crossunder(close, vstopa)
vstopshortcondition = close < vstopa and close < vstopb and close < vstopc and vstopa < vstopb and vstopa < vstopc and vstopb < vstopc
vstopshortclosecondition = crossover(close, vstopa)

///Renko///
TF = input(title='TimeFrame', type=input.resolution, defval="240")
ATRlength = input(title="ATR length", type=input.integer, defval=60, minval=2, maxval=100)
SMAlength = input(title="SMA length", type=input.integer, defval=5, minval=2, maxval=100)
SMACurTFlength = input(title="SMA CurTF length", type=input.integer, defval=20, minval=2, maxval=100)

HIGH = security(syminfo.tickerid, TF, high)
LOW = security(syminfo.tickerid, TF, low)
CLOSE = security(syminfo.tickerid, TF, close)
ATR = security(syminfo.tickerid, TF, atr(ATRlength))
SMA = security(syminfo.tickerid, TF, sma(close, SMAlength))
SMACurTF = sma(close, SMACurTFlength)

RENKOUP = float(na)
RENKODN = float(na)
H = float(na)
COLOR = color(na)
BUY = int(na)
SELL = int(na)
UP = bool(na)
DN = bool(na)
CHANGE = bool(na)

RENKOUP := na(RENKOUP[1]) ? (HIGH + LOW) / 2 + ATR / 2 : RENKOUP[1]
RENKODN := na(RENKOUP[1]) ? (HIGH + LOW) / 2 - ATR / 2 : RENKODN[1]
H := na(RENKOUP[1]) or na(RENKODN[1]) ? RENKOUP - RENKODN : RENKOUP[1] - RENKODN[1]
COLOR := na(COLOR[1]) ? color.white : COLOR[1]
BUY := na(BUY[1]) ? 0 : BUY[1]
SELL := na(SELL[1]) ? 0 : SELL[1]
UP := false
DN := false
CHANGE := false

if not CHANGE and close >= RENKOUP[1] + H * 3
    CHANGE := true
    UP := true
    RENKOUP := RENKOUP[1] + ATR * 3
    RENKODN := RENKOUP[1] + ATR * 2
    COLOR := color.lime
    SELL := 0
    BUY := BUY + 3
    BUY

if not CHANGE and close >= RENKOUP[1] + H * 2
    CHANGE := true
    UP := true
    RENKOUP := RENKOUP[1] + ATR * 2
    RENKODN := RENKOUP[1] + ATR
    COLOR := color.lime
    SELL := 0
    BUY := BUY + 2
    BUY

if not CHANGE and close >= RENKOUP[1] + H
    CHANGE := true
    UP := true
    RENKOUP := RENKOUP[1] + ATR
    RENKODN := RENKOUP[1]
    COLOR := color.lime
    SELL := 0
    BUY := BUY + 1
    BUY

if not CHANGE and close <= RENKODN[1] - H * 3
    CHANGE := true
    DN := true
    RENKODN := RENKODN[1] - ATR * 3
    RENKOUP := RENKODN[1] - ATR * 2
    COLOR := color.red
    BUY := 0
    SELL := SELL + 3
    SELL

if not CHANGE and close <= RENKODN[1] - H * 2
    CHANGE := true
    DN := true
    RENKODN := RENKODN[1] - ATR * 2
    RENKOUP := RENKODN[1] - ATR
    COLOR := color.red
    BUY := 0
    SELL := SELL + 2
    SELL

if not CHANGE and close <= RENKODN[1] - H
    CHANGE := true
    DN := true
    RENKODN := RENKODN[1] - ATR
    RENKOUP := RENKODN[1]
    COLOR := color.red
    BUY := 0
    SELL := SELL + 1
    SELL

plotshape(UP, style=shape.arrowup, location=location.abovebar, size=size.normal)
plotshape(DN, style=shape.arrowdown, location=location.belowbar, size=size.normal)

p1 = plot(RENKOUP, style=plot.style_line, linewidth=1, color=COLOR)
p2 = plot(RENKODN, style=plot.style_line, linewidth=1, color=COLOR)
fill(p1, p2, color=COLOR, transp=80)

///Long Entry///
longcondition = vstoplongcondition and UP
if (longcondition)
    strategy.entry("Long", strategy.long)
    
///Long exit///
closeconditionlong = vstoplongclosecondition or DN
if (closeconditionlong)
    strategy.close("Long")
    
// ///Short Entry///
// shortcondition = vstopshortcondition and DN
// if (shortcondition)
//     strategy.entry("Short", strategy.short)
    
// ///Short exit///
// closeconditionshort = vstopshortclosecondition or UP
// if (closeconditionshort)
//     strategy.close("Short")

Mais.