モメント インディケーター 取引戦略

作者: リン・ハーンチャオチャン開催日:2023年12月15日15時31分52秒
タグ:

img

概要

モメントインジケーター決定取引戦略は,トレンドフォロー戦略である.ダブル指数移動平均を用いてモメントインジケーターを構築し,価格変動率インジケーターと組み合わせて取引シグナルを生成する.モメントインジケーターが上昇すると,ロングシグナルを生成する.モメントインジケーターが低下すると,ショートシグナルを生成する.この戦略は,市場の中期トレンドを追跡したいトレーダーに適している.

戦略原則

この戦略は,ダブル指数移動平均をベースとしたディシジョンポイントオシレーターを使用してモメンタムを測定する.まず,日々の価格変動率を計算し,その後31日および20日間のダブル指数移動平均を使用して価格変動率を個別にスムーズにします.最後に,取引信号を発行するために9日間のスムーズ移動平均を使用します.速い線がスローラインの上にあるとき,それは牛市場を示します.速い線がスローラインの下にあるとき,それは熊市場を示します.

この戦略は,横向市場での誤った信号を避けるために価格変動率指標も導入している.特に,過去30日間の価格変動を計算し,移動平均値によって市場が活発であるかどうかを判断する.取引信号は,市場が活発であるときにのみ発行される.

利点分析

この戦略は,モメントインジケーターと価格変動率インジケーターを組み合わせ,中期トレンドを効果的に特定し,不安定な市場で頻繁な取引を避けることができます.移動平均のような単純なトレンドフォロー戦略と比較して,間違った取引の確率を大幅に減らすことができます.また,リスクは,時間をかけて損失を削減し,取引損失を効果的に制御するためにストップ損失ポイントを設定することによって制御されます.

リスク分析

この戦略は,主に中長期トレンド取引に依存し,短期間の価格変動を把握できない.急激な市場動向がある場合,ストップ損失ポイントが破られ,損失が大きくなる可能性があります.また,不適切なパラメータ設定も戦略に影響を与える可能性があります.例えば,ダブル指数移動平均パラメータがあまりにも短く設定されている場合,間違った取引の確率が増加します.

リスクを防ぐために,ストップ・ロスのポイントは,ストップ・ロスの範囲を拡大するために適切に調整することができます.急激な市場の動きが起こると,ストップ・ロスの破損の可能性を避けるために戦略は一時的にオフにすることができます.パラメータチューニングのために,最適なパラメータを選択するために詳細なバックテストを実行する必要があります.

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

戦略は以下の側面で最適化できます.

  1. 波動性指標のような他のフィルタリング指標を追加して,急激な市場変動の期間中に取引を避ける.

  2. 傾向の方向と強さの判断を助ける機械学習モデルを追加し,信号の精度を向上させることができます.

  3. 相対強度指数やストカスティックオシレーターなど 様々なインパクトインジケーターを試して 入出タイミングを最適化します

  4. リアルタイム取引では,最新の市場状況と組み合わせたパラメータを動的に調整し,最適なパラメータの組み合わせを追求します.

結論

モメントインジケーター決定取引戦略は,一般的に安定した中長期トレンドフォロー戦略である. 双指数移動平均モメント指標と価格変動率指標を組み合わせることで,トレンドを効果的に特定し,間違った取引を回避する. 一方,ストップ損失ポイントを設定することによってリスクを制御する. パラメータが適切に調整され,バックテスト結果が良好であれば,過剰なリターンを追求する中長期投資家に適している. もちろん,トレーダーは依然として戦略に急激な市場変動がもたらすリスクに気づかなければなりません.


/*backtest
start: 2022-12-08 00:00:00
end: 2023-11-10 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
strategy("Decision BF", overlay=false, initial_capital=10000, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.075)

/////////////// Time Frame ///////////////
testStartYear = input(2017, "Backtest Start Year") 
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay, 0, 0)

testStopYear = input(2019, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(31, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay, 0, 0)

testPeriod() => true

/////////////// Decision ///////////////
src = input(ohlc4, title="Source")
length1 = input(31, title="First Smoothing")
length2 = input(20, title="Second Smoothing")
siglength = input(9, title="Signal Smoothing")
fr = input(true, title="Fill Region")

calc_csf(src, length) => 
	sm = 2.0 / length
	csf = 0.0
	csf := (src - nz(csf[1])) * sm + nz(csf[1])
	csf
i = (src / nz(src[1], src)) * 100
pmol2 = calc_csf(i - 100, length1)
pmol = calc_csf(10 * pmol2, length2)
pmols = ema(pmol, siglength)
d = pmol - pmols
duml = plot(fr ? (d > 0 ? pmol : pmols) : na, style=plot.style_circles, color=color.yellow, linewidth=0, title="DummyL")

hc = d > 0 ? d > d[1] ? color.lime : color.green : d < d[1] ? color.red : color.orange

///////////// Rate Of Change ///////////// 
source = close
roclength = input(30, minval=1)
pcntChange = input(7, minval=1)
roc = 100 * (source - source[roclength]) / source[roclength]
emaroc = ema(roc, roclength / 2)
isMoving() => emaroc > (pcntChange / 2) or emaroc < (0 - (pcntChange / 2))

/////////////// Strategy ///////////////
long = d > 0 and isMoving() 
short = d < 0 and isMoving() 

last_long = 0.0
last_short = 0.0
last_long := long ? time : nz(last_long[1])
last_short := short ? time : nz(last_short[1])

long_signal = crossover(last_long, last_short)
short_signal = crossover(last_short, last_long)

last_open_long_signal = 0.0
last_open_short_signal = 0.0
last_open_long_signal := long_signal ? open : nz(last_open_long_signal[1])
last_open_short_signal := short_signal ? open : nz(last_open_short_signal[1])

last_long_signal = 0.0
last_short_signal = 0.0
last_long_signal := long_signal ? time : nz(last_long_signal[1])
last_short_signal := short_signal ? time : nz(last_short_signal[1])

in_long_signal = last_long_signal > last_short_signal
in_short_signal = last_short_signal > last_long_signal

last_high = 0.0
last_low = 0.0
last_high := not in_long_signal ? na : in_long_signal and (na(last_high[1]) or high > nz(last_high[1])) ? high : nz(last_high[1])
last_low := not in_short_signal ? na : in_short_signal and (na(last_low[1]) or low < nz(last_low[1])) ? low : nz(last_low[1])

sl_inp = input(2.0, title='Stop Loss %') / 100
tp_inp = input(5000.0, title='Take Profit %') / 100
 
take_level_l = strategy.position_avg_price * (1 + tp_inp)
take_level_s = strategy.position_avg_price * (1 - tp_inp)

since_longEntry = barssince(last_open_long_signal != last_open_long_signal[1]) 
since_shortEntry = barssince(last_open_short_signal != last_open_short_signal[1])

slLong = in_long_signal ? strategy.position_avg_price * (1 - sl_inp) : na
slShort = strategy.position_avg_price * (1 + sl_inp)
long_sl = in_long_signal ? slLong : na
short_sl = in_short_signal ? slShort : na

/////////////// Execution ///////////////
if testPeriod()
    strategy.entry("Long",  strategy.long, when=long)
    strategy.entry("Short", strategy.short, when=short)
    strategy.exit("L Ex", "Long", stop=long_sl, limit=take_level_l, when=since_longEntry > 0)
    strategy.exit("S Ex", "Short", stop=short_sl, limit=take_level_s, when=since_shortEntry > 0)

/////////////// Plotting ///////////////
sigl = plot(false ? na : pmols, title="PMO Signal", color=color.gray, linewidth=2, title="Signal")
mdl = plot(false ? na : pmol, title="PMO", color=color.black, linewidth=2, title="PMO")
fill(duml, sigl, color.green, transp=20, title="PosFill")
fill(duml, mdl, color.red, transp=20, title="NegFill")
bgcolor(isMoving() ? long ? color.lime : short ? color.red : na : color.white, transp=70)
bgcolor(long_signal ? color.lime : short_signal ? color.red : na, transp=50)

もっと