Estratégia de negociação de combinação de média móvel de Hull e RSI estocástico

Autora:ChaoZhang, Data: 2023-10-18 12:40:23
Tags:

img

Resumo

Esta estratégia usa a média móvel de Hull para determinar a direção da tendência e a combina com o RSI estocástico para sinais de entrada. Os negócios longos são feitos quando a linha média do HMA cruza acima da linha inferior e os negócios curtos quando ela cruza abaixo da linha superior. Além disso, os negócios longos são inseridos quando a linha do RSI estocástico K cruza abaixo da linha D da zona de sobrecompra, enquanto os negócios curtos são inseridos em cruzes acima da zona de sobrevenda.

Estratégia lógica

Os principais componentes desta estratégia são a média móvel Hull para a direção da tendência e o RSI estocástico para os sinais de entrada de tempo.

Em primeiro lugar, o cálculo do MA de Hull inclui fórmulas para as faixas média, superior e inferior.

A direção da tendência é determinada pela relação entre a faixa média e as faixas superior/inferior.

O cálculo do RSI estocástico também é definido, incluindo os valores suavizados K e D. O valor K usa uma suavização da SMA no RSI, enquanto o valor D é uma segunda suavização da SMA no K.

Após a determinação da direção da tendência, as negociações longas são realizadas quando a linha K do Stoch RSI cruza abaixo da linha D da zona de sobrecompra durante uma tendência de alta.

A combinação do filtro de tendência de Hull e da análise de sobrecompra/supervenda do RSI do Stoch fornece uma abordagem robusta de vários fatores para iniciar negociações.

Vantagens

Os principais benefícios desta estratégia são:

  1. O MA Hull identifica eficazmente a direcção geral da tendência do mercado.

  2. O RSI do Stoch determina os níveis de sobrecompra/supervenda para entradas de tempo.

  3. Usar ambos juntos reduz os falsos sinais e combina os pontos fortes.

  4. Flexibilidade para otimizar parâmetros para diferentes símbolos e prazos.

  5. As bandas de casco identificam o potencial de suporte e resistência dinâmicas.

  6. Inclui regras de dimensionamento das posições e de gestão do risco.

  7. Capacidade multi-asset através do dicionário de dados do casco.

  8. Componentes otimizáveis para melhorar a rentabilidade e reduzir os tiros.

Riscos

Alguns riscos a considerar:

  1. O Hull MA tem atraso e pode perder as mudanças de tendência.

  2. O RSI do Stoch pode gerar sinais excessivos se os parâmetros não forem otimizados.

  3. A incompatibilidade entre os parâmetros Hull e Stoch pode causar maus sinais.

  4. Bandas de casco muito largas ou estreitas afetarão a qualidade do sinal.

  5. Os mercados voláteis recentes desafiam os indicadores de médio e longo prazo.

  6. Descoordenações de dados entre Hull e Stoch causando sinais falsos.

  7. As mudanças acentuadas de tendência não detectadas pelo Hull podem causar perdas.

  8. Precisamos de testes expandidos em vários prazos e símbolos.

Algumas maneiras de resolver estes problemas:

  1. Encurtar o comprimento MA do casco para uma maior sensibilidade à tendência.

  2. Optimize o RSI do Stoch para filtrar falsos cruzamentos.

  3. Encontre a largura de canal de banda ideal do casco.

  4. Adicionar indicadores de confirmação adicionais como o MACD.

  5. Incorporar estratégias de stop loss para controlar o risco.

Oportunidades de otimização

Algumas formas de melhorar esta estratégia:

  1. Teste em mais símbolos em vários prazos para verificar a robustez.

  2. Incorporar mecanismos de stop loss como trailing stops ou médias móveis.

  3. Otimizar as regras de entrada, definir filtros mais rigorosos para reduzir os falsos sinais.

  4. Explorar usando bandas de casco para definir melhor suporte e resistência.

  5. Avaliar indicadores de confirmação adicionais para melhorar a fiabilidade do sinal.

  6. Optimização de parâmetros para comprimentos, níveis de sobrecompra/supervenda, etc.

  7. Introduzir um melhor dimensionamento das posições e uma melhor gestão dos riscos.

  8. Regras adicionais de entrada, stop loss e take profit essenciais para negociação ao vivo.

  9. Otimizar o comprimento do casco para uma melhor sensibilidade à tendência.

  10. Adicionar filtros ou indicadores de confirmação para melhorar a qualidade do sinal.

  11. Explorar bandas de casco para níveis dinâmicos de apoio/resistência.

  12. Otimizar os parâmetros do RSI do Stoch, como comprimento, sobrecompra/supervenda.

  13. Implementar dimensionamento avançado das posições e gestão de riscos.

Conclusão

No geral, esta é uma abordagem eficaz que combina tendência e impulso. No entanto, as fraquezas inerentes do indicador significam que os sinais não devem ser confiados cegamente sem otimização e controles de risco adicionais. Com parâmetros refinados, filtros adicionais e stop losses, esta estratégia oferece potencial. É necessário testes mais extensos para parâmetros, gerenciamento de risco e dimensionamento de posição para torná-la robusta e lucrativa para negociação ao vivo.


/*backtest
start: 2023-10-16 00:00:00
end: 2023-10-17 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
//Basic Hull Ma Pack tinkered by InSilico 
//Converted to Strategy by DashTrader
strategy("Hull Suite + Stoch RSI Strategy v1.1", overlay=true, pyramiding=1, initial_capital=100, default_qty_type= strategy.percent_of_equity, default_qty_value = 100, calc_on_order_fills=false, slippage=0,commission_type=strategy.commission.percent,commission_value=0.023)
strat_dir_input = input(title="Strategy Direction", defval="all", options=["long", "short", "all"])
strat_dir_value = strat_dir_input == "long" ? strategy.direction.long : strat_dir_input == "short" ? strategy.direction.short : strategy.direction.all
strategy.risk.allow_entry_in(strat_dir_value)
//////////////////////////////////////////////////////////////////////
// Testing Start dates
testStartYear = input(2016, "Backtest Start Year")
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0)
//Stop date if you want to use a specific range of dates
testStopYear = input(2030, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(30, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,0,0)

stoch_upper_input = input(88, "Stoch Upper Threshold", type=input.float)
stoch_lower_input = input(5, "Stoch Lower Threshold", type=input.float)
sl = input(0.7, "SL %", type=input.float, step=0.1)
tp = input(2.1, "TP %", type=input.float, step=0.1)
// slowEMA = ema(close, slowEMA_input)

// vwap = vwap(close)
// rsi = rsi(close, rsi_input)


// stoch rsi
smoothK = 3
smoothD = 3
lengthRSI = 14
lengthStoch = 14
rsi1 = rsi(close, 14)
k = sma(stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d = sma(k, smoothD)

testPeriod() =>
    time >= testPeriodStart and time <= testPeriodStop ? true : false
// Component Code Stop
//////////////////////////////////////////////////////////////////////
//INPUT
src = input(close, title="Source")
modeSwitch = input("Hma", title="Hull Variation", options=["Hma", "Thma", "Ehma"])
length = input(180, title="Length(180-200 for floating S/R , 55 for swing entry)")
switchColor = input(true, "Color Hull according to trend?")
candleCol = input(false,title="Color candles based on Hull's Trend?")
visualSwitch  = input(true, title="Show as a Band?")
thicknesSwitch = input(1, title="Line Thickness")
transpSwitch = input(40, title="Band Transparency",step=5)

//FUNCTIONS
//HMA
HMA(_src, _length) =>  wma(2 * wma(_src, _length / 2) - wma(_src, _length), round(sqrt(_length)))
//EHMA    
EHMA(_src, _length) =>  ema(2 * ema(_src, _length / 2) - ema(_src, _length), round(sqrt(_length)))
//THMA    
THMA(_src, _length) =>  wma(wma(_src,_length / 3) * 3 - wma(_src, _length / 2) - wma(_src, _length), _length)
    
//SWITCH
Mode(modeSwitch, src, len) =>
      modeSwitch == "Hma"  ? HMA(src, len) :
      modeSwitch == "Ehma" ? EHMA(src, len) : 
      modeSwitch == "Thma" ? THMA(src, len/2) : na
      
//OUT
HULL = Mode(modeSwitch, src, length)
MHULL = HULL[0]
SHULL = HULL[2]

//COLOR
hullColor = switchColor ? (HULL > HULL[2] ? #00ff00 : #ff0000) : #ff9800

//PLOT
///< Frame
Fi1 = plot(MHULL, title="MHULL", color=hullColor, linewidth=thicknesSwitch, transp=50)
Fi2 = plot(visualSwitch ? SHULL : na, title="SHULL", color=hullColor, linewidth=thicknesSwitch, transp=50)
///< Ending Filler
fill(Fi1, Fi2, title="Band Filler", color=hullColor, transp=transpSwitch)
///BARCOLOR
barcolor(color = candleCol ? (switchColor ? hullColor : na) : na)

bgcolor(color = k < stoch_lower_input  and crossover(k, d) ? color.green : na)
bgcolor(color = d > stoch_upper_input and crossover(d, k) ? color.red : na)

notInTrade = strategy.position_size == 0

if notInTrade and HULL[0] > HULL[2] and testPeriod() and k < stoch_lower_input and crossover(k, d)
// if HULL[0] > HULL[2] and testPeriod()
    stopLoss = close * (1 - sl / 100) 
    profit25 = close * (1 + (tp / 100) * 0.25)
    profit50 = close * (1 + (tp / 100) * 0.5)
    takeProfit = close * (1 + tp / 100)
    
    
    strategy.entry("long", strategy.long, alert_message="buy")
    strategy.exit("exit long 25%", "long", stop=stopLoss, limit=profit25, qty_percent=25, alert_message="profit_25")
    strategy.exit("exit long 50%", "long", stop=stopLoss, limit=profit50, qty_percent=25, alert_message="profit_50")
    strategy.exit("exit long", "long", stop=stopLoss, limit=takeProfit)
    
    // line.new(bar_index, profit25, bar_index + 4, profit25, color=color.green)
    // line.new(bar_index, profit50, bar_index + 4, profit50, color=color.green)
    // box.new(bar_index, stopLoss, bar_index + 4, close, border_color=color.red, bgcolor=color.new(color.red, 80))
    // box.new(bar_index, close, bar_index + 4, takeProfit, border_color=color.green, bgcolor=color.new(color.green, 80))

    
if notInTrade and HULL[0] < HULL[2] and testPeriod() and d > stoch_upper_input and crossover(d, k)
// if HULL[0] < HULL[2] and testPeriod()
    stopLoss = close * (1 + sl / 100)
    profit25 = close * (1 - (tp / 100) * 0.25)
    profit50 = close * (1 - (tp / 100) * 0.5)
    takeProfit = close * (1 - tp / 100)
    
    

    strategy.entry("short", strategy.short, alert_message="sell")
    strategy.exit("exit short 25%", "short", stop=stopLoss, limit=profit25, qty_percent=25, alert_message="profit_25")
    strategy.exit("exit short 50%", "short", stop=stopLoss, limit=profit50, qty_percent=25, alert_message="profit_50")
    strategy.exit("exit short", "short", stop=stopLoss, limit=takeProfit)
    
    // line.new(bar_index, profit25, bar_index + 4, profit25, color=color.green)
    // line.new(bar_index, profit50, bar_index + 4, profit50, color=color.green)
    // box.new(bar_index, stopLoss, bar_index + 4, close, border_color=color.red, bgcolor=color.new(color.red, 80))
    // box.new(bar_index, close, bar_index + 4, takeProfit, border_color=color.green, bgcolor=color.new(color.green, 80))

// var table winrateDisplay = table.new(position.bottom_right, 1, 1)
// table.cell(winrateDisplay, 0, 0, "Winrate: " + tostring(strategy.wintrades / strategy.closedtrades * 100, '#.##')+" %", text_color=color.white)

Mais.