Анализ стратегии RSI и OTT

Автор:Чао Чжан, Дата: 2023-10-09 16:21:20
Тэги:

Обзор

Эта стратегия называется RSI_OTT-TP/SL. Она сочетает в себе индикатор RSI и диапазоны OTT для определения торговых сигналов, относящихся к следующей стратегии тренда. Стратегия оценивает направление тренда рынка с помощью индикатора RSI и использует диапазоны OTT для определения конкретных точек входа.

Логика стратегии

  1. Эта стратегия использует индикаторы RSI и OTT для определения тренда и пунктов входа.

  2. RSI используется для оценки общего направления тренда. RSI может показать, является ли рынок перекупленным или перепроданным. Пересечение RSI выше уровня перекупленности является сигналом покупки, а пересечение ниже уровня перепроданности является сигналом продажи.

  3. OTT-диапазоны используются для обнаружения точек входа. Они представляют собой диапазоны, сформированные на основе индикатора скорости изменения волатильности (VAR). Когда цена проходит через нижний диапазон вверх, это сигнал покупки. Когда цена проходит через верхний диапазон вниз, это сигнал продажи.

  4. После определения тренда и подтверждения точки входа, эта стратегия будет открывать длинные или короткие позиции, когда цена превышает диапазоны OTT.

  5. Приобретение прибыли и остановка потери могут быть установлены с помощью входных ящиков для пользователей для настройки.

  6. Стратегия также позволяет торговать только длинным, коротким или обоими направлениями.

Преимущества

  1. Сочетание диапазонов RSI и OTT может найти высокую вероятность входа в точку при точном оценке тренда.

  2. OTT-диапазоны используют индикатор импульса и очень чувствительны к колебаниям цен, которые могут обнаружить поворотные моменты рано.

  3. Функции take profit и stop loss помогают зафиксировать прибыль и ограничить убытки до их расширения, что способствует контролю рисков.

  4. Структура кода ясна с достаточным количеством комментариев, легко понятна и изменяется.

  5. Параметры стратегии могут быть гибко скорректированы через интерфейс для адаптации к различным рыночным условиям.

Риски

  1. RSI имеет отстающую эмиссию и может пропустить точки переворота тренда, что приводит к ненужным потерям.

  2. ОТТ-диапазоны также могут генерировать ложные сигналы.

  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")




Больше