Chiến lược biến động giá RSI Mean Reversion


Ngày tạo: 2023-09-26 19:55:03 sửa đổi lần cuối: 2023-09-26 19:55:03
sao chép: 2 Số nhấp chuột: 749
1
tập trung vào
1617
Người theo dõi

Tổng quan

Chiến lược này sử dụng các chỉ số RSI để xác định cơ hội bán tháo, tham gia vào các đợt khi giá giảm, và đạt được lợi nhuận lâu dài bằng cách giảm chi phí giữ vị trí bằng giá trị trung bình liên tục. Đồng thời, chiến lược tham gia cơ chế DCA để kiểm soát rủi ro hơn nữa.

Nguyên tắc chiến lược

Chiến lược này đầu tiên tính toán chỉ số RSI để xác định thị trường có bị bán quá mức hay không. Khi RSI thấp hơn 30, nó cho thấy cơ hội bán quá mức.

Sau khi mở vị trí, chiến lược sẽ thiết lập 6 giá quay trở lại giá trung bình, lần lượt là 98%, 97%, 95%, 90%, 84% và 70% của giá hiện tại. Khi giá chạm vào những giá này, sẽ tiếp tục thêm vị trí. Bằng cách tiếp tục trung bình, bạn có thể giảm chi phí giữ vị trí.

Ngoài ra, chiến lược cũng tính giá trung bình của vị thế. Khi giá tăng hơn 5% giá trung bình, bắt đầu dừng. Trong khi đó, nếu giá tiếp tục tăng, vượt quá 5% giá dừng của giá trung bình, tất cả đều dừng.

Cuối cùng, chiến lược này cũng thêm vào cơ chế DCA. Mỗi thứ Hai, nếu có vị trí nắm giữ và giá thấp hơn giá trung bình, vị trí có số tiền cố định sẽ được thêm vào. Điều này làm giảm chi phí nắm giữ hơn nữa.

Phân tích lợi thế

Lợi thế lớn nhất của chiến lược này là việc sử dụng các cơ chế trung bình và DCA để kiểm soát rủi ro. Cụ thể, bao gồm các điểm sau:

  1. Sử dụng chiến lược nhập cảnh theo đợt, bạn có thể phân tán rủi ro mở vị trí và tránh bỏ lỡ điểm thấp nhất.

  2. Thiết lập nhiều giá trung bình trở lại, bạn có thể giảm chi phí giữ vị trí và kiểm soát hiệu quả rủi ro giảm.

  3. Tính toán giá trung bình của vị trí, dừng lại kịp thời sau khi đạt được lợi nhuận, khóa thu nhập.

  4. Sử dụng cơ chế DCA để giảm chi phí nắm giữ và kiểm soát rủi ro.

  5. Sử dụng chỉ số RSI để xác định thời điểm thị trường, tránh đặt vị trí ở điểm cao.

  6. Sử dụng bộ lọc theo đường thẳng để tránh đảo ngược.

Phân tích rủi ro

Chiến lược này cũng có một số rủi ro, bao gồm:

  1. Chiến lược không thể xác định được điểm đảo ngược của thị trường, và nếu thị trường duy trì mức thấp trong thời gian dài, việc làm quá nhiều liên tục sẽ làm tăng tổn thất.

  2. Chiến lược không tính đến cơ chế dừng lỗ, không thể kiểm soát hiệu quả tổn thất đơn lẻ.

  3. Chiến lược này không giới hạn số lần mở vị trí, và nếu thị trường giảm mạnh, vị trí sẽ tăng lên.

  4. Cơ chế DCA có rủi ro về thời gian và không đảm bảo rằng bạn sẽ mở vị trí ở điểm thấp nhất.

Giải pháp tương ứng:

  1. Có thể kết hợp các chỉ số khác để đánh giá cấu trúc thị trường, tránh chỉ phụ thuộc vào RSI.

  2. Tăng dừng di chuyển hoặc dừng thu nhỏ.

  3. Giới hạn số lượng tầng để tránh quá nhiều vị trí.

  4. Tối ưu hóa thời gian mở cửa DCA bằng cách ổn định hơn.

Hướng tối ưu hóa

Chính sách này có thể được tối ưu hóa theo các khía cạnh sau:

  1. Tối ưu hóa các thuật toán trung bình, sử dụng một cách khoa học hơn để tính toán giá trị trở lại.

  2. Tối ưu hóa hệ thống ngăn chặn, có thể sử dụng ngăn chặn di động hoặc ngăn chặn thang.

  3. Tăng các chiến lược dừng lỗ để kiểm soát tốt hơn các khoản lỗ đơn lẻ.

  4. Kết hợp với các chỉ số khác để đánh giá cấu trúc thị trường, tránh chỉ phụ thuộc vào RSI.

  5. Tối ưu hóa logic mở vị trí DCA, tránh rủi ro mở vị trí tại thời điểm cố định.

  6. Thêm mô-đun quản lý vị trí để tối ưu kích thước vị trí.

  7. Thiết lập tham số tối ưu hóa để làm cho chiến lược phù hợp hơn với đặc điểm thống kê của thị trường.

  8. Tham gia logic chuyển đổi, cách chuyển đổi chiến lược trong các môi trường thị trường khác nhau.

Tóm tắt

Chiến lược này nói chung là một chiến lược đầu tư dài hạn sử dụng thời điểm phán đoán RSI, nhập vào theo từng đợt để có giá trị trung bình. Nó rất phù hợp với thị trường tiền kỹ thuật số hiện nay có biến động cao, có thể sử dụng hiệu quả các vùng xung đột để quản lý chi phí giữ.

Mã nguồn chiến lược
/*backtest
start: 2023-08-26 00:00:00
end: 2023-09-25 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=4
// © A3Sh

// RSI Strategy that buys the dips, works with Price Averaging and has a Dollar Cost Average option.
// When the price drops below specified percentages of the price (6 PA layers), new entries are openend to average the price of the assets.
// Open entries are closed by a specified take profit.
// Entries can be reopened, after closing and consequently crossing a PA layer again.
// The idea is to lower the average position price to a point that when the market rises, the current price crosses over the average position price.
// When the current price crosses the average position size and reaches the specified take profit, all entries are closed at once.
// In case the market drops significantly, there is an option to activate DCA to lower the average price further.

// RSI code adapted from the Optimized RSI Buy the Dips strategy, by Coinrule
// https://www.tradingview.com/script/Pm1WAtyI-Optimized-RSI-Strategy-Buy-The-Dips-by-Coinrule/
// Pyramiding entries code adapted from Pyramiding Entries on Early Trends startegy, by Coinrule
// https://www.tradingview.com/script/7NNJ0sXB-Pyramiding-Entries-On-Early-Trends-by-Coinrule/
// Plot entry layers code adapted from HOWTO Plot Entry Price by vitvlkv
// https://www.tradingview.com/script/bHTnipgY-HOWTO-Plot-Entry-Price/
// Buy every week code based on the following question in Stack Overflow
// https://stackoverflow.com/questions/59870411/in-pine-script-how-can-you-do-something-once-per-day-or-keep-track-if-somethin


strategy(title = "RSI+PA+DCA", pyramiding = 16, overlay = true, initial_capital = 400, default_qty_type = strategy.percent_of_equity, default_qty_value = 15, commission_type = strategy.commission.percent, commission_value = 0.075)

port = input(15, title = "Portfolio %", type = input.float, step = 0.1, minval = 0.1, maxval = 100)
q = (strategy.equity / 100 * port) / open

// Long position entry layers. Percentage from the entry price of the the first long
PositionInputs = input("++++", title = "+++++ Long Positions VA Layers +++++")

ps2 = input(2,  title = "2nd Long Entry %", step = 0.1)
ps3 = input(3,  title = "3rd Long Entry %", step = 0.1)
ps4 = input(5,  title = "4th Long Entry %", step = 0.1)
ps5 = input(10, title = "5th Long Entry %", step = 0.1)
ps6 = input(16, title = "6th Long Entry %", step = 0.1)


// Calculate Moving Averages
maInput = input("++++", title = "+++++ Moving Average Filter +++++")

plotMA = input(title = "Plot Moving Average", defval = false)
movingaverage_signal = sma(close, input(100))
plot (plotMA ? movingaverage_signal : na, color = color.white)

// RSI inputs and calculations
rsiInput = input( "++++", title = "+++++ RSI Inputs +++++" )

length =     input( 14 )
overSold =   input( 30, title = "oversold, entry trigger long position" )
overBought = input( 70, title = "overbought, has no specific function")
price = close
vrsi = rsi(price, length)

// Long trigger (co)
co = crossover(vrsi, overSold) and close < movingaverage_signal

// Take profit
takeprofit = input("++++", title = "+++++ Take Profit +++++")

ProfitTarget_Percent = input(5)


// Store values to create and plot the different DCA layers
long1 = valuewhen(co, close, 0)
long2 = valuewhen(co, close - (close / 100 * ps2), 0)
long3 = valuewhen(co, close - (close / 100 * ps3), 0)
long4 = valuewhen(co, close - (close / 100 * ps4), 0)
long5 = valuewhen(co, close - (close / 100 * ps5), 0)
long6 = valuewhen(co, close - (close / 100 * ps6), 0)

eps1 = 0.00
eps1 := na(eps1[1]) ? na : eps1[1]

eps2 = 0.00
eps2 := na(eps2[1]) ? na : eps2[1]

eps3 = 0.00
eps3 := na(eps3[1]) ? na : eps3[1]

eps4 = 0.00
eps4 := na(eps4[1]) ? na : eps4[1]

eps5 = 0.00
eps5 := na(eps5[1]) ? na : eps5[1]

eps6 = 0.00
eps6 := na(eps6[1]) ? na : eps6[1]

plot (strategy.position_size > 0 ? eps1 : na, title = "Long entry 1", style = plot.style_linebr)
plot (strategy.position_size > 0 ? eps2 : na, title = "Long entry 2", style = plot.style_linebr)
plot (strategy.position_size > 0 ? eps3 : na, title = "Long entry 3", style = plot.style_linebr)
plot (strategy.position_size > 0 ? eps4 : na, title = "Long entry 4", style = plot.style_linebr)
plot (strategy.position_size > 0 ? eps5 : na, title = "Long entry 5", style = plot.style_linebr)
plot (strategy.position_size > 0 ? eps6 : na, title = "Long entry 6", style = plot.style_linebr)


// Plot position average price
plot (strategy.position_avg_price, title = "Average price", style = plot.style_linebr, color = color.red, linewidth = 2)


// Take profit and exit all on take profit above position average price
tpv = strategy.position_avg_price + (strategy.position_avg_price / 100 * ProfitTarget_Percent)

tpl1 = close < tpv ? eps1 + close * (ProfitTarget_Percent / 100) : tpv
tpl2 = close < tpv ? eps2 + close * (ProfitTarget_Percent / 100) : tpv
tpl3 = close < tpv ? eps3 + close * (ProfitTarget_Percent / 100) : tpv
tpl4 = close < tpv ? eps4 + close * (ProfitTarget_Percent / 100) : tpv
tpl5 = close < tpv ? eps5 + close * (ProfitTarget_Percent / 100) : tpv
tpl6 = close < tpv ? eps6 + close * (ProfitTarget_Percent / 100) : tpv


// Open DCA order once at the start of the week
dcaWeek = input("++++", title = "+++++ Open DCA order once every week +++++")

newWeek = change(time("W"))
dcatime = input(title = "Buy a fixed amount every Monday", defval = false)
fixedAmount = input(40, title = "Fixed amount currency for DCA orders", step = 0.1)
dcaq = fixedAmount / open
plotchar (dcatime ? newWeek : na, "buy at Week start", "▼", location.top, size = size.tiny, color = color.white)
bgcolor (dcatime and newWeek ? color.white : na, transp = 50)

// Submit entry orders
if (co and strategy.opentrades == 0)
    eps1 := long1
    eps2 := long2
    eps3 := long3
    eps4 := long4
    eps5 := long5
    eps6 := long6

    strategy.entry("Long1", strategy.long, q)

if (strategy.opentrades == 1)
    strategy.entry("Long2", strategy.long, q, limit = eps2)

    
if (strategy.opentrades == 2)
    strategy.entry("Long3", strategy.long, q, limit = eps3)


if (strategy.opentrades == 3)
    strategy.entry("Long4", strategy.long, q, limit = eps4)


if (strategy.opentrades == 4)
    strategy.entry("Long5", strategy.long, q, limit = eps5)

    
if (strategy.opentrades == 5) 
    strategy.entry("Long6", strategy.long, q, limit = eps6)
    
// Submit Weekly DCA order, only when price is below position average price and when a position is open
if (dcatime and newWeek and strategy.position_size > 0 and close < strategy.position_avg_price) 
    strategy.entry("DCA", strategy.long, dcaq)


// Exit orders
if (strategy.position_size > 0)
    strategy.exit(id = "Exit 1", from_entry = "Long1", limit = tpl1)
    strategy.exit(id = "Exit 2", from_entry = "Long2", limit = tpl2)
    strategy.exit(id = "Exit 3", from_entry = "Long3", limit = tpl3)
    strategy.exit(id = "Exit 4", from_entry = "Long4", limit = tpl4)
    strategy.exit(id = "Exit 5", from_entry = "Long5", limit = tpl5)
    strategy.exit(id = "Exit 6", from_entry = "Long6", limit = tpl6)
    strategy.exit(id = "Exit DCA", from_entry = "DCA", limit = tpv)
 

// Make sure that all open limit orders are canceled after exiting all the positions 
longClose = strategy.position_size[1] > 0 and strategy.position_size == 0 ? 1 : 0   
if longClose
    strategy.cancel_all()