モメント・ムービング・平均クロスオーバー戦略

作者: リン・ハーンチャオチャン, 日付: 2023-09-21 21:29:22
タグ:

概要

この戦略は,市場傾向の方向性を決定し,買い売りシグナルを生成するために,高速移動平均値とスロー移動平均値のクロスオーバー原則を利用する.この戦略は,中期取引に適したシンプルで容易な実装です.

戦略の論理

この戦略は,2つの移動平均線,一方の高速線と一方のスローラインを使用する.高速線は3日間のEMA,スローラインは15日間のEMAを使用する.高速線が下からスローラインを越えると,上向きの傾向を示し,購入信号を与える.逆に,高速線が上からスローラインを下に越えると,下向きの傾向を示し,販売信号を与える.

この戦略は,より速い3日間のEMAを迅速な出口ラインとして設定する.価格がこの迅速な出口ラインを下回ると,トレンドが逆転し,既存のロングポジションを退出すべきであると判断する.同様に,価格が出口ライン上に戻ると,新たな上昇傾向を示し,再びロングに入ることを示す.

特定の操作信号は以下のように設定されます.

  1. 低線から低線を横切って,長線を横切る

  2. 速線が下を横切る ゆっくりした線が上を横切る 短線を横切る

  3. 価格が急出線を下回り,ロングポジションを閉じる

  4. 価格が快速出口線を突破し,再びロングに

利点

  • 簡単に操作できる 移動平均のパラメータを2つ設定するだけで 簡単に実装できます

  • 十分なバックテストデータがあり,実行可能性を評価するために共通の指標を使用

  • 最適化のための多くの設定可能なパラメータ

  • リスクをより良く制御するために,ストップ損失として迅速な出口線を採用します.

  • 明確な戦略論理,明示的な買い物・売り物信号

  • 適正な操作頻度,過剰な取引を避ける

リスク

  • 傾向が不明である場合,傾向をフォローする戦略よりも多くの誤った信号を受けやすい.

  • 移動平均値は遅い性質を持ち,ターンポイントを逃す可能性があります

  • 固定パラメータは市場の変化に適応できないので,最適化が必要です

  • ストップ・ロスはあまりにも柔らかく,時間内にストップ・ロスはできないかもしれない.

  • 頻繁に信号が発信されれば,取引コストが上がる

  • シグナルが異なる場合があり,他の指標と確認する必要がある

リスクはパラメータの最適化,フィルターの追加,ストップ損失の緩和,パラメータのタイムリー更新などによって管理できます

強化

  • 市場条件に適したパラメータをテストし最適化する

  • より多くの指標を導入し,堅牢なシステムを形成する

  • リアルタイム市場に基づいて適応パラメータ設定を構築

  • よりスマートな最適化のために機械学習モデルを適用する

  • より良いリスク管理のために動的または後続ストップ損失を設定する

  • 差異を避けるため,ボリューム指標を組み合わせる

結論

これは比較的単純な二重移動平均クロスオーバー戦略である. 急速な移動平均と遅い移動平均の相互作用に基づいて市場トレンドと取引信号を決定する. 戦略は実行しやすく,最適化によって適応することができます. しかし,いくつかのリスクもあります. 信号を確認し,リスクを管理するためにより多くのフィルターが必要です. 正しく最適化し,中期取引に適用すると,非常に実践的な定量的な取引システムになることができます.


/*backtest
start: 2023-01-01 00:00:00
end: 2023-02-03 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/
// © ehaarjee, ECHKAY, JackBauer007

//@version=4
//study(title="Tale_indicators", overlay=true)
strategy("Tale Indicators Strategy", overlay=true, precision=8, max_bars_back=200, pyramiding=0, initial_capital=20000, commission_type="percent", commission_value=0.1)

len_fast = input(3, minval=1, title="FAST EMA")
src_fast = input(close, title="Source for Fast")
fastMA = ema(src_fast, len_fast)
plot(fastMA, title="Slow EMA", color=color.orange)

len_slow = input(15, minval=1, title="SLOW EMA")
src_slow = input(close, title="Source for Slow")
slowMA = ema(src_slow, len_slow)
plot(slowMA, title="Fast EMA", color=color.blue)

len_fast_exit = input(3, minval=1, title="FAST EMA Exit")
src_fast_exit = input(close, title="Source for Fast Exit")
fastMAE = ema(src_fast_exit, len_fast_exit)
plot(fastMAE, title="Fast EMA Ex", color=color.red)


src_slow_enter_short = input(low, title="Source for Short Entry")
slowMASEn = ema(src_slow_enter_short, len_slow)

src_slow_enter_long = input(high, title="Source for Long Entry")
slowMALEn = ema(src_slow_enter_long, len_slow)

src_slow_exit_short = input(low, title="Source for Short Exit")
slowMASEx = ema(src_slow_enter_short, len_slow)

src_slow_exit_long = input(high, title="Source for Long Exit")
slowMALEx = ema(src_slow_enter_long, len_slow)

enter_long = crossover(fastMA, slowMALEn)
enter_short = crossunder(fastMA, slowMASEn)
exit_long = crossunder(fastMAE, slowMALEx)
exit_short = crossover(fastMAE, slowMALEx)

out_enter = iff(enter_long == true, 1, iff(enter_short == true, -1, 0))
plotarrow(out_enter, "Plot Enter Points", colorup=color.green, colordown=color.red, maxheight = 30)

bull = fastMA > slowMALEn
bear = fastMA < slowMASEn

c = bull ? color.green : bear ? color.red  : color.white
bgcolor(c)

exit_tuner = input(0.005, title="Exit Tuner to touch slowEMA")

bull_exit = (bull and (low>(fastMAE*(1+exit_tuner)))) or exit_long or (not(bear) and (fastMAE>high))
bear_exit = (bear and ((fastMAE*(1-exit_tuner))>high)) or exit_short or (not(bull) and (low>fastMAE))

bull_r = (bull and ((bull_exit[1]) or (bull_exit[2] and bull_exit[1])) and (low<=fastMAE))
bear_r = (bear and ((bear_exit[1]) or (bull_exit[2] and bull_exit[1])) and (fastMAE<=high))

bull_re = (bull and (low<slowMALEn)) and not(enter_long)
bear_re = (bear and (high>slowMASEn)) and not(enter_short)

bull_ree = (bull and ((low<slowMALEn) and not(bull_re[1] or enter_long[1]))) 
bear_ree = (bear and ((high>slowMASEn) and not(bear_re[1] or enter_short[1])))

bull_reenter =  (bull_r) and not(enter_long)
bear_reenter =  (bear_r) and not(enter_short)

plotshape(bull_exit, "Plot Bull Exit", style = shape.arrowdown, color=color.green, size=size.small, text="ExL", location=location.abovebar)
plotshape(bear_exit, "Plot Bear Exit", style = shape.arrowup, color=color.red, size=size.small, text="ExS", location=location.belowbar)

plotshape(bull_reenter, "Plot Bull ReEnter", style = shape.arrowup, color=color.green, size=size.small, text="ReL", location=location.belowbar)
plotshape(bear_reenter, "Plot Bear ReEnter", style = shape.arrowdown, color=color.red, size=size.small, text="ReS", location=location.abovebar)

run_strategy = input(true, title="Run Strategy")
// === INPUT BACKTEST RANGE ===
fromMonth = input(defval = 1,    title = "From Month",      type = input.integer, minval = 1, maxval = 12)
fromDay   = input(defval = 1,    title = "From Day",        type = input.integer, minval = 1, maxval = 31)
fromYear  = input(defval = 2020, title = "From Year",       type = input.integer, minval = 2000)
thruMonth = input(defval = 1,    title = "Thru Month",      type = input.integer, minval = 1, maxval = 12)
thruDay   = input(defval = 1,    title = "Thru Day",        type = input.integer, minval = 1, maxval = 31)
thruYear  = input(defval = 2100, title = "Thru Year",       type = input.integer, minval = 2000)

// === INPUT SHOW PLOT ===
showDate  = input(defval = true, title = "Show Date Range", type = input.bool)
// === FUNCTION EXAMPLE ===
start     = timestamp(fromYear, fromMonth, fromDay, 00, 00)        // backtest start window
finish    = timestamp(thruYear, thruMonth, thruDay, 23, 59)        // backtest finish window
window()  => true       // create function "within window of time"

var long_position_open = false
var short_position_open = false


if (enter_long and not(bull_exit) and not(long_position_open))
//    strategy.entry("LO", strategy.long, qty=4)
    long_position_open := true
    if (short_position_open)
//        strategy.close("SO")
        short_position_open := false

if (bull_reenter and not(long_position_open))  
//    strategy.entry("LO", strategy.long, qty=1)
    long_position_open := true

if (bull_exit and long_position_open)
//  strategy.close("LO")
    long_position_open := false
    
if (enter_short and not(bear_exit) and not(short_position_open))
//    strategy.entry("SO", strategy.short, qty=4)
    short_position_open := true
    if(long_position_open)
//        strategy.close("LO")
        long_position_open := false

if (bear_reenter and not(short_position_open))  
//    strategy.entry("SO", strategy.long, qty=1)
    long_position_open := true

if (bear_exit and short_position_open)
//    strategy.close("SO")
    short_position_open := false

if(run_strategy)
    strategy.entry("LO", strategy.long, when=(window() and enter_long), qty=4)
    strategy.entry("LO", strategy.long, when=(window() and bull_reenter and not(long_position_open)), qty=1)
    strategy.close("LO", when=(window() and bull_exit and long_position_open))
    strategy.entry("SO", strategy.short, when=(window() and enter_short), qty=4)
    strategy.entry("SO", strategy.short, when=(window() and bear_reenter and not(short_position_open)), qty=1)
    strategy.close("SO", when=(window() and bear_exit and short_position_open))


もっと