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

作者: リン・ハーンチャオチャン開催日:2023年10月10日 10:44:25
タグ:

概要

移動平均クロスオーバー戦略は,移動平均に基づいた一般的に使用される取引戦略である.これは,より速い移動平均と,より遅い移動平均のクロスオーバーを取引信号として使用する.より速い移動平均が,より遅い移動平均を下から越えると,それは購入信号である.より速い移動平均が,より遅い移動平均を下から越えると,それは販売信号である.この戦略は,より速いMAとして50日間MAと,より遅いMAとして200日間MAを使用する.

戦略の論理

この戦略の基本論理は,移動平均の理論に基づいている.移動平均は価格変動を効果的に平滑させ,価格傾向を示すことができる.より速いMAは価格変化により敏感であり,傾向逆転点を捕捉することができる.より遅いMAは価格変化に敏感ではなく,短期変動をフィルタリングすることができます.より速いMAがより遅いMAを超越したとき,それは価格の上昇傾向を示します.より速いMAがより遅いMAを下回ると,それは価格の下落傾向を示します.

この戦略は,まず50日M&Aと200日M&Aを定義する. 速いM&Aが遅いM&Aを上回るときにロングエントリー条件が設定される. 速いM&Aが遅いM&Aを下回るときにショートエントリー条件が設定される. 重複する取引を避けるために,この戦略は isEntryと isExitフラグを制御するために使用する. エントリー条件が満たされたとき, isEntryは trueに設定される. 終了条件が満たされたとき, isExitは trueに設定される. ロングポジションは isEntryが falseで買い信号が表示されたときにのみ開かれる. ショートポジションは isExitが falseで売り信号が表示されたときにのみ開かれる.

さらに,戦略は,利益とストップロスのレベルも設定します.ユーザーは入力を通じてTP/SLパーセント距離を定義できます.TPとSL価格はエントリー価格パーセントに基づいて計算されます.ポジションサイズが0を超えるとTPとSLはロングTP/SLパーセントに基づいて実行されます.ポジションサイズが0未満の場合TPとSLはショートTP/SLパーセントに基づいて実行されます.

利点分析

この戦略の利点は以下の通りです.

  1. 実行が簡単です. 取引経験のない初心者向けに適しています.

  2. リスク管理による制御可能な引き下げ 移動平均は短期変動をフィルタリングし 停止を避けることができます

  3. 適応性のためのカスタマイズ可能なパラメータ.ユーザーはMA期間やTP/SLレベルなどのパラメータを最適化することができます.

  4. 明確な可視化.戦略は,チャート上の主要なMA,エントリ,TP/SLレベルをプロットします.

  5. 拡張可能な枠組み 戦略構造が完成した.それを強化するために新しい信号と指標を追加することができます.

リスク分析

この戦略のリスクは以下のとおりです.

  1. 極端な市場イベントで損失を止めることができず,大きな引き下げにつながります.より速いMAは価格変動に敏感で,極端な条件では失敗する可能性があります.

  2. 市場が急落し 連続した損失を招く

  3. 取引コストは考慮されません.実際の取引における手数料と滑り込みは,収益性に大きな影響を与えます.

  4. バックテストオーバーフィッティング.実際の市場条件は複雑で,バックテスト結果はライブパフォーマンスを代表しない可能性があります.

解決策としては,

  1. より広いストップ損失を使用するか,追加のブレイクストップ損失を追加します.

  2. MA距離を拡大し,取引頻度を減らしたり,他のフィルターを追加したりします.

  3. 実際の取引コストを考慮し より広い利益目標範囲を設定します

  4. パラメータを徐々に最適化し,市場の状況の変化を考慮して過剰なフィッティングを減らす.

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

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

  1. 最適なパラメータを見つけるために異なるパラメータの組み合わせをテストします 例えば MA 期間です

  2. MACD,KD などなど,他の指標をフィルターとして追加します.

  3. ストップ・ロスの戦略を最適化して リスク管理を改善します 例えばストップ・ロスの後退などです

  4. リスクをコントロールしながら 利潤を拡大するためにレバレッジを使って ポジションの大きさを増やす

  5. 取引コストを考慮し リアルタイムの取引のパラメータを最適化します

  6. 過剰配合を減らすために,統計的方法を使用してパラメータの安定性を評価する.

結論

結論として,このMAクロスオーバー戦略は明確な論理を持ち,実装が簡単で,アルゴ取引の導入戦略として適しています. しかし,リスクと制限もあります. 安定した利益を達成するために,慎重なパラメータとフィルター最適化,リスク制御が必要です. この戦略は,ユーザーが独自の取引スタイルに合わせて革新と最適化するために大きな拡張性を持っています.


/*backtest
start: 2023-10-02 00:00:00
end: 2023-10-09 00:00:00
period: 3m
basePeriod: 1m
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/
// © gjfsdrtytru

//@version=4
strategy("Backtest Engine", "Backtest", overlay=true, commission_type=strategy.commission.percent, commission_value=0.07, initial_capital = 1000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, currency = currency.USD)


// Start code here...
fastMA = sma(close,50)
slowMA = sma(close,200)

plot(fastMA, "Fast MA",  color.blue)
plot(slowMA, "Slow MA",  color.red)

// Long Enrty/Exit
longCondition = crossover(fastMA,slowMA)
closeLong = crossover(slowMA,fastMA)

// Short Enrty/Exit
shortCondition = crossover(slowMA,fastMA)
closeShort = crossover(fastMA,slowMA)


// Bot web-link alert - {{strategy.order.comment}}
botLONG = "ENTRY LONG ALERT"
botCLOSELONG = "CLOSE LONG ALERT"
botSHORT = "ENTRY SHORT ALERT"
botCLOSESHORT = "CLOSE SHORT ALERT"

//////////////////////////////////////////////////////////////////
//////////////////////// BACKTEST ENGINE \\\\\\\\\\\\\\\\\\\\\\\\\
/////////////////// [NO USER INPUT REQUIRED] /////////////////////
//////////////////////////////////////////////////////////////////

// Time period
testStartYear = input(2020, "Backtest Start Year")
testStartMonth = input(5, "Backtest Start Month")
testStartDay = input(11, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0)

periodLength = input(3650, "Backtest Period (days)", minval=0,tooltip="Days until strategy ends") * 86400000 // convert days into UNIX time
testPeriodStop = testPeriodStart + periodLength

testPeriod() =>
    time >= testPeriodStart and time <= testPeriodStop ? true : false

// Convert Take profit and Stop loss to percentage
longTP = input(title="Long Take Profit (%)", type=input.float, minval=0.0, step=0.1, defval=0) * 0.01 // Set levels with input options
longSL = input(title="Long Stop Loss (%)", type=input.float, minval=0.0, step=0.1, defval=0) * 0.01 // Set levels with input options
shortTP = input(title="Short Take Profit (%)", type=input.float, minval=0.0, step=0.1, defval=0) * 0.01 // Set levels with input options
shortSL = input(title="Short Stop Loss (%)", type=input.float, minval=0.0, step=0.1, defval=0) * 0.01 // Set levels with input options

// 0% TP/SL = OFF (a value of 0 turns off TP/SL feature)
longProfitPerc = longTP == 0 ? 1000 : longTP
longStopPerc = longSL == 0 ? 1 : longSL
shortProfitPerc = shortTP == 0 ? 1 : shortTP
shortStopPerc = shortSL == 0 ? 1000 : shortSL

// Determine TP/SL price based on percentage given
longProfitPrice  = strategy.position_avg_price * (1 + longProfitPerc)
longStopPrice  = strategy.position_avg_price * (1 - longStopPerc)
shortProfitPrice  = strategy.position_avg_price * (1 - shortProfitPerc)
shortStopPrice  = strategy.position_avg_price * (1 + shortStopPerc)

// Anti-overlap
isEntry_Long = false
isEntry_Long := nz(isEntry_Long[1], false)
isExit_Long = false
isExit_Long := nz(isExit_Long[1], false)
isEntry_Short = false
isEntry_Short := nz(isEntry_Short[1], false)
isExit_Short = false
isExit_Short := nz(isExit_Short[1], false)

entryLong = not isEntry_Long and longCondition
exitLong = not isExit_Long and closeLong
entryShort = not isEntry_Short and  shortCondition
exitShort = not isExit_Short and closeShort

if (entryLong)
    isEntry_Long := true
    isExit_Long := false
if (exitLong)
    isEntry_Long := false
    isExit_Long := true
if (entryShort)
    isEntry_Short := true
    isExit_Short := false
if (exitShort)
    isEntry_Short := false
    isExit_Short := true

// Order Execution
if testPeriod() 
    if entryLong
        strategy.entry(id="Long", long=true, when = entryLong, comment=botLONG) // {{strategy.order.comment}}
    if entryShort
        strategy.entry(id="Short", long=false, when = entryShort, comment=botSHORT) // {{strategy.order.comment}}


// TP/SL Execution
if (strategy.position_size > 0)
    strategy.exit(id="Long SL/TP", from_entry="Long", limit=longProfitPrice, stop=longStopPrice)
    strategy.close(id="Long", when=exitLong, comment=botCLOSELONG) // {{strategy.order.comment}}

if (strategy.position_size < 0)
    strategy.exit(id="Short TP/SL", from_entry="Short", limit=shortProfitPrice, stop=shortStopPrice)
    strategy.close(id="Short", when=exitShort, comment=botCLOSESHORT) // {{strategy.order.comment}}
    
// Draw Entry, TP and SL Levels for Long Positions
plot(strategy.position_size > 0 ? longTP == 0 ? na : longProfitPrice : na, style=plot.style_linebr, color=color.green, title="Long TP")
plot(strategy.position_size > 0 ? strategy.position_avg_price : na, style=plot.style_linebr, color=color.blue, title="Long Entry")
plot(strategy.position_size > 0 ? longSL == 0 ? na : longStopPrice : na, style=plot.style_linebr, color=color.red, title="Long SL")
// Draw Entry, TP and SL Levels for Short Positions
plot(strategy.position_size < 0 ? shortTP == 0 ? na : shortProfitPrice : na, style=plot.style_linebr, color=color.green, title="Short TP")
plot(strategy.position_size < 0 ? strategy.position_avg_price : na, style=plot.style_linebr, color=color.blue, title="Short Entry")
plot(strategy.position_size < 0 ? shortSL == 0 ? na : shortStopPrice : na, style=plot.style_linebr, color=color.red, title="Short SL")

もっと