[기술적 분석] 지표/전략 : 상대 강도 Xtra (RSX, Relative Strength Xtra)

반응형

  

  RSX는 RSI Xtra, RSI Smoothed, RSQI(Relative Strength Quality Index) 등 다양한 이름으로 부르기도 하는데, 뭐라고 부르든 공히 상대 강도 지수(RSI, Relative Strength Index)의 노이즈를 제거한 것을 말하는 것이다. RSI는 노이즈가 심해 여기에 이동평균을 적용하여 이것으로 거래를 했는데 이것과 개념은 비슷하다고 보면 된다. 

 

  RSX는 일전에 이동 평균 종류를 소개할 때 나왔던 JMA(Jurik Moving Average)를 만든 Jurik Research라는 곳에서 RSI에 평활화를 적용하여 만든 것으로 그들이 말하는 장점은 노이즈 제거, 평활화 과정에서 래깅 제거이다. 실제로 적용된 모습을 보면 RSI와 비교하여 노이즈가 없으며 단순 이동 평균을 적용한 RSI 이동평균에 비하여 시차가 제거된 모습이다.

 

RSX(Relative Strength Xtra)와 상대 강도 지수(RSI, Relative Strength Index) 비교

반응형

 

  단, RSI에 이동평균을 적용할 때 단순 이동 평균이 아닌, ZLMA(Zero-Lag Moving Average)나, HMA(Hull Moving Average)를 적용하면 RSI 이동평균도 RSX와 유사한 모습을 보이게 되며 이들이 만든 JMA(Jurik Moving Average)를 적용하면 그 모습은 더욱더 흡사해진다.

 

  사용법과 매매전략은 RSI 기반이다 보니 RSI와 거의 흡사하다. 30에서 매수 포지션, 70에서 매도 포지션을 검토하며 그 외 다른 지표들과 결합하거나 특히 RSI와 결합하여 Convergence & Divergence 즉, RSI 이동평균과 RSX의 교차 지점에 매수 / 매도 포지션을 취하는 전략을 사용하기도 한다.

 

 

  마지막으로 RSX 트레이딩 뷰 파인 스크립트 소스와 pandas-ta 소스를 공유한다.

 

  • RSX (Relative Strength Xtra) 트레이딩 뷰 파인 스크립트 지표 소스
//@version=5
indicator(title="Relative Strength Xtra", shorttitle="RSX", format=format.price, precision=2, timeframe="", timeframe_gaps=true)
sourceInput = input.source(close, "RSX Source", group="RSX Settings")
lengthInput = input.int(14, minval=1, title="RSX Length", group="RSX Settings")
lower = input.int(30, title="Lower", group="Band Settings")
upper = input.int(70, title="Upper", group="Band Settings")

clampmax = 100
clampmin = 0
f90_ = 0.0
f88 = 0.0
f28 = 0.0
f30 = 0.0
f38 = 0.0
f40 = 0.0
f48 = 0.0
f50 = 0.0
f58 = 0.0
f60 = 0.0
f68 = 0.0
f70 = 0.0
f78 = 0.0
f80 = 0.0
f90_ := (nz(f90_[1]) == 0.0) ? 1.0 : (nz(f88[1]) <= nz(f90_[1])) ? nz(f88[1])+1 : nz(f90_[1])+1
f88 := (nz(f90_[1]) == 0.0) and (lengthInput-1 >= 5) ? lengthInput-1.0 : 5.0 
f8 =  100.0*(sourceInput) 
f18 = 3.0 / (lengthInput + 2.0) 
f20 = 1.0 - f18 
f10 = nz(f8[1])
v8 = f8 - f10 
f28 := f20 * nz(f28[1]) + f18 * v8 
f30 := f18 * f28 + f20 * nz(f30[1])
vC = f28 * 1.5 - f30 * 0.5 
f38 := f20 * nz(f38[1]) + f18 * vC 
f40 := f18 * f38 + f20 * nz(f40[1])
v10 = f38 * 1.5 - f40 * 0.5 
f48 := f20 * nz(f48[1]) + f18 * v10 
f50 := f18 * f48 + f20 * nz(f50[1])
v14 = f48 * 1.5 - f50 * 0.5 
f58 := f20 * nz(f58[1]) + f18 * math.abs(v8) 
f60 := f18 * f58 + f20 * nz(f60[1])
v18 = f58 * 1.5 - f60 * 0.5
f68 := f20 * nz(f68[1]) + f18 * v18 
f70 := f18 * f68 + f20 * nz(f70[1])
v1C = f68 * 1.5 - f70 * 0.5 
f78 := f20 * nz(f78[1]) + f18 * v1C 
f80 := f18 * f78 + f20 * nz(f80[1])
v20 = f78 * 1.5 - f80 * 0.5
f0 = ((f88 >= f90_) and (f8 != f10)) ? 1.0  : 0.0
f90 = ((f88 == f90_) and (f0 == 0.0))  ? 0.0  : f90_
v4_ = ((f88 < f90) and (v20 > 0.0000000001)) ? (v14 / v20 + 1.0) * 50.0 : 50.0
rsx = (v4_ > 100.0) ? 100.0 : (v4_ < 0.0) ? 0.0 : v4_
rsiUpperBand = hline(upper, "RSI Upper Band", color=color.gray)
midline = hline(50, "RSI Middle Band", color=color.gray)
rsiLowerBand = hline(lower, "RSI Lower Band", color=color.gray)
fill(rsiUpperBand, rsiLowerBand, color=color.new(color.gray, 80), title="RSI Background Fill")
plot(rsx, color=color.yellow, title="RSX")

 

 

  • RSX (Relative Strength Xtra) 트레이딩 뷰 파인 스크립트 전략 소스
//@version=5
strategy(title="Relative Strength Xtra", shorttitle="RSX", overlay=false, margin_long=100, margin_short=100, default_qty_type=strategy.percent_of_equity, default_qty_value=50, commission_type=strategy.commission.percent, commission_value=0.2, pyramiding=0)

sourceInput = input.source(close, "RSX Source", group="RSX Settings")
lengthInput = input.int(14, minval=1, title="RSX Length", group="RSX Settings")
lower = input.int(30, title="Lower", group="Band Settings")
upper = input.int(70, title="Upper", group="Band Settings")

clampmax = 100
clampmin = 0
f90_ = 0.0
f88 = 0.0
f28 = 0.0
f30 = 0.0
f38 = 0.0
f40 = 0.0
f48 = 0.0
f50 = 0.0
f58 = 0.0
f60 = 0.0
f68 = 0.0
f70 = 0.0
f78 = 0.0
f80 = 0.0
f90_ := (nz(f90_[1]) == 0.0) ? 1.0 : (nz(f88[1]) <= nz(f90_[1])) ? nz(f88[1])+1 : nz(f90_[1])+1
f88 := (nz(f90_[1]) == 0.0) and (lengthInput-1 >= 5) ? lengthInput-1.0 : 5.0 
f8 =  100.0*(sourceInput) 
f18 = 3.0 / (lengthInput + 2.0) 
f20 = 1.0 - f18 
f10 = nz(f8[1])
v8 = f8 - f10 
f28 := f20 * nz(f28[1]) + f18 * v8 
f30 := f18 * f28 + f20 * nz(f30[1])
vC = f28 * 1.5 - f30 * 0.5 
f38 := f20 * nz(f38[1]) + f18 * vC 
f40 := f18 * f38 + f20 * nz(f40[1])
v10 = f38 * 1.5 - f40 * 0.5 
f48 := f20 * nz(f48[1]) + f18 * v10 
f50 := f18 * f48 + f20 * nz(f50[1])
v14 = f48 * 1.5 - f50 * 0.5 
f58 := f20 * nz(f58[1]) + f18 * math.abs(v8) 
f60 := f18 * f58 + f20 * nz(f60[1])
v18 = f58 * 1.5 - f60 * 0.5
f68 := f20 * nz(f68[1]) + f18 * v18 
f70 := f18 * f68 + f20 * nz(f70[1])
v1C = f68 * 1.5 - f70 * 0.5 
f78 := f20 * nz(f78[1]) + f18 * v1C 
f80 := f18 * f78 + f20 * nz(f80[1])
v20 = f78 * 1.5 - f80 * 0.5
f0 = ((f88 >= f90_) and (f8 != f10)) ? 1.0  : 0.0
f90 = ((f88 == f90_) and (f0 == 0.0))  ? 0.0  : f90_
v4_ = ((f88 < f90) and (v20 > 0.0000000001)) ? (v14 / v20 + 1.0) * 50.0 : 50.0
rsx = (v4_ > 100.0) ? 100.0 : (v4_ < 0.0) ? 0.0 : v4_
rsiUpperBand = hline(upper, "RSI Upper Band", color=color.gray)
midline = hline(50, "RSI Middle Band", color=color.gray)
rsiLowerBand = hline(lower, "RSI Lower Band", color=color.gray)
fill(rsiUpperBand, rsiLowerBand, color=color.new(color.gray, 80), title="RSI Background Fill")
plot(rsx, color=color.yellow, title="RSX")

startDate = input.time(defval=timestamp("01 Jan 1970 00:00 +0000"), group = "Test Range")
finishDate = input.time(defval=timestamp("31 Dec 2025 24:00 +0000"), group = "Test Range")
time_condition = time >= startDate and time <= finishDate
 
if(time_condition)
	if ta.crossunder(rsx, lower)
		strategy.entry("매수", strategy.long, oca_type=strategy.oca.cancel, comment="매수")
	if ta.crossover(rsx, upper)
		strategy.close_all('매도')
 
bgcolor(strategy.position_size > 0 ? color.new(color.yellow,90) : na)

 

 

  • RSX (Relative Strength Xtra) pandas-ta 소스
import pandas as pd
import pandas_ta as ta
import FinanceDataReader as fdr

data = fdr.DataReader('005930')
rsx = ta.rsx(close = data['Close'], length=14)
data = pd.concat([data, rsx], axis=1)
data.dropna(inplace=True)
반응형