Chiến lược giao dịch RSI chậm

Tác giả:ChaoZhang, Ngày: 2023-10-07 15:38:56
Tags:

Tổng quan

Chiến lược giao dịch RSI trì hoãn sử dụng chỉ số RSI thông thường để xác định các điều kiện mua quá nhiều và bán quá nhiều, và trì hoãn nhập thị trường trong một khoảng thời gian nhất định sau khi tín hiệu xuất hiện để tránh tổn thất không cần thiết từ các vụ phá vỡ giả. Ý tưởng chính của chiến lược này là sử dụng chỉ số RSI để đánh giá các điều kiện thị trường mua quá nhiều và bán quá nhiều và đạt được thời gian nhập chính xác hơn bằng cách trì hoãn nhập dựa trên phán quyết này.

Chiến lược logic

Chiến lược này sử dụng chỉ số RSI 21 giai đoạn để xác định các điều kiện mua quá mức và bán quá mức. Khi chỉ số RSI vượt quá mức mua quá mức xác định bởi người dùng (thất định 60), thị trường được coi là mua quá mức. Khi chỉ số RSI vượt dưới mức bán quá mức xác định bởi người dùng (thất định 40), thị trường được coi là bán quá mức.

Sau khi xác định các tín hiệu mua quá mức hoặc bán quá mức, chiến lược không nhập thị trường ngay lập tức. Thay vào đó, nó bắt đầu đếm thời gian trì hoãn. Khi thời gian trì hoãn (bài 15 mặc định) được đáp ứng, nó đi ngắn dựa trên tín hiệu mua quá mức và dài dựa trên tín hiệu bán quá mức.

Chiến lược này cho phép người dùng điều chỉnh thời gian trì hoãn để đạt được thời gian nhập khác nhau. Thời gian trì hoãn lâu hơn có thể tránh nhiều sự đột phá giả, nhưng cũng có thể bỏ lỡ cơ hội nhập tốt hơn. Người dùng cần điều chỉnh tham số thời gian trì hoãn dựa trên các đặc điểm của các sản phẩm cụ thể.

Ngoài ra, chiến lược cũng thực hiện các tùy chọn như dừng lỗ, lấy lợi nhuận, giao dịch ngược, v.v. Người dùng có thể chọn dừng lỗ cố định, dừng lỗ sau, lấy lợi nhuận cố định và vân vân để quản lý các vị trí.

Ưu điểm

  1. Sử dụng chỉ số RSI để xác định chính xác các điều kiện mua quá mức / bán quá mức và nắm bắt các cơ hội đảo ngược.

  2. Việc xuất nhập muộn tránh mất mát từ các vụ phá vỡ giả mạo. Nhiều vụ phá vỡ không nhất thiết dẫn đến sự đảo ngược thực sự.

  3. Thời gian trì hoãn có thể điều chỉnh cho phép thời gian nhập chính xác. Người dùng có thể tối ưu hóa thời gian trì hoãn dựa trên các đặc điểm của sản phẩm để nhập tốt nhất.

  4. Thực hiện dừng lỗ và lấy lợi nhuận để kiểm soát rủi ro. Chiến lược cung cấp nhiều cách như cố định SL / TP, SL theo dõi vv để quản lý rủi ro.

  5. Tùy chọn giao dịch ngược thích nghi với các sản phẩm khác nhau. Người dùng có thể chọn logic bình thường hoặc ngược để phòng ngừa sự không chắc chắn.

Rủi ro

  1. Rủi ro của các tín hiệu giả từ RSI Các tín hiệu RSI có thể không phải lúc nào cũng chính xác và đôi khi có thể đưa ra các tín hiệu sai.

  2. Rủi ro bỏ lỡ cơ hội nếu quá chậm trễ. Thời gian chậm trễ quá mức có thể dẫn đến các điểm nhập cảnh bị bỏ lỡ.

  3. Tăng rủi ro mất mát từ giao dịch ngược. Mặc dù giao dịch ngược bảo hiểm sự không chắc chắn, nó cũng có thể khuếch đại tổng tổn thất.

  4. Rủi ro là SL sẽ bị đuổi theo quá gần và bị ngăn chặn sớm.

  5. Lợi nhuận không đủ do TP cố định không chính xác. TP cố định không thể đạt được lợi nhuận tối đa và cần dự báo hợp lý.

Để giải quyết những rủi ro này, các đề xuất tối ưu hóa là:

  1. lọc tín hiệu RSI với các chỉ số khác như KDJ, MACD vv để cải thiện độ tin cậy.

  2. Kiểm tra lại với dữ liệu lịch sử để tìm thời gian trì hoãn tối ưu cho mỗi sản phẩm.

  3. Sử dụng logic ngược lại một cách thận trọng, tốt nhất là kết hợp với xu hướng theo.

  4. Giữ đệm rộng cho SL để tránh giá quá gần.

  5. Kiểm tra các tỷ lệ TP khác nhau để tìm ra tối ưu.

Cơ hội tối ưu hóa

Chiến lược có thể được tối ưu hóa thêm trong các khía cạnh sau:

  1. Kết hợp nhiều chỉ số để lọc các tín hiệu nhập cảnh, ví dụ: KDJ, MACD với RSI để có các tín hiệu mạnh mẽ hơn.

  2. Điều chỉnh động thời gian trì hoãn dựa trên sự biến động của thị trường.

  3. Tối ưu hóa các chiến lược SL / TP, chẳng hạn như SL động, tỷ lệ thu hồi lợi nhuận SL, SL dựa trên thời gian v.v., làm cho chúng thích nghi tốt hơn với biến động thị trường.

  4. Kết hợp xu hướng. Đánh giá xem hướng đột phá có phù hợp với xu hướng chính hay không. Cũng điều chỉnh thời gian trì hoãn dựa trên động lực đột phá.

  5. Sử dụng máy học để tìm kết hợp tham số tối ưu. ML có thể tự động điều chỉnh các tham số dựa trên tập dữ liệu đào tạo và backtest lớn.

Tóm lại, chiến lược có nhiều chỗ để tối ưu hóa thông qua kết hợp chỉ số, điều chỉnh động các tham số, tích hợp xu hướng vv ML cũng là một hướng hứa hẹn cho tương lai.

Tóm lại

Chiến lược RSI trì hoãn nói chung sử dụng RSI để xác định các điều kiện mua quá mức / bán quá mức, và trì hoãn nhập vào trong một khoảng thời gian sau khi tín hiệu xảy ra để tránh tổn thất không cần thiết do giả mạo. Chiến lược có những lợi thế như xác định tín hiệu chính xác, nhập chậm để tránh phá vỡ sai, thời gian trì hoãn có thể điều chỉnh, thực hiện SL / TP v.v. Nhưng các rủi ro như tín hiệu RSI không đáng tin cậy, cơ hội bị bỏ lỡ từ sự chậm trễ quá mức tồn tại. Những điều này có thể được cải thiện hơn nữa thông qua tối ưu hóa độ chính xác tín hiệu thông qua kết hợp chỉ số, điều chỉnh thời gian trì hoãn động, các chiến lược SL / TP tốt hơn v.v. Chiến lược có cơ hội tối ưu hóa rộng và đáng để khám phá.


/*backtest
start: 2023-01-01 00:00:00
end: 2023-10-06 00:00:00
period: 1d
basePeriod: 1h
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/
// © tweakerID and © BacktestRookies

// This strategy uses a 21 period RSI with an overbought (RSI indicator 
// is greater than) level of 60 (user defined) to determines long entries and an oversold 
// (RSI indicator is less than) level of 40 (user defined) for shorts. It introduces a bar delay that starts
// counting when the RSI < Oversold or RSI > Overbought conditions are true, delaying the entry with 
// the amount of bars determined by the user. The trading logic can be reversed, which seems to work better.

//@version=4
strategy("Delayed RSI Strategy", 
     overlay=false, 
     default_qty_type=strategy.percent_of_equity, 
     default_qty_value=100, 
     initial_capital=10000, 
     commission_value=0.04, 
     calc_on_every_tick=false, 
     slippage=0)
     
direction = input(0, title = "Strategy Direction", type=input.integer, minval=-1, maxval=1)
strategy.risk.allow_entry_in(direction == 0 ? strategy.direction.all : 
 (direction < 0 ? strategy.direction.short : strategy.direction.long))

// Bought and Sold Boolean Signal
bought = strategy.position_size > strategy.position_size[1] 
 or strategy.position_size < strategy.position_size[1]

/////////////////////// STRATEGY INPUTS ////////////////////////////////////////
title1=input(true, "-----------------Strategy Inputs-------------------")  

rsiLen=input(21, title="RSI Length")
i_OB = input(60, title="Overbought")
i_OS = input(40, title="Oversold")
i_delay = input(15, title="Entry Delay (# of Bars)")
i_Close= input(false, title="Use Strategy Close")

/////////////////////// BACKTESTER /////////////////////////////////////////////
title2=input(true, "-----------------General Inputs-------------------")  

// Backtester General Inputs
i_SL=input(true, title="Use Stop Loss and Take Profit")
TS=input(false, title="Use Trailing Stop")
i_SLType=input(defval="ATR Stop", title="Type Of Stop", options=["Strategy Stop", "Swing Lo/Hi", "ATR Stop"])
i_SPL=input(defval=10, title="Swing Point Lookback")
i_PercIncrement=input(defval=3, step=.1, title="Swing Point SL Perc Increment")*0.01
i_ATR = input(14, title="ATR Length")
i_ATRMult = input(3, step=.1, title="ATR Multiple")
i_TPRRR = input(2, step=.1, title="Take Profit Risk Reward Ratio")
DPR=input(false, "Allow Direct Position Reverse")
reverse=input(true, "Reverse Trades")

// Swing Points Stop and Take Profit
SwingStopProfit() =>
    LL=(lowest(i_SPL))*(1-i_PercIncrement)
    HH=(highest(i_SPL))*(1+i_PercIncrement)
    LL_price = valuewhen(bought, LL, 0)
    HH_price = valuewhen(bought, HH, 0)
    entry_LL_price = strategy.position_size > 0 ? LL_price : na 
    entry_HH_price = strategy.position_size < 0 ? HH_price : na 
    tp=strategy.position_avg_price + (strategy.position_avg_price - entry_LL_price)*i_TPRRR
    stp=strategy.position_avg_price - (entry_HH_price - strategy.position_avg_price)*i_TPRRR
    [entry_LL_price, entry_HH_price, tp, stp]

// ATR Stop
ATRStop() =>
    ATR=atr(i_ATR)*i_ATRMult
    ATRLong = ohlc4 - ATR
    ATRShort = ohlc4 + ATR
    ATRLongStop = valuewhen(bought, ATRLong, 0)
    ATRShortStop = valuewhen(bought, ATRShort, 0)
    LongSL_ATR_price = strategy.position_size > 0 ? ATRLongStop : na 
    ShortSL_ATR_price = strategy.position_size < 0 ? ATRShortStop : na 
    ATRtp=strategy.position_avg_price + (strategy.position_avg_price - LongSL_ATR_price)*i_TPRRR
    ATRstp=strategy.position_avg_price - (ShortSL_ATR_price - strategy.position_avg_price)*i_TPRRR
    [LongSL_ATR_price, ShortSL_ATR_price, ATRtp, ATRstp]
    
// Strategy Stop
StrategyStop(bought) =>
    float LongStop = na
    float ShortStop = na
    float StratTP = na
    float StratSTP = na
    [LongStop, ShortStop, StratTP, StratSTP]

//TrailingStop
TrailingStop(SL,SSL) =>
    dif=(valuewhen(strategy.position_size>0 and strategy.position_size[1]<=0, high,0))
     -strategy.position_avg_price
    trailOffset     = strategy.position_avg_price - SL
    var tstop = float(na)
    if strategy.position_size > 0
        tstop := high- trailOffset - dif
        if tstop<tstop[1]
            tstop:=tstop[1]
    else
        tstop := na
    StrailOffset     = SSL - strategy.position_avg_price
    var Ststop = float(na)
    Sdif=strategy.position_avg_price-(valuewhen(strategy.position_size<0 
     and strategy.position_size[1]>=0, low,0))
    if strategy.position_size < 0
        Ststop := low+ StrailOffset + Sdif
        if Ststop>Ststop[1]
            Ststop:=Ststop[1]
    else
        Ststop := na
    [tstop, Ststop]
  
//Stop Loss & Take Profit Switches  
SLTPLogic(LongStop, ShortStop, StratTP, StratSTP, LongSL_ATR_price, ShortSL_ATR_price, ATRtp, ATRstp,
 entry_LL_price, entry_HH_price, tp, stp) =>
    SL= i_SLType == "Swing Lo/Hi" ? entry_LL_price : i_SLType == "ATR Stop" ? LongSL_ATR_price : LongStop
    SSL= i_SLType == "Swing Lo/Hi" ? entry_HH_price : i_SLType == "ATR Stop" ? ShortSL_ATR_price : ShortStop
    TP= i_SLType == "Swing Lo/Hi" ? tp : i_SLType == "ATR Stop" ? ATRtp : StratTP
    STP= i_SLType == "Swing Lo/Hi" ? stp : i_SLType == "ATR Stop" ? ATRstp : StratSTP
    [SL, SSL, TP, STP]


/////////////////////// STRATEGY LOGIC /////////////////////////////////////////

rsi = rsi(close, rsiLen)
isOB= rsi > i_OB
isOS= rsi < i_OS
BarsSinceOB = barssince(not isOB)
BarsSinceOS = barssince(not isOS)

BUY = BarsSinceOS == i_delay
SELL = BarsSinceOB == i_delay

/////////////////////// FUNCTION CALLS /////////////////////////////////////////

// Stops and Profits
[entry_LL_price, entry_HH_price, tp, stp] = SwingStopProfit()
[LongSL_ATR_price, ShortSL_ATR_price, ATRtp, ATRstp] = ATRStop()
[LongStop, ShortStop, StratTP, StratSTP] = StrategyStop(bought)
[SL, SSL, TP, STP] = SLTPLogic(LongStop, ShortStop, StratTP, StratSTP, 
 LongSL_ATR_price, ShortSL_ATR_price, ATRtp, ATRstp, entry_LL_price, entry_HH_price, tp, stp)
[tstop, Ststop] = TrailingStop(SL,SSL)

// Entries
if reverse
    if not DPR
        strategy.entry("long", strategy.long, when=SELL and strategy.position_size == 0)
        strategy.entry("short", strategy.short, when=BUY and strategy.position_size == 0)
    else     
        strategy.entry("long", strategy.long, when=SELL)
        strategy.entry("short", strategy.short, when=BUY)
else
    if not DPR 
        strategy.entry("long", strategy.long, when=BUY and strategy.position_size == 0)
        strategy.entry("short", strategy.short, when=SELL and strategy.position_size == 0)
    else
        strategy.entry("long", strategy.long, when=BUY)
        strategy.entry("short", strategy.short, when=SELL)
// Exits
if i_SL
    strategy.exit("TP & SL", "long", limit=TP, stop=TS? tstop : SL)
    strategy.exit("TP & SL", "short", limit=STP, stop=TS? Ststop : SSL)
    
if i_Close
    strategy.close_all(when=cross(rsi, 50))

/////////////////////// PLOTS //////////////////////////////////////////////////

//Plots
rsiplot = plot(rsi, "RSI", color=#7E57C2)
band1 = hline(i_OB, "Upper Band", color=#787B86)
bandm = hline(50, "Middle Band", color=color.new(#787B86, 50))
band0 = hline(i_OS, "Lower Band", color=#787B86)
fill(band1, band0, color=color.rgb(126, 87, 194, 90), title="Background")
plot(rsi, "RSI", color=#7E57C2)
// OSOBCount = plot(isOB ? BarsSinceOB : isOS ? BarsSinceOS : na, transp=100)
// OSOBColor = color.from_gradient(isOB ? BarsSinceOB : BarsSinceOS, 0, 20, color.black, isOB ? color.red : isOS ? color.green : na)
// OBP = plot(rsi > i_OB ? rsi : na, color=color.white, display=display.none)
// fill(plot(i_OB, display=display.none), OBP, color=OSOBColor, transp=0, fillgaps=false)
// OSP = plot(rsi < i_OS ? rsi : na, color=color.white, display=display.none)
// fill(plot(i_OS, display=display.none), OSP, color=OSOBColor, transp=0, fillgaps=false)

// plotshape(BUY ? 1 : na, style=shape.arrowdown, location=location.bottom, 
//  color=color.green, title="Bullish Setup", size=size.normal)
// plotshape(SELL ? 1 : na, style=shape.arrowup, location=location.top, 
//  color=color.red, title="Bearish Setup", size=size.normal)



Thêm nữa