O recurso está a ser carregado... Carregamento...

Estratégia de negociação VWAP com detecção de anomalias de volume

Autora:ChaoZhang, Data: 2024-06-07 15:44:04
Tags:VWAPRSIDTJSMA

img

Resumo

Esta estratégia baseia-se em vários níveis de VWAP (Volume Weighted Average Price), incluindo o preço aberto, preço alto, preço baixo e o VWAP de velas com volume anormalmente alto. A estratégia utiliza os níveis de VWAP como suporte e resistência, considerando também situações de volume anormais. Quando o preço atravessa os níveis de VWAP e atende a certas condições, a estratégia gera sinais de negociação. Além disso, a estratégia usa o indicador RSI para detectar mudanças de momento como condição de saída.

Princípios de estratégia

  1. Calcular vários níveis de VWAP, incluindo o VWAP de preço aberto, o VWAP de preço elevado, o VWAP de preço baixo e o VWAP de velas com volume anormalmente elevado.
  2. Detetar velas com volume anormalmente elevado e redefinir as variáveis cumulativas para o VWAP de volume anormalmente elevado nessas velas.
  3. Defina os valores de deslocamento acima e abaixo dos níveis VWAP como condições de desencadeamento dos sinais de negociação.
  4. Verifique se há lacunas no lado oposto do VWAP para evitar sinais falsos.
  5. Gerar múltiplos sinais de negociação com base na posição de preço em relação ao VWAP e na relação entre o preço de fechamento e o preço de abertura, incluindo os tipos Wick e Crossover.
  6. Utilize o indicador RSI para detectar mudanças de ímpeto e fechar transações correspondentes quando o RSI exceder 70 ou cair abaixo de 30.

Análise das vantagens

  1. A estratégia utiliza vários níveis de VWAP, fornecendo informações de suporte e resistência mais abrangentes.
  2. Ao detectar velas com volume anormalmente elevado, a estratégia pode capturar mudanças significativas no mercado.
  3. A definição de valores de deslocamento pode filtrar alguns sinais de ruído e melhorar a qualidade dos sinais de negociação.
  4. A estratégia considera situações de lacunas no lado oposto do VWAP, evitando alguns falsos sinais.
  5. Os sinais de negociação múltiplos são gerados com base na posição de preço em relação ao VWAP e na relação entre o preço de fechamento e o preço de abertura, aumentando a flexibilidade da estratégia.
  6. O uso do indicador RSI como condição de saída pode ajudar a estratégia a sair das negociações em tempo hábil quando a dinâmica muda.

Análise de riscos

  1. A estratégia baseia-se em níveis de VWAP, que podem perder a sua eficácia em condições de mercado extremas.
  2. A apreciação de um volume anormalmente elevado baseia-se num limiar fixo, que pode não se adaptar às diferentes situações de mercado.
  3. A fixação dos valores de deslocamento pode ter de ser ajustada em função dos diferentes mercados e instrumentos de negociação.
  4. A estratégia gera múltiplos sinais de negociação, o que pode conduzir a excesso de negociação e a elevados custos de transação.
  5. O indicador RSI pode produzir sinais de saída atrasados, fazendo com que a estratégia tenha maiores riscos.

Orientações de otimização

  1. Otimizar o método de cálculo dos níveis VWAP, por exemplo, considerando períodos de tempo mais longos ou utilizando métodos ponderados.
  2. Otimizar os critérios de avaliação para volumes anormalmente elevados, como a adoção de limiares adaptativos ou a combinação com outros indicadores de volume.
  3. Realizar a otimização dos parâmetros dos valores de deslocamento para encontrar a gama de desvio ideal.
  4. Introduzir medidas de gestão do risco, tais como a fixação de níveis de stop-loss e take-profit, para controlar a exposição ao risco de operações individuais.
  5. Tente outros indicadores de momento ou combine vários indicadores para obter sinais de saída mais precisos.
  6. Filtrar os sinais de negociação para reduzir o excesso de negociação e reduzir os custos de transação.

Resumo

Esta estratégia utiliza vários níveis de VWAP e detecção de volume anormal para gerar sinais de negociação diversos. Considerando a posição relativa do preço para VWAP, a relação entre o preço de fechamento e o preço de abertura, e o indicador RSI, a estratégia tenta capturar mudanças significativas do mercado e transações de saída em tempo hábil. No entanto, a estratégia também tem alguns riscos, como adaptabilidade a condições extremas do mercado, overtrading e sinais de saída atrasados. Para melhorar ainda mais a estratégia, pode-se considerar a otimização do método de cálculo do VWAP, os critérios de julgamento para volume anormal, a definição de valores de deslocamento e a introdução de medidas de gerenciamento de risco e mais combinações de indicadores.


/*backtest
start: 2024-05-30 00:00:00
end: 2024-06-06 00:00:00
period: 4h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
strategy("5 Anchored VWAP Strategy with Abnormally High Volume Candle", overlay=true)

// Initialize VWAP variables
var float vwap_open = na
var float vwap_high = na
var float vwap_low = na
var float vwap_high_volume = na

var float cum_v_open = 0
var float cum_v_high = 0
var float cum_v_low = 0
var float cum_v_high_volume = 0

var float cum_pv_open = 0
var float cum_pv_high = 0
var float cum_pv_low = 0
var float cum_pv_high_volume = 0

var float highest_volume = 0

// Initialize YTD high and low variables
var float ytd_high = na
var float ytd_low = na

// Parameters for abnormal volume detection
length = 20
volume_threshold = 2.0

// Displacement parameters
displacement_percentage = 0.01 // 1% displacement

// Calculate average volume
avg_volume = ta.sma(volume, length)

// Check if it's the first day of the year
is_first_day_of_year = year(time) != year(time[1])

// Reset YTD high and low on the first day of the year
if is_first_day_of_year
    ytd_high := high
    ytd_low := low

// Update YTD high and low
ytd_high := na(ytd_high) ? high : math.max(ytd_high, high)
ytd_low := na(ytd_low) ? low : math.min(ytd_low, low)

// Update cumulative variables for open VWAP
cum_v_open += volume
cum_pv_open += close * volume
if cum_v_open != 0
    vwap_open := cum_pv_open / cum_v_open

// Update cumulative variables for high VWAP
if high == ytd_high
    cum_v_high := 0
    cum_pv_high := 0

cum_v_high += volume
cum_pv_high += close * volume
if cum_v_high != 0
    vwap_high := cum_pv_high / cum_v_high

// Update cumulative variables for low VWAP
if low == ytd_low
    cum_v_low := 0
    cum_pv_low := 0

cum_v_low += volume
cum_pv_low += close * volume
if cum_v_low != 0
    vwap_low := cum_pv_low / cum_v_low

// Check for new high-volume candle that is also abnormally high and reset cumulative variables for high-volume VWAP
new_high_volume = false
if volume > highest_volume and volume > volume_threshold * avg_volume
    highest_volume := volume
    cum_v_high_volume := 0
    cum_pv_high_volume := 0
    new_high_volume := true

cum_v_high_volume += volume
cum_pv_high_volume += close * volume
if cum_v_high_volume != 0
    vwap_high_volume := cum_pv_high_volume / cum_v_high_volume

// Plot VWAPs
plot(vwap_open, color=color.red, linewidth=2, title="VWAP Open")
plot(vwap_high, color=color.green, linewidth=2, title="VWAP High")
plot(vwap_low, color=color.blue, linewidth=2, title="VWAP Low")
plot(vwap_high_volume, color=color.purple, linewidth=2, title="VWAP High Volume")

// Plot a vertical line on the chart only when a new high-volume VWAP anchor occurs
bgcolor(new_high_volume ? color.new(color.purple, 90) : na, offset=-1)

// Calculate displacement amounts
displacement_amount_open = vwap_open * displacement_percentage
displacement_amount_high = vwap_high * displacement_percentage
displacement_amount_low = vwap_low * displacement_percentage
displacement_amount_high_volume = vwap_high_volume * displacement_percentage

// Check for gaps on the opposite side of a VWAP
gap_up_opposite_open = na(close[1]) ? false : (open > close[1] and open < vwap_open and close[1] > vwap_open)
gap_down_opposite_open = na(close[1]) ? false : (open < close[1] and open > vwap_open and close[1] < vwap_open)

gap_up_opposite_high = na(close[1]) ? false : (open > close[1] and open < vwap_high and close[1] > vwap_high)
gap_down_opposite_high = na(close[1]) ? false : (open < close[1] and open > vwap_high and close[1] < vwap_high)

gap_up_opposite_low = na(close[1]) ? false : (open > close[1] and open < vwap_low and close[1] > vwap_low)
gap_down_opposite_low = na(close[1]) ? false : (open < close[1] and open > vwap_low and close[1] < vwap_low)

gap_up_opposite_high_volume = na(close[1]) ? false : (open > close[1] and open < vwap_high_volume and close[1] > vwap_high_volume)
gap_down_opposite_high_volume = na(close[1]) ? false : (open < close[1] and open > vwap_high_volume and close[1] < vwap_high_volume)

// RSI calculation for momentum change detection
rsi = ta.rsi(close, 14)
long_exit_condition = rsi > 70
short_exit_condition = rsi < 30

// Debugging Plots
plotshape(not gap_up_opposite_open and not gap_down_opposite_open and close > vwap_open and low < vwap_open - displacement_amount_open and close[1] < vwap_open, style=shape.triangledown, location=location.abovebar, color=color.red, size=size.small, title="Open Long Signal")
plotshape(not gap_up_opposite_open and not gap_down_opposite_open and close < vwap_open and high > vwap_open + displacement_amount_open and close[1] > vwap_open, style=shape.triangleup, location=location.belowbar, color=color.green, size=size.small, title="Open Short Signal")

plotshape(not gap_up_opposite_high and not gap_down_opposite_high and close > vwap_high and low < vwap_high - displacement_amount_high and close[1] < vwap_high, style=shape.triangledown, location=location.abovebar, color=color.blue, size=size.small, title="High Long Signal")
plotshape(not gap_up_opposite_high and not gap_down_opposite_high and close < vwap_high and high > vwap_high + displacement_amount_high and close[1] > vwap_high, style=shape.triangleup, location=location.belowbar, color=color.orange, size=size.small, title="High Short Signal")

plotshape(not gap_up_opposite_low and not gap_down_opposite_low and close > vwap_low and low < vwap_low - displacement_amount_low and close[1] < vwap_low, style=shape.triangledown, location=location.abovebar, color=color.purple, size=size.small, title="Low Long Signal")
plotshape(not gap_up_opposite_low and not gap_down_opposite_low and close < vwap_low and high > vwap_low + displacement_amount_low and close[1] > vwap_low, style=shape.triangleup, location=location.belowbar, color=color.yellow, size=size.small, title="Low Short Signal")

plotshape(not gap_up_opposite_high_volume and not gap_down_opposite_high_volume and close > vwap_high_volume and low < vwap_high_volume - displacement_amount_high_volume and close[1] < vwap_high_volume, style=shape.triangledown, location=location.abovebar, color=color.teal, size=size.small, title="High Volume Long Signal")
plotshape(not gap_up_opposite_high_volume and not gap_down_opposite_high_volume and close < vwap_high_volume and high > vwap_high_volume + displacement_amount_high_volume and close[1] > vwap_high_volume, style=shape.triangleup, location=location.belowbar, color=color.fuchsia, size=size.small, title="High Volume Short Signal")

// Trading signals based on VWAP support/resistance with displacement, no gaps on the opposite side, and bounce conditions
if not gap_up_opposite_open and not gap_down_opposite_open
    if (close > vwap_open and low < vwap_open)
        if close > open
            strategy.entry("Long_Open_Wick", strategy.long, comment="Wick")
        else
            strategy.entry("Long_Open_Crossover", strategy.long, comment="Crossover")
    
    if (close < vwap_open and high > vwap_open)
        if close < open
            strategy.entry("Short_Open_Wick", strategy.short, comment="Wick")
        else
            strategy.entry("Short_Open_Crossover", strategy.short, comment="Crossover")

if not gap_up_opposite_high and not gap_down_opposite_high
    if (close > vwap_high and low < vwap_high)
        if close > open
            strategy.entry("Long_High_Wick", strategy.long, comment="Wick")
        else
            strategy.entry("Long_High_Crossover", strategy.long, comment="Crossover")
    
    if (close < vwap_high and high > vwap_high)
        if close < open
            strategy.entry("Short_High_Wick", strategy.short, comment="Wick")
        else
            strategy.entry("Short_High_Crossover", strategy.short, comment="Crossover")

if not gap_up_opposite_low and not gap_down_opposite_low
    if (close > vwap_low and low < vwap_low)
        if close > open
            strategy.entry("Long_Low_Wick", strategy.long, comment="Wick")
        else
            strategy.entry("Long_Low_Crossover", strategy.long, comment="Crossover")
    
    if (close < vwap_low and high > vwap_low)
        if close < open
            strategy.entry("Short_Low_Wick", strategy.short, comment="Wick")
        else
            strategy.entry("Short_Low_Crossover", strategy.short, comment="Crossover")

if not gap_up_opposite_high_volume and not gap_down_opposite_high_volume
    if (close > vwap_high_volume and low < vwap_high_volume)
        if close > open
            strategy.entry("Long_High_Volume_Wick", strategy.long, comment="Wick")
        else
            strategy.entry("Long_High_Volume_Crossover", strategy.long, comment="Crossover")
    
    if (close < vwap_high_volume and high > vwap_high_volume)
        if close < open
            strategy.entry("Short_High_Volume_Wick", strategy.short, comment="Wick")
        else
            strategy.entry("Short_High_Volume_Crossover", strategy.short, comment="Crossover")

// Exit trades based on RSI momentum change
if strategy.position_size > 0 and long_exit_condition
    strategy.close("Long_Open_Wick")
    strategy.close("Long_Open_Crossover")
    strategy.close("Long_High_Wick")
    strategy.close("Long_High_Crossover")
    strategy.close("Long_Low_Wick")
    strategy.close("Long_Low_Crossover")
    strategy.close("Long_High_Volume_Wick")
    strategy.close("Long_High_Volume_Crossover")

if strategy.position_size < 0 and short_exit_condition
    strategy.close("Short_Open_Wick")
    strategy.close("Short_Open_Crossover")
    strategy.close("Short_High_Wick")
    strategy.close("Short_High_Crossover")
    strategy.close("Short_Low_Wick")
    strategy.close("Short_Low_Crossover")
    strategy.close("Short_High_Volume_Wick")
    strategy.close("Short_High_Volume_Crossover")

Relacionados

Mais.