移動平均のクロスオーバー戦略の9種類

作者: リン・ハーンチャオチャン,日付: 2024-01-02 10:37:21
タグ:

img

概要

この戦略は,クロスオーバー取引の異なるパラメータ設定を持つ移動平均を2つ使用し,トレンド方向とオープン/クローズポジションを決定する. 戦略は,単純な移動平均 (SMA),指数関数移動平均 (EMA),重量移動平均 (WMA),アルヌ・レグウ移動平均 (ALMA),ボリューム重量移動平均 (VWMA),などを含む9種類の異なる移動平均から選択することができます. 戦略はまた,ストップ損失と利益のレベルを設定します.

戦略の論理

この戦略の主な論理は,2つの移動平均線の値を比較し,その交差点に基づいて市場のトレンド方向を決定することです.具体的には,2つの移動平均線を使用して,高速線とスローラインを設定します.高速線がスローラインの上を横切ると,市場は上昇傾向にあり,長くなると考えます.高速線がスローラインの下を横切ると,市場は下落傾向にあり,短くなると考えます.

ポジションに入れた後,価格がストップ・ロスのラインに触れた場合,損失を削減するためにポジションを退場します.価格が利益のラインに触れた場合,期待どおり利益をロックするためにポジションを退場します. これにより,利益をロックし,損失がさらに拡大するのを防ぐことができます.

コード論理から考えれば 戦略は4つの部分に分けられる:

  1. 移動平均を計算します.移動平均のタイプをユーザが選択した上で,速い線と遅い線の移動平均を計算します.

  2. 取引シグナルを生成します. 速いラインとスローラインの交差状況に基づいて,長い信号と短い信号を生成します.

  3. ストップ・ロスト・テイク・プロフィートのレベルを設定します. 入場価格とセット・ストップ・ロスト/テイク・プロフィートの割合に基づいて,ストップ・ロスト・テイク・プロフィートのレベルをリアルタイムで計算します.

  4. ストップ・ロスト/テイク・プロフィート・シグナルで出口

利点分析

この戦略の最大の利点は,多くの種類の移動平均値から自由に選択できるようにすることです.異なるタイプの移動平均値は価格に対する異なる感度を持っています.ユーザーは自身のニーズに基づいて適切な移動平均値を選択できます.また,移動平均値の長さは時間次元を最適化するためにカスタマイズできます.

また,ストップ・ロストとテイク・プロフィートのメカニズムが設定されているという利点もあります. これにより,さらなる損失を効果的に防止し,利益をロックすることができます. 全体的に,この戦略は高度なカスタマイズ可能性があり,異なるニーズを持つユーザーに適しています.

リスク分析

この戦略の主なリスクは,移動平均値が遅れることである.価格が突然激動すると,移動平均値が間に合わないため,最適なエントリーまたは出口時間を逃す可能性があります.これは大きな損失につながる可能性があります.

また,ストップ・ロストとテイク・プロフィートのレベルを設定することがリスクである.範囲が小さすぎると,スカルパーに脆弱である可能性がある.大きすぎると,利益を間に合わないことが容易である.したがって,ストップ・ロスト/テイク・プロフィートのパラメータは,ライブ・トレード中に市場状況に応じて最適化する必要があります.

一般的には,この戦略は主にトレンド方向を決定するために移動平均値に依存している.したがって,突然のイベントが大きな価格変動を引き起こす場合,その有効性は損なわれる可能性があります. さらに,パラメータ設定は戦略の収益にも大きな影響を与えます.

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

この戦略は,次の側面で最適化できます.

  1. 移動平均のタイプを最適化します.異なる市場環境と取引製品に基づいて,より適切な移動平均を選択します.

  2. 移動平均のパラメータを最適化し 移動平均の長さを調整し 市場の特徴に合わせて調整する

  3. フィルタリングのために他の指標を追加します. MACD,RSI,その他の指標は,明確な傾向がない場合の頻繁な取引を避けるために追加できます.

  4. ストップ・ロスト/テイク・プロフィートの比率を最適化します. 過去データに基づいて最適なストップ・ロスト/テイク・プロフィートのパラメータを計算します.

  5. 機械学習モデルを追加します.LSTM,ランダムフォレストアルゴリズムを使用して価格動きを予測し,取引信号を生成します.

  6. ストップ・ロスのアルゴリズムを採用します.ストップ・ロスの線が価格動きと共に徐々に動いて,ヒットする確率を減らすようにします.

結論

この戦略は比較的単純で直接的である.クロスオーバーを通じてトレンド方向を決定し,典型的なトレンドフォロー戦略に属している.利点は,容易に理解し,カスタマイズ可能な移動平均種類とパラメータで非常に柔軟である.欠点は突然の出来事に対する反応が遅い,一定の遅れである.一般的に,この戦略は長期の安定したリターンを求める投資家に適している.安定性とリターンのさらなる改善は最適化によって達成できる.


/*backtest
start: 2022-12-26 00:00:00
end: 2024-01-01 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=3
strategy("Kozlod - Yet Another Moving Average Cross Strategy", shorttitle="kozlod_yamacs", overlay = true)

// 
// author: Kozlod
// date: 2018-03-06
// 

////////////
// INPUTS //
////////////

ma_type      = input(title = "MA Type",          defval = "SMA", options = ['SMA', 'EMA', 'WMA', 'ALMA', 'VWMA', 'HMA', 'LSMA', 'SMMA', 'DEMA'])
short_ma_len = input(title = "Short MA Length",  defval = 5,     minval = 1)
short_ma_src = input(title = "Short MA Source",   defval = close)
long_ma_len  = input(title = "Long MA Length",   defval = 15,    minval = 2)
long_ma_src  = input(title = "Long MA Source",    defval = close)
alma_offset  = input(title = "ALMA Offset",     type = float,   defval = 0.85,  step = 0.01, minval = 0, maxval = 1)
alma_sigma   = input(title = "ALMA Sigma",      type = float,   defval = 6,     step = 0.01)
lsma_offset  = input(title = "LSMA Offset",      defval = 0,     step = 1)

sl_lev_perc  = input(title = "SL Level % (0 - Off)", type = float,   defval = 0,  minval = 0, step = 0.01)
pt_lev_perc  = input(title = "PT Level % (0 - Off)", type = float,   defval = 0,  minval = 0, step = 0.01)

// Set initial values to 0
short_ma = 0.0
long_ma  = 0.0

// Simple Moving Average (SMA)
if ma_type == 'SMA' 
    short_ma := sma(short_ma_src, short_ma_len)
    long_ma  := sma(long_ma_src,  long_ma_len)

// Exponential Moving Average (EMA)
if ma_type == 'EMA'
    short_ma := ema(short_ma_src, short_ma_len)
    long_ma  := ema(long_ma_src,  long_ma_len)

// Weighted Moving Average (WMA)
if ma_type == 'WMA'
    short_ma := wma(short_ma_src, short_ma_len)
    long_ma  := wma(long_ma_src,  long_ma_len)

// Arnaud Legoux Moving Average (ALMA)
if ma_type == 'ALMA'
    short_ma := alma(short_ma_src, short_ma_len,  alma_offset, alma_sigma)
    long_ma  := alma(long_ma_src,  long_ma_len,   alma_offset, alma_sigma)

// Hull Moving Average (HMA)
if ma_type == 'HMA'
    short_ma := wma(2*wma(short_ma_src, short_ma_len/2)-wma(short_ma_src, short_ma_len), round(sqrt(short_ma_len)))
    long_ma  := wma(2*wma(long_ma_src,  long_ma_len /2)-wma(long_ma_src,  long_ma_len),  round(sqrt(long_ma_len)))

// Volume-weighted Moving Average (VWMA)
if ma_type == 'VWMA'
    short_ma := vwma(short_ma_src, short_ma_len)
    long_ma  := vwma(long_ma_src,  long_ma_len)

// Least Square Moving Average (LSMA)
if ma_type == 'LSMA'
    short_ma := linreg(short_ma_src, short_ma_len, lsma_offset)
    long_ma  := linreg(long_ma_src,  long_ma_len,  lsma_offset)

// Smoothed Moving Average (SMMA)    
if ma_type == 'SMMA'
    short_ma := na(short_ma[1]) ? sma(short_ma_src, short_ma_len) : (short_ma[1] * (short_ma_len - 1) + short_ma_src) / short_ma_len
    long_ma  := na(long_ma[1])  ? sma(long_ma_src,  long_ma_len)  : (long_ma[1]  * (long_ma_len  - 1) + long_ma_src)  / long_ma_len

// Double Exponential Moving Average (DEMA)
if ma_type == 'DEMA'
    e1_short = ema(short_ma_src, short_ma_len)
    e1_long  = ema(long_ma_src,  long_ma_len)
    
    short_ma := 2 * e1_short - ema(e1_short, short_ma_len)
    long_ma  := 2 * e1_long  - ema(e1_long,  long_ma_len)

/////////////
// SIGNALS //
/////////////

long_signal  = crossover( short_ma, long_ma)
short_signal = crossunder(short_ma, long_ma)

// Calculate PT/SL levels 
// Initial values 
last_signal    = 0
prev_tr_price  = 0.0
pt_level       = 0.0
sl_level       = 0.0

// Calculate previous trade price
prev_tr_price := long_signal[1] or short_signal[1] ? open : nz(last_signal[1]) != 0 ? prev_tr_price[1] : na

// Calculate SL/PT levels 
pt_level := nz(last_signal[1]) == 1 ? prev_tr_price * (1 + pt_lev_perc / 100) : nz(last_signal[1]) == -1 ? prev_tr_price * (1 - pt_lev_perc / 100)  : na
sl_level := nz(last_signal[1]) == 1 ? prev_tr_price * (1 - sl_lev_perc / 100) : nz(last_signal[1]) == -1 ? prev_tr_price * (1 + sl_lev_perc / 100)  : na

// Calculate if price hit sl/pt 
long_hit_pt = pt_lev_perc > 0 and nz(last_signal[1]) ==  1 and close >= pt_level
long_hit_sl = sl_lev_perc > 0 and nz(last_signal[1]) ==  1 and close <= sl_level

short_hit_pt = pt_lev_perc > 0 and nz(last_signal[1]) ==  -1 and close <= pt_level
short_hit_sl = sl_lev_perc > 0 and nz(last_signal[1]) ==  -1 and close >= sl_level

// What is last active trade? 
last_signal := long_signal ? 1 : short_signal ? -1 : long_hit_pt or long_hit_sl or short_hit_pt or short_hit_sl ? 0 : nz(last_signal[1])

//////////////
// PLOTTING //
//////////////

// Plot MAs
plot(short_ma, color = red,   linewidth = 2)
plot(long_ma,  color = green, linewidth = 2)


// Plot Levels 
plotshape(prev_tr_price, style = shape.cross, color = gray, location  = location.absolute, size = size.small)


plotshape(sl_lev_perc > 0 ? sl_level : na, style = shape.cross, color = red,   location  = location.absolute, size = size.small)
plotshape(pt_lev_perc > 0 ? pt_level : na, style = shape.cross, color = green, location  = location.absolute, size = size.small)

//////////////
// STRATEGY //
//////////////

strategy.entry("long",  true,  when = long_signal)
strategy.entry("short", false, when = short_signal)

strategy.close("long",  when = long_hit_pt  or long_hit_sl)
strategy.close("short", when = short_hit_pt or short_hit_sl)

もっと