Chiến lược giao dịch xu hướng khối lượng RSI YinYang

Tác giả:ChaoZhang, Ngày: 2023-12-22 14:29:05
Tags:

img

Tổng quan

Chiến lược này là một chiến lược theo xu hướng sử dụng sự kết hợp của chỉ số sức mạnh tương đối (RSI) và khối lượng để xác định hướng xu hướng và theo xu hướng.

  1. Sử dụng Trung bình Di chuyển Lượng Đặt cân để tính đường trung và kết hợp thông tin khối lượng để xác định điểm trung của xu hướng
  2. Thiết lập vùng mua và bán dựa trên đường giữa
  3. Sử dụng thông tin RSI để điều chỉnh phạm vi bán và mua
  4. Đặt lệnh dừng lỗ và lấy lợi nhuận sau khi vào vùng mua/bán
  5. Có cơ chế nhập lại

Chiến lược logic

Chiến lược này sử dụng các chỉ số và tham số sau:

  • Midline: Volume Weighted Moving Average của giá cao nhất và giá thấp nhất trong các giai đoạn nhất định để xác định điểm trung tâm của xu hướng
  • RSI: Chỉ số sức mạnh tương đối được tính trên một số khoảng thời gian nhất định, chuyển đổi thành phạm vi 0-1.
  • Mua khu vực: Midline cộng với số tiền điều chỉnh RSI ở tỷ lệ nhất định, bước dài khi giá nhập
  • Khu vực bán: Midline trừ số tiền điều chỉnh RSI ở tỷ lệ nhất định, nhập ngắn khi giá nhập
  • Đường lợi nhuận: Đường trung gian
  • Đường dừng lỗ: Một tỷ lệ phần trăm nhất định bên dưới vùng mua / trên vùng bán

Khi giá vào vùng mua hoặc bán, một lệnh hướng tương ứng sẽ được mở. Các đường dừng lỗ và lấy lợi nhuận sau đó được thiết lập. Khi lấy lợi nhuận hoặc dừng lỗ được kích hoạt, vị trí sẽ được đóng. Một cơ chế tái nhập cũng được thiết lập để các lệnh mới có thể được mở khi tín hiệu kích hoạt lại nếu được cấu hình.

Ưu điểm

Những lợi thế của chiến lược này bao gồm:

  1. Sử dụng cả RSI và khối lượng để xác định xu hướng, cải thiện độ chính xác
  2. Điều chỉnh theo tham số RSI làm cho vùng mua / bán thích nghi tốt hơn với xu hướng thực tế
  3. Thông tin khối lượng gán trọng lượng cao hơn cho các hành động giá, làm cho đường trung gian chính xác hơn
  4. Có cơ chế dừng lỗ để kiểm soát rủi ro
  5. Cho phép tái nhập cảnh, giảm rủi ro của các vụ trốn thoát giả

Rủi ro

Ngoài ra còn có một số rủi ro:

  1. Các thông số RSI và khối lượng không chính xác có thể ảnh hưởng đến độ chính xác vùng mua/bán
  2. Midline có thể không xác định chính xác xu hướng, gây ra sự phá vỡ sai
  3. Stop loss quá rộng có thể dẫn đến tổn thất cao hơn
  4. Thêm vào có thể gây ra giao dịch quá mức

Giải pháp:

  1. Điều chỉnh RSI và chu kỳ khối lượng để phù hợp với điều kiện thị trường
  2. Sử dụng các chỉ số khác để xác minh tín hiệu mua/bán
  3. Cắt chặt lệnh dừng lỗ để hạn chế lỗ
  4. Giới hạn giao dịch mỗi ngày để ngăn chặn giao dịch quá mức

Tối ưu hóa

Chiến lược này có thể được tối ưu hóa bằng cách:

  1. Thử các chỉ số khác để xác minh tín hiệu ví dụ: nến, chỉ số biến động vv
  2. Thêm các cơ chế định kích thước vị trí, ví dụ như người chiến thắng kim tự tháp
  3. Sử dụng thuật toán học máy để cải thiện độ chính xác vùng mua / bán
  4. Đánh giá các thông số tối ưu cho dừng lỗ và lấy lợi nhuận
  5. Các thông số cần thử nghiệm và tối ưu hóa riêng biệt cho các sản phẩm khác nhau

Kết luận

Kết luận, đây là một chiến lược theo xu hướng định lượng sử dụng chỉ số RSI và khối lượng. Nó có hệ thống xác minh kép để xác định tín hiệu, dừng lỗ / lợi nhuận để kiểm soát rủi ro và cơ chế tái nhập để cải thiện lợi nhuận. Với điều chỉnh tham số và tối ưu hóa thuật toán, nó có thể trở thành một chiến lược giao dịch xu hướng rất thực tế.


/*backtest
start: 2023-11-21 00:00:00
end: 2023-12-21 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/
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@    ,@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@      @@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@        @@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@         @@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@           @@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@        .@@@@@@@@@@@@@@@            @@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@          *@@@@@@@@@@@@@@             @@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@         @@@@@@@@@@@@@@@               @@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@     @@@@@@@@@@@@@@@@                 @@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                  @@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.                    @@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                      @@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.                         @
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                             @
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@,                                       @
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                                                @
// @@@@@@@@@@@@@@@@@@@@@@@@@@@                                                    @
// @@@@@@@@@@@@@@@@@@@@@@@@@                                                     @@
// @@@@@@@@@@@@@@@@@@@@@@@                                                       @@
// @@@@@@@@@@@@@@@@@@@@@@                                                       @@@
// @@@@@@@@@@@@@@@@@@@@@*                @@@@@                                 @@@@
// @@@@@@@@@@@@@@@@@@@@@               @@@@@@@@@                              @@@@@
// @@@@@@@@@@@@@@@@@@@@@              @@@@@@@@@@@                           @@@@@@@
// @@@@@@@@@@@@@@@@@@@@@               @@@@@@@@%                           @@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@                                                @@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@                                            @@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@                                        %@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@                                   @@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@                           @@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@                @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// © YinYangAlgorithms

//@version=5
strategy("YinYang RSI Volume Trend Strategy", shorttitle="YinYang RSVT Strategy", overlay=true )
// ~~~~~~~~~~~ INPUTS ~~~~~~~~~~~ //
len = input.int(80, "Trend Length:", tooltip="How far back should we span this indicator?\nThis length effects all lengths of the indicator")
purchaseSrc = input.source(close, "Purchase Source (Long and Short):", tooltip="What source needs to exit the purchase zone for a purchase to happen?")
exitSrc = input.source(close, "Exit Source (Long and Short):", tooltip="What source needs to hit a exit condition to stop the trade (Take profit, Stop Loss or hitting the other sides Purchase Zone)?")
useTakeProfit = input.bool(true, "Use Take Profit", tooltip="Should we take profit IF we cross the basis line and then cross it AGAIN?")
useStopLoss = input.bool(true, "Use Stop Loss", tooltip="Stop loss will ensure you don't lose too much if its a bad call")
stopLossMult = input.float(0.1, "Stoploss Multiplier %:", tooltip="How far from the purchase lines should the stop loss be")
resetCondition = input.string("Entry", "Reset Purchase Availability After:", options=["Entry", "Stop Loss", "None"],
 tooltip="If we reset after a condition is hit, this means we can purchase again when the purchase condition is met. \n" +
 "Otherwise, we will only purchase after an opposite signal has appeared.\n" +
 "Entry: means when the close enters the purchase zone (buy or sell).\n" +
 "Stop Loss: means when the close hits the stop loss location (even when were out of a trade)\n" +
 "This allows us to get more trades and also if our stop loss initally was hit but it WAS a good time to purchase, we don't lose that chance.")

// ~~~~~~~~~~~ VARIABLES ~~~~~~~~~~~ //
var bool longStart = na
var bool longAvailable = na
var bool longTakeProfitAvailable = na
var bool longStopLoss = na
var bool shortStart = na
var bool shortAvailable = na
var bool shortTakeProfitAvailable = na
var bool shortStopLoss = na

resetAfterStopLoss = resetCondition == "Stop Loss"
resetAfterEntry = resetCondition == "Entry"

// ~~~~~~~~~~~ CALCULATIONS ~~~~~~~~~~~ //
// Mid Line
midHigh = ta.vwma(ta.highest(high, len), len)
midLow = ta.vwma(ta.lowest(low, len), len)
mid = math.avg(midHigh, midLow)
midSmoothed = ta.ema(mid, len)

//Volume Filtered
avgVol = ta.vwma(volume, len)
volDiff = volume / avgVol
midVolSmoothed = ta.vwma(midSmoothed * volDiff, 3)

//RSI Filtered
midDifference = ta.sma(midHigh - midLow, len)
midRSI = ta.rsi(midVolSmoothed, len) * 0.01
midAdd = midRSI * midDifference

//Calculate Zones
purchaseZoneHigh = midSmoothed + midAdd
purchaseZoneLow = midSmoothed - midAdd
purchaseZoneBasis = math.avg(purchaseZoneHigh, purchaseZoneLow)

//Create Stop Loss Locations
stopLossHigh = purchaseZoneHigh * (1 + (stopLossMult * 0.01))
stopLossLow = purchaseZoneLow * (1 - (stopLossMult * 0.01))

// ~~~~~~~~~~~ PURCHASE CALCULATIONS ~~~~~~~~~~~ //
//Long
longEntry = ta.crossunder(purchaseSrc, purchaseZoneLow)
longStart := ta.crossover(purchaseSrc, purchaseZoneLow) and longAvailable
longAvailable := ta.crossunder(purchaseSrc, purchaseZoneHigh) or (resetAfterStopLoss and longStopLoss) or (resetAfterEntry and longEntry) ? true : longStart ? false : longAvailable[1]
longEnd = ta.crossover(exitSrc, purchaseZoneHigh)
longStopLoss := ta.crossunder(exitSrc, stopLossLow)
longTakeProfitAvailable := ta.crossover(exitSrc, purchaseZoneBasis) ? true : longEnd ? false : longTakeProfitAvailable[1]
longTakeProfit = ta.crossunder(exitSrc, purchaseZoneBasis) and longTakeProfitAvailable

//Short
shortEntry = ta.crossover(purchaseSrc, purchaseZoneHigh)
shortStart := ta.crossunder(purchaseSrc, purchaseZoneHigh) and shortAvailable
shortAvailable := ta.crossover(purchaseSrc, purchaseZoneLow) or (resetAfterStopLoss and shortStopLoss) or (resetAfterEntry and shortEntry)? true : shortStart ? false : shortAvailable[1]
shortEnd = ta.crossunder(exitSrc, purchaseZoneLow)
shortStopLoss := ta.crossover(exitSrc, stopLossHigh)
shortTakeProfitAvailable := ta.crossunder(exitSrc, purchaseZoneBasis) ? true : shortEnd ? false : shortTakeProfitAvailable[1]
shortTakeProfit = ta.crossover(exitSrc, purchaseZoneBasis) and shortTakeProfitAvailable

// ~~~~~~~~~~~ PLOTS ~~~~~~~~~~~ //
shortLine = plot(purchaseZoneHigh, color=color.green)
shortStopLossLine = plot(stopLossHigh, color=color.green) //color=color.rgb(0, 97, 3)
fill(shortLine, shortStopLossLine, color = color.new(color.green, 90))
plot(purchaseZoneBasis, color=color.white)
longLine = plot(purchaseZoneLow, color=color.red)
longStopLossLine = plot(stopLossLow, color=color.red) //color=color.rgb(105, 0, 0)
fill(longLine, longStopLossLine, color=color.new(color.red, 90))

// ~~~~~~~~~~~ STRATEGY ~~~~~~~~~~~ //
if (longStart)
    strategy.entry("buy", strategy.long)
else if (longEnd or (useStopLoss and longStopLoss) or (useTakeProfit and longTakeProfit))
    strategy.close("buy")

if (shortStart)
    strategy.entry("sell", strategy.short)
else if (shortEnd or (useStopLoss and shortStopLoss) or (useTakeProfit and shortTakeProfit))
    strategy.close("sell")

// ~~~~~~~~~~~ ALERTS ~~~~~~~~~~~ //
if longStart or (longEnd or (useStopLoss and longStopLoss) or (useTakeProfit and longTakeProfit)) or shortStart or (shortEnd or (useStopLoss and shortStopLoss) or (useTakeProfit and shortTakeProfit))
    alert("{{strategy.order.action}} | {{ticker}} | {{close}}", alert.freq_once_per_bar)

Thêm nữa