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

作者: リン・ハーンチャオチャン開催日:2023年10月24日 16時39分40秒
タグ:

img

概要

この戦略は,移動平均のクロスオーバー原理に基づいています.短期移動平均が下から長期移動平均を横切ると長くなって,短期移動平均が上から長期移動平均を下回ると短くなってしまいます.これは戦略に従う典型的な傾向です.

戦略の論理

戦略は主に短期および長期の単純な移動平均を計算し,その交差に基づいてトレンド方向を決定します.

具体的には,まずは短期移動平均 xMA と長期移動平均を計算し,短期期間が Len で,長期期間が 2*Len である.

その後,短期MAが長期MAを超越しているかどうかを確認し,クロスオーバーが発生した場合に長い信号を生成します.また,短期MAが長期MAを下回っているかどうかを確認し,クロスオーバーが発生した場合に短い信号を生成します.

ロング・シグナルを受け取ると,ポジションがない場合,市場価格でロング・ポジションを開く.ショート・シグナルを受け取ると,ポジションがない場合,市場価格でショート・ポジションを開く.

さらに,ストップ・ロストとテイク・プロフィート・ポイントが設定されています.ロング・トレードでは,ストップ・ロストはエントリー価格 - ストップ・ロストパーセント *エントリー価格,およびエントリー価格 + テイク・プロフィートパーセント *エントリー価格で利益を設定します.ショート・トレードでは,ストップ・ロストはエントリー価格 + ストップ・ロストパーセント *エントリー価格,およびエントリー価格 - テイク・プロフィートパーセント *エントリー価格で利益を設定します.

最後に,動向平均は,傾向決定を助けるために視覚化のためにプロットされています.

利点

  • シンプルで分かりやすい,初心者にも適しています.

  • 移動平均のクロスオーバーに基づいて市場動向を効果的に追跡できる.

  • ストップ・ロストとテイク・プロフィートを設定することで リスクは制御されます

  • 移動平均値の可視化によって 傾向の変化が直感的に反映されます

リスク

  • 移動平均値は遅延効果があり,最良のエントリーポイントを逃す可能性があります.

  • 不適切なストップ損失設定により,ストップが幅が幅が大きくすぎたり,狭すぎたりすることがあります.

  • 価格の振動は 誤った信号を生む可能性があります

  • 移動平均期のみをベースに最適化することで 過適性が生じる可能性があります.

これらのリスクは,緩やかなストップを使用し,移動平均期間の組み合わせを最適化し,フィルター指標を追加することによって軽減できます.

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

  • MACD,KDJなどの他の指標を追加して フィルタリングをします 偽信号を避けるためです

  • 最適なパラメータを見つけるため,短期間と長い移動平均期間の組み合わせを最適化します.

  • ストップ・ロストやトレリング・ストップなどの ストップ・ロスト/トレイン・プロフィート戦略をテストします

  • 資本利用を最適化するために ポジションサイズを追加します

概要

この戦略は明確で単純な論理を持ち,移動平均のクロスオーバーに基づいてトレンドを効果的に追跡することができ,制御可能なリスクを持っています. 初心者が学ぶのに適しています. しかし,移動平均だけに頼ることは誤った信号を生む可能性があります. より堅固になるために,さまざまな側面で最適化するにはまだ多くの余地があります.


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

//@version=5
//@strategy_alert_message {{strategy.order.alert_message}} 
////////////////////////////////////////////////////////////
//  Copyright by HPotter v2.0 19/09/2023
// MA Crossover Bot for OKX Exchange
////////////////////////////////////////////////////////////
var ALERTGRP_CRED = "entry"
signalToken = input("", "Signal Token", inline = "11", group = ALERTGRP_CRED)
OrderType = input.string("market", "Order Type", options = ["market", "limit"], inline = "21", group = ALERTGRP_CRED)
OrderPriceOffset = input.float(0, "Order Price Offset", minval = 0, maxval = 100, step = 0.01, inline = "21", group = ALERTGRP_CRED)
InvestmentType = input.string("percentage_balance", "Investment Type", options = ["margin", "contract", "percentage_balance", "percentage_investment"], inline = "31", group = ALERTGRP_CRED)
Amount = input.float(100, "Amount", minval = 0.01, inline = "31", group = ALERTGRP_CRED)

getAlertMsg(action, instrument, signalToken, orderType, orderPriceOffset, investmentType, amount) =>
    str = '{'
    str := str + '"action": "' + action + '", '
    str := str + '"instrument": "' + instrument + '", '
    str := str + '"signalToken": "' + signalToken + '", '
    //str := str + '"timestamp": "' + str.format_time(timenow, "yyyy-MM-dd'T'HH:mm:ssZ", "UTC+0") + '", '
    str := str + '"timestamp": "' + '{{timenow}}' + '", '
    str := str + '"orderType": "' + orderType + '", '
    str := str + '"orderPriceOffset": "' + str.tostring(orderPriceOffset) + '", '
    str := str + '"investmentType": "' + investmentType + '", '
    str := str + '"amount": "' + str.tostring(amount) + '"'
    str := str + '}'
    str

getOrderAlertMsgExit(action, instrument, signalToken) =>
    str = '{'
    str := str + '"action": "' + action + '", '
    str := str + '"instrument": "' + instrument + '", '
    str := str + '"signalToken": "' + signalToken + '", '
    str := str + '"timestamp": "' + '{{timenow}}' + '", '
    str := str + '}'
    str

strategy(title='OKX: MA Crossover', overlay=true)
Len = input(13)
Profit = input.float(7, title='Take Profit %', minval=0.01) / 100
Stop =  input.float(7, title='Stop Loss %', minval=0.01) / 100
xMA = ta.sma(close, Len)
//Robot State
isLong = strategy.position_size > 0 
isShort = strategy.position_size < 0 
isFlat = strategy.position_size == 0 
//Current Signal
doLong = low < xMA[1] ? true : false
doShort =   high > xMA[1] ? true:  false
//Backtest Start Date
tm =  timestamp(2022, 01, 01, 09, 30)
//Entry and exit orders
if  doLong[2] == false and isLong == false and doLong and time > tm
    strategy.cancel_all()
    buyAlertMsgExit = getOrderAlertMsgExit(action = 'EXIT_LONG', instrument = syminfo.ticker, signalToken = signalToken)
    buyAlertMsg = getAlertMsg(action = 'ENTER_LONG', instrument = syminfo.ticker, signalToken = signalToken, orderType =  OrderType, orderPriceOffset =  OrderPriceOffset, investmentType =  InvestmentType, amount = Amount)
    strategy.entry('Long', strategy.long, limit = close, comment='Long', alert_message =buyAlertMsg)
    strategy.exit("ExitLong", 'Long', stop=close - close * Stop  , limit = close + close * Profit , qty_percent = 100, alert_message = buyAlertMsgExit)  
if doShort[2] == false and isShort == false and doShort and time > tm
    strategy.cancel_all()
    sellAlertMsgExit = getOrderAlertMsgExit(action = 'EXIT_SHORT', instrument = syminfo.ticker, signalToken = signalToken)
    sellAlertMsg = getAlertMsg(action = 'ENTER_SHORT', instrument = syminfo.ticker, signalToken = signalToken, orderType =  OrderType, orderPriceOffset =  OrderPriceOffset, investmentType =  InvestmentType, amount = Amount)
    strategy.entry('Short', strategy.short, limit=close, comment='Short', alert_message = sellAlertMsg)
    strategy.exit("ExitShort", 'Short', stop=close + close * Stop  , limit = close - close * Profit  , qty_percent = 100, alert_message = sellAlertMsgExit)  
//Visual
barcolor(isShort  ? color.red : isLong ? color.green : color.blue)
plot(xMA, color=color.new(color.red, 0), title='MA')

もっと