ダイナミックボラティリティ調整トレンドフォロー戦略


作成日: 2024-01-24 11:13:39 最終変更日: 2024-01-24 11:13:39
コピー: 0 クリック数: 325
1
フォロー
1179
フォロワー

ダイナミックボラティリティ調整トレンドフォロー戦略

概要

この独特な規則化された体系化された取引戦略は,トレンドフォローのカテゴリーに属します.これは,株価を直接使用するのではなく,価格が統一された価格の配列を使用して取引信号を生成します.この戦略は,高級ポジション調整とリスク管理技術を採用しています.これらの技術は,通常,機関ポートフォリオ管理でのみ使用され,商品取引アドバイザー (CTA) とフューチャーファンドなどのポジション調整の証明技術です.

戦略原則

統一価格は,価格の時間序列全体から計算された変動率調整された価格の累積日利率である.変動率調整ウィンドウ期間は,ユーザーによって定義される.統合価格に基づいて,ハル移動平均が計算され,主要トレンド判断指標として使用される.ハル移動平均ウィンドウ期間は,ユーザーによって定義され,デフォルトで100日間で,トレンド判断の感性を保証し,同時に過度に頻繁な取引を避ける.

取引戦略の核心は非常にシンプルで,一式化された価格は,Hull移動平均を横断して上方へ多行し,空白を横断して下方へ.新しい取引シグナルは,主動的に古い逆転ポジションを平らげる.

持仓規模は,最近の価格変動とユーザーによって定義された年次リスク目標に基づいています.実質的には,変動率に応じてポジションの大きさを調整します.変動率が低いときは,持仓が大きい,変動率が高いときは,持仓が小さい.最近の変動率は,価格対数リターンの標準差の14日であり,一年間の予想変動率に推移されます.その後,ユーザーによって設定された年次リスク目標に応じてポジションを調整します.デフォルトのリスク目標は,保守的な10%です.

ストップダストは,最近の価格平均の実際の波動幅の倍数に基づいて設定され,ユーザは設定できます.

戦略的優位性

  • 価格の統一処理を利用して偽信号の確率を下げる
  • ポジションの動態調整,リスクのコントロール
  • リアルタイム・ストップ・ローズにより大きな損失を回避する
  • 取引戦略はシンプルで直感的で理解しやすい

戦略リスク

  • ハル移動平均は,主要指標として,遅滞している.
  • 波動率を利用してポジションを調整し,リスクをコントロールしながら,利益の余地を制限する可能性があります.
  • ストップダメージは,突破によって引き起こされる可能性が高い

リスク管理策には,異なる移動平均の組み合わせを使用し,ポジションのリスク目標を調整するなどがあります.

戦略の最適化

  • 移動平均指標の効果をテストする
  • 移動平均のパラメータを最適化する
  • 余分な時間を過ごしたり 余分な時間を過ごしたり
  • ストップを調整し,ベストポイントを探します.
  • テストする他の方法

要約する

この戦略は,価格の統一化,動的調節,ストップなど,複数の技術制御リスクを統合している. シンプルなトレンドフォローの原則を使用し,取引を行う. 市場や個人の状況に応じてパラメータ調整を最適化することができる. 更にテストを検証する価値があり,実用化の可能性がある.

ストラテジーソースコード
/*backtest
start: 2023-01-17 00:00:00
end: 2024-01-23 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/
// © Crunchster1

//@version=5
strategy(title="Crunchster's Normalised Trend Strategy", shorttitle="Normalised Trend Strategy", overlay=false )

// Inputs and Parameters
src = input(close, 'Source', group='Strategy Settings')
length = input.int(title="Lookback period for price normalisation filter", defval=14, minval=2, group='Strategy Settings', tooltip='This sets the lookback period for the volatility adjustment of returns, which is used to transform the price series into the "real price"')
hlength = input.int(title="Lookback period for Hull Moving Average", defval=100, minval=2, group='Strategy Settings')
offset = input.int(title="HMA Offset", defval=0, minval=0, group='Strategy Settings')
long = input(true, 'Long', inline='08', group='Strategy Settings')
short = input(true, 'Short', inline='08', group='Strategy Settings', tooltip='Toggle long/short strategy on/off')

stopMultiple = input.float(1, 'Stop multiple', step=0.25, group='Risk Management Settings', tooltip='Multiple for ATR, setting hard stop loss from entry price')
lev = input.float(1, 'Max Leverage', step=0.5, group='Risk Management Settings', tooltip='Max leverage sets maximum allowable leverage of total capital (initial capital + any net profit), capping maximum volatility adjusted position size')
riskT = input.float(10, maxval=75, title='Annualised Volatility Target %', group='Risk Management Settings', tooltip='Specify annual risk target, used to determine volatility adjusted position size. Annualised daily volatility is referenced to this value and position size adjusted accordingly')
comp = input(false, 'Compounding', inline='09', group='Risk Management Settings')
Comppct = input.float(50, '%', step=5, inline='09', group='Risk Management Settings', tooltip='Toggle compounding of profit, and set % of profit to compound')

// Backtesting period
FromDay = input.int(defval=1, title='From Day', minval=1, maxval=31, inline='04', group='Backtest range')
FromMonth = input.int(defval=1, title='From Mon', minval=1, maxval=12, inline='04', group='Backtest range')
FromYear = input.int(defval=2018, title='From Yr', minval=1900, inline='04', group='Backtest range', tooltip='Set start of backtesting period')
ToDay = input.int(defval=1, title='To Day', minval=1, maxval=31, inline='05', group='Backtest range')
ToMonth = input.int(defval=1, title='To Mon', minval=1, maxval=12, inline='05', group='Backtest range')
ToYear = input.int(defval=9999, title='To Yr', minval=1900, inline='05', group='Backtest range', tooltip='Set end of backtesting period')

start = timestamp(FromYear, FromMonth, FromDay, 00, 00)
finish = timestamp(ToYear, ToMonth, ToDay, 23, 59)
window = true

// Normalised returns calculation
nRet = (src - src[1]) / ta.stdev((src - src[1]), length)

nPrice = ta.cum(nRet)

//Hull Moving Average - using normalised price series
fHMA = ta.wma(2 * ta.wma(nPrice[offset], hlength / 2) - ta.wma(nPrice[offset], hlength), math.round(math.sqrt(hlength)))

//Risk Management formulae
strategy.initial_capital = 50000
tr = math.max(high - low, math.abs(high - close), math.abs(low - close)) //True range
stopL = ta.sma(tr, 14) //Average true range
stdev = ta.stdev(close-close[1], 14) //volatility of recent returns
maxcapital = strategy.initial_capital+strategy.netprofit //Maximum capital available to invest - initial capital net of profit
annvol = 100*math.sqrt(365)*stdev/close //converts recent volatility of returns into annualised volatility of returns - assumes daily timeframe

risk = 1.1
if comp
    risk := (strategy.initial_capital+(Comppct*strategy.netprofit/100))//adjust investment capital to include compounding
else
    risk := strategy.initial_capital

shares = (risk * (riskT/annvol)) / close //calculates volatility adjusted position size, dependent on user specified annualised risk target
if ((shares*close) > lev*maxcapital) //ensures position size does not exceed available capital multiplied by user specified maximum leverage
    shares := lev*maxcapital/close

//To set the price at the entry point of trade
Posopen() =>
    math.abs(strategy.position_size[1]) <= 0 and math.abs(strategy.position_size) > 0

var float openN = na
if Posopen()
    openN := stopL

// Strategy Rules
if long
    longCondition = ta.crossover(nPrice, fHMA) and window
    exitlong = ta.crossunder(nPrice, fHMA)
    if (longCondition)
        strategy.entry('Go Long!', strategy.long, qty=shares)
    if strategy.position_size > 0    
        strategy.exit('Stop Long', from_entry = 'Go Long!', stop=(strategy.opentrades.entry_price(0) - (openN * stopMultiple)))
    if (exitlong)
        strategy.close('Go Long!', immediately = true)

if short
    shortCondition = ta.crossunder(nPrice, fHMA) and window
    exitshort = ta.crossover(nPrice, fHMA)
    if (shortCondition)
        strategy.entry('Go Short!', strategy.short, qty=shares)
    if strategy.position_size < 0   
        strategy.exit('Stop Short', from_entry = 'Go Short!', stop=(strategy.opentrades.entry_price(0) + (openN * stopMultiple)))
    if (exitshort)
        strategy.close('Go Short!', immediately = true)

// Visuals of trend and direction
plot(nPrice, title='Real Price', color=color.black)

MAColor = fHMA > fHMA[3] ? #00ff00 : #ff0000
MA1 = plot(fHMA, title='Hull MA', color=MAColor)
MA2 = plot(fHMA[3], title='Hull MA Offset', color=MAColor)
fill(MA1, MA2, title='Band Filler', color=MAColor)