Ý tưởng cốt lõi của chiến lược này là làm cho chu kỳ dẻo lỏng của chỉ số RSI trở nên động, tự động điều chỉnh theo mối liên quan giữa giá cả và động lực, do đó cải thiện tính thiết thực của chỉ số RSI.
Chiến lược này đầu tiên tính toán động lực của giá, sau đó tính toán hệ số liên quan giữa giá và động lực. Khi hệ số liên quan gần 1 thì giá và động lực có liên quan tích cực cao; khi hệ số liên quan gần 1 thì giá và động lực có liên quan tiêu cực cao.
Độ dài chu kỳ mịn của chỉ số RSI có thể được điều chỉnh tùy thuộc vào sự liên quan của giá và động lực. Khi có liên quan cao, sử dụng chu kỳ RSI ngắn hơn; Khi có liên quan thấp, sử dụng chu kỳ RSI dài hơn.
Cụ thể, chiến lược này đặt độ dài chu kỳ RSI thành một phạm vi, mặc định là 20-50. Sau khi tính toán các hệ số liên quan đến giá cả và động lực, các hệ số liên quan được lập bản đồ đến phạm vi 20-50 thông qua phương pháp lập bản đồ tuyến tính, là độ dài chu kỳ mịn cuối cùng của RSI.
Điều này có thể tự động điều chỉnh các tham số của chỉ số RSI tùy theo tình hình thị trường, sử dụng RSI ngắn hơn để làm cho nó nhạy cảm hơn khi biến đổi giá và biến đổi động lực có liên quan mạnh mẽ; sử dụng RSI dài hơn khi liên quan không mạnh mẽ, để giảm ảnh hưởng của tiếng ồn đến tín hiệu.
Chiến lược này có ý tưởng học hỏi bằng cách động điều chỉnh chu kỳ làm mịn RSI, nhưng thực hiện cụ thể vẫn còn rất nhiều chỗ để cải thiện. Điều quan trọng là tìm ra các yếu tố quyết định ảnh hưởng đến lựa chọn tham số RSI và chuyển chúng thành các chỉ số có thể định lượng. Đồng thời, đừng hoàn toàn phụ thuộc vào mô hình, cũng cần tối ưu hóa phạm vi tham số dựa trên kinh nghiệm và phản hồi.
/*backtest
start: 2023-09-06 00:00:00
end: 2023-10-06 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy("Dynamic RSI Momentum", "DRM Strategy", process_orders_on_close = true, default_qty_type = strategy.percent_of_equity, default_qty_value = 50 )
// +++++++++++++++++++++
// ++ INPUT ++
// +++++++++++++++++++++
// Momentum
len = input.int(10, "Momentum Length", 1, group = "Dynamic RSI Momentum")
src = input.source(close, "Source", group = "Dynamic RSI Momentum")
min_rsi = input.int(20, "Min RSI", group = "Dynamic RSI Momentum")
max_rsi = input.int(50, "Max RSI", group = "Dynamic RSI Momentum")
upLvl = input.float(70, "OverBought", 0, 100, group = "Dynamic RSI Momentum")
dnLvl = input.float(30, "OverSold", 0, 100, group = "Dynamic RSI Momentum")
// +++++++++++++++++++++
// ++ CALCULATION ++
// +++++++++++++++++++++
// RMA Function
rmaFun(src, len) =>
sma = ta.sma(src, len)
alpha = 1/len
sum = 0.0
sum := na(sum[1]) ? sma : alpha * src + (1 - alpha) * nz(sum[1])
// RSI Function
rsiFun(src, len) =>
100 - 100 / (1 + rmaFun(src - src[1] > 0 ? src - src[1] : 0, len) /
rmaFun(src[1] - src > 0 ? src[1] - src : 0, len))
// Momentum
momVal = src - src[len]
// Calculation Price vs Momentum
corr = ta.correlation(src, momVal, len)
corr := corr > 1 or corr < -1 ? float(na) : corr
rsiLen = 0
rsiLen := int(min_rsi + nz(math.round((1 - corr) * (max_rsi-min_rsi) / 2, 0), 0))
rsiMom = rsiFun(src, rsiLen)
// +++++++++++++++++++++
// ++ STRATEGY ++
// +++++++++++++++++++++
long = ta.crossover(rsiMom, dnLvl)
short = ta.crossunder(rsiMom, upLvl)
// +++> Long <+++++
if long and not na(rsiMom)
strategy.entry("Long", strategy.long)
// +++> Short <+++++
if short and not na(rsiMom)
strategy.entry("Short", strategy.short)
// +++++++++++++++++++++
// ++ PLOT ++
// +++++++++++++++++++++
plot(rsiMom, "Dynamic RSI Momentum", rsiMom < dnLvl ? color.green : rsiMom > upLvl ? color.red : color.yellow)
hline(50, "Mid Line", color.gray)
upperLine = hline(upLvl, "Upper Line", color.gray)
lowerLine = hline(dnLvl, "Lower Line", color.gray)
fill(upperLine, lowerLine, color.new(color.purple, 90), "Background Fill")