该策略基于3条不同周期的EMA平均线,通过判断价格是否处于EMA平均线之上,来判断目前的趋势方向。当短期EMA线上穿长期EMA线时生成买入信号;当短期EMA线下穿长期EMA线时生成卖出信号。该策略追踪趋势运行,在趋势转向时及时平仓。
该策略使用3条EMA平均线,分别是10日线、20日线和50日线。其判断规则为:
当10日EMA线和20日EMA线同时位于50日EMA线之上时,定义为上升趋势;
当10日EMA线和20日EMA线同时位于50日EMA线之下时,定义为下降趋势;
当短期EMA线(10日线和20日线)上穿长期EMA线(50日线)时产生买入信号;
当短期EMA线(10日线和20日线)下穿长期EMA线(50日线)时产生卖出信号;
在上升趋势中持有多头仓位,下降趋势中持有空头仓位;
在趋势转向时(EMA短期线与长期线发生穿透)平掉当前信号方向的头寸。
该策略通过 capture profit,通过及时平仓锁定盈利的方式轮番进行多空操作。
该策略具有以下优势:
该策略也存在一些风险:
针对以上风险,可以通过以下方法加以优化:
该策略可以从以下几个方向进行优化:
参数优化。可以测试不同EMA周期的参数组合,找到最佳的参数;
交易成本优化。适当优化开仓规则,减少不必要的频繁交易;
止损策略优化。设定合理的止损水平,控制单笔损失;
结合其他指标。运用MACD,KDJ等其他指标辅助判断,优化入场时机。
该策略整体来说较为简单实用。其利用EMA判断趋势运行方向,附带适当的止损策略,可以有效控制风险。同时也存在一些优化空间,若果结合参数优化、止损策略、其他指标等,该策略的效果还具有很大提升空间。
/*backtest start: 2024-01-28 00:00:00 end: 2024-01-31 04:00:00 period: 45m basePeriod: 5m 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/ // © mattehalen //@version=4 //study("EMA 10,20 59",overlay=true) strategy("EMA 10,20 59",overlay=true) infoBox = input(true, title="infoBox", type=input.bool) infoBox2 = input(false, title="infoBox2", type=input.bool) BuySellSignal_Bool = input(false, title="Buy & SellSignal", type=input.bool) infoBoxSize = input(title="infoBoxSize", defval=size.large, options=[size.auto, size.tiny, size.small, size.normal, size.large, size.huge]) ema1Value = input(10) ema2Value = input(20) ema3Value = input(59) maxLoss = input(3000) ema1 = ema(close,ema1Value) ema2 = ema(close,ema2Value) ema3 = ema(close,ema3Value) objcnt = 0 buyTitle = tostring(close[1]) myProfit = float(0) plot(ema1,title="ema1",color=color.red,linewidth=2) plot(ema2,title="ema2",color=color.green,linewidth=2) plot(ema3,title="ema3",color=color.black,linewidth=2) Buytrend = (ema1 and ema2 > ema3) and (ema1[1] and ema2[1] > ema3[1]) BarssinceBuyTrend = barssince(Buytrend) BarssinceSellTrend = barssince(not Buytrend) closeAtBuyTrend = close[1] bgcolor(Buytrend ? color.green : color.red,transp=70) BuySignal = Buytrend and not Buytrend[1] and BuySellSignal_Bool BuySignalOut = Buytrend and (crossunder(ema1,ema2)) and BuySellSignal_Bool BarssinceBuy = barssince(BuySignal) bgcolor(BuySignal ? color.green : na , transp=30) bgcolor(BuySignalOut ? color.black : na , transp=30) plot(BarssinceBuy,title="BarssinceBuy",display=display.none) SellSignal = not Buytrend and Buytrend[1] and BuySellSignal_Bool SellSignalOut = not Buytrend and (crossover(ema1,ema2)) and BuySellSignal_Bool BarssinceSell = barssince(SellSignal) bgcolor(SellSignal ? color.red : na , transp=30) bgcolor(SellSignalOut ? color.black : na , transp=30) plot(BarssinceSell,title="BarssinceSell",display=display.none) buyProfit = float(0) cntBuy =0 sellProfit = float(0) cntSell =0 buyProfit := Buytrend and not Buytrend[1]? nz(buyProfit[1]) + (close[BarssinceBuyTrend[1]]-close) : nz(buyProfit[1]) cntBuy := Buytrend and not Buytrend[1]? nz(cntBuy[1]) + 1: nz(cntBuy[1]) sellProfit := not Buytrend and Buytrend[1]? nz(sellProfit[1]) + (close-close[BarssinceSellTrend[1]]) : nz(sellProfit[1]) cntSell := not Buytrend and Buytrend[1]? nz(cntSell[1]) + 1 : nz(cntSell[1]) totalProfit = buyProfit + sellProfit // if (Buytrend and not Buytrend[1] and infoBox==true) // l = label.new(bar_index - (BarssinceBuyTrend[1]/2), na,text="Close = " + tostring(close) + "\n" + "Start = "+tostring(close[BarssinceBuyTrend[1]]) + "\n" + "Profit = "+tostring(close[BarssinceBuyTrend[1]]-close) ,style=label.style_labelup, yloc=yloc.belowbar,color=color.red,size=infoBoxSize) // if (not Buytrend and Buytrend[1] and infoBox==true) // l = label.new(bar_index - (BarssinceSellTrend[1]/2), na,text="Close = " + tostring(close) + "\n" + "Start = "+tostring(close[BarssinceSellTrend[1]]) + "\n" + "Profit = "+tostring(close-close[BarssinceSellTrend[1]]) ,style=label.style_labeldown, yloc=yloc.abovebar,color=color.green,size=infoBoxSize) // if (BuySignalOut and not BuySignalOut[1] and infoBox2==true) // // l = label.new(bar_index - (BarssinceBuy[0]/2), na,text="Close = " + tostring(close) + "\n" + "Start = "+tostring(close[BarssinceBuy[0]]) + "\n" + "Profit = "+tostring(close-close[BarssinceBuy[0]]) ,style=label.style_labelup, yloc=yloc.belowbar,color=color.purple,size=infoBoxSize // l = label.new(bar_index, na,text="Close = " + tostring(close) + "\n" + "Start = "+tostring(close[BarssinceBuy[0]]) + "\n" + "Profit = "+tostring(close-close[BarssinceBuy[0]]) ,style=label.style_labelup, yloc=yloc.belowbar,color=color.lime,size=infoBoxSize) // if (SellSignalOut and not SellSignalOut[1] and infoBox2==true) // // l = label.new(bar_index - (BarssinceSell[0]/2), na,text="Close = " + tostring(close) + "\n" + "Start = "+tostring(close[BarssinceSell[0]]) + "\n" + "Profit = "+tostring(close[BarssinceSell[0]]-close) ,style=label.style_labeldown, yloc=yloc.abovebar,color=color.purple,size=infoBoxSize) // l = label.new(bar_index, na,text="Close = " + tostring(close) + "\n" + "Start = "+tostring(close[BarssinceSell[0]]) + "\n" + "Profit = "+tostring(close[BarssinceSell[0]]-close) ,style=label.style_labeldown, yloc=yloc.abovebar,color=color.fuchsia,size=infoBoxSize) // l2 = label.new(bar_index, na, 'buyProfit in pip = '+tostring(buyProfit)+"\n"+ 'cntBuy = '+tostring(cntBuy) +"\n"+ 'sellProfit in pip = '+tostring(sellProfit)+"\n"+ 'cntSell = '+tostring(cntSell) +"\n"+ 'totalProfit in pip = '+tostring(totalProfit) , // color=totalProfit>0 ? color.green : color.red, // textcolor=color.white, // style=label.style_labeldown, yloc=yloc.abovebar, // size=size.large) // label.delete(l2[1]) //-------------------------------------------------- //-------------------------------------------------- if (Buytrend) strategy.close("short", comment = "Exit short") strategy.entry("long", true) strategy.exit("Max Loss", "long", loss = maxLoss) //if BuySignalOut // strategy.close("long", comment = "Exit Long") if (not Buytrend) // Enter trade and issue exit order on max loss. strategy.close("long", comment = "Exit Long") strategy.entry("short", false) strategy.exit("Max Loss", "short", loss = maxLoss) //if SellSignalOut // Force trade exit. //strategy.close("short", comment = "Exit short") //-------------------------------------------------- //-------------------------------------------------- //--------------------------------------------------