Chiến lược này dựa trên 3 đường EMA của các giai đoạn khác nhau. Nó đánh giá hướng xu hướng hiện tại bằng cách xem giá có nằm trên đường EMA hay không. Khi đường EMA ngắn hạn vượt qua đường EMA dài hạn, một tín hiệu mua được tạo ra. Khi đường EMA ngắn hạn vượt qua đường EMA dài hạn, một tín hiệu bán được tạo ra. Chiến lược này theo dõi xu hướng và đóng các vị trí kịp thời khi xu hướng đảo ngược.
Chiến lược sử dụng 3 đường EMA, tương ứng là 10 ngày, 20 ngày và 50 ngày.
Khi cả EMA 10 ngày và EMA 20 ngày đều trên EMA 50 ngày, nó được định nghĩa là xu hướng tăng;
Khi cả EMA 10 ngày và EMA 20 ngày đều dưới EMA 50 ngày, nó được định nghĩa là xu hướng giảm;
Khi đường EMA ngắn hạn (10 ngày và 20 ngày) vượt qua đường EMA dài hạn (50 ngày), một tín hiệu mua được tạo ra;
Khi đường EMA ngắn hạn (10 ngày và 20 ngày) vượt dưới đường EMA dài hạn (50 ngày), một tín hiệu bán được tạo ra;
Giữ vị trí dài trong xu hướng tăng và giữ vị trí ngắn trong xu hướng giảm;
Đóng vị trí định hướng hiện tại khi xu hướng đảo ngược (EMA ngắn hạn vượt qua EMA dài hạn).
Chiến lược thu được lợi nhuận bằng cách đóng các vị trí kịp thời để khóa lợi nhuận và xen kẽ giữa các vị trí dài và ngắn.
Những lợi thế của chiến lược này là:
Có một số rủi ro trong chiến lược này:
Trong các thị trường giới hạn phạm vi, các đường EMA có thể giao nhau thường xuyên, dẫn đến chi phí giao dịch cao từ các vị trí mở và đóng thường xuyên;
Việc xác định xu hướng bởi EMA có thể thất bại sau khi chênh lệch giá, bỏ lỡ các cơ hội nhập cảnh tốt.
Để tối ưu hóa rủi ro, một số phương pháp có thể được sử dụng:
Các quy tắc vị trí mở có thể được nới lỏng thích hợp khi EMA gần để tránh giao dịch quá mức;
Xác định xu hướng kết hợp các chỉ số khác để tránh sự cố EMA.
Chiến lược có thể được tối ưu hóa từ các khía cạnh sau:
Tối ưu hóa tham số. Kiểm tra các kết hợp thời gian EMA khác nhau để tìm các tham số tối ưu;
Tối ưu hóa chi phí giao dịch. Tối ưu hóa các quy tắc vị trí mở đúng cách để giảm giao dịch thường xuyên không cần thiết;
Tối ưu hóa chiến lược dừng lỗ. Đặt mức dừng lỗ hợp lý để kiểm soát lỗ đơn;
Sử dụng MACD, KDJ và các chỉ số khác để giúp xác định thời gian nhập khẩu tối ưu.
Nói chung, chiến lược này khá đơn giản và thực tế. Nó sử dụng EMA để xác định hướng xu hướng với chiến lược dừng lỗ thích hợp để kiểm soát rủi ro một cách hiệu quả. Ngoài ra còn có phòng tối ưu hóa. Bằng cách kết hợp tối ưu hóa tham số, chiến lược dừng lỗ và các chỉ số khác, hiệu suất của chiến lược này có thể được cải thiện hơn nữa.
/*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") //-------------------------------------------------- //-------------------------------------------------- //--------------------------------------------------