Đây là một chiến lược theo dõi xu hướng RSI kép sử dụng hai chỉ số RSI cho tín hiệu giao dịch dài và ngắn, kết hợp với hệ thống trung bình động để xác định hướng xu hướng. Nó thuộc thể loại các chiến lược thuật toán RSI kép. Chiến lược đầu tiên sử dụng các chỉ số RSI để xác định tín hiệu tăng và giảm, sau đó sử dụng trung bình động để xác nhận hướng xu hướng cho các giao dịch dài hoặc ngắn.
Chiến lược RSI kép chủ yếu sử dụng hai chỉ số RSI với khung thời gian khác nhau cho tín hiệu giao dịch. Đầu tiên nó thiết lập hai thông số RSI, một RSI dài hơn là chỉ số chính và một RSI ngắn hơn là bộ lọc phụ trợ. Khi RSI dài hơn phá vỡ dưới đường bán quá mức, một tín hiệu dài được tạo ra. Khi RSI ngắn hơn phá vỡ trên đường mua quá mức, một tín hiệu ngắn được tạo ra. Điều này tạo thành hệ thống chéo RSI kép cho các cơ hội giao dịch.
Để lọc các tín hiệu sai, chiến lược cũng kết hợp SMA và EMA trung bình động để phát hiện xu hướng. Chỉ khi SMA ngắn vượt trên EMA dài, tín hiệu RSI dài được coi là tín hiệu. Và chỉ khi SMA ngắn vượt dưới EMA dài, tín hiệu RSI ngắn được coi là tín hiệu. Điều này đảm bảo tín hiệu RSI phù hợp với hướng xu hướng và tránh giao dịch chống lại xu hướng.
Ngoài ra, chiến lược cũng thiết lập logic dừng lỗ và lấy lợi nhuận. Sau khi mở các vị trí, hai lệnh lấy lợi nhuận có kích thước khác nhau được đặt, cùng với mức dừng lỗ.
Chiến lược thuật toán RSI kép có những lợi thế sau:
Các chỉ số RSI hai khung thời gian có thể xác định chính xác hơn các tín hiệu tăng và giảm. Sự kết hợp của các chỉ số RSI dài và ngắn có thể lọc một số tín hiệu sai và cải thiện chất lượng tín hiệu.
Hệ thống trung bình động giúp xác định hướng xu hướng chính, tránh giao dịch chống lại xu hướng và có thể lọc hầu hết các giao dịch tiếng ồn, cải thiện tỷ lệ thắng.
Cơ chế dừng lỗ và lấy lợi nhuận linh hoạt cho phép lợi nhuận cao hơn thông qua các cài đặt lấy lợi nhuận khác nhau và quản lý rủi ro thông qua dừng lỗ.
Logic giao dịch đơn giản và rõ ràng, dễ hiểu và tối ưu hóa. Nó phù hợp với các nhà giao dịch thuật toán để học.
Mặc dù có những lợi thế, chiến lược RSI kép cũng có những rủi ro sau:
Bản thân RSI có hiệu quả hạn chế trong các thị trường khác nhau và đảo ngược xu hướng.
Mặc dù các đường trung bình động lọc tiếng ồn nhỏ, nhưng chúng ít hiệu quả hơn trong việc phát hiện các thay đổi xu hướng chu kỳ trung gian và có thể bỏ lỡ các điểm chuyển hướng xu hướng.
Cài đặt stop loss và take profit không đúng có thể dẫn đến stop quá rộng hoặc lợi nhuận quá nhỏ, làm suy giảm hiệu suất chiến lược.
Các vị trí dài / ngắn lớn có thể dẫn đến tổn thất lớn hơn.
Để giải quyết những rủi ro này, các tham số có thể được điều chỉnh, các chỉ số xu hướng và đảo ngược tiên tiến hơn có thể được giới thiệu, logic dừng và lợi nhuận được tối ưu hóa và kích thước vị trí được kiểm soát để giảm thiểu rủi ro.
Chiến lược RSI kép có thể được tối ưu hóa thêm trong các khía cạnh sau:
Kiểm tra các kết hợp tham số khác nhau để tìm thấy các khoảng thời gian RSI dài và ngắn tối ưu.
Đưa ra các chỉ số khác như MACD để phân tích xu hướng và đảo ngược tốt hơn.
Tối ưu hóa chiến lược dừng lỗ và lấy lợi nhuận, sử dụng dừng lại hoặc di chuyển lấy lợi nhuận để linh hoạt hơn.
Thêm mô-đun điều khiển kích cỡ vị trí để điều chỉnh các vị trí dài / ngắn trong các giai đoạn chu kỳ xu hướng khác nhau.
Kết hợp các mô hình học máy để cải thiện độ chính xác nhập và xuất.
Backtest trên các sản phẩm khác nhau và khung thời gian để tối ưu hóa.
Tóm lại, chiến lược RSI kép là một chiến lược theo xu hướng điển hình. Ý tưởng của nó là kết hợp các tín hiệu RSI kép và lọc tiếng ồn trung bình chuyển động là rất cổ điển và thực tế. Mặc dù có những lĩnh vực để cải thiện, nhưng logic tổng thể rõ ràng và dễ hiểu và tối ưu hóa. Đây là một chiến lược tuyệt vời cho người mới bắt đầu giao dịch thuật toán để học và thực hành. Thông qua tối ưu hóa liên tục và lặp lại dựa trên nguyên tắc
/*backtest start: 2023-11-07 00:00:00 end: 2023-11-14 00:00:00 period: 1m basePeriod: 1m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=4 strategy("Growth Producer", overlay=true, initial_capital = 1000, currency = "USD", pyramiding = 2, commission_type=strategy.commission.percent, commission_value=0.07, default_qty_type = strategy.percent_of_equity, default_qty_value = 100) //Functions Atr(p) => atr = 0. Tr = max(high - low, max(abs(high - close[1]), abs(low - close[1]))) atr := nz(atr[1] + (Tr - atr[1])/p,Tr) /// TREND ribbon_period = input(19, "Period", step=1) leadLine1 = ema(close, ribbon_period) leadLine2 = sma(close, ribbon_period) p1 = plot(leadLine1, color= #53b987, title="EMA", transp = 50, linewidth = 1) p2 = plot(leadLine2, color= #eb4d5c, title="SMA", transp = 50, linewidth = 1) fill(p1, p2, transp = 60, color = leadLine1 > leadLine2 ? #53b987 : #eb4d5c) // Relative volatility index length = input(120,"RVI period", minval=1), src = close len = 14 stddev = stdev(src, length) upper = ema(change(src) <= 0 ? 0 : stddev, len) lower = ema(change(src) > 0 ? 0 : stddev, len) rvi = upper / (upper + lower) * 100 benchmark = input(35, "RVI benchmark", minval=10, maxval=100, step=0.1) // Plot RVI // h0 = hline(80, "Upper Band", color=#C0C0C0) // h1 = hline(20, "Lower Band", color=#C0C0C0) // fill(h0, h1, color=#996A15, title="Background") // offset = input(0, "Offset", type = input.integer, minval = -500, maxval = 500) // plot(rvi, title="RVI", color=#008000, offset = offset) /// MFI input mfi_source = hlc3 mfi_length = input(19, "MFI Length", minval=1) mfi_lower = input(15, "MFI Lower level", minval=0, maxval=50) mfi_upper = input(90, "MFI Higher level", minval=50, maxval=100) // MFI upper_s = sum(volume * (change(mfi_source) <= 0 ? 0 : mfi_source), mfi_length) lower_s = sum(volume * (change(mfi_source) >= 0 ? 0 : mfi_source), mfi_length) mf = rsi(upper_s, lower_s) // mfp = plot(mf, color=color.new(color.gray,0), linewidth=1) // top = hline(mfi_upper, color=color.new(color.gray, 100), linewidth=1, editable=false) // bottom = hline(mfi_lower, color=color.new(color.gray,100), linewidth=1, editable=false) // hline(0, color=color.new(color.black,100), editable=false) // hline(100, color=color.new(color.black,100), editable=false) // Breaches // b_color = (mf > mfi_upper) ? color.new(color.red,70) : (mf < mfi_lower) ? color.new(color.green,60) : na // bgcolor(HighlightBreaches ? b_color : na) // fill(top, bottom, color=color.gray, transp=75) // Initial inputs Act_RSI_VWAP_long = input(true, "RSI VOLUME WEIGHTED AVERAGE PRICE LONG") RSI_VWAP_length_long = input(16, "RSI-VWAP LENGTH LONG") RSI_VWAP_overSold_long = input(13, "RSI-VWAP OVERSOLD LONG", type=input.float) RSI_VWAP_overBought_long = input(68, "RSI-VWAP OVERBOUGHT LONG", type=input.float) Act_RSI_VWAP_short = input(true, "RSI VOLUME WEIGHTED AVERAGE PRICE SHORT") RSI_VWAP_length_short = input(14, "RSI-VWAP LENGTH SHORT") RSI_VWAP_overSold_short = input(7, "RSI-VWAP OVERSOLD SHORT", type=input.float) RSI_VWAP_overBought_short = input(68, "RSI-VWAP OVERBOUGHT SHORT", type=input.float) // RSI with VWAP as source RSI_VWAP_long = rsi(vwap(close), RSI_VWAP_length_long) RSI_VWAP_short = rsi(vwap(close), RSI_VWAP_length_short) // Plot Them Separately. // Plotting LONG, Put overlay=false // r=plot(RSI_VWAP_long, color = RSI_VWAP_long > RSI_VWAP_overBought_long ? color.red : RSI_VWAP_lnog < RSI_VWAP_overSold_long ? color.lime : color.blue, title="rsi", linewidth=2, style=plot.style_line) // h1=plot(RSI_VWAP_overBought_long, color = color.gray, style=plot.style_stepline) // h2=plot(RSI_VWAP_overSold_long, color = color.gray, style=plot.style_stepline) // fill(r,h1, color = RSI_VWAP_long > RSI_VWAP_overBought_long ? color.red : na, transp = 60) // fill(r,h2, color = RSI_VWAP_long < RSI_VWAP_overSold_long ? color.lime : na, transp = 60) // Plotting SHORT, Put overlay=false // r=plot(RSI_VWAP_short, color = RSI_VWAP_short > RSI_VWAP_overBought_short ? color.red : RSI_VWAP_short < RSI_VWAP_overSold_short ? color.lime : color.blue, title="rsi", linewidth=2, style=plot.style_line) // h1=plot(RSI_VWAP_overBought_short, color = color.gray, style=plot.style_stepline) // h2=plot(RSI_VWAP_overSold_short, color = color.gray, style=plot.style_stepline) // fill(r,h1, color = RSI_VWAP_short > RSI_VWAP_overBought_short ? color.red : na, transp = 60) // fill(r,h2, color = RSI_VWAP_short < RSI_VWAP_overSold_short ? color.lime : na, transp = 60) /////// STRATEGY Take Profit / Stop Loss //////// ////// LONG ////// long_tp1_inp = input(3.3, title='Long Take Profit 1 %', step=0.1)/100 long_tp1_qty = input(15, title="Long Take Profit 1 Qty", step=1) long_tp2_inp = input(12, title='Long Take Profit 2%', step=0.1)/100 long_tp2_qty = input(100, title="Long Take Profit 2 Qty", step=1) long_sl_inp = input(3.3, title='Long Stop Loss %', step=0.1)/100 long_take_level_1 = strategy.position_avg_price * (1 + long_tp1_inp) long_take_level_2 = strategy.position_avg_price * (1 + long_tp2_inp) long_stop_level = strategy.position_avg_price * (1 - long_sl_inp) ////// SHORT ////// short_tp1_inp = input(3.2, title='Short Take Profit 1 %', step=0.1)/100 short_tp1_qty = input(20, title="Short Take Profit 1 Qty", step=1) short_tp2_inp = input(5.5, title='Short Take Profit 2%', step=0.1)/100 short_tp2_qty = input(100, title="Short Take Profit 2 Qty", step=1) short_sl_inp = input(3.2, title='Short Stop Loss %', step=0.1)/100 short_take_level_1 = strategy.position_avg_price * (1 - short_tp1_inp) short_take_level_2 = strategy.position_avg_price * (1 - short_tp2_inp) short_stop_level = strategy.position_avg_price * (1 + short_sl_inp) ///Strategy_Conditions /// LONG /// entry_long =(crossover(RSI_VWAP_long, RSI_VWAP_overSold_long) and leadLine2<leadLine1) or (crossunder(mf,mfi_lower) and leadLine2<leadLine1) entry_price_long=valuewhen(entry_long,close,0) exit_long =crossunder(RSI_VWAP_long, RSI_VWAP_overBought_long) /// SHORT /// entry_short =crossunder(RSI_VWAP_short, RSI_VWAP_overBought_short) and leadLine2>leadLine1 or (crossover(mf,mfi_upper) and leadLine2>leadLine1) entry_price_short=valuewhen(entry_short,close,0) exit_short =crossover(RSI_VWAP_short, RSI_VWAP_overSold_short) ////// BACKTEST PERIOD /////// testStartYear = input(2019, "Backtest Start Year") testStartMonth = input(1, "Backtest Start Month") testStartDay = input(1, "Backtest Start Day") testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0) testStopYear = input(2020, "Backtest Stop Year") testStopMonth = input(12, "Backtest Stop Month") testStopDay = input(31, "Backtest Stop Day") testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,0,0) testPeriod() => true if testPeriod() if strategy.position_size == 0 or strategy.position_size > 0 and rvi>benchmark strategy.entry("long", true, when = entry_long, comment="Insert Enter Long Comment") strategy.exit("TP1","long", qty_percent=long_tp1_qty, limit=long_take_level_1, stop=long_stop_level) strategy.exit("TP2","long", qty_percent=long_tp2_qty, limit=long_take_level_2, stop=long_stop_level) strategy.close("long", when=exit_long, comment = "Insert Exit Long Comment") if strategy.position_size == 0 or strategy.position_size < 0 and rvi>benchmark strategy.entry("short", false, when = entry_short, comment="Insert Enter Short Comment") strategy.exit("TP1","short", qty_percent=short_tp1_qty, limit=short_take_level_1, stop=short_stop_level) strategy.exit("TP2","short", qty_percent=short_tp2_qty, limit=short_take_level_2, stop=short_stop_level) strategy.close("short", when=exit_short, comment = "Insert Exit Short Comment") // LONG POSITION plot(strategy.position_size > 0 ? long_take_level_1 : na, style=plot.style_linebr, color=color.green, linewidth=1, title="1st Long Take Profit") plot(strategy.position_size > 0 ? long_take_level_2 : na, style=plot.style_linebr, color=color.green, linewidth=1, title="2nd Long Take Profit") plot(strategy.position_size > 0 ? long_stop_level : na, style=plot.style_linebr, color=color.red, linewidth=1, title="Long Stop Loss") // SHORT POSITION plot(strategy.position_size < 0 ? short_take_level_1 : na, style=plot.style_linebr, color=color.green, linewidth=1, title="1st Short Take Profit") plot(strategy.position_size < 0 ? short_take_level_2 : na, style=plot.style_linebr, color=color.green, linewidth=1, title="2nd Short Take Profit") plot(strategy.position_size < 0 ? short_stop_level : na, style=plot.style_linebr, color=color.red, linewidth=1, title="Long Stop Loss")