지연된 RSI 거래 전략

저자:차오장, 날짜: 2023-10-07 15:38:56
태그:

전반적인 설명

지연된 RSI 거래 전략은 기존의 RSI 지표를 사용하여 과잉 구매 및 과잉 판매 조건을 식별하고 신호가 표시된 후 특정 기간 동안 시장 진출을 지연하여 가짜 브레이크오웃으로 인한 불필요한 손실을 피합니다. 이 전략의 주요 아이디어는 RSI 지표를 사용하여 과잉 구매 및 과잉 판매 시장 조건을 판단하고이 판단에 따라 진입을 지연함으로써 보다 정확한 입시 시기를 달성하는 것입니다.

전략 논리

이 전략은 과반 구매 및 과반 판매 조건을 결정하기 위해 21 기간 RSI 지표를 사용합니다. RSI 지표가 사용자 정의 과반 구매 수준 (디폴트 60) 을 넘을 때 시장은 과반 구매로 간주됩니다. RSI가 사용자 정의 과반 판매 수준 (디폴트 40) 을 넘을 때 시장은 과반 판매로 간주됩니다.

과잉 구매 또는 과잉 판매 신호를 식별 한 후 전략은 즉시 시장에 진입하지 않습니다. 대신 지연 기간을 계산하기 시작합니다. 지연 기간 (예정 15 바) 이 충족되면 과잉 구매 신호를 기반으로 단위로, 과잉 판매 신호를 기반으로 길게 진입합니다.

이 전략은 사용자가 다른 입시 시기를 달성하기 위해 지연 기간을 조정할 수 있습니다. 더 긴 지연 기간은 더 많은 가짜 브레이크아웃을 피할 수 있지만 더 나은 입시 기회를 놓칠 수도 있습니다. 사용자는 특정 제품의 특성에 따라 지연 기간 매개 변수를 조정해야합니다.

또한, 전략은 또한 중지 손실, 이익 취득, 역 거래, 등과 같은 옵션을 구현합니다. 사용자는 고정 중지 손실, 후속 중지 손실, 고정 취득 등을 선택하여 포지션을 관리 할 수 있습니다. 거래 논리 또한 역으로 전환 될 수 있습니다. 즉 과잉 구매 신호에 길고 과잉 판매 신호에 짧습니다.

장점

  1. RSI 인디케이터를 활용하여 과잉 구매 / 과잉 판매 조건을 정확하게 파악하고 반전 기회를 잡습니다. RSI는 반전을 식별하는 데 널리 사용되는 성숙한 오시레이터입니다.

  2. 지연된 진입은 가짜 브레이크업의 손실을 피합니다. 많은 브레이크업은 반드시 실제 반전으로 이어지지 않습니다. 지연된 진입은 유효성을 확인합니다.

  3. 조정 가능한 지연 기간은 정확한 입시 시간을 허용합니다. 사용자는 최상의 입시를 위해 제품 특성에 따라 지연 기간을 최적화 할 수 있습니다.

  4. 위험을 통제하기 위해 손해를 멈추고 이익을 취하십시오. 전략은 고정 SL / TP, SL를 추적하는 등 위험을 관리하는 여러 가지 방법을 제공합니다.

  5. 리버스 거래 옵션은 다른 제품에 적응합니다. 사용자는 불확실성을 헤지하기 위해 정상 또는 리버스 로직을 선택할 수 있습니다.

위험성

  1. RSI의 가짜 신호의 위험 RSI 신호는 항상 정확하지 않을 수 있으며 때로는 잘못된 신호를 줄 수 있습니다.

  2. 지연이 너무 길면 기회를 놓칠 위험이 있습니다. 과도한 지연 기간은 출입 지점을 놓칠 수 있습니다.

  3. 리버스 트레이딩으로 인한 손실 위험이 증가합니다. 리버스 트레이딩은 불확실성을 헤지하지만 전체 손실을 증폭시킬 수도 있습니다.

  4. SL가 너무 가까이 다가와서 조기에 멈출 위험이 있습니다.

  5. 부적절한 고정 TP로 인한 적당한 이익 고정 TP는 최대 수익을 달성 할 수 없으며 합리적인 예측이 필요합니다.

이러한 위험을 해결하기 위해 최적화 제안은 다음과 같습니다.

  1. 신뢰성을 높이기 위해 KDJ, MACD 등과 같은 다른 지표로 RSI 신호를 필터하십시오.

  2. 과거 데이터로 백테스트하여 각 제품에 최적의 지연 기간을 찾습니다. 하나의 크기가 모든 것에 맞지 않습니다.

  3. 리버스 논리를 조심스럽게 사용하세요. 추세를 따르는 것과 결합하는 것이 좋습니다.

  4. SL를 뒤쳐서 가격이 너무 가까워지는 것을 피하기 위해 넓은 버퍼를 유지하십시오.

  5. 다양한 TP 비율을 테스트하여 최적을 찾습니다. 또한 동적 수익을 고려하십시오.

최적화 기회

이 전략은 다음 측면에서 더 이상 최적화 될 수 있습니다.

  1. 입시 신호를 필터링하기 위해 여러 지표를 결합하십시오. 예를 들어, KDJ, MACD와 RSI를 더 강력한 신호를 위해 결합하십시오.

  2. 시장의 변동성에 따라 지연 기간을 동적으로 조정합니다. 이것은 입력 정확성을 향상시키는 동시에 잘못된 브레이크오웃을 피합니다.

  3. SL/TP 전략을 최적화합니다. 예를 들어 동적 SL, 이익 재조정 비율 SL, 시간 기반 SL 등, 시장 변동에 더 잘 적응하도록 합니다.

  4. 트렌드를 포함합니다. 브레이크오웃 방향이 주요 트렌드와 일치하는지 측정합니다. 또한 브레이크오웃 모멘텀에 따라 지연 기간을 조정합니다.

  5. 기계 학습을 사용하여 최적의 매개 변수 조합을 찾을 수 있습니다. ML은 대규모 훈련 및 백테스트 데이터 세트를 기반으로 매개 변수를 자동 조정할 수 있습니다.

결론적으로, 전략은 지표 조합, 매개 변수 동적 조정, 트렌드 통합 등을 통해 최적화 할 수있는 충분한 공간이 있습니다. ML 또한 앞으로 나아가는 유망한 방향입니다.

요약

지연된 RSI 전략은 전반적으로 RSI를 이용하여 과잉 구매/ 과잉 판매 조건을 파악하고, 신호가 발생한 후 신호의 진입을 지연시켜 가짜아웃으로 인한 불필요한 손실을 피합니다. 이 전략은 정확한 신호 식별, 잘못된 브레이크를 피하기 위해 지연된 진입, 조정 가능한 지연 기간, SL/TP 구현 등과 같은 장점을 가지고 있습니다. 그러나 신뢰할 수없는 RSI 신호, 과도한 지연으로 인한 놓친 기회와 같은 위험이 있습니다. 이러한 것들은 지표 컴보, 동적 지연 기간 조정, 더 나은 SL/TP 전략 등을 통해 신호 정확성을 최적화함으로써 더 향상될 수 있습니다. 이 전략은 광범위한 최적화 기회를 가지고 있으며 탐구할 가치가 있습니다.


/*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)



더 많은