Bài viết này giải thích chi tiết một chiến lược giao dịch định lượng kết hợp chỉ số Stoch và EMA. Nó tạo ra các tín hiệu giao dịch dựa trên giá trị Stoch và sử dụng EMA để lọc các tín hiệu không chính thống.
I. Chiến lược logic
Các công cụ và logic chính là:
Tính toán chỉ số Stoch với các giá trị K và D, trong đó K phản ánh sự thay đổi giá nhanh và D là tín hiệu trơn tru.
Đặt vùng mua quá mức / bán quá mức cho Stock.
Tính toán EMA trong một khoảng thời gian để đánh giá xu hướng giá chính.
Chỉ thực hiện giao dịch khi tín hiệu Stoch đồng ý với hướng EMA.
Thiết lập các vị trí dài / ngắn trên các tín hiệu dừng lỗ và kiếm lợi nhuận.
Cùng nhau, Stoch nắm bắt các cơ hội mua quá mức / bán quá mức và EMA lọc ra các tín hiệu không hợp lệ, tạo thành một chiến lược mạnh mẽ.
II. Lợi thế của Chiến lược
Ưu điểm lớn nhất là sự bổ sung của các chỉ số. Stoch đánh giá mức O/S và EMA xu hướng chính, kết hợp để giảm lỗi.
Ngoài ra, các giá trị K / D có thể điều chỉnh cho phép tối ưu hóa trên các sản phẩm khác nhau.
Cuối cùng, lệnh dừng lỗ / lấy lợi nhuận xác định rõ rủi ro / phần thưởng cho quản lý tiền thận trọng.
III. Những điểm yếu tiềm tàng
Tuy nhiên, một số vấn đề tiềm ẩn là:
Thứ nhất, cả Stoch và EMA có thể bị chậm lại, gây ra các mục nhập tối ưu bị bỏ lỡ.
Thứ hai, việc dừng chặt chẽ có thể sớm gây ra nhiều bất lực.
Cuối cùng, tối ưu hóa tham số rộng rãi là cần thiết để tránh quá phù hợp.
IV. Tóm tắt
Tóm lại, bài viết này đã giải thích một chiến lược định lượng kết hợp Stoch và EMA. Nó xác định cơ hội đảo ngược quá mua / quá bán, với EMA lọc ra các tín hiệu không hợp lệ. Với điều chỉnh đúng cách, chiến lược này có thể đạt được lợi nhuận ổn định nhưng cần quản lý các rủi ro đã đề cập.
/*backtest start: 2023-08-15 00:00:00 end: 2023-08-26 00:00:00 period: 1h basePeriod: 15m 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/ //@version=5 strategy(title="EMA Stoch Strategy For ProfitView", overlay=true, calc_on_every_tick=true, process_orders_on_close=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1, initial_capital=1000) // take profit e stop loss TakeProfitPercent = input.float(defval = 0.0, title="Take Profit (%) [0 = Disabled]",minval = 0, step=.25,group='TP / SL') StopLossPercent = input.float(defval = 0.0, title="Stop Loss (%) [0 = Disabled]",minval = 0, step=.25,group='TP / SL') // Stoch smoothK = input.int(1, title="K Smoothing", minval=1,group='Stochastic') periodD = input.int(3, title="D Smoothing", minval=1,group='Stochastic') lenghtRSI= input.int(14, "RSI Length", minval=1) lenghtStoch = input.int(14, "Stochastic Length", minval=1) src = input(close, title="RSI Source") rsi1 = ta.rsi(src, lenghtRSI) k = ta.sma(ta.stoch(rsi1, rsi1, rsi1, lenghtStoch), smoothK) d = ta.sma(k, periodD) plot(k, title="K", color=#2962FF) plot(d, title="D", color=#FF6D00) // bgcolor(color=color.from_gradient(k, 0, 100, color.new(#2962FF, 100), color.new(#2962FF, 95)), title="K BG") // bgcolor(color=color.from_gradient(d, 0, 100, color.new(#FF6D00, 100), color.new(#FF6D00, 95)), title="D BG") // ema src1= input(close,title='Source EMA ',group='EMA') len1= input(200,title='Length EMA ',group='EMA') ema1= ta.ema(src1,len1) plot(ema1,title='EMA',color= color.blue ,linewidth=2) // signals LongVal= input(20,title='Stoch below/cross this value for Long signals',group='Signal Options') scegliLong= input.string('Stoch Below Value', options= ['Stoch Below Value' , 'K&D Cross Below Value' , 'Stoch CrossUp the Value'] , title='Long Signal Type') long1= scegliLong == 'Stoch Below Value' ? k < LongVal and d < LongVal and close > ema1 : na long2= scegliLong == 'K&D Cross Below Value' ? ta.cross(k,d) and k < LongVal and d < LongVal and close > ema1 : na long3= scegliLong == 'Stoch CrossUp the Value' ? ta.crossover(k,LongVal) and close > ema1 : na shortVal= input(80,title='Stoch above/cross this value for Short signals',group='Signal Options') scegliShort= input.string('Stoch Above Value', options= ['Stoch Above Value' , 'K&D Cross Above Value' , 'Stoch CrossDown the Value'] , title='Short Signal Type' ) short1= scegliShort == 'Stoch Above Value' ? k > shortVal and d > shortVal and close < ema1 : na short2= scegliShort == 'K&D Cross Above Value' ? ta.cross(k,d) and k > shortVal and d > shortVal and close < ema1 : na short3= scegliShort == 'Stoch CrossDown the Value' ? ta.crossunder(k,shortVal) and close < ema1 : na // Strategy Backtest Limiting Algorithm/ i_startTime = input(defval = timestamp("01 Jan 2014 00:00 +0000"), title = "Backtesting Start Time", inline="timestart", group='Backtesting') i_endTime = input(defval = timestamp("01 Jan 2100 23:59 +0000"), title = "Backtesting End Time", inline="timeend", group='Backtesting') timeCond = true pv_ex = input.string("deribit-testnet", title="Exchange", group='PV Settings') pv_sym = input.string("btc-perpetual", title="Symbol", group='PV Settings') pv_acc = input.string("", title="Account", group='PV Settings') pv_alert_long = input.string("", title="PV Alert Name Longs", group='PV Settings') pv_alert_short = input.string("", title="PV Alert Name Shorts", group='PV Settings') pv_alert_cancel = input.string("", title="PV Alert Name TP/SL", group='PV Settings') profit_abs = (close * (TakeProfitPercent / 100)) stop_abs = (close * (StopLossPercent / 100)) ProfitTarget = TakeProfitPercent > 0 ? profit_abs / syminfo.mintick : na LossTarget = StopLossPercent > 0 ? stop_abs / syminfo.mintick : na // Make sure we are within the bar range, Set up entries and exit conditions var entryprice = 0.0 var profitprice = 0.0 var stopprice = 0.0 exsym = pv_ex == "" ? "" : "ex=" + pv_ex + "," exsym := pv_sym == "" ? exsym : exsym + "sym=" + pv_sym if ((long1 or long2 or long3) and timeCond and strategy.position_size <= 0) strategy.entry("Long", strategy.long, when=barstate.isconfirmed) entryprice := close profitprice := entryprice+profit_abs stopprice := entryprice-stop_abs tpsl_str = TakeProfitPercent > 0 ? ",mytp=" + str.tostring(profitprice) : "" tpsl_str := StopLossPercent > 0 ? tpsl_str + ",mysl=" + str.tostring(stopprice) : tpsl_str alert(pv_alert_long + "(" + exsym + ",acc=" + pv_acc + tpsl_str + ")", alert.freq_once_per_bar_close) if ((short1 or short2 or short3) and timeCond and strategy.position_size >= 0) strategy.entry("Short", strategy.short, when=barstate.isconfirmed) entryprice := close profitprice := entryprice-profit_abs stopprice := entryprice+stop_abs tpsl_str = TakeProfitPercent > 0 ? ",mytp=" + str.tostring(profitprice) : "" tpsl_str := StopLossPercent > 0 ? tpsl_str + ",mysl=" + str.tostring(stopprice) : tpsl_str alert(pv_alert_short + "(" + exsym + ",acc=" + pv_acc + tpsl_str + ")", alert.freq_once_per_bar_close) tpsl_hit_long = (strategy.position_size[1] > 0 and ((TakeProfitPercent > 0 and high > profitprice[1]) or (StopLossPercent > 0 and low < stopprice[1]))) tpsl_hit_short = (strategy.position_size[1] < 0 and ((TakeProfitPercent > 0 and low < profitprice[1]) or (StopLossPercent > 0 and high > stopprice[1]))) if (tpsl_hit_long or tpsl_hit_short) alert(pv_alert_cancel + "(" + exsym + ",acc=" + pv_acc + ")", alert.freq_once_per_bar) strategy.exit("Exit Long (TP/SL)", from_entry = "Long" , profit = ProfitTarget, loss = LossTarget) strategy.exit("Exit Short (TP/SL)", from_entry = "Short", profit = ProfitTarget, loss = LossTarget) plot(entryprice, title="Entry Price", color=strategy.opentrades > 0 ? color.gray : color.new(color.gray, 100)) plot(profitprice, title="Profit Price", color=strategy.opentrades > 0 and TakeProfitPercent > 0 ? color.green : color.new(color.green, 100)) plot(stopprice, title="Stop Price", color=strategy.opentrades > 0 and StopLossPercent > 0? color.red : color.new(color.red, 100))