適応型移動平均に基づくトレンドフォロー戦略


作成日: 2024-01-30 16:30:20 最終変更日: 2024-01-30 16:30:20
コピー: 0 クリック数: 846
1
フォロー
1617
フォロワー

適応型移動平均に基づくトレンドフォロー戦略

概要

この戦略は,Kaufman自主適応移動平均 (KAMA) 指数を使用したトレンド追跡取引システムを設計した.このシステムは,トレンドが形成されたときに迅速にトレンドを追跡し,震動の際のノイズをフィルターする.同時に,システムは,パラパラ線転換システム (PSAR) と平均リアル波動率追跡ストップ (ATRトラリングストップ) をストップメカニズムとして統合し,強力なリスク管理能力を有している.

戦略原則

  • KAMA指標の長さは,最近の市場変動率の動向に合わせて調整されている.価格の変化が最近のノイズより大きいときは,EMAウィンドウが短くなり,価格の変化が最近のノイズより小さいときはEMAウィンドウが長くなっている.これは,KAMAがトレンドを素早く追跡し,振動的な状況でノイズをフィルターすることを可能にする.

  • システムは,主に最速のKAMA ((KAMA 1) によってトレンドの方向を判断する.KAMA 1は,上向きに多行し,下向きに空行する.偽突破をフィルターするために,KAMAフィルターが設定されている.KAMA 1の変化は,最近の波動が標準差を超えるとのみ,取引シグナルが生成される.

  • 止損に関しては,システムでは3つの選択可能な止損方法を提供しています:KAMAベースの反転,PSARの反転,ATR移動止損. 投資家は,1つまたは複数の組み合わせを使用することを個別的に選択することができます.

優位分析

  • KAMA指標の独特な設計により,システムは新興トレンドを迅速に捉え,波動的な状況で取引を停止し,取引頻度を効果的に制御し,不必要なスライドポイントと手数料の損失を減らすことができます.

  • システム内蔵の多種多様の止損メカニズム. 投資家は,個人のリスクの好みに応じて,適切な止損方案を選択し,単一の損失を強力に制御することができる.

  • このシステムは,指数とストップラインを完全にベースにしており,常見の移位取引の誤入問題を回避しています.

  • 複数のパラメータの設定と条件の組み合わせは,システムカスタマイズに大きな余地を提供します. ユーザーは,場所に応じて,異なる品種と周期のために最適化することができます.

リスク分析

  • システム上のリスクは考慮されず,極端な状況では,損失を効果的に制御することはできません.

  • 系統PARAMETERSは,異なる品種に異なる周期で調整する必要がある場合があり,そうでなければ,過度に過激な,または過度に保守的な結果が生じます.

  • KAMA指数のみをストップとして頼る場合,震動の状況で閉じ込められやすい.これはPSARまたはATR移動ストップと組み合わせて使用する必要が解決される.

最適化の方向

  • 動揺とトレンド転換の段階で誤信号を避けるために,ADXや隠された変動率の指標のようなトレンドフィルターを追加します.

  • 単一品種および固定周期に対してPARAMETERSを最適化および反測し,安定性を高める.最適化次元には,KAMAパラメータの組み合わせ,止損パラメータなどが含まれている.

  • パラメータ最適化ではなく,MACHINE LEARNINGモデルを試す. ニューラルネットワークや意思決定ツリーモデルで,大量の歴史データを使って,取引のタイミングと停止を判断するトレーニングを行う.

  • 戦略をデジタル通貨などの他の品種に移植しようとします. これはPARAMETERSの調整または他の補助指標の追加を必要とするかもしれません.

要約する

この戦略は,KAMAのトレンド判断と複数のストップ手段を統合し,トレンドの方向を効果的に追跡し,リスクを制御します.KAMA指標のユニークな特徴は,戦略が新興トレンドの方向を迅速に判断し,偽の突破を回避することを可能にします.カスタマイズ可能で最適化可能なPARAMETERSは,ユーザーに個性的な調整のための大きな余地を提供します.

ストラテジーソースコード
/*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/
// © BenHampson
// @version=4
// Credit to:
// - ChuckBanger for much of the KAMA code
// - cheatcountry for the KAMA Filter code
// - millerrh for much of the ATR Stop code
// - racer8 for much of the Position Sizing code

// I have combined aspects of their work and built upon it to form a strategy I like. 
// The KAMA, with its filter, is used for entry.
// An ATR trailing stop loss, PSAR, and the KAMA can all optionally be used as exits, or you can use a combination of the three.

strategy(title="KAMA Strategy - Kaufman's Adaptive Moving Average", shorttitle="KAMA Strategy", overlay=true)

src = input(title="Source", type=input.source, defval=close)

// Exits
KAMA1SL = input(title = 'KAMA 1 Stop Loss', type = input.bool, defval = true)
ATRTSL = input(title = 'ATR Trailing Stop Loss', type = input.bool, defval = false)
PSARSL = input(title = 'PSAR Stop Loss', type = input.bool, defval = false)

// KAMA 1 (Fastest)
length1 = input(title="KAMA 1: Length", type=input.integer, defval=14)
fastLength1 = input(title="KAMA 1: Fast KAMA Length", type=input.integer, defval=2)
slowLength1 = input(title="KAMA 1: Slow KAMA Length", type=input.integer, defval=20)

length2 = input(title="KAMA 2: Length 2", type=input.integer, defval=15)
fastLength2 = input(title="KAMA 2: Fast KAMA Length", type=input.integer, defval=3)
slowLength2 = input(title="KAMA 2: Slow KAMA Length", type=input.integer, defval=22)

length3 = input(title="KAMA 3: Length 3", type=input.integer, defval=16)
fastLength3 = input(title="KAMA 3: Fast KAMA Length", type=input.integer, defval=4)
slowLength3 = input(title="KAMA 3: Slow KAMA Length", type=input.integer, defval=24)

length4 = input(title="KAMA 4: Length", type=input.integer, defval=17)
fastLength4 = input(title="KAMA 4: Fast KAMA Length", type=input.integer, defval=5)
slowLength4 = input(title="KAMA 4: Slow KAMA Length", type=input.integer, defval=26)

// KAMA 5 (Medium)
length5 = input(title="KAMA 5: Length", type=input.integer, defval=18)
fastLength5 = input(title="KAMA 5: Fast KAMA Length", type=input.integer, defval=6)
slowLength5 = input(title="KAMA 5: Slow KAMA Length", type=input.integer, defval=28)

length6 = input(title="KAMA 6: Length", type=input.integer, defval=19)
fastLength6 = input(title="KAMA 6: Fast KAMA Length", type=input.integer, defval=7)
slowLength6 = input(title="KAMA 6: Slow KAMA Length", type=input.integer, defval=30)

length7 = input(title="KAMA 7: Length", type=input.integer, defval=20)
fastLength7 = input(title="KAMA 7: Fast KAMA Length", type=input.integer, defval=8)
slowLength7 = input(title="KAMA 7: Slow KAMA Length", type=input.integer, defval=32)

// KAMA 8 (Slowest)
length8 = input(title="KAMA 8: Length", type=input.integer, defval=21)
fastLength8 = input(title="KAMA 8: Fast KAMA Length", type=input.integer, defval=9)
slowLength8 = input(title="KAMA 8: Slow KAMA Length", type=input.integer, defval=34)

// Kaufman's Adaptive Moving Average
getKAMA(src, length1, fastLength1, slowLength1) =>
    mom = abs(change(src, length1))
    volatility = sum(abs(change(src)), length1)
    
    // Efficiency Ratio
    er = volatility != 0 ? mom / volatility : 0
    
    fastAlpha = 2 / (fastLength1 + 1)
    slowAlpha = 2 / (slowLength1 + 1)
    
    // KAMA Alpha
    sc = pow((er * (fastAlpha - slowAlpha)) + slowAlpha, 2)
    
    kama = 0.0
    kama := sc * src + (1 - sc) * nz(kama[1])
    kama

kama1 = getKAMA(src, length1, fastLength1, slowLength1)
kama2 = getKAMA(src, length2, fastLength2, slowLength2)
kama3 = getKAMA(src, length3, fastLength3, slowLength3)
kama4 = getKAMA(src, length4, fastLength4, slowLength4)
kama5 = getKAMA(src, length5, fastLength5, slowLength5)
kama6 = getKAMA(src, length6, fastLength6, slowLength6)
kama7 = getKAMA(src, length7, fastLength7, slowLength7)
kama8 = getKAMA(src, length8, fastLength8, slowLength8)

//If the kama1 has increased...
kama1delta = kama1[0] - kama1[1]
kama3delta = kama3[0] - kama3[1]
kama8delta = kama8[0] - kama8[1]

// KAMA Plots
plot(kama1, title="KAMA 1", color=#e91e63, display=display.all, linewidth=2)
plot(kama2, title="KAMA 2", color=color.red, display=display.all)
plot(kama3, title="KAMA 3", color=color.red, display=display.all)
plot(kama4, title="KAMA 4", color=color.orange, display=display.all)
plot(kama5, title="KAMA 5", color=color.orange, display=display.all)
plot(kama6, title="KAMA 6", color=color.yellow, display=display.all)
plot(kama7, title="KAMA 7", color=color.yellow, display=display.all)
plot(kama8, title="KAMA 8", color=color.white, display=display.all)



//========================================= KAMA FILTER ===========================================

// Copyright (c) 2019-present, Franklin Moormann (cheatcountry)
// Moving Average Adaptive Filter [CC] script may be freely distributed under the MIT license.

entryFilter = input(title="KAMA Entry Filter", type=input.float, defval=1, minval=0.01)
exitFilter = input(title="KAMA Exit Filter", type=input.float, defval=0.5, minval=0.01)

entryMAAF = entryFilter * stdev(kama1delta, length1)
exitMAAF = exitFilter * stdev(kama1delta, length1)
srcEma = ema(src, length1)



//========================================= TRAILING ATR STOP ====================================

// The following is an adaptation of Trailing ATR Stops by @millerrh
// He based it on scripts by @garethyeo & @SimpleCryptoLife

// Inputs

atrLookback = input(defval=14,title="Trailing ATR Lookback Period",type=input.integer)
multiplier = input(defval=3,title="Trailing ATR Multiplier",type=input.float, step=0.1, minval=0.5, maxval=4)
trailMode = input(title="Trail Mode", defval="Trailing", options=["Running", "Trailing"])
trigInput = input(title="Trigger Trailing Stop On", defval="Wick", options=["Close","Wick"]) 

// Calculate ATR
atrValue = atr(atrLookback)
atrMultiplied = atrValue * multiplier

// Plot the price minus the ATR
atrLow = low - atrMultiplied

// Calculate the low trailing ATRs every time. The trailing stop loss never goes down.
// Set them to something to start with
trailAtrLow = atrLow

// If the ATR Low has gone up AND it has gone above the trail, the low trailing ATR should also go up. If the ATR Low has gone up or down, but not below the trail, the ATR trail stays where it is
trailAtrLow := na(trailAtrLow[1]) ? trailAtrLow : atrLow >= trailAtrLow[1] ? atrLow : trailAtrLow[1]

// Trigger stop based on candle close or low
trigSupport = trigInput == "Close" ? close : trigInput == "Wick" ? low : na

// Determine if price is below support
supportHit = trigSupport <= trailAtrLow

// If price is below support, reset the trailing ATR
trailAtrLow := supportHit ? atrLow : trailAtrLow

// Plot Lines
plotLow = ATRTSL ? trailAtrLow : na
plot(plotLow, title="ATR Low", color=color.white, transp=50, style=plot.style_linebr, linewidth=1, display=display.all)



//====================================== PSAR STOP ==========================================

start = input(0.02, "PSAR Start")
increment = input(0.02, "PSAR Increment")
maximum = input(0.2, "PSAR Max Value")
psar = sar(start, increment, maximum)
psarPlot  = PSARSL ? psar : na
plot(psarPlot, "Parabolic SAR", style=plot.style_cross, color=#3A6CA8, display=display.all)



//========================================= ENTRY & EXITS =====================================================

// Entry
long = kama1delta > 0 and kama1delta > entryMAAF
strategy.entry("Buy", true, when = long) 

// Close
longClose = (PSARSL ? crossunder(close, psar) : na) or (KAMA1SL ? kama1delta < 0 and abs(kama1delta) > exitMAAF : na) or (ATRTSL ? supportHit : na)
strategy.close("Buy", when = longClose, comment = "Sell")