アダプティブ・ムービング・メアディアに基づく戦略をフォローする傾向

作者: リン・ハーンチャオチャン開催日:2024年1月30日 16時30分20秒
タグ:

img

概要

この戦略は,トレンドをフォローする取引システムを設計するために,カフマン適応移動平均 (KAMA) インジケーターを使用しています. 動揺する市場中にトレンドが形成され,ノイズをフィルタリングするときに迅速にトレンドを追跡することができます. 同時に,システムは,強力なリスク制御能力を持つストップ損失メカニズムとしてパラボリックSAR (PSAR) と平均真範囲トレーリングストップも統合しています.

戦略の論理

  • KAMA指標の長さは,最近の市場変動に基づいて動的に調整されます.価格の変化が最近のノイズよりも大きいとき,EMAウィンドウは短くなります.価格の変化が最近のノイズよりも小さいとき,EMAウィンドウは長くなります.これは,KAMAが不安定な市場中にノイズをフィルタリングしながらトレンドを迅速に追跡できるようにします.

  • このシステムは主に最も速いKAMA (KAMA 1) をベースにトレンド方向を判断する.KAMA 1が上を向いていると長行し,KAMA 1が下を向いていると短行する.偽ブレイクをフィルタリングするために,KAMAフィルタが設定されている.KAMA 1の変化が最近の変動の1つの標準偏差を超えるとのみ取引信号が生成される.

  • ストップ・ロスは,KAMA逆転,PSAR逆転,ATRトレーリング・ストップの3つのオプションストップ・ロスを提供する.投資家は1つまたは組み合わせを選択することができます.

利点分析

  • KAMA指標のユニークなデザインにより,新興傾向を迅速に把握し,不安定な市場中に取引を停止し,取引頻度を効果的に制御し,不必要なスライドと手数料を削減できます.

  • このシステムには複数のストップ・ロスのメカニズムが組み込まれています.投資家は個々の損失を効果的に制御するために,個人リスクの好みに応じて適切なストップ・ロスのスキームを選択できます.

  • このシステムは完全に指標とストップ・ロスの線に基づいていて,取引の移動によって引き起こされる一般的な誤入問題を回避します.

  • 複数のパラメータ設定とコンディション組み合わせは,システムのカスタマイゼーションに大きなスペースを提供します.ユーザーは異なる製品と周波数に応じて最適化することができます.

リスク分析

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

  • システム PARAMETERS は,異なる製品と頻度に応じて調整する必要がある場合があります.そうでなければ,過剰に攻撃的または過度に保守的な結果を生むでしょう.

  • ストップ・ロスのため,KAMA インディケーターのみを頼りにすると,不安定な市場では簡単にストップに引っかかる.これを解決するには,PSAR または ATR トレイリングストップと組み合わせることが必要です.

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

  • ADX や暗黙の変動などのトレンドフィルタリングインジケーターを追加することで,不安定なトレンドやトレンド移行段階において間違った信号を生むのを避ける.

  • 安定性を向上させるために,個々の製品と固定周波数のパラメータを最適化およびバックテストする.最適化次元には,KAMAパラメータ組み合わせ,ストップ損失パラメータなどが含まれます.

  • パラメータ最適化ではなく マシン学習モデルを試してみてください ニューラルネットワークや意思決定ツリーモデルを 膨大な履歴データで訓練して 入口と出口のタイミングを判断し ストップ損失をします

  • 戦略を暗号通貨などの他の製品に移行してみてください.これは PARAMETERS を調整したり,他の補助指標を追加したりする必要があります.

概要

この戦略は,トレンド判断のためのKAMAと複数のストップロスの方法を統合して,トレンド方向を効果的に追跡し,リスクを制御する.KAMA指標のユニークさは,戦略が急速に新興トレンドの方向を決定し,偽のブレイクアウト問題を回避することを可能にします.カスタマイズ可能および最適化可能なパラメータは,ユーザーに個別調整のための大きなスペースを提供します.パラメータを最適化し,個々の製品と周波数のためのMACHINE LEARNINGモデルを統合することで,戦略のパフォーマンスはさらに向上することができます.


/*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")

もっと