この戦略は,2つの異なるパラメータの設定の移動平均を交差操作に用い,交差信号によってトレンドの方向を判断し,開口と閉口を行う.この戦略は,9つの異なるタイプの移動平均を選択することを許可する.これには,単純移動平均 (SMA),指数移動平均 (EMA),加重移動平均 (WMA),アルモ移動平均 (ALMA),数値移動平均 (VWMA) などが含まれます.この戦略は,同時に,ストップ・ロズとストップ・ロズを設定します.
この戦略の核心的な論理は,2つの移動平均の値を比較して,2つの移動平均の交差によって市場のトレンド方向を判断することです.具体的には,私たちは2つの移動平均を設定します. 快線と遅線を横切ると,市場が上昇傾向に入ると考え,多めにします. 快線を下に横切ると,市場が下降傾向に入ると考え,空白します.
ポジションに入った後,価格が止損線に触れたら損失がでて,ポジションを退出する.価格が止損線に触れたら利益が期待値に達したときにポジションを退出する.このようにして利益をロックして,損失の拡大を防ぐことができる.
この戦略は,コードロジックからすると,主に4つの部分に分けられます.
移動平均を計算する. ユーザが選択した移動平均のタイプに応じて,快線と慢線の移動平均を計算する.
取引信号を生成する.快線と慢線の交差に応じて多行と空行信号を生成する.
ストップ・ストップ・ポジションの設定. 入場価格と設定されたストップ・ストップ・パーセンテージに基づいて,ストップ・ストップ・ラインとストップ・ストップ・ラインの価格をリアルタイムで計算する.
入場と出場。多多空信号で入場し,止損停止信号で出場する。
この戦略の最大の利点は,複数の種類の移動平均を自由に選択できるという点にある.異なるタイプの移動平均は価格に対する感受性が異なるため,ユーザーは自分のニーズに応じて適切な移動平均を選択することができる.さらに,移動平均の長さをカスタマイズして,時間次元に対する最適化を実現することができる.
もう一つの優点は,ストップ・ストップ・メカニズムが設定されていることです.これは,損失がさらに拡大するのを効果的に防止し,同時に利益をロックすることができます.全体的に,この戦略は,柔軟で,カスタマイズ可能な程度が高く,異なるニーズを持つユーザーに適しています.
この戦略の主なリスクは,移動平均が遅滞性を持つことにある.価格が突然大幅な波動を起こしたとき,移動平均は時間内に反応できず,最適な入場または出場のタイミングを逃す可能性がある.このとき,大きな損失が生じます.
もう一つのリスクは,ストップ・ストップ・ポジションの設定である.設定幅が小さすぎると,ブレートされる可能性があり,大きすぎると,利益のロックが十分には及ばない可能性もある.だから,実盤では,市場の状況に応じてストップ・ストップのパラメータを最適化しなければならない.
全体として,この戦略は,移動平均によってトレンドの方向を決定するので,突然の出来事が価格の大幅な変動を引き起こす場合,効果は割引されます.さらに,パラメータの設定は,戦略の収益にも大きな影響を与えるでしょう.
この戦略は以下の点で最適化できます.
移動平均の種類を最適化します. 異なる市場環境と取引の種類に応じて,より適切な移動平均を選択します.
移動平均の最適化パラメータ.移動平均の期間長さを調整して,市場特性に適したものにする.
他の指標のフィルターを追加します. MACD,RSIなどの他の指標を添加して,トレンドのない市場で頻繁に取引を避けることができます.
最適化ストップ・ストップ比率. 履歴データに基づいて最適化ストップ・ストップパラメータを計算する.
機械学習モデルの追加. LSTM,ランダムフォレストなどのアルゴリズムを使用して,価格動きを予測し,取引シグナルを生成する.
ストップトラッキングアルゴリズムを使用する. ストップラインを価格の動きに合わせて徐々に移動させ,ストップが誘発される確率を減らす.
この戦略は,全体として比較的単純で直接で,トレンドの方向を交叉判断することによって,典型的なトレンドフォロー戦略に属している.利点は,単純で分かりやすいこと,柔軟性が高いこと,移動平均のタイプとパラメータを自分で選択できること.欠点は,突発的な出来事に対する反応が遅いこと,ある程度の遅れがあることである.全体として,この戦略は,長期にわたる安定した収益を追求する投資家に適している.最適化により,戦略の安定性と収益水準をさらに向上させることができる.
/*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)