Chiến lược này xác định các cơ hội bán quá mức bằng cách sử dụng chỉ số RSI và nắm giữ các vị trí theo lô khi giá giảm để giảm dần cơ sở chi phí và đạt được lợi nhuận dài hạn.
Chiến lược đầu tiên tính toán chỉ số RSI để xác định xem thị trường có bị bán quá mức hay không. Khi chỉ số RSI dưới 30, nó báo hiệu cơ hội bán quá mức. Trong trường hợp này, nếu giá dưới đường trung bình động 100 giai đoạn, một vị trí dài sẽ được mở.
Sau khi mở vị trí, chiến lược thiết lập 6 mức giá đảo ngược trung bình ở mức 98%, 97%, 95%, 90%, 84% và 70% của giá hiện tại. Khi giá đạt mức này, sẽ có thêm các vị trí. Bằng cách trung bình liên tục xuống, cơ sở chi phí của vị trí có thể được giảm.
Ngoài ra, giá trung bình của vị trí được tính toán. Lợi nhuận bắt đầu khi giá tăng hơn 5% so với giá trung bình. Ngoài ra, nếu giá tiếp tục tăng trên giá lợi nhuận 5% của giá trung bình, tất cả các vị trí sẽ được đóng.
Cuối cùng, một cơ chế DCA được đưa vào chiến lược. Mỗi thứ Hai, nếu có các vị trí mở và giá thấp hơn giá trung bình, một số tiền cố định sẽ được thêm vào vị trí. Điều này làm giảm thêm cơ sở chi phí.
Lợi thế lớn nhất của chiến lược này là việc sử dụng cơ chế trung bình xuống và cơ chế DCA để kiểm soát rủi ro.
Lấy các vị trí theo lô đa dạng hóa rủi ro mở và tránh bỏ lỡ điểm thấp nhất.
Việc thiết lập nhiều mức giá đảo ngược trung bình giảm dần cơ sở chi phí và quản lý rủi ro giảm.
Tính toán giá vị trí trung bình cho phép lấy lợi nhuận kịp thời và khóa lợi nhuận khi ở màu xanh lá cây.
Áp dụng DCA làm giảm thêm cơ sở chi phí và kiểm soát rủi ro.
Sử dụng chỉ số RSI ngăn chặn việc mở các vị trí ở đỉnh.
Bộ lọc trung bình động tránh các giao dịch đảo ngược.
Chiến lược này cũng có một số rủi ro:
Chiến lược không thể xác định các điểm đảo ngược thị trường.
Không có cơ chế dừng lỗ để kiểm soát hiệu quả lỗ giao dịch duy nhất.
Không có giới hạn về số lượng các vị trí, có thể dẫn đến sự gia tăng đột ngột nếu thị trường sụp đổ mạnh mẽ.
DCA mang rủi ro thời gian và không đảm bảo mở các vị trí ở điểm thấp nhất.
Các giải pháp có thể:
Kết hợp các chỉ số khác để đánh giá cấu trúc thị trường thay vì chỉ dựa vào RSI.
Thêm stop loss di chuyển hoặc giảm dần.
Hạn chế số lượng bổ sung vị trí.
Tối ưu hóa logic nhập DCA cho một cơ chế ổn định hơn.
Chiến lược có thể được cải thiện theo những cách sau:
Tối ưu hóa thuật toán đảo ngược trung bình cho một cách tiếp cận khoa học hơn.
Cải thiện các cơ chế thu lợi nhuận, chẳng hạn như dừng lại hoặc thu lợi nhuận nhiều lớp.
Thêm stop loss để kiểm soát rủi ro giao dịch duy nhất tốt hơn.
Bao gồm các chỉ số khác để phân tích cấu trúc thị trường thay vì chỉ RSI.
Tối ưu hóa logic DCA để tránh rủi ro nhập vào thời gian cố định.
Thêm kích thước vị trí để tối ưu hóa tổng kích thước vị trí.
Tối ưu hóa các thông số để phù hợp với các đặc điểm thống kê thị trường.
Thêm logic chuyển đổi để thích nghi với các chế độ thị trường khác nhau.
Tóm lại, đây là một chiến lược đầu tư dài hạn sử dụng chỉ số RSI cho thời gian và trung bình xuống với nhiều mục nhập để có cơ sở chi phí thấp hơn. Nó rất phù hợp với thị trường tiền điện tử biến động hiện tại để quản lý chi phí vị trí trong các khoảng thời gian khác nhau.
/*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()