La estrategia de cruce de dos EMA es una estrategia de negociación cuantitativa que abre y cierra posiciones basadas en el cruce de dos líneas EMA con períodos diferentes.
La estrategia utiliza dos líneas EMA, una es una línea EMA de 25 períodos como la línea rápida, y la otra es una línea EMA de 50 períodos como la línea lenta.
Después de ir largo, establece el take profit al 2% del precio de entrada y el stop loss al 2% del precio de entrada.
El núcleo de esta estrategia es usar el cruce de las líneas rápidas y lentas de la EMA para juzgar las tendencias y reversiones del mercado. Cuando la línea rápida cruza por encima, se juzga como un mercado alcista y va largo. Cuando la línea rápida cruza por debajo, se juzga como un mercado bajista y va corto.
La doble estrategia de cruce de la EMA tiene las siguientes ventajas:
En general, esta estrategia evalúa claramente el mercado, utiliza las ventajas de la propia EMA y obtiene buenos rendimientos a medio y corto plazo controlando los riesgos.
La doble estrategia de cruce de la EMA también presenta algunos riesgos:
Estos riesgos se pueden optimizar y resolver de las siguientes maneras:
Las principales direcciones de optimización para esta estrategia incluyen:
Estas optimizaciones pueden mejorar las tasas de rendimiento y ganancias manteniendo la estrategia simple y clara.
En resumen, la Estrategia Dual EMA Crossover es una estrategia comercial cuantitativa muy práctica. Es fácil de entender e implementar, y captura eficazmente las tendencias del mercado. Al mismo tiempo, tiene espacio para la optimización. Se pueden lograr mejoras adicionales en las tasas de retorno a través de ajustes y combinaciones de parámetros. La simplicidad y la directitud de esta estrategia vale la pena aprender y aplicar para los inversores.
/*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")