動的位置再バランス傾向追跡システム

作者: リン・ハーンチャオチャン,日付: 2024-01-26 14:41:08
タグ:

img

概要

この戦略は,指数的な移動平均クロスオーバーシステムとタートル取引システムを統合しています. これは,2つの人気のある体系的な取引戦略です. ポジションを動的に管理することによって,リアルタイムで市場の動向を追跡するために,毎日タイムフレームのために特別に設計されています.

戦略の論理

戦略には2つのサブ戦略があります.トレンド戦略とブレークアウト戦略です.

トレンド戦略は,高速EMAと遅いEMAクロスオーバーを取引信号として使用する.高速EMA期間はユーザーによって定義され,遅いEMA期間は高速EMAの5倍である.シグナルは,EMA差を252期リターン標準偏差で割ることで生成される.これはより信頼性の高い信号を生み出すために波動性調整されている.新しいトレンド形成を検出する際に長または短に移動する.

ブレイクアウト戦略は,固定回顧期間の最高高値と最低低値の平均値をベースラインとして使用する.価格が一定パーセントでベースラインの上/下を突破すると,ロング/ショート信号が生成される.

ポジションのサイジングは,最近の価格変動とユーザーによって定義された年間リスク目標に基づいて行われます.変動が低いときはより大きなサイズが取られ,変動が高いときはより小さなサイズが取られます.これはリスク調整によるダイナミックなポジション管理を実現します.

ハードストップは平均値の倍数として設定されます. トレイリングストップは最近の最高値または最低値です.

利点分析

この戦略の主な利点は以下の通りである.

  1. トレンド追跡とブレイクアウトのサブ戦略を組み合わせることで,異なる市場環境に強く適応できます.

  2. 先進的なポジションサイズ化とリスク管理技術を適用することで,ポジションを動的に管理し,リスクを効果的に制御できます.

  3. 波動性調整のポジションは,最近の波動性と年次リスク目標に基づいて,波動性が高い/低い制度では,ポートフォリオリスクが比較的安定しています.

  4. 実際の価格変動に基づいてストップ損失を設定することで,ストップランスの不必要な小損失を回避できます.

  5. リアルタイムでトレイルストップを調整し 柔軟にトレンドをフォローして 利益を記録し タイミングでストップします

リスク分析

この戦略の主なリスクは,

  1. パラメータ最適化に依存する.異なるパラメータは戦略のパフォーマンスに大きく影響するので,最適なパラメータを見つけるために包括的なテストが必要です.

  2. 動揺するトレンドで頻繁にストップアウトする.ストップ損失幅は緩和され,ストップメカニズムは最適化される.

  3. 初期資本と取引コストに対する敏感性 初期資本の不足と高額な取引コストが収益性に悪影響を及ぼします

  4. ポジションのサイズ付けとリスク管理のために正確な波動性見積もりに依存する.不正確な波動性見積もりにより,ポジションが大きすぎたり,小さすぎたりする.

オプティマイゼーションの方向性

主な最適化方向は以下の通りである.

  1. 最大の歴史的データセットでバックテストを重ねて最適なパラメータセットを検索します

  2. 移動停止,時間停止,変動停止などの様々な停止をテストすることによって停止メカニズムを改善します.

  3. 最適なリスク・リターンプロフィールを見つけるために,異なるリスクターゲットをテストすることによって,ポジションサイズとリスク管理を最適化します.また,異なるレバレッジレベルの影響をテストします.

  4. 信号の精度と戦略の強さを高めるため 補助指標を試してください

  5. ポジションアロケーションの精度を向上させるため,より高いタイムフレーム信号で意思決定を支援することによって,異なる保持期間をテストする.

結論

この戦略は,トレンドフォローとブレイクアウトという2つの主要な戦略を統合している.先進的なダイナミックポジション調整技術を適用することで,市場が利益に向かって動いていることを追跡しながらリスクを効果的に制御する.強力な利益の可能性を示し,さらなるテストと最適化に価値がある.


/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
period: 1h
basePeriod: 15m
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 Turtle and Trend System", shorttitle="Turtle Trend", overlay=true, slippage=10, pyramiding=1, precision = 4, calc_on_order_fills = false, calc_on_every_tick = false, default_qty_value = 0.1, initial_capital = 1000, commission_value = 0.06, process_orders_on_close = true)

// Inputs and Parameters
src = input(close, 'Source', group='Strategy Settings')
length = input.int(title="Lookback period for fast EMA", defval=10, minval=2, group='Strategy Settings', tooltip='This sets the lookback period for the fast exponential moving average. The slow EMA is 5x the fast EMA length')
blength = input.int(title="Lookback period for Breakout", defval=20, minval=5, step=5, group='Strategy Settings')

long = input(true, 'Long', inline='08', group='Strategy toggle')
short = input(true, 'Short', inline='08', group='Strategy toggle', tooltip='Toggle long/short strategy on/off')

EMAwt = input(false, 'Trend', inline='01', group='Strategy toggle')
breakwt = input(true, 'Breakout', inline='01', group='Strategy toggle', tooltip='Toggle trend/breakout strategy on/off')

stopMultiple = input.float(2, 'Stop multiple', step=0.5, group='Risk Management Settings', tooltip='Multiple for ATR, setting hard stop loss from entry price')
trail = input.int(10, 'Trail lookback', step=5, group='Risk Management Settings', tooltip='Lookback period for the trailing stop')
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(15, 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(true, '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 = time >= start and time <= finish

// Breakout strategy
lower = ta.lowest(low[1], blength)
upper = ta.highest(high[1], blength)
basis = math.avg(upper, lower)
signal = 20*(close - basis) / (upper - lower)

// Trend strategy
fEMA = ta.ema(close[1], length)
sEMA = ta.ema(close[1], length*5)
emadiff = fEMA - sEMA
nemadiff = 5*emadiff/(ta.stdev(close - close[1], 252))

//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

// Trailing stop
tlower = ta.lowest(low[1], trail)
tupper = ta.highest(high[1], trail)
tbasis = math.avg(tupper, tlower)
tsignal = 20*(close - tbasis) / (tupper - tlower)

// Strategy Rules
if EMAwt
    if long
        longCondition2 = (nemadiff >2 and nemadiff[1] <2) and window
        exitlong = tsignal <= -10
        if (longCondition2)
            strategy.entry('Trend Long!', strategy.long, qty=shares)
        if strategy.position_size > 0    
            strategy.exit('Stop Long', from_entry = 'Trend Long!', stop=(strategy.opentrades.entry_price(0) - (openN * stopMultiple)))
        if (exitlong)
            strategy.close('Trend Long!', immediately = true)

    if short
        shortCondition2 = (nemadiff <-1 and nemadiff[1] >-1) and window
        exitshort = tsignal >= 10
        if (shortCondition2)
            strategy.entry('Trend Short!', strategy.short, qty=shares)
        if strategy.position_size < 0   
            strategy.exit('Stop Short', from_entry = 'Trend Short!', stop=(strategy.opentrades.entry_price(0) + (openN * stopMultiple)))
        if (exitshort)
            strategy.close('Trend Short!', immediately = true)

if breakwt
    if long
        longCondition1 = (signal >= 10) and window
        exitlong = tsignal <= -10
        if (longCondition1)
            strategy.entry('Break Long!', strategy.long, qty=shares)
        if strategy.position_size > 0    
            strategy.exit('Stop Long', from_entry = 'Break Long!', stop=(strategy.opentrades.entry_price(0) - (openN * stopMultiple)))
        if (exitlong)
            strategy.close('Break Long!', immediately = true)

    if short
        shortCondition1 = (signal <= -10) and window
        exitshort = tsignal >= 10
        if (shortCondition1)
            strategy.entry('Break Short!', strategy.short, qty=shares)
        if strategy.position_size < 0   
            strategy.exit('Stop Short', from_entry = 'Break Short!', stop=(strategy.opentrades.entry_price(0) + (openN * stopMultiple)))
        if (exitshort)
            strategy.close('Break Short!', immediately = true)

// Visuals of trend and direction
plot(nemadiff, title='EMA Forecast', color=color.black, display=display.none)
plot(ta.sma(ta.median(math.sqrt(math.pow(nemadiff,2)), 700), 350), 'Forecast mean', color=color.rgb(245, 0, 0), display=display.none)

MAColor = fEMA > sEMA ? #00ff00 : #ff0000
MA1 = plot(fEMA, title='Fast EMA', color=MAColor)
MA2 = plot(sEMA, title='Slow EMA', color=MAColor)
fill(MA1, MA2, title='Band Filler', color=MAColor)

もっと