2つの移動平均のクロスオーバートレンド戦略

作者: リン・ハーンチャオチャン, 日付: 2023-12-06 11:52:10
タグ:

img

概要

ダブル・ムービング・アベア・クロスオーバー・トレンド戦略は,ムービング・アベアに基づいたトレード戦略である.高速EMAと遅いSMA線のクロスオーバーを買い売り信号として使用し,MACD指標のダイバージェンスをフィルター信号に組み合わせる.この戦略は価格,トレンド,モメントなどの複数の要因を考慮し,比較的完全な取引システムを形成する.

戦略原則

この戦略は,200日間の長さのEMAと100日間の長さのSMAという2つの移動平均を使用する.価格が両線を上向きに突破すると,購入信号が生成される.価格が両線を下向きに突破すると,販売信号が生成される.これは振動傾向と短期的な引き下げを効果的にフィルターすることができます.

信号の信頼性をさらに向上させるために,MACDインジケーターも導入されている.価格がEMAとSMAを突破して信号を形成するとき,MACDの速い線は下からスローラインを突破し,MACDヒストグラムは0軸以上で,実際の購入信号を誘発する必要があります.逆に,MACDの速い線が上からスローラインを突破し,MACDヒストグラムが0軸以下で,それは実際の販売信号を誘発します.

さらに,ストップ・ロストとテイク・プロフィートは戦略に設定されています.戦略がポジションを開いた後,ストップ・ロスト・ポイントとテイク・プロフィートは,ユーザーによって設定されたパーセントに従って計算され設定されます. これにより,単一の取引のリスクを効果的に制御できます.

要約すると,この戦略は複数の指標を包括的に考慮し,購入・販売シグナルに厳格なフィルタリング条件を設定し,リスク管理のためにストップ・ロストとテイク・プロフィートを採用し,比較的厳格で完全な取引システムを形成します.

利点分析

二重移動平均のクロスオーバートレンド戦略には以下の利点があります.

  1. 複数の指標を組み合わせ,価格,傾向,勢いを包括的に考慮し,信号の厳格なフィルタリング条件を設定することで,誤った信号を効果的に回避し,信号の信頼性を向上させることができます.

  2. 異なるパラメータを持つ2つの移動平均値を使用することで,市場のトレンドをよりよく特定し,振動する市場をフィルタリングすることができます. 急速なEMA線は,価格の変化をタイムリーに追跡するために使用されます. 遅いSMA線は,長期的トレンドを決定するために使用されます. 2つのラインの組み合わせはよりよく機能します.

  3. MACD指標は,異なる市場の特徴に応じて調整できるカスタマイズ可能なパラメータを導入し,高度な柔軟性を持っています.MACDの設定は,取引信号が同時に価格,トレンドおよびモメントによってサポートされることを保証し,したがって非常に強力なアプリケーション価値を持っています.

  4. ストップ・ロストとテイク・プロフィートポイントを設定することで,単一の取引損失を最大限に制御し,過度の損失を回避することができます. 利益の獲得のための合理的なパーセント設定は,部分的な利益をロックし,利益を得た後に市場リスクの曝露を減らすことができます.

  5. この戦略のパラメータは柔軟に設定され,戦略は最適化結果に基づいて調整することができます.これは非常に実用的です.さまざまな市場とパラメータをテストし最適化するのに十分なスペースがあります.

リスク分析

二重移動平均のクロスオーバートレンド戦略には,主に次の分野でのリスクもあります.

  1. 株価が激しい変動を示す場合,EMAとSMAは何度も誤って交差し,取引シグナルが頻繁に開閉される.これは取引の頻度と手数料の支出を増加させる.

  2. MACDインジケーターは,特に勢いがまだ不明確である過程で,誤ったブレイクがある可能性があります. この場合,信号も信頼性がなく,不必要な損失を引き起こす可能性があります.

  3. ストップ損失設定の位置と比率は,利益と損失結果に大きな影響を与える.ストップ損失が小さすぎると,捕まるリスクがある.ストップ損失が大きすぎると,単一の損失が重すぎることがあります.これは最適なパラメータを見つけるのに十分なテストを必要とします.

  4. トレンド追跡指標として,価格が急激に逆転すると移動平均の有効性は値下げされます. 戦略は価格逆転に打たれ,より大きな損失を引き起こす前に損失を止める時間がありません.

対応する解は以下のとおりです.

  1. 変動性のある市場では,クロスオーバー頻度を減らすために,低パラメータの EMA と SMA を使用して移動平均のパラメータを適切に調整する.

  2. フィルタリング条件を増加させる.例えば,MACDがゼロ線上下を突破するなど,誤った突破を一定程度減らすことができる.KDJとBOLLなどの他の指標を組み合わせることも検討できる.

  3. ストップ損失位置と比率の設定は,最適なパラメータを見つけるために十分なバックテストと最適化が必要です.この根拠に基づいて,継続的なモニタリングと動的調整も検討する必要があります.

  4. 迅速な価格逆転を特定するためのメカニズムが設定され,異常な逆転が検出された場合,リスクの暴露を制御するためにポジションを削減したり取引戦略を一時停止したりなどの緊急措置が講じられます.

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

2つの移動平均のクロスオーバートレンド戦略のさらなる最適化には,主に以下の側面の余地があります.

  1. より良いパラメータを見つけるために,BOLLチャネルを組み込み,変動の影響を考慮するより多くの指標を組み合わせてテストする.

  2. 移動平均長さのパラメータを最適化して,異なる市場条件下で最適なパラメータ組み合わせを見つけます.ローリングパラメータの最適化もオプションです.

  3. より科学的で合理的なストップ・ロスを設定し,トラッキング・ストップ・ロスを導入したり,歴史的な統計結果に基づくダイナミックなリスク・リターン比率を設定することなど,利益戦略を採用します.これは戦略の安定性をさらに向上させることができます.

  4. 異常な価格逆転の自動識別と緊急対応のためのメカニズムを確立します. 極端な市場状況では,大きな損失を避けるためにポジションを積極的に削減するか戦略を停止します.

  5. 外国為替,暗号通貨などの取引品種を拡大する. 戦略の適用性を拡大するために,異なる品種にわたるパラメータの堅牢性をテストする.

  6. 戦略の資本管理戦略を最適化すること,例えば固定額取引,固定ポジション比等. 単一の取引損失リスクを制御し,全体的な資本曲線を安定させる.

結論

ダブル・ムービング・平均クロスオーバートレンド戦略は,複数の要因を包括的に考慮する.取引信号を生成する際には,信号の信頼性を確保するために価格,トレンド,インパルスなどの複数の指標からのサポートを必要とする.戦略は,個々の取引のリスクを効果的に制御するために移動ストップ損失と利益を取ることも採用する. 戦略の柔軟なパラメータ設定は,自動取引に非常に実用的である.

しかし,どの戦略も完璧にはなれない.この戦略は,頻繁な取引,偽のブレイク,ストップ損失ポジショニングなど,アプリケーションにおいてもいくつかの困難に直面する.戦略の堅牢性と収益性をさらに高めるためには,パラメータポートフォリオの最適化,新しい技術指標の導入,ストップ損失メカニズムの改善など,多くの側面で努力する必要がある.

概要すると,ダブル移動平均クロスオーバートレンド戦略は,比較的完全で厳格な取引システムを形成する.将来の研究と応用における継続的な最適化と改善を通じて,この戦略は,より大きな実用的な価値を達成する可能性がある.


/*backtest
start: 2023-11-01 00:00:00
end: 2023-11-30 23:59:59
period: 2h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
// Hi,
// This is my first strategy made by myself(except for the MACD indicator). I'm publishing this to get myself out there and for some newer people to see how a basic strategy works. All credits go to Zen&TheArtofTrading, for teaching me almost everything I know about Pinescript
// The strategy is basically an MACD crossover trend strategy. If the MACD line crosses the signal line upward, above the zero point of the histogram, while the price is above 200 EMA and 100 SMA it's a buy signal
// If the MACD line crosses the signal line downward, while below zero point of the histogram, as well as the price being below 200 EMA and 100 SMA it's a sell signal
// I used the 200 EMA and 100 SMA because I wanted to filter weak signals as much as possible when the market is ranging, if you have any suggestions to go around this better, please let me know, still learning everyday

// If you have any suggestions, tips or tricks please let me know. I'm still new to Pinescript, but having a lot of fun trying stuff out. If you see something in my code that you don't understand, feel free to ask, I'll try to answer as best as I can

// I opened the strategy with predetermined backtesting pyramiding, currency etc. This made the progress of backtesting multiple TP and SL easier. Also the commission value is from Binance Futures, I just left it in there for anyone who wants to just copy this strategy
strategy("MACD Crossover Trend Strategy Template", overlay = true )

// Determining inputs and values, I just copied the built-in MACD strategy and removed everything I didn't need, just needed the barebone indicator and added EMA + SMA inputs
fast_length = input(title = "Fast Length", type = input.integer, defval = 12, group = "MACD Values")
slow_length = input(title = "Slow Length", type = input.integer, defval = 26, group = "MACD Values")
src = input(title = "Source", type = input.source, defval = close, group = "MACD Values")
signal_length = input(title = "Signal Smoothing", type=input.integer, minval = 1, maxval = 50, defval = 9, group = "MACD Values")
sma_source = input(title = "Simple MA (Oscillator)", type = input.bool, defval = false, group = "MACD Values")
sma_signal = input(title = "Simple MA (Signal Line)", type = input.bool, defval = false, group = "MACD Values")
fast_ma = sma_source ? sma(src, fast_length) : ema(src, fast_length)
slow_ma = sma_source ? sma(src, slow_length) : ema(src, slow_length)
macd = fast_ma - slow_ma
signal = sma_signal ? sma(macd, signal_length) : ema(macd, signal_length)
hist = macd - signal
emaLength = input(title = "EMA", type = input.integer, defval = 200, step = 10, group = "Moving Averages")
smaLength = input(title = "SMA", type = input.integer, defval = 100, step = 10, group = "Moving Averages")

// Input backtest range, you can adjust this here or in the input options
fromMonth = input(defval = 1,    title = "From Month",      type = input.integer, minval = 1, maxval = 12, group = "Backtest Date Range")
fromDay   = input(defval = 1,    title = "From Day",        type = input.integer, minval = 1, maxval = 31, group = "Backtest Date Range")
fromYear  = input(defval = 2000, title = "From Year",       type = input.integer, minval = 1970, group = "Backtest Date Range")
thruMonth = input(defval = 1,    title = "Thru Month",      type = input.integer, minval = 1, maxval = 12, group = "Backtest Date Range")
thruDay   = input(defval = 1,    title = "Thru Day",        type = input.integer, minval = 1, maxval = 31, group = "Backtest Date Range")
thruYear  = input(defval = 2099, title = "Thru Year",       type = input.integer, minval = 1970, group = "Backtest Date Range")

// Inputs for EMA, SMA and to adjust your take profit and stop losses in the input options while backtesting, it's result of your input is calculated back to percentages
ema = ema(close, emaLength)
sma = sma(close, smaLength)
profitlong = input(title = "Profit Long %", type = input.float, defval = 2, minval = 0.1, maxval = 100, step = 0.1, group = "TP / SL %") * 0.01
losslong = input(title = "Loss Long %", type = input.float, defval = 1, minval = 0.1, maxval = 100, step = 0.1, group = "TP / SL %") * 0.01
profitshort = input(title = "Profit Short %", type = input.float, defval = 2, minval = 0.1, maxval = 100, step = 0.1, group = "TP / SL %") * 0.01
lossshort = input(title = "Loss Short %", type = input.float, defval = 1, minval = 0.1, maxval = 100, step = 0.1, group = "TP / SL %") * 0.01

// Check EMA and SMA also check the backtest range. inDataRange is a true or false statement, true if the date right now is between the parameters that's filled at the corresponding inputs
// (for example 1-1-2020 till 12-12-2020, if that specific bar is between these dates, statement is true and trade will be executed)
// If the date is not in between the given parameters, statement turns to false and it won't allow new trades and closes all current trades as seen with the strategy.close_all function
inDataRange = (time >= timestamp(syminfo.timezone, fromYear, fromMonth, fromDay, 0, 0)) and (time < timestamp(syminfo.timezone, thruYear, thruMonth, thruDay, 0, 0))
long = close > ema and close > sma and inDataRange
short = close < ema and close < sma and inDataRange

// Entry and exit signals + checking backtest date range, what the signals are supposed to do is noted at the beginning of the code
// I want a way to filter out weak signals that are ranging around the zero point of the histogram. 
// So far couldn't think of a decent way to do this over multiple symbols since the range of the histogram changes with every symbol, sometimes ranging between 0 and 1 or sometimes ranging between 0 and 1000
// I could probably use a cofficiency or something, but that's beyond my grasp at the moment
// Also I wanted a way to let my strategy determine a stop loss based on the pullback and having a 1.5 risk/reward TP on top of that. Couldn't really figure out a way to determine the pullback
if (crossover(macd, signal) and macd > 0)
    strategy.entry("Long", long = strategy.long,
     comment = "Long Buy",
     when = long)

strategy.exit("Exit Long", "Long", profit = close * profitlong / syminfo.mintick, loss = close * losslong / syminfo.mintick)


if (crossunder(macd, signal) and macd < 0)
    strategy.entry("Short", long = strategy.short,
     comment = "Short Buy",
     when = short)

strategy.exit("Exit Short", "Short", profit = close * profitshort / syminfo.mintick, loss = close * lossshort / syminfo.mintick)

// To make sure the backtesting doesn't leave a position open beyond, or before, our applied dates
if (not inDataRange)
    strategy.close_all()

// plot(strategy.equity, title="equity", color=color.red, linewidth=2, style=plot.style_areabr)

もっと