이 전략은 RSI_OTT-TP/SL이라고 불린다. 이 전략은 RSI 지표와 OTT 파동으로 가져오는 거래 신호의 판단을 결합하고, 트렌드 추적 전략에 속한다. 전략은 RSI 지표를 통해 시장의 트렌드 방향을 결정하고, OTT 파동으로 가져오는 특정 진입 지점을 배치한다. 전략은 또한 사용자가 스톱 스톱 손실 비율을 설정할 수 있도록 허용하며, 수익을 잠금하거나 손실을 피하기 위해 자동으로 스톱 스톱 손실을 할 수 있다.
이 전략은 RSI와 OTT 두 가지 지표를 사용하여 트렌드 및 진입 지점을 판단합니다.
RSI는 전반적인 트렌드 방향을 판단하는 데 사용됩니다. RSI 지표는 시장이 과매매 또는 과매매임을 표시 할 수 있습니다. RSI 상단에 설정 된 과매매 영역은 과매매 신호이며, 아래의 과매매 영역은 과매 지역입니다. 이 전략의 기본 RSI 길이는 6이며, 과매매 라인은 50이며, 과매매 영역은 50입니다.
OTT 파동은 입시점을 발견하기 위해 사용된다. 그것은 변동률 지표 VAR의 기초에서 형성된 파동이다. 가격이 아래에서 위쪽으로 OTT 하향 궤도를 돌파할 때, 더 많은 신호를; 가격이 위에서 아래로 OTT 상향 궤도를 돌파할 때, 공백 신호를한다.
트렌드를 판단하고 입시점을 확인한 후, 이 전략은 OTT 파도를 돌파할 때 포지션을 상장하거나 상장한다.
스톱 스톱 손실은 사용자가 직접 설정할 수 있도록 입력 상자를 설정합니다. 스톱 스톱 또는 스톱 손실 가격이 발생하면 전략이 자동으로 청산됩니다.
이 전략은 오너, 오피스 또는 양방향 거래를 허용한다.
RSI와 OTT 파장을 결합하면 트렌드를 정확하게 판단할 수 있는 높은 확률의 진입 지점을 찾을 수 있다.
OTT은 유동량 지표를 활용하여 가격 변동에 매우 민감하여 전환점을 미리 발견할 수 있다.
전략은 스톱 스톱 손실 기능을 제공하여 수익을 잠금 할 수 있으며 손실이 확대되기 전에 손실을 중단 할 수 있습니다. 이는 위험을 통제하는 데 도움이됩니다.
코드 구조는 명확하고, 코멘트가 풍부하며, 이해하기 쉽고 수정하기 쉽다.
전략 파라미터는 인터페이스를 통해 다양한 시장 환경에 적응할 수 있도록 유연하게 조정할 수 있습니다.
RSI 지표는 추세 전환점을 놓칠 수 있으며 불필요한 손실을 초래할 수 있습니다.
OTT 대역은 또한 잘못된 신호를 생성할 수 있으며, K선 형태를 결합하여 검증하는 것이 좋습니다.
스톱 스톱 손실 설정이 잘못되면 전략의 성능에도 영향을 미치며, 다양한 품종에 따라 변수를 조정해야 한다.
전략은 단일 품종 재검토에만 기반하며, 실판에서 다른 품종의 매개 변수는 개별적으로 최적화해야 한다.
응답 시간 창이 짧기 때문에 전략의 유효성을 완전히 검증할 수 없습니다. 응답 주기를 확장하는 것이 좋습니다.
다른 지표들 (MACD, KD 등) 을 필터링하는 것도 고려할 수 있습니다.
동적으로 변동률에 기반한 방법으로 스톱 스톱 손실을 조정할 수 있다.
다양한 품종의 파라미터 최적화를 연구하고 파라미터 선택 기준을 수립할 수 있다.
동적으로 최적화 정책의 매개 변수를 시도할 수 있는 기계 학습 방법.
가격확인을 추가하여 가짜 돌파구를 방지할 수 있다. 또한 평균 지표를 사용하여 추세를 판단할 수 있다.
MA를 통과하는 것이 단순한 비율적 중단보다는 중단의 방법으로 고려 될 수 있습니다.
이 전략은 전체적으로 전형적인 트렌드 추적 전략이다. 그것은 먼저 RSI를 통해 트렌드 방향을 판단하고, 그 다음 OTT 대역 보조를 사용하여 특정 입시 시점을 결정하고, 마지막으로 스톱 스톱을 설정하여 수익을 잠금하고 위험을 제어한다. 이 전략의 장점은 지표 포트폴리지가 간단하고 효과적이며, 재측량 성능도 좋다. 그러나 RSI 지연, 대역 오류 등의 위험도 존재한다. 이것은 우리가 실장에서 적용할 때, 매개 변수를 세심하게 최적화하고, 다른 기술 지표에 추가하여 확인 할 수 있으므로 전략의 안정성을 향상시킵니다.
/*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")