
Стратегия относительного количества - это количественная торговая стратегия, основанная на аномалиях объема торгов и колебаниях цен. Эта стратегия определяет, является ли объем торгов аномальным путем сравнения текущего объема торгов с историческим средним объемом торгов, а также в сочетании с средним диапазоном реальных колебаний определяет, находится ли цена в относительно стабильном диапазоне.
Центральная логика относительной стоимости стратегии основана на двух показателях, один - относительный объем сделки, другой - диапазон колебаний цены.
Во-первых, мы рассчитываем простое скользящее среднее объема сделок за последние 20 циклов, как историческое среднее количество сделок. Затем мы устанавливаем множительный параметр (например, 1,5-кратный), который мы считаем аномальным, когда текущий объем сделок больше, чем средний объем сделок в 1,5 раза.
Во-вторых, мы рассчитываем среднюю реальную колебательность (ATR) за последние 14 циклов как меру колебания цен. При этом рассчитываем стандартную разницу средней колебательности. Если текущая реальная колебательность находится между средней положительной и отрицательной стандартной разницами, мы считаем, что колебания цен находятся в относительно равномерном диапазоне.
Когда вышеупомянутые два условия одновременно выполнены, то есть появляется многосигнал, открывается много позиций. В процессе удержания позиции, максимально низкая точка минус два раза ATR в качестве стоп-поста, максимальная точка минус два раза ATR в качестве стоп-поста.
Самым большим преимуществом стратегии относительных цен является то, что она улавливает ценовые тенденции, вызванные необычными объемами торгов. Когда объем торгов всплеск, это представляет собой изменение отношения участников рынка, что часто указывает на прорыв цен и формирование новых тенденций.
С другой стороны, стратегия также учитывает волатильность цен, что позволяет сигналам происходить в периоды относительной стабильности цен. Это позволяет избежать огромного риска потерь, вызванных отслеживанием во время сильных колебаний. Это также увеличивает возможности для получения прибыли, поскольку тенденции обычно начинают прорываться только после относительной стабильности.
Наибольший риск этой стратегии заключается в том, что индикатор объема торгов не может на 100% определить новую тенденцию, и всплеск объема торгов может быть ложным прорывом, и цена быстро перевернется. В этом случае стратегия VRFS понесет большие потери.
Для уменьшения потерь можно соответствующим образом скорректировать параметры относительной величины сделки, установив более строгие критерии для суждения об аномальных объемах торгов. Или добавить другие показатели суждения, такие как увеличение анализа объема торгов, чтобы определить, соответствует ли рост объема торгов сумме торгов.
Эта стратегия может быть оптимизирована в следующих аспектах:
Добавление других показателей, таких как взлеты и падения, объемы торгов и т.д., делает сигналы об аномальных объемах торгов более надежными.
ATR параметры могут быть оптимизированы для различных акций, чтобы более точно определить диапазон стабильности цен.
Добавление алгоритмов машинного обучения, которые позволяют положительно оценивать аномалии в объеме торгов, а не просто сравнивать их с историческими средними значениями.
Прогнозы ценовых колебаний используют модели глубокого обучения, а не только исторические ATR.
Стратегия относительных цен выдает торговый сигнал, используя аномалию объема торговли в качестве характерного сигнала в сочетании с оценкой ценовой стабильности. Стратегия проста, практична и эффективна при отслеживании аномального объема торговли акциями. Но также существует определенный риск ложного сигнала.
/*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)