
Chiến lược giao dịch chéo EMA kép (Dual EMA Crossover Strategy) là một chiến lược giao dịch định lượng dựa trên hai chu kỳ khác nhau của đường chéo EMA để mở vị trí và vị trí. Chiến lược này đơn giản, hiệu quả, dễ hiểu và là một chiến lược giao dịch định lượng thường được sử dụng.
Chiến lược này sử dụng hai đường EMA trung bình, một đường EMA 25 chu kỳ làm đường nhanh và một đường EMA 50 chu kỳ làm đường chậm. Khi đi qua đường chậm trên đường nhanh, hãy làm nhiều hơn; khi đi qua đường chậm dưới đường nhanh, hãy làm trống.
Sau khi thực hiện nhiều, thiết lập dừng là 2% giá nhập, dừng là 2% giá nhập, và khi giá đạt đến dừng hoặc dừng, xóa vị trí.
Cốt lõi của chiến lược này là sử dụng giao điểm của đường EMA để đánh giá xu hướng thị trường và đảo ngược. Khi đi lên, đánh giá là thị trường bò và làm nhiều, khi đi xuống, đánh giá là thị trường gấu và làm trống. Cài đặt dừng lỗ để khóa lợi nhuận và kiểm soát rủi ro.
Chiến lược giao chéo hai EMA có những lợi thế sau:
Nhìn chung, chiến lược này đánh giá thị trường bằng logic rõ ràng, sử dụng lợi thế của chính EMA để có được lợi nhuận ngắn và trung bình tốt với giả định rằng rủi ro có thể được kiểm soát.
Chiến lược giao chéo hai đường EMA nhanh chậm cũng có một số rủi ro:
Những rủi ro này có thể được giải quyết một cách tối ưu bằng cách:
Chiến lược này cũng có các hướng tối ưu hóa chính như sau:
Những cải tiến này có thể giúp tăng lợi nhuận và tỷ lệ thắng trong khi duy trì chiến lược đơn giản và rõ ràng.
Chiến lược giao dịch chéo hai đường EMA nhanh và chậm nói chung là một chiến lược giao dịch định lượng rất thực tế. Nó dễ hiểu và thực hiện, nắm bắt xu hướng thị trường một cách hiệu quả.
/*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")