RSI 및 OTT 대역 전략 분석

저자:차오장, 날짜: 2023-10-09 16:21:20
태그:

전반적인 설명

이 전략은 RSI_OTT-TP/SL라고 불린다. 트렌드 다음 전략에 속하는 거래 신호를 결정하기 위해 RSI 지표와 OTT 대역을 결합한다. 이 전략은 RSI 지표를 통해 시장 트렌드 방향을 판단하고 특정 입구점을 찾기 위해 OTT 대역을 사용합니다. 또한 사용자가 수익을 확보하거나 손실을 자동으로 피하기 위해 수익을 취하고 손실을 중지 할 비율을 설정할 수 있습니다.

전략 논리

  1. 이 전략은 트렌드 및 입점 지점을 결정하기 위해 RSI와 OTT 지표를 사용합니다.

  2. RSI는 전반적인 트렌드 방향을 판단하는 데 사용됩니다. RSI는 시장이 과소매 또는 과소매인지 알 수 있습니다. RSI가 과소매 수준을 넘어서면 구매 신호이며 과소매 수준을 넘어서면 판매 신호입니다. 기본 RSI 길이는 6, 과소매 수준은 50이며 과소매 수준도 50입니다.

  3. OTT 대역은 입구 지점을 발견하는 데 사용됩니다. 그들은 변동성 변화율 (VAR) 표시를 기반으로 형성된 대역입니다. 가격이 하위 대역을 상향으로 돌파하면 구매 신호입니다. 가격이 상위 대역을 아래로 돌파하면 판매 신호입니다.

  4. 트렌드를 결정하고 엔트리 포인트를 확인한 후, 이 전략은 가격이 OTT 대역을 넘을 때 긴 또는 짧은 포지션을 열 것입니다.

  5. 이윤을 취하고 손실을 멈추는 것은 사용자가 사용자 지정 할 수있는 입력 상자를 통해 설정 할 수 있습니다. 이 전략은 수익을 취하거나 손실을 멈추는 가격에 닿을 때 자동으로 포지션을 닫습니다.

  6. 이 전략은 또한 단지 긴, 짧은 또는 두 방향 거래를 허용합니다.

장점

  1. RSI와 OTT 밴드를 결합하면 정확한 트렌드 판단에 따라 높은 확률의 입구점을 찾을 수 있습니다.

  2. OTT 대역은 동력 지표를 사용하며 가격 변동에 매우 민감하여 전환점을 일찍 발견 할 수 있습니다.

  3. 이윤을 취하고 손실을 멈추는 기능은 이익을 잠금하고 손실이 확장되기 전에 손실을 제한하는데 도움이 됩니다. 이는 위험 통제에 도움이 됩니다.

  4. 코드의 구조는 충분한 언급과 함께 명확하고 이해하기 쉽고 수정 할 수 있습니다.

  5. 전략 매개 변수는 인터페이스를 통해 다양한 시장 환경에 적응하도록 유연하게 조정할 수 있습니다.

위험성

  1. RSI는 지연된 발행을 가지고 있으며 트렌드 전환 지점을 놓치고 불필요한 손실을 초래할 수 있습니다.

  2. OTT 대역은 또한 잘못된 신호를 생성 할 수 있습니다. 촛불 패턴으로 확인하는 것이 좋습니다.

  3. 부적절한 수익 및 스톱 손실 설정은 전략 성과에 영향을 미칩니다. 매개 변수는 다른 제품에 맞게 조정해야합니다.

  4. 전략은 하나의 제품에서만 백테스트됩니다. 매개 변수는 라이브 거래에서 다른 제품에 대해 별도로 최적화되어야합니다.

  5. 백테스트 시간 창은 짧고 전략의 효과를 완전히 검증하지 않을 수 있습니다. 백테스트 기간을 확장하는 것이 좋습니다.

최적화 방향

  1. 잘못된 항목을 줄이기 위해 MACD, KD 등 필터링을 위한 다른 지표를 추가하는 것을 고려하십시오.

  2. 이윤을 취하고 손실을 멈추는 범위는 변동성에 따라 동적으로 조정할 수 있습니다.

  3. 다른 제품들에 대한 연구 매개 변수 최적화

  4. 전략 매개 변수를 동적으로 최적화하기 위해 기계 학습 방법을 시도하십시오.

  5. 부피 확인을 추가하여 잘못된 파열을 피합니다. 부피 지표는 또한 추세를 결정하는 데 사용될 수 있습니다.

  6. 단순 비율의 스톱 로스 대신 MA 침투를 스톱 로스로 사용하는 것을 고려하십시오.

요약

요약하면, 이것은 전형적인 트렌드 다음 전략입니다. 그것은 먼저 RSI를 통해 트렌드 방향을 판단하고, 특정 입구 지점을 결정하는 데 도움이되는 OTT 밴드를 사용하고, 마지막으로 수익을 잠금하고 위험을 제어하기 위해 수익을 취하고 손실을 중지합니다. 이 전략의 장점은 간단하고 효과적인 지표 조합과 좋은 백테스트 결과입니다. 그러나 RSI 지연 및 OTT 밴드 잘못된 신호와 같은 몇 가지 위험도 있습니다. 이것은 라이브 거래에서 매개 변수를 신중하게 최적화하고, 전략 안정성을 향상시키기 위해 확인을 위해 다른 기술적 지표를 추가해야합니다. 지속적인 최적화와 검증으로,이 전략은 매우 실용적인 트렌드 다음 템플릿 전략이 될 수 있습니다.


/*backtest
start: 2023-09-08 00:00:00
end: 2023-10-08 00:00:00
period: 2h
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/
// © BigCoinHunter

//@version=5
strategy(title="RSI_OTT-TP/SL", overlay=true, 
     pyramiding=0, default_qty_type=strategy.percent_of_equity, 
     default_qty_value=100, initial_capital=1000, 
     currency=currency.USD, commission_value=0.05, 
     commission_type=strategy.commission.percent, 
     process_orders_on_close=true)

//----------- get the user inputs --------------

//---------- RSI -------------
price = input(close, title="Source")

RSIlength = input.int(defval=6,title="RSI Length") 
RSIoverSold = input.int(defval=50, title="RSI OverSold", minval=1)
RSIoverBought = input.int(defval=50, title="RSI OverBought", minval=1)

//------- OTT Bands ----------------
src = close
length=input.int(defval=1, title="OTT Period", minval=1)
percent=input.float(defval=5, title="OTT Percent", step=0.1, minval=0.001)

mav = input.string(title="OTT MA Type", defval="VAR", options=["SMA", "EMA", "WMA", "TMA", "VAR", "WWMA", "ZLEMA", "TSF"])

ottUpperPercent = input.float(title="OTT Upper Line Coeff", defval=0.01, minval = 0.001, step=0.001)
ottLowerPercent = input.float(title="OTT Lower Line Coeff", defval=0.01, minval = 0.001, step=0.001)

Var_Func(src,length)=>
    valpha=2/(length+1)
    vud1=src>src[1] ? src-src[1] : 0
    vdd1=src<src[1] ? src[1]-src : 0
    vUD=math.sum(vud1,9)
    vDD=math.sum(vdd1,9)
    vCMO=nz((vUD-vDD)/(vUD+vDD))
    VAR=0.0
    VAR:=nz(valpha*math.abs(vCMO)*src)+(1-valpha*math.abs(vCMO))*nz(VAR[1])
    
VAR=Var_Func(src,length)

Wwma_Func(src,length)=>
    wwalpha = 1/ length
    WWMA = 0.0
    WWMA := wwalpha*src + (1-wwalpha)*nz(WWMA[1])
    
WWMA=Wwma_Func(src,length)

Zlema_Func(src,length)=>
    zxLag = length/2==math.round(length/2) ? length/2 : (length - 1) / 2
    zxEMAData = (src + (src - src[zxLag]))
    ZLEMA = ta.ema(zxEMAData, length)
    
ZLEMA=Zlema_Func(src,length)

Tsf_Func(src,length)=>
    lrc = ta.linreg(src, length, 0)
    lrc1 = ta.linreg(src,length,1)
    lrs = (lrc-lrc1)
    TSF = ta.linreg(src, length, 0)+lrs
    
TSF=Tsf_Func(src,length)

getMA(src, length) =>
    ma = 0.0
    if mav == "SMA"
        ma := ta.sma(src, length)
        ma

    if mav == "EMA"
        ma := ta.ema(src, length)
        ma

    if mav == "WMA"
        ma := ta.wma(src, length)
        ma

    if mav == "TMA"
        ma := ta.sma(ta.sma(src, math.ceil(length / 2)), math.floor(length / 2) + 1)
        ma

    if mav == "VAR"
        ma := VAR
        ma

    if mav == "WWMA"
        ma := WWMA
        ma

    if mav == "ZLEMA"
        ma := ZLEMA
        ma

    if mav == "TSF"
        ma := TSF
        ma
    ma
    
MAvg=getMA(src, length)
fark=MAvg*percent*0.01
longStop = MAvg - fark
longStopPrev = nz(longStop[1], longStop)
longStop := MAvg > longStopPrev ? math.max(longStop, longStopPrev) : longStop
shortStop =  MAvg + fark
shortStopPrev = nz(shortStop[1], shortStop)
shortStop := MAvg < shortStopPrev ? math.min(shortStop, shortStopPrev) : shortStop
dir = 1
dir := nz(dir[1], dir)
dir := dir == -1 and MAvg > shortStopPrev ? 1 : dir == 1 and MAvg < longStopPrev ? -1 : dir
MT = dir==1 ? longStop: shortStop

OTT=MAvg>MT ? MT*(200+percent)/200 : MT*(200-percent)/200

light_green=#08ff12
light_red=#fe0808

OTTupper = nz(OTT[2])*(1+ottUpperPercent)
OTTlower = nz(OTT[2])*(1-ottLowerPercent)

p1 = plot(OTTupper, color=light_green, linewidth=1, title="OTT UPPER")
p2 = plot(nz(OTT[2]), color=color.new(color.yellow,0), linewidth=1, title="OTT MIDDLE")
p3 = plot(OTTlower, color=light_red, linewidth=1, title="OTT LOWER")

fill(plot1=p1, plot2=p3, title="OTT Background", color=color.new(color.aqua,90), fillgaps=false, editable=true)

buyEntry = ta.crossover(src, OTTlower)
sellEntry = ta.crossunder(src, OTTupper)

//---------- input TP/SL ---------------
tp = input.float(title="Take Profit:", defval=0.0, minval=0.0, maxval=100.0, step=0.1) * 0.01
sl = input.float(title="Stop Loss:  ", defval=0.0, minval=0.0, maxval=100.0, step=0.1) * 0.01

isEntryLong = input.bool(defval=true, title= 'Long Entry', inline="11")
isEntryShort = input.bool(defval=true, title='Short Entry', inline="11")

//---------- backtest range setup ------------
fromDay   = input.int(defval = 1, title = "From Day", minval = 1, maxval = 31)
fromMonth = input.int(defval = 1, title = "From Month", minval = 1, maxval = 12)
fromYear  = input.int(defval = 2021, title = "From Year", minval = 2010)
toDay     = input.int(defval = 30, title = "To Day", minval = 1, maxval = 31)
toMonth   = input.int(defval = 12, title = "To Month", minval = 1, maxval = 12)
toYear    = input.int(defval = 2022, title = "To Year", minval = 2010)

//------------ time interval setup -----------
start     = timestamp(fromYear, fromMonth, fromDay, 00, 00)  // backtest start window
finish    = timestamp(toYear, toMonth, toDay, 23, 59)        // backtest finish window
window()  => true // create function "within window of time"

//------- define the global variables ------
var bool long = true
var bool stoppedOutLong = false
var bool stoppedOutShort = false

//--------- Colors ---------------
//TrendColor = RSIoverBought and (price[1] > BBupper and price < BBupper) and BBbasis < BBbasis[1] ? color.red : RSIoverSold and (price[1] < BBlower and price > BBlower) and BBbasis > BBbasis[1] ? color.green : na
//bgcolor(switch2?(color.new(TrendColor,50)):na)


//--------- calculate the input/output points -----------
longProfitPrice  = strategy.position_avg_price * (1 + tp)     // tp -> take profit percentage
longStopPrice = strategy.position_avg_price * (1 - sl)        // sl -> stop loss percentage

shortProfitPrice  = strategy.position_avg_price * (1 - tp)
shortStopPrice = strategy.position_avg_price * (1 + sl)


//---------- RSI + Bollinger Bands Strategy -------------
vrsi = ta.rsi(price, RSIlength)

rsiCrossOver = ta.crossover(vrsi, RSIoverSold)
rsiCrossUnder = ta.crossunder(vrsi, RSIoverBought)

OTTCrossOver = ta.crossover(src, OTTlower)
OTTCrossUnder = ta.crossunder(src, OTTupper)

if (not na(vrsi))

    if rsiCrossOver and OTTCrossOver
        long := true
        
    if rsiCrossUnder and OTTCrossUnder
        long := false

//------- define the global variables ------
buySignall = false
sellSignall = false

//------------------- determine buy and sell points ---------------------
buySignall := window() and long  and (not stoppedOutLong)
sellSignall := window() and (not long)  and (not stoppedOutShort)


//---------- execute the strategy -----------------
if(isEntryLong and isEntryShort)
    if long 
        strategy.entry("LONG", strategy.long, when = buySignall, comment = "ENTER LONG")
        stoppedOutLong := true
        stoppedOutShort := false
    else 
        strategy.entry("SHORT", strategy.short, when = sellSignall, comment = "ENTER SHORT")
        stoppedOutLong  := false
        stoppedOutShort := true

else if(isEntryLong)
    strategy.entry("LONG", strategy.long,  when = buySignall)
    strategy.close("LONG", when = sellSignall)
    if long 
        stoppedOutLong := true
    else
        stoppedOutLong  := false

else if(isEntryShort)
    strategy.entry("SHORT", strategy.short, when = sellSignall)
    strategy.close("SHORT", when = buySignall)
    if not long
        stoppedOutShort := true
    else
        stoppedOutShort := false
    

//----------------- take profit and stop loss -----------------
if(tp>0.0 and sl>0.0)
    if ( strategy.position_size > 0 )
        strategy.exit(id="LONG", limit=longProfitPrice, stop=longStopPrice, comment="Long TP/SL Trigger")

    else if ( strategy.position_size < 0 )
        strategy.exit(id="SHORT", limit=shortProfitPrice, stop=shortStopPrice, comment="Short TP/SL Trigger")

else if(tp>0.0)
    if ( strategy.position_size > 0 )
        strategy.exit(id="LONG", limit=longProfitPrice, comment="Long TP Trigger")

    else if ( strategy.position_size < 0 )
        strategy.exit(id="SHORT", limit=shortProfitPrice, comment="Short TP Trigger")
        
else if(sl>0.0)
    if ( strategy.position_size > 0 )
        strategy.exit(id="LONG",  stop=longStopPrice, comment="Long SL Trigger")

    else if ( strategy.position_size < 0 )
        strategy.exit(id="SHORT",  stop=shortStopPrice, comment="Short SL Trigger")




더 많은