Estratégia de acompanhamento de tendências em quadros de tempo múltiplos baseada em supertendências

Autora:ChaoZhang, Data: 2024-02-21 11:05:17
Tags:

img

Resumo

A ideia central desta estratégia é combinar vários prazos para identificar tendências de mercado, usando o indicador Supertrend de prazos mais altos como um filtro e gerando sinais de compra e venda de prazos mais baixos.

Estratégia lógica

A estratégia recupera os valores do indicador Supertrend de um período de tempo mais longo (default 4x do período de tempo atual) chamando a função de segurança. O indicador Supertrend consiste em duas linhas: a linha Supertrend e a linha de tendência.

A direção do indicador de Supertrend do quadro de tempo superior serve como uma condição de filtro. Os sinais de negociação só são gerados quando as direções do Supertrend de ambos os quadros de tempo se alinham. Isso significa que os sinais só são acionados quando ambos os quadros de tempo dão sinais na mesma direção.

Isto evita interferências do ruído do mercado em prazos mais curtos e melhora a fiabilidade do sinal.

Vantagens

  • Filtra o ruído de prazos mais baixos utilizando informações sobre a estrutura do mercado de prazos mais elevados
  • Sinais mais fiáveis resultantes da combinação de análises de vários prazos
  • Parâmetros Supertrend personalizáveis para otimização de estratégia
  • Configurações integradas de intervalo de datas para restringir o período de backtest

Análise de riscos

  • Os sinais de atraso de um prazo mais longo podem perder oportunidades de curto prazo
  • Incorrecções nos julgamentos sobre a estrutura do mercado a prazo mais longo
  • Potenciais sinais errôneos do próprio Supertrend
  • As restrições relativas à data do backtest podem omitir dados importantes e afetar a precisão dos resultados

Soluções:

  • Ajuste fino de configurações de intervalos de tempo mais altos para reduzir o atraso do sinal
  • Adicionar outros indicadores para confirmar julgamentos de prazo mais longo
  • Otimizar os parâmetros da Supertrend para melhorar a qualidade do sinal
  • Expandir progressivamente o período de tempo de backtest para testar a robustez

Orientações de otimização

Esta estratégia pode ser melhorada em vários domínios:

  1. Otimizar parâmetros Supertrend para melhor combinação de parâmetros
  2. Adicionar outros indicadores para criar modelos multifatores
  3. Teste diferentes combinações de prazos altos e baixos
  4. Incorporar mecanismos de stop loss para controlar os riscos
  5. Utilize o aprendizado de máquina para ajustar dinamicamente parâmetros

Através da otimização de parâmetros, da combinação de indicadores, da melhoria das paradas de perda e da introdução do aprendizado de máquina, pode ser alcançada uma melhoria significativa do desempenho para esta estratégia de rastreamento de tendências de vários prazos.

Conclusão

Esta estratégia aproveita habilmente julgamentos de tendência de maior prazo para orientar a execução de negociações em prazos mais baixos. Tal design de multitimeframe pode efetivamente filtrar o ruído do mercado e identificar direções de tendência mais claras. As configurações de data incorporadas também tornam o backtesting mais flexível.


/*backtest
start: 2023-02-14 00:00:00
end: 2024-02-20 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/
// © HeWhoMustNotBeNamed

//@version=4
strategy("Higher TF - Repainting", overlay=true, initial_capital = 100000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true)

HTFMultiplier = input(4, minval=1, step=1)

SupertrendMult = input(1)
SupertrendPd = input(4, minval=4, step=4)

backtestBars = input(title="Backtest from ", defval=10, minval=1, maxval=30)
backtestFrom = input(title="Timeframe", defval="years", options=["days", "months", "years"])

repaintOption = input(title="Repaint", defval="Yes", options=["Yes", "No - set lookahead false", "No - do not use security"])

f_multiple_resolution(HTFMultiplier) => 
    target_Res_In_Min = timeframe.multiplier * HTFMultiplier * (
      timeframe.isseconds   ? 1. / 60. :
      timeframe.isminutes   ? 1. :
      timeframe.isdaily     ? 1440. :
      timeframe.isweekly    ? 7. * 24. * 60. :
      timeframe.ismonthly   ? 30.417 * 24. * 60. : na)

    target_Res_In_Min     <= 0.0417       ? "1S"  :
      target_Res_In_Min   <= 0.167        ? "5S"  :
      target_Res_In_Min   <= 0.376        ? "15S" :
      target_Res_In_Min   <= 0.751        ? "30S" :
      target_Res_In_Min   <= 1440         ? tostring(round(target_Res_In_Min)) :
      tostring(round(min(target_Res_In_Min / 1440, 365))) + "D"

f_getBackTestTimeFrom(backtestFrom, backtestBars)=>
    byDate = backtestFrom == "days"
    byMonth = backtestFrom == "months"
    byYear = backtestFrom == "years"
    
    date = dayofmonth(timenow)
    mth = month(timenow)
    yr = year(timenow)
    
    leapYearDaysInMonth = array.new_int(12,0)
    array.set(leapYearDaysInMonth,0,31)
    array.set(leapYearDaysInMonth,1,29)
    nonleapYearDaysInMonth = array.new_int(12,0)
    array.set(leapYearDaysInMonth,0,31)
    array.set(leapYearDaysInMonth,1,28)
    
    restMonths = array.new_int(10,0)
    array.set(leapYearDaysInMonth,0,31)
    array.set(leapYearDaysInMonth,1,30)
    array.set(leapYearDaysInMonth,2,31)
    array.set(leapYearDaysInMonth,3,30)
    array.set(leapYearDaysInMonth,4,31)
    array.set(leapYearDaysInMonth,5,31)
    array.set(leapYearDaysInMonth,6,30)
    array.set(leapYearDaysInMonth,7,31)
    array.set(leapYearDaysInMonth,8,30)
    array.set(leapYearDaysInMonth,9,31)
    
    array.concat(leapYearDaysInMonth,restMonths)
    array.concat(nonleapYearDaysInMonth,restMonths)
    isLeapYear = yr % 4 == 0 and (year%100 != 0 or year%400 == 0)
    numberOfDaysInCurrentMonth = isLeapYear ? array.get(leapYearDaysInMonth, mth-2) : array.get(nonleapYearDaysInMonth, mth-2)
    if(byDate)
        mth := (date - backtestBars) < 0 ? mth - 1 : mth
        yr := mth < 1 ? yr - 1 : yr
        mth := mth < 1 ? 1 : mth
        date := (date - backtestBars) < 0 ? numberOfDaysInCurrentMonth - backtestBars + date + 1 : date - backtestBars + 1
    if(byMonth)
        date := 1
        yr := (mth - (backtestBars%12)) < 0 ? yr - int(backtestBars/12) - 1 : yr - int(backtestBars/12)
        mth := mth - (backtestBars%12) + 1
    if(byYear)
        date := 1
        mth := 1
        yr := yr - backtestBars
    [date, mth, yr]


repaint = repaintOption == "Yes"
useSecurityLookahead = repaintOption == "No - set lookahead false"

[SupertrendRepaint, DirRepaint] = security(syminfo.tickerid, f_multiple_resolution(HTFMultiplier), supertrend(SupertrendMult, SupertrendPd), lookahead = true, gaps=true)
[SupertrendNoLookahead, DirNoLookahead] = security(syminfo.tickerid, f_multiple_resolution(HTFMultiplier), supertrend(SupertrendMult, SupertrendPd), lookahead = false, gaps=false)

[SupertrendRegular, DirRegular] = supertrend(SupertrendMult, SupertrendPd)

[date, mth, yr] = f_getBackTestTimeFrom(backtestFrom, backtestBars)
inDateRange = time >= timestamp(syminfo.timezone, yr, mth, date, 0, 0)

longCondition = repaint ? DirRepaint == -1 : useSecurityLookahead? DirNoLookahead == -1 : DirRegular == -1
shortCondition = repaint ? DirRepaint == 1 : useSecurityLookahead? DirNoLookahead == 1 : DirRegular == 1
strategy.entry("Buy", strategy.long, when=longCondition and inDateRange)
strategy.entry("Sell", strategy.short, when=shortCondition and inDateRange)


Mais.