Tendência de ID de duplo quadro temporal Seguindo a estratégia

Autora:ChaoZhang, Data: 2023-11-07 16:31:07
Tags:

img

Resumo

Esta estratégia usa o Índice Direcional Médio (DI +) e Índice Direcional Negativo (DI-) em dois prazos para determinar a direção da tendência para negociações longas e curtas. Quando o DI + é maior que o DI - em prazos maiores e menores, ele indica uma tendência ascendente e um sinal longo é acionado. Quando o DI - é maior que o DI + em ambos os prazos, ele indica uma tendência descendente e um sinal curto é acionado.

Como funciona

A estratégia baseia-se em vários princípios:

  1. Calcule DI+ e DI-. Obtenha DI+ e DI- usando preços altos, próximos e baixos.

  2. Comparar DI+ e DI- em dois intervalos de tempo. Calcular DI+ e DI- respectivamente no período de tempo principal do gráfico (por exemplo, 1 hora) e um período de tempo maior (por exemplo, diário). Comparar os valores entre os dois intervalos de tempo.

  3. Determine a direção da tendência. Quando o DI+ é maior que o DI- em ambos os prazos maiores e menores, indica uma tendência ascendente. Quando o DI- é maior que o DI+ em ambos os prazos, indica uma tendência descendente.

  4. DI+>DI- em ambos os quadros dá sinal longo.

  5. Usar o ATR para calcular o stop loss dinâmico para seguir a tendência.

  6. Condições de saída: saída quando o stop loss é atingido ou o preço reverte.

Vantagens

A estratégia apresenta as seguintes vantagens:

  1. Usando o DI de duplo quadro de tempo, filtramos algumas falhas.

  2. O ATR trailing stop maximiza a proteção dos lucros e evita que as paradas sejam muito apertadas.

  3. O stop loss oportuno controla as perdas em operações individuais.

  4. A negociação com a tendência permite a captação contínua de tendências.

  5. Regras simples e claras, fáceis de implementar para negociação ao vivo.

Riscos e soluções

Há também vários riscos:

  1. O DI tem efeito de atraso, pode perder o tempo de entrada, pode otimizar parâmetros ou adicionar outros indicadores.

  2. O duplo quadro de tempo pode ter divergência entre o TF maior e menor. Adicione mais validação de quadro de tempo.

  3. Stop loss muito agressivo pode causar excesso de negociação.

  4. A serralheira no mercado lateral pode causar trocas frequentes.

  5. A otimização de parâmetros depende de dados históricos e pode ser sobreajustada.

Orientações de otimização

A estratégia pode ser melhorada nos seguintes aspectos:

  1. Otimizar os parâmetros de cálculo do DI para o melhor conjunto de parâmetros.

  2. Adicionar outros filtros de indicadores para melhorar a precisão do sinal, por exemplo, MACD, KDJ, etc.

  3. Melhorar a estratégia de stop loss para adaptar mais condições de mercado, tais como trailing stop ou ordens pendentes.

  4. Adicione filtros de sessão de negociação para evitar eventos noticiosos significativos.

  5. Teste a robustez dos parâmetros em diferentes produtos para melhorar a adaptabilidade.

  6. Introduzir aprendizado de máquina para treinar modelos com dados históricos.

Conclusão

Em resumo, esta é uma estratégia típica de seguimento de tendências que usa DI para determinar a direção da tendência e definir stop loss para bloquear lucros ao longo da tendência. A vantagem reside em sua lógica clara e facilidade de implementação para negociação ao vivo.


/*backtest
start: 2022-10-31 00:00:00
end: 2023-11-06 00:00:00
period: 1d
basePeriod: 1h
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/
// © DojiEmoji

//@version=5
strategy("DI+/- multi TF Strat [KL]", overlay=true, pyramiding=1, initial_capital=1000000000, default_qty_type=strategy.percent_of_equity, default_qty_value=5)
var string GROUP_ALERT    = "Alerts"
var string GROUP_SL       = "Stop loss"
var string GROUP_ORDER    = "Order size"
var string GROUP_TP       = "Profit taking"
var string GROUP_HORIZON  = "Time horizon of backtests"
var string GROUP_IND      = "Directional IndicatorDI+ DI-"

// ADX Indicator {
adx_len = input(14, group=GROUP_IND, tooltip="Typically 14")
tf1 = input.timeframe("", title="DI +/- in Timeframe 1", group=GROUP_IND, tooltip="Main: DI+ > DI-")
tf2 = input.timeframe("1D", title="DI +/- in Timeframe 2", group=GROUP_IND, tooltip="Confirmation: DI+ > DI-")
// adx_thres = input(20, group=GROUP_IND)   //threshold not used in this strategy

get_ADX(_high, _close, _low) =>
// (high, close, mid) -> [plus_DM, minus_DM]
    // Based on TradingView user BeikabuOyaji's implementation
    _tr = math.max(math.max(_high - _low, math.abs(_high - nz(_close[1]))), math.abs(_low - nz(_close[1])))
    smooth_tr = 0.0
    smooth_tr := nz(smooth_tr[1]) - nz(smooth_tr[1]) / adx_len + _tr

    smooth_directional_mov_plus = 0.0
    smooth_directional_mov_plus := nz(smooth_directional_mov_plus[1]) - nz(smooth_directional_mov_plus[1]) / adx_len + (_high - nz(_high[1]) > nz(_low[1]) - _low ? math.max(_high - nz(_high[1]), 0) : 0)

    smooth_directional_mov_minus = 0.0
    smooth_directional_mov_minus := nz(smooth_directional_mov_minus[1]) - nz(smooth_directional_mov_minus[1]) / adx_len + (nz(_low[1]) - _low > _high - nz(_high[1]) ? math.max(nz(_low[1]) - _low, 0) : 0)

    plus_DM = smooth_directional_mov_plus / smooth_tr * 100
    minus_DM = smooth_directional_mov_minus / smooth_tr * 100
    // DX = math.abs(plus_DM - minus_DM) / (plus_DM + minus_DM) * 100   // DX not used in this strategy
    [plus_DM, minus_DM]

// DI +/- from timeframes 1 and 2
[plus_DM_tf1, minus_DM_tf1] = get_ADX(request.security(syminfo.tickerid, tf1, high), request.security(syminfo.tickerid, tf1, close),request.security(syminfo.tickerid, tf1, low))
[plus_DM_tf2, minus_DM_tf2] = get_ADX(request.security(syminfo.tickerid, tf2, high),request.security(syminfo.tickerid, tf2, close),request.security(syminfo.tickerid, tf2, low))
// } end of block: ADX Indicator


var string ENUM_LONG      = "LONG"
var string LONG_MSG_ENTER = input.string("Long entered", title="Alert MSG for buying (Long position)", group=GROUP_ALERT)
var string LONG_MSG_EXIT  = input.string("Long closed", title="Alert MSG for closing (Long position)", group=GROUP_ALERT)
backtest_timeframe_start = input(defval=timestamp("01 Apr 2020 13:30 +0000"), title="Backtest Start Time", group=GROUP_HORIZON)
within_timeframe         = true

// Signals for entry
_uptrend_confirmed = plus_DM_tf1 > minus_DM_tf1 and plus_DM_tf2 > minus_DM_tf2
entry_signal_long = _uptrend_confirmed

plotshape(_uptrend_confirmed, style=shape.triangleup, location=location.bottom, color=color.green)
plotshape(not _uptrend_confirmed, style=shape.triangledown, location=location.bottom, color=color.red)

// Trailing stop loss ("TSL") {
tsl_multi                 = input.float(2.0, title="ATR Multiplier for trailing stoploss", group=GROUP_SL)
SL_buffer                 = ta.atr(input.int(14, title="Length of ATR for trailing stoploss", group=GROUP_SL)) * tsl_multi
TSL_source_long           = low
var stop_loss_price_long  = float(0)
var pos_opened_long       = false

stop_loss_price_long := pos_opened_long ? math.max(stop_loss_price_long, TSL_source_long - SL_buffer) : TSL_source_long - SL_buffer

// MAIN: {
if pos_opened_long and TSL_source_long <= stop_loss_price_long
    pos_opened_long := false
    alert(LONG_MSG_EXIT, alert.freq_once_per_bar)
    strategy.close(ENUM_LONG, comment=close < strategy.position_avg_price ? "stop loss" : "take profit")

// (2) Update the stoploss to latest trailing amt.
if pos_opened_long
    strategy.exit(ENUM_LONG, stop=stop_loss_price_long, comment="SL")

// (3) INITIAL ENTRY:
if within_timeframe and entry_signal_long
    pos_opened_long := true
    alert(LONG_MSG_ENTER, alert.freq_once_per_bar)
    strategy.entry(ENUM_LONG, strategy.long, comment="long")

// Plotting: 
TSL_transp_long = pos_opened_long and within_timeframe ? 0 : 100
plot(stop_loss_price_long, color=color.new(color.green, TSL_transp_long))

// CLEAN UP: Setting variables back to default values once no longer in use
if ta.change(strategy.position_size) and strategy.position_size == 0
    pos_opened_long := false

if not pos_opened_long
    stop_loss_price_long := float(0)

// } end of MAIN block


Mais.