Estratégia de negociação quantitativa de cruzamento de três médias móveis + indicador William


Data de criação: 2023-09-28 10:58:16 última modificação: 2023-09-28 10:58:16
cópia: 1 Cliques: 833
1
focar em
1617
Seguidores

Visão geral

A estratégia combina três médias móveis de deslizamento, um índice relativamente forte (RSI) e o índice de William, para identificar a direção da tendência do preço da ação e procurar oportunidades de entrada quando a tendência se reverte. Quando as três médias móveis de deslizamento para cima (para baixo) estão alinhadas, o RSI está acima (para baixo) de 50, e um sinal de William para baixo (para cima) aparece.

Princípio da estratégia

A estratégia usa três médias móveis suaves de diferentes períodos, incluindo a linha rápida, a linha média e a linha lenta. Quando a linha rápida atravessa a linha média, o preço da ação entra em uma tendência ascendente; quando a linha rápida atravessa a linha média, a ação entra em uma tendência descendente. Depois de determinar se a ação está em uma tendência ascendente ou descendente, a estratégia espera que a primeira oportunidade de negociação apareça.

Concretamente, uma vez que o preço das ações entra em uma tendência de alta, a estratégia espera que as cinco condições seguintes sejam atendidas simultaneamente para abrir mais posições:

  1. A linha rápida, a linha média e a linha lenta são todas para cima.
  2. RSI acima de 50;
  3. A forma descendente do indicador William;
  4. O preço das ações está a cair.
  5. Não há posições atualmente.

A estratégia espera que as seguintes cinco condições sejam simultaneamente satisfeitas antes de abrir uma posição de curto prazo após o preço da ação entrar em uma tendência de queda:

  1. A linha rápida, a linha média e a linha lenta estão todas para baixo.
  2. RSI abaixo de 50;
  3. O índice de William, em forma ascendente;
  4. O preço das ações despencou;
  5. Não há posições atualmente.

Depois de fazer mais curto prazo, a estratégia define um ponto de parada e um ponto de parada para controlar o risco. Concretamente, o ponto de parada é uma determinada porcentagem do preço de entrada e o ponto de parada é o preço após a entrada se mover em uma direção favorável.

Vantagens estratégicas

  1. A combinação de vários indicadores de confirmação de entrada, pode efetivamente evitar a falsa ruptura. As três linhas uniformes determinam a direção da tendência, o indicador William capta sinais de reversão e o RSI filtra oscilações, aumentando a precisão da entrada.

  2. A configuração de um ponto de parada de perda permite um bom controle do risco-benefício de cada unidade, garantindo que as negociações lucrativas sejam maiores do que as perdidas.

  3. A lógica da estratégia é clara e fácil de entender, a configuração dos parâmetros é razoável e adequada para o uso de comerciantes de todos os níveis.

Risco estratégico

  1. Em situações de turbulência, o indicador pode emitir um sinal errado, resultando em entrada desnecessária. Pode-se filtrar parte da turbulência através da otimização dos parâmetros do RSI.

  2. O cruzamento entre linhas rápidas pode causar falsas rupturas e deve ser usado em conjunto com outros indicadores. Pode-se considerar a inclusão de indicadores de volume de transação.

  3. O ponto de parada muito próximo do preço de entrada pode ser impedido de sair, e a configuração do ponto de parada precisa ser ajustada para a posição apropriada.

  4. O ponto de parada está muito longe do preço de entrada e pode não ser capaz de parar a saída, o ponto de parada também precisa ser ajustado para a posição apropriada.

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

  1. É possível testar combinações de parâmetros de diferentes períodos, otimizando os parâmetros das três médias e do RSI.

  2. Pode-se adicionar outros indicadores, como o indicador de volume de transações, para determinar se o volume de transações é notável antes da ruptura.

  3. A configuração de parâmetros da estratégia pode ser testada em diferentes variedades.

  4. A curva de ganhos pode ser desenhada com base nos resultados da retrospectiva e a configuração do parâmetro de parada de perda pode ser testada.

  5. Pode-se tentar fazer simulações de negociação antes da ativação e otimizar a configuração dos parâmetros.

Resumir

A estratégia é clara em termos de lógica, e usa uma combinação de indicadores para entrar e sair, para controlar o risco. Há muito espaço para otimizar os parâmetros da estratégia, testando diferentes configurações de parâmetros. A estratégia pode ser uma estratégia de negociação quantitativa de lucro estável.

Código-fonte da estratégia
/*backtest
start: 2023-08-28 00:00:00
end: 2023-09-27 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//This script is a combination of 3 smoothed moving averages, and RSI. When moving averages are aligned upward (downward) and RSI is above (below) 50 and a down (up) William fractal appears, it enters long (short) position. Exiting from long and short entries are defined by StopLoss and TargetProfit.

//@version=5

strategy(title="3SmmaCrossUp + Fractal + RSI", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, currency=currency.USD, commission_type=strategy.commission.percent, commission_value=0.03)

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// inputs

// Global
src = input(close, title="Source")
stopLoss = input.float(defval = 0.1, title = "Stop Loss %", minval = 0, maxval=100, step = 0.1)
targetProfit = input.float(defval = 0.4, title = "Target Profit %", minval = 0, maxval=100, step = 0.1)

// Smooth Moving Average
fastSmmaLen = input.int(21, minval=1, title="Fast Length", group = "Smooth Moving Average")
midSmmaLen = input.int(50, minval=1, title="Mid Length",group = "Smooth Moving Average")
slowSmmaLen = input.int(200, minval=1, title="Slow Length",group = "Smooth Moving Average")

// RSI
rsiLen = input.int(defval=14, title="length", minval=1, maxval=1000, step=1, group="RSI")

// Fractals
n = input.int(title="Periods", defval=2, minval=2, group = "Fractals")

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// initialization

var waitingFirstTradeInUpwardTrend = false
var waitingFirstTradeInDownwardTrend = false

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// functions

smma(ma, src, len) => 
    smma = 0.0
    smma := na(smma[1]) ? ma : (smma[1] * (len - 1) + src) / len
    smma
    
fractals(n, highs, lows) =>
    // UpFractal
    bool upflagDownFrontier = true
    bool upflagUpFrontier0 = true
    bool upflagUpFrontier1 = true
    bool upflagUpFrontier2 = true
    bool upflagUpFrontier3 = true
    bool upflagUpFrontier4 = true
    for i = 1 to n
        upflagDownFrontier := upflagDownFrontier and (highs[n-i] < highs[n])
        upflagUpFrontier0 := upflagUpFrontier0 and (highs[n+i] < highs[n])
        upflagUpFrontier1 := upflagUpFrontier1 and (highs[n+1] <= highs[n] and highs[n+i + 1] < highs[n])
        upflagUpFrontier2 := upflagUpFrontier2 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+i + 2] < highs[n])
        upflagUpFrontier3 := upflagUpFrontier3 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+3] <= highs[n] and highs[n+i + 3] < highs[n])
        upflagUpFrontier4 := upflagUpFrontier4 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+3] <= highs[n] and highs[n+4] <= highs[n] and highs[n+i + 4] < highs[n])
    flagUpFrontier = upflagUpFrontier0 or upflagUpFrontier1 or upflagUpFrontier2 or upflagUpFrontier3 or upflagUpFrontier4
    
    upFractal = (upflagDownFrontier and flagUpFrontier)
    
    // downFractal
    bool downflagDownFrontier = true
    bool downflagUpFrontier0 = true
    bool downflagUpFrontier1 = true
    bool downflagUpFrontier2 = true
    bool downflagUpFrontier3 = true
    bool downflagUpFrontier4 = true
    
    for i = 1 to n
        downflagDownFrontier := downflagDownFrontier and (lows[n-i] > lows[n])
        downflagUpFrontier0 := downflagUpFrontier0 and (lows[n+i] > lows[n])
        downflagUpFrontier1 := downflagUpFrontier1 and (lows[n+1] >= lows[n] and lows[n+i + 1] > lows[n])
        downflagUpFrontier2 := downflagUpFrontier2 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+i + 2] > lows[n])
        downflagUpFrontier3 := downflagUpFrontier3 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+3] >= lows[n] and lows[n+i + 3] > lows[n])
        downflagUpFrontier4 := downflagUpFrontier4 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+3] >= lows[n] and lows[n+4] >= lows[n] and lows[n+i + 4] > lows[n])
    flagDownFrontier = downflagUpFrontier0 or downflagUpFrontier1 or downflagUpFrontier2 or downflagUpFrontier3 or downflagUpFrontier4
    
    downFractal = (downflagDownFrontier and flagDownFrontier)
    [upFractal, downFractal]

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// calcs

[upFractal, downFractal] = fractals(n, high, low)


rsiIsHigh = ta.rsi(src, rsiLen) >= 50 


slowMa = ta.sma(src, slowSmmaLen)
midMa = ta.sma(src, midSmmaLen)
fastMa = ta.sma(src, fastSmmaLen)

slowSmma = smma(slowMa ,src, slowSmmaLen)
midSmma = smma(midMa, src, midSmmaLen)
fastSmma = smma(fastMa, src, fastSmmaLen)

isFastSmmaUpward = ta.rising(fastSmma, 1)
isMidSmmaUpward = ta.rising(midSmma, 1)
isSlowSmmaUpward = ta.rising(slowSmma, 1)

isFastSmmaDownward = ta.falling(fastSmma, 1)
isMidSmmaDownward = ta.falling(midSmma, 1)
isSlowSmmaDownward = ta.falling(slowSmma, 1)

slowMovingAveragesAreUpward = isMidSmmaUpward and isSlowSmmaUpward
slowMovingAveragesAreDownward = isMidSmmaDownward and isSlowSmmaDownward

justEnteredUpwardTrend = ta.crossover(fastSmma, midSmma) ? true : false
justEnteredDownwardTrend = ta.crossunder(fastSmma, midSmma) ? true : false

waitingFirstTradeInUpwardTrend := justEnteredUpwardTrend == true ? true : (isFastSmmaDownward or isMidSmmaDownward or isSlowSmmaDownward ? false : waitingFirstTradeInUpwardTrend)
waitingFirstTradeInDownwardTrend := justEnteredDownwardTrend == true ? true : (isFastSmmaUpward or isMidSmmaUpward or isSlowSmmaUpward ? false : waitingFirstTradeInDownwardTrend)

priceCrossedOverSlowMa = ta.crossover(close, slowSmma)
priceCrossedUnderSlowMa = ta.crossunder(close, slowSmma)

enterLongCondition = barstate.isconfirmed and low > fastSmma and rsiIsHigh and (downFractal or priceCrossedOverSlowMa) and waitingFirstTradeInUpwardTrend and strategy.position_size == 0

enterShortCondition = barstate.isconfirmed and high < fastSmma and (not rsiIsHigh) and (upFractal or priceCrossedUnderSlowMa) and waitingFirstTradeInDownwardTrend and strategy.position_size == 0

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// strategy

if(enterLongCondition)
    strategy.entry(id="L", direction=strategy.long)
    waitingFirstTradeInUpwardTrend := false

if(enterShortCondition)
    strategy.entry(id="S", direction=strategy.short)
    waitingFirstTradeInDownwardTrend := false
    
if(strategy.position_size > 0)
    strategy.exit(id="EL", stop=strategy.position_avg_price * (1 - stopLoss/100), limit=strategy.position_avg_price * (1+targetProfit/100)) 
if(strategy.position_size < 0)
    strategy.exit(id="ES", stop=strategy.position_avg_price * (1 + stopLoss/100), limit=strategy.position_avg_price * (1-targetProfit/100)) 

///////////////////////////////////////////////////////////////////////////////////////////////////////////////// plots

plot(series = slowSmma, title="Slow SMMA", linewidth=3)
plot(series = midSmma, title="Mid SMMA", linewidth=2)
plot(series = fastSmma, title="Fast SMMA", linewidth=1)
plotchar(series=rsiIsHigh, title='rsiIsHigh', char='')
plotchar(series=justEnteredUpwardTrend, title='justEnteredUpwardTrend', char='')
plotchar(series=justEnteredDownwardTrend, title='justEnteredDownwardTrend', char='')
plotchar(series=waitingFirstTradeInUpwardTrend, title='waitingFirstTradeInUpwardTrend', char='')
plotchar(series=waitingFirstTradeInDownwardTrend, title='waitingFirstTradeInDownwardTrend', char='')
plotchar(series=enterLongCondition, title='enterLongCondition' , char='')
plotchar(series=enterShortCondition, title='enterShortCondition' , char='')
plotshape(series=upFractal, title='upFractal', style=shape.triangleup, location=location.abovebar, color=#009688, size = size.tiny)
plotshape(series=downFractal, title='downFractal', style=shape.triangledown, location=location.belowbar, color=color.red, size = size.tiny)