RSIとOTT帯の戦略分析

作者: リン・ハーンチャオチャン,日付: 2023年10月9日 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")




もっと