A estratégia de preço de volume relativo é uma estratégia quantitativa de negociação baseada em volume de negociação anormal e volatilidade de preços. Esta estratégia compara o volume de negociação atual com a média histórica para determinar se o volume de negociação é anormal.
A lógica central da estratégia de preços de volume relativo baseia-se em dois indicadores de julgamento: volume de negociação relativo e faixa de flutuação de preços.
Em primeiro lugar, calcula-se a média móvel simples do volume de negociação nos 20 períodos mais recentes como o volume médio histórico de negociação. Em seguida, definimos um parâmetro múltiplo (como 1,5 vezes). Quando o volume de negociação atual é maior que 1,5 vezes o volume médio de negociação, consideramos o volume de negociação anormal e pertencente a uma situação de volume relativo.
Em segundo lugar, calcula-se o intervalo verdadeiro médio (ATR) ao longo dos 14 períodos mais recentes como medida da volatilidade dos preços. Ao mesmo tempo, calcula-se o desvio padrão da volatilidade média. Se a volatilidade real atual estiver entre a média mais ou menos um desvio padrão, consideramos que a flutuação dos preços está em um intervalo relativamente estável.
Quando as duas condições acima são satisfeitas ao mesmo tempo, um sinal longo é emitido para abrir uma posição longa. Durante o período de detenção, duas vezes o ATR é usado como nível de stop loss, e o preço mais alto menos duas vezes o ATR é usado como nível de take profit.
A maior vantagem da estratégia de preço de volume relativo é que ela capta as tendências de preço provocadas pelo volume de negociação anormal. Quando o volume de negociação aumenta, ele representa uma mudança na atitude dos participantes do mercado, o que muitas vezes sinaliza que os preços estão despencando e a formação de novas tendências. Comparando a relação entre o volume de negociação e as médias históricas, a estratégia pode determinar efetivamente o momento do volume de negociação anormal.
Por outro lado, a estratégia também considera a taxa de volatilidade, de modo que os sinais ocorrem durante períodos de preços relativamente estáveis. Isso evita o enorme risco de perda causado por perseguir altas durante flutuações violentas. Também aumenta as oportunidades de lucro porque as tendências geralmente começam a romper após a relativa estabilidade.
O maior risco desta estratégia é que o indicador de volume de negociação não pode ter 100% de certeza de novas tendências.
Para reduzir as perdas, ajustar adequadamente os parâmetros do
A estratégia pode ser otimizada nos seguintes aspectos:
Adicionar outros indicadores para julgamento, tais como taxa de variação, volume de negócios, etc., para tornar os sinais anormais de volume de negociação mais confiáveis.
O parâmetro ATR pode ser otimizado para diferentes stocks para determinar com mais precisão a faixa de preços estável.
Adicione algoritmos de aprendizagem de máquina para julgar ativamente o volume de negociação anormal, não apenas uma simples comparação com médias históricas.
Usar modelos de aprendizagem profunda para prever a volatilidade dos preços, não apenas com base no ATR histórico.
A estratégia de preço de volume relativo captura o volume de negociação anormal como um sinal característico e combina julgamento de estabilidade de preços para emitir sinais de negociação. A estratégia é simples e prática e funciona bem no rastreamento do volume de negociação de ações anormal.
/*backtest start: 2022-12-21 00:00:00 end: 2023-12-27 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 (kevinhhl) //@version=4 strategy("[KL] Relative Volume + ATR Strategy",overlay=true,pyramiding=1) ENUM_LONG = "Long" // Timeframe { backtest_timeframe_start = input(defval = timestamp("01 Apr 2016 13:30 +0000"), title = "Backtest Start Time", type = input.time) USE_ENDTIME = input(false,title="Define backtest end-time (If false, will test up to most recent candle)") backtest_timeframe_end = input(defval = timestamp("01 May 2021 19:30 +0000"), title = "Backtest End Time (if checked above)", type = input.time) within_timeframe = true // } len_volat = input(14,title="Length of ATR to determine volatility") ATR_volat = atr(len_volat) avg_ATR_volat = sma(ATR_volat, len_volat) std_ATR_volat = stdev(ATR_volat, len_volat) // } // Trailing stop loss { ATR_X2_TSL = atr(input(14,title="Length of ATR for trailing stop loss")) * input(2.0,title="ATR Multiplier for trailing stop loss",type=input.float) TSL_source = low var stop_loss_price = float(0) TSL_line_color = color.green, TSL_transp = 100 if strategy.position_size == 0 or not within_timeframe TSL_line_color := color.black stop_loss_price := TSL_source - ATR_X2_TSL else if strategy.position_size > 0 stop_loss_price := max(stop_loss_price, TSL_source - ATR_X2_TSL) TSL_transp := 0 plot(stop_loss_price, color=color.new(TSL_line_color, TSL_transp)) // } // Signals for entry { _avg_vol = sma(volume,input(20, title="SMA(volume) length (for relative comparison)")) _relative_vol = _avg_vol * input(1.5,title="Multiple of avg vol to consider relative volume as being high",type=input.float) __lowerOfOpenClose = min(open,close) _wickRatio_lower = (__lowerOfOpenClose - low) / (high - low) entry_signal1 = volume > _relative_vol entry_signal2 = ATR_volat < avg_ATR_volat + std_ATR_volat and ATR_volat > avg_ATR_volat - std_ATR_volat // } alert_per_bar(msg)=> prefix = "[" + syminfo.root + "] " suffix = "(P=" + tostring(close) + "; atr=" + tostring(ATR_volat) + ")" alert(tostring(prefix) + tostring(msg) + tostring(suffix), alert.freq_once_per_bar) // MAIN: if within_timeframe if strategy.position_size > 0 and strategy.position_size[1] > 0 and (stop_loss_price/stop_loss_price[1]-1) > 0.005 alert_per_bar("TSL raised to " + tostring(stop_loss_price)) // EXIT :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: // placed before entry, will re-enter if stopped out exit_msg = close <= strategy.position_avg_price ? "stop loss" : "take profit" if strategy.position_size > 0 and TSL_source <= stop_loss_price strategy.close(ENUM_LONG, comment=exit_msg) // ENTRY ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: if entry_signal1 and entry_signal2// and entry_signal3 entry_msg = strategy.position_size > 0 ? "adding" : "initial" strategy.entry(ENUM_LONG, strategy.long, comment=entry_msg) // CLEAN UP: if strategy.position_size == 0 stop_loss_price := float(0)