일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |
- 인과추론
- 프롬프트
- 아하모먼트
- 데이터
- 주가데이터
- DataAnalyst
- 데이터분석
- 트위먼의법칙
- 성장
- DataAnalysis
- aha-moment
- 데이터디스커버리플랫폼
- 전환분석
- 분석한스푼
- pandasai
- data
- PyGWalker
- n8n
- 야구
- 시각화
- EDA
- 글또
- 신기효과
- gapminder
- 벅슨의역설
- data-analysis
- 데이터분석가
- productanalysis
- retentioneering
- 프롬프트엔지니어링
데이터 생존 로그
Python으로 이해하는 주가지표① - RSI(Relative Strength Index) (feat. 엔비디아) 본문
RSI(Relative Strength Index, 상대강도지수)라는 주가 지표를
파이썬을 통해 계산해보고 직관적으로 이해해봅시다.
RSI란 무엇일까?
RSI는 가격의 상승압력과 하락압력 간의 상대적인 강도를 나타낸다고 한다. (출처)
(무슨 말인지 직관적으로 이해가 잘 안되지만.. 일단 pass)
RSI는 그 종목이 과매수 상태인지 과매도 상태인지를 판단할 때 사용한다.
일반적으로 RSI가 70% 이상이면 과매수, 30% 이하면 과매도로 판단한다.
RSI는 다음과 같은 복잡한 식으로 표현된다.
RSI = 100 - 100 / (1+RS)
RS = (평균 이득) / (평균 손실)
위 식을 파이썬으로 나타내보고 지표를 직관적으로 이해해보고,
엔비디아 주가에서 RSI를 뽑아보자!
RSI 뽑아보기
RSI를 뽑기 위한 랜덤 데이터를 만들어보자.
다음은 2024년 1월 1일부터 20일 간 랜덤으로 주가 데이터를 만드는 코드이다.
import pandas as pd
import numpy as np
# 예시 데이터 생성
np.random.seed(0) # 결과 일관성을 위해 시드 설정
dates = pd.date_range('2024-01-01', periods=20) # 20일간의 날짜
prices = np.random.normal(100, 10, size=len(dates)) # 10에서 100사이의 값만 가지도록
# 데이터프레임 생성
df = pd.DataFrame({'Date': dates, 'Price': prices})
만들어진 데이터로 이전 날짜 대비 증감을 계산해보도록 하자.
# 가격 변동 계산
df['Price Change'] = df['Price'].diff()
Price Change라는 값은 날짜 증감을 담고 있다.
다음은 이득과 손실을 계산해보자.
증감이 0보다 큰지 여부에 따라 값을 그대로 가져오면 된다.
# 이득과 손실 계산
df['Gain'] = df['Price Change'].apply(lambda x: x if x > 0 else 0)
df['Loss'] = df['Price Change'].apply(lambda x: -x if x < 0 else 0)
df
다음으로, 평균 이득과 평균 손실을 계산해야하는데,
일반적으로 14일을 기준으로 평균을 계산한다고 한다.
# 평균 이득과 평균 손실 계산 (14일 기준)
window = 14
df['Avg Gain'] = df['Gain'].rolling(window=window).mean()
df['Avg Loss'] = df['Loss'].rolling(window=window).mean()
14일 평균으로 계산했기 때문에 13행(index = 12)까지는 값이 없다.
이번엔 RS를 뽑아보자!
# RS 계산
df['RS'] = df['Avg Gain'] / df['Avg Loss']
df
RS는 1을 기점으로 분포되어있다.
- 평균 이득이 더 크다면 1보다 큰 수를 가지고
- 평균 손실이 더 크다면 1보다 작은 수를 가진다.
따라서,
- RS가 큰 값을 가질수록 최근 14일간 손실보다 이득이 더 크다는 것을 의미하고
- RS가 작은 값을 가질수록 최근 14일간 이득보다 손실이 더 크다는 것을 의미한다!
최종적으로 우리의 목표인 RSI를 구해보자!
# RSI 계산
df['RSI'] = 100 - (100 / (1 + df['RS']))
df
RSI가 30 ~ 70 사이에 존재하므로, 과매도 혹은 과매수 구간은 아닌 것으로 보인다.
그럼 RSI의 의미를 살펴볼까?
- 최근 14일의 평균 이득과 손실이 같다면, RS = 1이다.
- RS = 1이라면 RSI는 50이 된다.
- 즉, RSI가 50이라면 평균 이득과 평균 손실이 동일한 상태임을 의미한다!
자 이번엔 RSI의 기준이었던 30과 70의 의미를 역산을 통해 알아보면
- RSI = 30이라면, RS = 3 / 7이어야한다.
- 따라서, 평균 이득 : 평균 손실 = 3 : 7이어야 하며,
- 이는 평균 이득보다 평균 손실이 2.3배 이상일 때를 의미한다!
- RSI = 70이라면, RS = 7 / 3이어야 한다.
- 따라서, 평균 이득 : 평균 손실 = 7 : 3이어야 하며,
- 이는 평균 손실보다 평균 이득이 2.3배 이상일 때를 의미한다!
엔비디아 주가에서 RSI 뽑아보기
요즘 엔비디아 주가는 연일 최고치를 경신하고 있다.
(곧 조정이 오겠지... 라며 구경만 하다가 못들어간 사람이 바로 나다🥲)
yfinance를 통해 엔비디아 주가를 불러와서 RSI를 확인해보자!
(yfinance가 무엇인지 모르겠다면? → 링크 클릭해보기!)
import yfinance as yfinance
import matplotlib.pyplot as plt
# 2023년 12월 ~ 24년 2월
nvidia_data = yfinance.download('NVDA', start='2023-12-01', end='2024-02-29')
# RSI 집계하는 함수
def calculate_rsi(data, window=14):
delta = data['Adj Close'].diff() # 수정 종가 기준으로 집계
gain = (delta.where(delta > 0, 0)).rolling(window=window).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean()
rs = gain / loss
rsi = 100 - (100 / (1 + rs))
return rsi
nvidia_data['RSI'] = calculate_rsi(nvidia_data)
fig, ax = plt.subplots(2, 1, figsize=(14, 10))
# 주가 그래프
ax[0].plot(nvidia_data.index, nvidia_data['Adj Close'], label='NVDA Adjusted Close', color='blue')
ax[0].set_title('NVIDIA Adjusted Close Price')
ax[0].set_ylabel('Price ($)')
ax[0].legend()
# RSI 그래프
ax[1].plot(nvidia_data.index, nvidia_data['RSI'], label='RSI', color='purple')
ax[1].axhline(70, linestyle='--', color='red', label='Overbought (70)')
ax[1].axhline(30, linestyle='--', color='green', label='Oversold (30)')
ax[1].set_title('NVIDIA RSI')
ax[1].set_ylabel('RSI')
ax[1].set_ylim(0, 100)
ax[1].legend()
plt.tight_layout()
plt.show()
RSI에 따르면,
- 1월 11일에 80을 기록하며 과매수 구간에 진입
- 2월 20일에 65를 기록하며 과매수 구간 탈출
- 그 이후 70 선을 횡보
함을 알 수 있다!
요약
- RSI를 통해 현재 시점이 과매수 혹은 과매도 구간인지 판단할 수 있다.
- RSI는 최근 n일 간 평균 이득과 평균 손실의 비율을 나타내며
- 2.3배를 기준으로 과매도, 과매수를 판단한다.
- 엔비디아는 광기다
'생존 도구🏹' 카테고리의 다른 글
🔄데이터 분석가가 써먹는 전환 분석의 다섯 가지 접근법(feat. 로그 데이터, SQL) (0) | 2024.10.27 |
---|---|
GPT한테 SQL 쿼리 짜달라고 하기 (0) | 2024.03.17 |
yfinance(야후 파이낸스)로 주가 데이터 손질하기 (1) | 2024.01.07 |
Retentioneering: 그 복잡한 product data를 간단하고 자유도 높게 다룰 수 있다고? (2) | 2023.12.17 |
아하모먼트: 왜 우리 서비스를 계속 써요? (0) | 2023.12.08 |