相対量価格戦略は,異常な取引量と価格変動に基づいた定量的な取引戦略である.この戦略は,現在の取引量と歴史的な平均を比較して取引量が異常かどうかを決定する.また,価格が比較的安定しているかどうかを判断するために平均の真の範囲間隔を組み合わせる.取引量が異常に増加し,価格が比較的安定しているとき,それはエントリー信号とみなされる.
相対量価格戦略の基本論理は,相対取引量と価格変動範囲という2つの判断指標に基づいています.
まず,過去20期間の取引量の単純な移動平均を,歴史的な平均取引量として計算します.次に複数のパラメータ (例えば1.5倍) を設定します.現在の取引量が平均取引量の1.5倍以上の場合,取引量は異常であり,相対的な取引量の状況に属していると考えます.
2つ目は,最も最近の14期間の平均真差 (ATR) を価格変動の測定値として計算する.同時に,平均変動の標準偏差を計算する.現在の真差が平均プラスまたはマイナス1標準偏差の間である場合,価格変動は比較的安定した範囲であると考えます.
上記2つの条件が同時に満たされた場合,ロングシグナルがロングポジションを開設するために発行されます.保持期間中,ストップ・ロストレベルとして2倍のATRが使用され,最大価格マイナス2倍のATRが利益のレベルとして使用されます.
相対量価格戦略の最大の利点は,異常な取引量によって引き起こされる価格動向を把握することです.取引量が急上昇すると,市場の参加者の態度の変化を表し,しばしば価格ブレイクと新しい傾向の形成をシグナルします.取引量と歴史的な平均値の関係を比較することによって,戦略は異常な取引量のタイミングを効果的に決定することができます.
一方,戦略は変動率も考慮し,比較的安定した価格期間中にシグナルが発生するようにする.これは暴力的な変動の間に高値を追いかけるために引き起こされる大きな損失のリスクを回避する.傾向は通常相対的な安定後に突破し始めるため,利益の機会も増加する.
この戦略の最大のリスクは,取引量指標が新しい傾向について100%確実であることはできないことである.取引量の急上昇は偽のブレイクになり,価格が急速に逆転する可能性がある.そのような場合,戦略は大きな損失を被る.
損失を減らすために, "相対的な取引量"のパラメータを適切に調整し,異常な取引量を判断するためのより厳格な基準を設定します. または,取引量の増加と売上高の増加に一致するかどうかを分析するなどの他の判断指標を追加します.
戦略は以下の側面で最適化できます.
取引量の異常信号をより信頼性のあるものにするために,変化比,売上高など,判断のための他の指標を追加します.
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)