CAP03부터 Finterstella를 이용한 기술적 투자전략에 대한 포스트를 연재하고 있다. 오늘은 "상대 강도 지수" - Relative Strength Index (RSI)를 이용한 투자전략을 벡테스팅하겠다. CAP02에서 MACD는 모멘텀 전략으로만 사용했다. 즉 오르는 주식은 미래에도 계속 오르고, 내려가는 주식은 미래에도 계속 내려간다라는 가정을 하는 전략이다. 이번 전략도 모멘텀을 가정해서 사용할 수 있다. 하지만 평균 회귀 (Mean resversion)이라는 정 반대의 가정으로도 적용해 볼 수 있다. 매우 많이 하락한 주식은 결국 평균으로 회귀하기 때문에 오르고, 그 반대도 가능하다는 가정이다. RSI 지표를 모멘텀과 평균 회귀로 사용해보고 둘의 결과를 비교해보는 게 오늘의 목적이다.
import finterstellar as fs
def get_data(stock,start,end):
df = fs.get_price(stock,start_date=start,end_date=end)
fs.draw_chart(df,right=stock)
return df
symbol= 'SOXL'
df = get_data(symbol,'2020-01-01','2021-10-31')
언제나처럼 finterstella 라이브러리를 impot 하고, 주가 데이터를 dataframe으로 불러왔다. 이번에는 변동성이 큰 미국의 반도체 ETF SOXL을 불러와봤다.
본격적으로 벡테스팅을 하기 전에, RSI에 대해서 간단히 소개하겠다.
주식차트의 상승폭과 하락폭의 개수를 이용하는 전략이다. w 일 동안 상승폭의 개수 평균 (AU)와 하락폭의 개수 평균 (AD)을 계산한다. 이때 w 일 동안의 평균은 지수 이동 평균 (EMA)의 개념을 넣어서 계산하므로 공식은 다음과 같다.
- AU(t) = AU(t-1) * (w-1)/2 + 상승폭(t) * 1/w
- AD(t) = AD(t-1) * (w-1)/2 + 하락폭(t) * 1/w
RSI 는 전체 상승+하락폭 중에서 상승폭의 비율을 의미하고, 다음과 같이 계산할 수 있다.
- RSI = 100 * AU / ( AU + AD )
fs.rsi(df,w=10) # w 는 10일로 했다
fs.draw_chart(df,left='rsi',right=symbol)
Finterstella 에는 fs.rsi 내장 함수가 구현되어있기 때문에, 쉽게 1줄로 구현 가능하다. 일반적으로 w는 2주를 쓴다고 한다. 주말 빼고 10일로 설정했고, 주가를 오른쪽, RSI 값을 왼쪽에 표시해서 시각화해보았다.
RSI는 비율이기 때문에 0부터 100까지의 값을 가진다. RSI를 만든 월레스 와일더 (J. Welles Wilder Jr) 는 RSI > 70을 과매수 상태, RSI < 30을 과매도 상태로 정의했다. 물론 다른 값을 넣어도 상관없을 것이다. 와일더의 계산법을 이용해서 평균 회귀 전략, 모멘텀 전략 둘 다 테스트해보겠다.
평균 회귀 (Mean reversion)
- RSI > 70 : Short
- RSI < 30 : Long
def RSI(df,buy,sell):
fs.rsi(df,w=10)
fs.draw_chart(df,left='rsi',right=symbol)
fs.indicator_to_signal(df,factor='rsi',buy=buy,sell=sell) # buy sell zero signal 생성
fs.position(df) # position 산출 (주식보유현황 보여쥼)
fs.evaluate(df,cost=.001) # 수익률 계산 cost: 매매 수수료
fs.performance(df,rf_rate=0.01) # 총 performance 출력 rf_rat: 무위험 이자율
fs.draw_trade_results(df)
df = get_data(symbol,'2020-01-01','2021-10-31')
RSI(df,30,70)
- CAGR: 59.60%
- Accumulated return:130.81%
- Average return: 26.18%
- Benchmark return : 152.38%
- Number of trades: 4
- Number of win: 2
- Hit ratio: 50.00%
- Investment period: 1.8yrs
- Sharpe ratio: 0.57
- MDD: -72.48%
- Benchmark MDD: -80.40%
주가 폭락, 후 꾸준한 상승기 (2020-01 ~ 2021-01) 에는 제대로 대응을 못하지만, 박스권일 때 (2021-04 ~) 에는 수익을 내는 것을 확인할 수 있다.
모멘텀 (Momentum)
- RSI > 70 : Long
- RSI < 30 : short
df = get_data(symbol,'2020-01-01','2021-10-31')
RSI(df,70,30)
- CAGR: 20.45%
- Accumulated return: 39.50%
- Average return: 14.17%
- Benchmark return : 152.38%
- Number of trades: 3
- Number of win: 2
- Hit ratio: 66.67%
- Investment period: 1.8yrs
- Sharpe ratio: 0.22
- MDD: -50.32%
- Benchmark MDD: -80.40%
주가의 급하락은 잘 방어했고, 상승자에도 benchmark 수익은 따라잡는다. 하지만 박스권은 하나도 대처를 못하고, 처참한 결과가 나왔다.
결론 및 주관적 해석
오늘은 RSI 지표를 이용해서, SOXL ETF를 가지고 평균 회귀와 모멘텀 전략을 벡테스팅하고 결과를 비교해보았다. 비교 결과 모멘텀 전략은 급하락에 대한 방어, 상승장에서 수익을 보는것을 확인 했고 박스권에서는 힘을 못 쓰는것을 확인했다. 평균회귀 전략은 박스권에서 수익을 보는것을 확인했고, 급하락에 대한 방어를 못하고, 상승장에서 큰 수익을 못 내는것을 확인했다. 모멘텀 전략은 테슬라, 애플같은 빅테크주, 평균회귀 전략은 박스권을 형성하는 안정적인 주식에 활용하면 유리할 것으로 생각된다.
*Reference
http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9791162244753#N)
'투자' 카테고리의 다른 글
퀀트킹 백테스터01 마법공식 백테스팅 (1) | 2022.01.10 |
---|---|
Python05 기술적투자04 Envelope 전략 (0) | 2021.12.03 |
Python03 기술적투자02 MACD전략 (0) | 2021.10.24 |
Python02 기술적투자01 라이브러리 소개 (0) | 2021.10.22 |
Python01 Financial data reader 와 pandas 를 이용한 이동평균선 구하기 (0) | 2021.07.23 |