双重EMAクロスオーバー戦略

作者: リン・ハーンチャオチャン,日付: 2024-02-22 16:18:39 詳細はこちら
タグ:

img

概要

ダブルEMAクロスオーバー戦略 (Dual EMA Crossover Strategy) は,異なる期間の2つのEMAラインのクロスオーバーに基づいてポジションを開閉する定量的な取引戦略である.この戦略は単純で,効果的で,理解しやすいもので,定量的な取引で一般的に使用される.

戦略の論理

この戦略は2つのEMAラインを使用します.一つは25期EMAラインが速いラインであり,もう一つは50期EMAラインがスローラインです.速いラインがスローラインを越えると,ロングに行く.速いラインがスローラインを下回ると,ショートに行く.

ロングした後に,入場価格の 2% に取利益と,入場価格の 2% にストップ・ロスを設定します.価格が取利益またはストップ・ロスを到達すると,ポジションを閉じる.ショートすることは同じです.

この戦略の核心は,EMAの高速線と遅い線のクロスオーバーを使用して市場動向と逆転を判断することです.高速線が上を横切ると,牛市場として判断され,ロングになります.高速線が下を横切ると,熊市場として判断され,ショートになります.利潤とストップロスは利益とリスクを制御するために設定されています.

利点分析

双重EMAクロスオーバー戦略には以下の利点があります.

  1. アイデアは明確で 論理は単純で 分かりやすく 実行できます
  2. 中期と短期間のトレンドを捉えるために 速い線と遅い線が一緒に働きます
  3. 市場が転換期を迎える時を把握できるのです
  4. リスク管理は,合理的な利益とストップ損失の設定によって行われます.

一般的にこの戦略は市場を明確に判断し,EMAの利点を利用し,リスクをコントロールしながら中期および短期的に良い利益を得ています.

リスク分析

双 EMA クロスオーバー 戦略には,いくつかのリスクもあります.

  1. 激しい市場変動の場合,EMAのクロスオーバー信号は不正確であり,判断が誤る可能性があります.
  2. 不合理な利益とストップ・ロスのポイントは より大きな動きを見逃すか,より大きな損失を伴う可能性があります
  3. 取引手数料やスリップの影響も無視できない.

これらのリスクは,次の方法で最適化され,解決できます.

  1. 他の指標を組み合わせて市場を判断し,EMAのクロスオーバー信号を誤って判断しないようにする.
  2. 利回りとリスクのバランスをとるために 利回りとストップロスのポイントをテストし最適化します
  3. 低手料の取引プラットフォームを選択し,適切なポジションサイズを増やす.

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

この戦略の主要な最適化方向は以下の通りである.

  1. 最適なパラメータの組み合わせを見つけるために EMA 期間パラメータを最適化します.
  2. 取引組合せを形成し,正確性を向上させるために判断のための他の指標を増やす.
  3. ダイナミックに取利益とストップ・ロスのポイントを調整します.例えば,損失が一定のレベルに達すると,ストップ・ロスのポイントを拡大し,利益が一定のレベルに達すると,取利益ポイントを移動します.
  4. 方向性取引における牛と熊の市場を区別する.

これらの最適化は 戦略をシンプルで明確にして 収益率と勝率を向上させることができます

概要

概要すると,ダブルEMAクロスオーバー戦略は,非常に実践的な定量的な取引戦略である.理解し,実装しやすく,市場動向を効果的に把握している.同時に,最適化のための余地がある.パラメータ調節と組み合わせによって収益率のさらなる改善を達成することができる.この戦略のシンプルさと直接性は,投資家にとって学び,適用する価値があります.


/*backtest
start: 2024-01-22 00:00:00
end: 2024-02-21 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// SEMA-X(SEMA CROSS) [AB] : Simple EMA cross strategy Alert & Backtest
// 1. 2 EMA cross
// 2. Next candle entry
// 3. TP & SL

//@version=5
strategy("SEMA-X", "SEMA-X", overlay=false, margin_long=1,
 initial_capital=1000000, default_qty_type=strategy.percent_of_equity, default_qty_value=100,
 commission_type=strategy.commission.percent, commission_value=0.075, slippage=3)

//****************************************************************************//
// Input
//****************************************************************************//
// EMA length
emaLen25 = input.int(25, "Short", minval=1, confirm=true, group="[EMA]----------", inline="1")
emaLen50 = input.int(50, "Long",  minval=1, confirm=true, group="[EMA]----------", inline="1")

// TP & SL
isLong   = input.bool(true, "Long - ",    confirm=true, group="[TP & SL(%)]----------", inline="1")
tpLong   = input.float(2, "TP", minval=0, confirm=true, group="[TP & SL(%)]----------", inline="1")*0.01
slLong   = input.float(2, "SL", minval=0, confirm=true, group="[TP & SL(%)]----------", inline="1")*0.01
isShort  = input.bool(false, "Short - ",  confirm=true, group="[TP & SL(%)]----------", inline="2")
tpShort  = input.float(2, "TP", minval=0, confirm=true, group="[TP & SL(%)]----------", inline="2")*0.01
slShort  = input.float(2, "SL", minval=0, confirm=true, group="[TP & SL(%)]----------", inline="2")*0.01

// Backtest period
sTime = input(timestamp("0001-01-01"), "Start", group="[Backtest]----------")
eTime = input(timestamp("9999-01-01"), "End",   group="[Backtest]----------")
inDateRange   = true
periodBg      = input.bool(false, "Backtest BGcolor", confirm=true, group="[Backtest]----------", inline="1")
bgLong        = input.bool(false, "Position BGcolor", confirm=true, group="[Backtest]----------", inline="1")
periodBgColor = periodBg and inDateRange ? color.new(color.green, 95) : na
bgcolor(periodBgColor, title="Backtest BGcolor")
bgColorLong   = bgLong and strategy.position_size>0 ? color.new(color.green, 95) : na
bgcolor(bgColorLong, title="Position BGcolor")

// IRISBOT
exchange = input.string("binance",  "Exchange", confirm=true, group="[IRISBOT]----------", inline="2", options=["binance", "bybit", "upbit"])
account  = input.string("account1", "Account",  confirm=true, group="[IRISBOT]----------", inline="2")
symbol   = input.string("BTC/USDT", "Symbol",   confirm=true, group="[IRISBOT]----------", inline="3")
strategy = input.string("sema-x",   "Strategy", confirm=true, group="[IRISBOT]----------", inline="3")
token    = input.string("token",    "Token",    confirm=true, group="[IRISBOT]----------", inline="4")
stRatio  = input.float(100.0,       "Ratio(%)", confirm=true, group="[IRISBOT]----------", inline="5", tooltip="하나의 거래소에서 이 전략을 몇 % 비중으로 투자할 것인가?") * 0.01
leverage = input.float(1,           "Leverage", confirm=true, group="[IRISBOT]----------", inline="5")
isPlotMsg = input.bool(false, "View alert msg", confirm=true, group="[IRISBOT]----------", inline="6")

//****************************************************************************//
// Process
//****************************************************************************//
ema25=ta.ema(close, emaLen25)
ema50=ta.ema(close, emaLen50)

// Entry condition
longCondition  = isLong and ta.crossover(ema25, ema50)
shortCondition = isShort and ta.crossunder(ema25, ema50)

// Entry price
var price=0.0
var pricePlot=0.0
if (longCondition or shortCondition) and strategy.position_size == 0
    price:=close
pricePlot:=price
if (strategy.position_size==0)
    pricePlot:=na

// Amount
amount = str.tostring(stRatio*100)

// IRISBOT alert msg (for auto trading, you can change this for autoview, tvextbot, thanksbot, etc webhookbot)
msgLong  = '{"exchange":"'+exchange+'","account":"'+account+'","strategy":"'+strategy+'","symbol":"'+symbol+'","type":"market","side":"buy","amount":"'+amount+'%","leverage":"'+str.tostring(leverage)+'","token":"'+token+'"}'
msgShort = '{"exchange":"'+exchange+'","account":"'+account+'","strategy":"'+strategy+'","symbol":"'+symbol+'","type":"market","side":"sell","amount":"'+amount+'%","leverage":"'+str.tostring(leverage)+'","token":"'+token+'"}'
msgExit  = '{"exchange":"'+exchange+'","account":"'+account+'","strategy":"'+strategy+'","symbol":"'+symbol+'","type":"market","side":"close","token":"'+token+'"}'

// Entry signal
if inDateRange
    strategy.entry("L", strategy.long,  when=longCondition,  comment="L", alert_message=msgLong)
    strategy.entry("S", strategy.short, when=shortCondition, comment="S", alert_message=msgShort)
    strategy.exit("XL", "L", profit=price*tpLong/syminfo.mintick,  loss=price*slLong/syminfo.mintick,  comment="X", alert_message=msgExit)
    strategy.exit("XS", "S", profit=price*tpShort/syminfo.mintick, loss=price*slShort/syminfo.mintick, comment="X", alert_message=msgExit)

//****************************************************************************//
// Plot
//****************************************************************************//
// Alert msg plot
var msgTable = table.new(position = position.bottom_right, columns = 2, rows = 3, bgcolor = color.new(color.blue, 80), border_width = 1)
if isPlotMsg
    if isLong
        table.cell(msgTable, 0, 0, "Long",  text_halign = text.align_left)
        table.cell(msgTable, 1, 0, msgLong,  text_halign = text.align_left)
    
    if isShort
        table.cell(msgTable, 0, 1, "Short", text_halign = text.align_left, bgcolor=color.new(color.red, 80))
        table.cell(msgTable, 1, 1, msgShort, text_halign = text.align_left, bgcolor=color.new(color.red, 80))
    
    if isLong or isShort
        table.cell(msgTable, 0, 2, "Exit",  text_halign = text.align_left, bgcolor=color.new(color.purple, 80))
        table.cell(msgTable, 1, 2, msgExit,  text_halign = text.align_left, bgcolor=color.new(color.purple, 80))

// EMA
e0=plot(ema25, "Short", color.green)
e1=plot(ema50, "Long", color.red)
fill(e0, e1, ema25>ema50 ? color.new(color.green, 50) : color.new(color.red, 50), "EMA BG")

// TP & SL
p0=plot(pricePlot, "Entry", color.black, style=plot.style_linebr)
p1=plot(pricePlot*(strategy.position_size>0 ? 1+tpLong : 1-tpShort), "TP", color.new(color.green, 50), style=plot.style_linebr)
p2=plot(pricePlot*(strategy.position_size>0 ? 1-slLong : 1+slShort), "SL", color.new(color.red, 50), style=plot.style_linebr)
fill(p0, p1, color.new(color.green, 80), "TP BG")
fill(p0, p2, color.new(color.red, 80), "SL BG")

もっと