파이썬 바이낸스 API로 차트 분석. 판다스 RSI (상대강도지수)
파이썬 바이낸스 API로 가져온 코인 데이터와 판다스 데이터프레임의 조합으로 시계열 데이터 분석을 쉽게 할 수 있습니다. 이번 포스팅에서는 파이썬 바이낸스 API의 get_historical_klines() 함수로 시간, 시가, 고가, 저가, 종가 데이터를 가져온 후 판다스 데이터프레임을 이용하여 RSI (상대강도지수)를 구하는 방법에 대해 알아보겠습니다.
글의 순서
RSI, (Relative Strength Index, 상대강도지수)
RSI 계산 방법
RSI 활용 방법
파이썬 코드 : 판다스 데이터프레임을 이용한 RSI
RSI, (Relative Strength Index, 상대강도지수)
RSI지표는 J. Welles Wilder가 1978년 “New Concepts in Technical Trading Systems” 라는 책에서 소개했습니다. RSI는 일정 기간 동안 주가가 전일 가격에 비해 상승했는지, 하락했는지의 추세를 0 ~ 100의 퍼센트 수치로 나타낸 지표입니다. 가격의 상승압력과 하락압력 간의 상대적인 강도를 나타낸다고도 표현합니다.
RSI는 현재가 과매수 상태인지, 과매도 상태인지를 알려줍니다. 여기서, 과매수란 주가 폭등으로 투자자들이 주식을 적정 수준 이상으로 매수하는 현상을 말합니다. 상승한 변화량이 크면 과매수로, 하락한 변화량이 크면 과매도로 판단하는 방식입니다. 보통 RSI 퍼센트 수치로는 30이하면 과매도, 70 이상이면 과매수로 해석합니다.
RSI 계산 방법
시간 간격을 하루 단위로 정해 놓고 계산해 보겠습니다. 시간 간격의 경우 하루가 아니라 1분, 1시간, 1주 등 다양하게 적용할 수 있습니다.
우리가 정한 기간에서 가격이 상승한 날의 상승분을 Up, 가격이 하락한 날의 하락분을 Down이라고 해보겠습니다. 상승분 Up 값의 n일 동안의 평균을 AU, 하락분 Down 값의 n일 동안의 평균을 AD하고 하면, AU와 AD의 비율을 상대강도라고 정의합니다. 상대강도가 크다는 것은 상승폭이 크다는 것을 의미합니다.
n일 동안이라고 말씀드렸는데요. 많은 애널리스트들은 9일, 14~15일, 25~28일 동안의 가격 변동으로 RSI를 구합니다. 주식 HTS(Home Trading System)에서는 기본값으로 14일이 설정되어 있는데, 사용자가 바꿀 수 있게 되어 있습니다.
RSI 계산방법을 정리해보겠습니다.
step1) 기간 선정 : n일
step2) 상승분 Up 값의 n일 동안의 평균 AU 구하기
step3) 하락분 Down 값의 n일 동안의 평균 AD 구하기
step4) 상대강도 RS = AU/AD 구하기
step5) 상대강도지수 RSI = RS/(1+RS) × 100% 구하기
RSI 활용 방법
RSI 50% 이상은 매수세 우세, 50%이하는 매도세 우세를 나타냅니다. 주식 HTS에서 보조지표 RSI를 선택하면, RSI를 나타낼 때, 70%, 30% 선이 그어져 있습니다. RSI는 대체로 이 두 선 사이, 그러니까 30~70% 구간에서 움직입니다. 그러다가 RSI 70% 이상이 되면 과매수, 30% 이하가 되면 과매도 상황으로 돌입한 것입니다.
단기적인 관점에서는 일반적으로 RSI가 70% 이상이 되어 과매수 상태였다가 70% 이하로 내려갈 때 매도하며, 30% 이하인 과매도 상태에서 30% 선을 교차해서 올라갈 때, 매수합니다.
반면, 장기적 관점에서는 좀 길게봐야 합니다. 장기적으로 상승추세일 때, 70% 이상일 때가 많으므로, 50% 보다 밑으로 떨어질 때(하향 돌파할 때) 매도하며, 장기적인 하락 추세일 때는 30% 이하일 때가 많으므로, 50%를 상향 돌파할 때 매수합니다.
파이썬 코드 : 판다스 데이터프레임을 이용한 RSI
지금까지의 과정을 ‘판다스 데이터프레임을 이용한 RSI’ 파이썬 코드에 나타내었습니다. 지난 포스팅 파이썬 바이낸스 API 시계열 데이터분석. 판다스 시간 처리의 판다스로 시계열데이터 전처리 (바이낸스 차트 분석)라는 파이썬 코드에 RSI 부분을 덧붙였습니다. RSI 부분만 출력하도록 했는데, 유심히 봐 주실 부분은 새롭게 데이터프레임을 만든 방법, shift 함수, np.where 함수입니다. 이동평균선 구할 때 사용했던 판다스 데이터프레임 함수인 rolling(n).mean()도 중요한 역할을 합니다.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
import os import time import pandas as pd import numpy as np from binance.client import Client import datetime from datetime import datetime, timezone, timedelta #01) 바이낸스 계정 접속 :: 파이썬 바이낸스 API api_key = os.getenv('Binan_API_KEY') api_secret = os.getenv('Binan_SECRET_KEY') client = Client(api_key, api_secret) print('\n','[ BINANCE ACCOUNT ACCESSED ]') #02) 시계열 데이터 수집 시작 시점 def get_time_stt(timestamp_now, interval, nbar): interval = str(interval) if interval == '1d': timestamp_stt = timestamp_now - nbar*24*60*60 utc_stt = datetime.fromtimestamp(int(timestamp_stt)) elif interval == '1h': timestamp_stt = timestamp_now - nbar*60*60 utc_stt = datetime.fromtimestamp(int(timestamp_stt)) elif interval == '15m': timestamp_stt = timestamp_now - nbar*15*60 utc_stt = datetime.fromtimestamp(int(timestamp_stt)) elif interval == '1m': timestamp_stt = timestamp_now - nbar*1*60 utc_stt = datetime.fromtimestamp(int(timestamp_stt)) return utc_stt #03) 현재시간 timestamp_now = time.time() utc_now = datetime.fromtimestamp(timestamp_now) #04) 시계열 데이터 수집 시점부터 현재까지의 bar 데이터(ohlcv 데이터) 획득 nbar = 30 n_rsi = 9 # RSI의 AU(Average of UP), AD(Average of Down)를 구하기 위한 구간(t_interval) 개수 t_interval = '1d' utc_ref = get_time_stt(timestamp_now, t_interval, nbar) utc_ref_str = datetime.strftime(utc_ref, '%Y-%m-%d %H:%M:%S') bars = client.get_historical_klines('BTCUSDT', t_interval, utc_ref_str, limit=1000) #04-1) ohlcv 데이터를 판다스 데이터프레임에 저장 후 출력 df_core = pd.DataFrame(bars) #05) ohlcv 데이터만 추출 for i in bars: del i[7:] df_core = pd.DataFrame(bars) #06) 데이터프레임 열 이름 붙여주기 df_core = pd.DataFrame(bars, columns=['time_open','open','high','low','close','volume','time_close']) #07) 데이터프레임 열 type을 실수형으로 변환 # df['c'] = df['a'] + df['b'] 처럼 열 연산으로 DataFrame의 새로운 열을 생성하기 위해 필요 df_core = df_core.astype({'open' : 'float', 'high' : 'float', 'low' : 'float', 'close' : 'float', 'volume' : 'float'}) #08) timestamp를 UTC로 변환 후 리스트로 저장 t_stt = [] t_end = [] for i in bars: t_stt.append(datetime.fromtimestamp(i[0]/1000)) t_end.append(datetime.fromtimestamp(i[6]/1000)) #09) UTC 리스트를 pandas DataFrame으로 저장 df_t_stt = pd.DataFrame(t_stt, columns=['time_open_utc']) df_t_end = pd.DataFrame(t_end, columns=['time_close_utc']) #10) UTC 데이터를 추가하여 pandas DataFrame 완성 df_1 = df_t_stt.join(df_core) df_org = df_1.join(df_t_end) # 11) RSI (Relative Strength Index, 상대강도지수) # 11-1) df 추출 : time_open_utc, open, high, low, close df = df_org[['time_open_utc', 'open', 'high', 'low', 'close','volume']] # 11-2) 데이터프레임 열 type을 실수형으로 변환 # 데이터프레임을 새로 생성했기 때문에, 새로 변환해야 함. df = df.astype({'open' : 'float', 'high' : 'float', 'low' : 'float', 'close' : 'float', 'volume' : 'float'}) # 11-2) 변동폭 계산 : 현재 종가 - 지난 종가 df['close_bef'] = df['close'].shift(1) df['updown'] = df['close'] - df['close_bef'] # 11-3) 상승, 하락 구분 df['up'] = np.where(df['updown'] > 0.0, df['updown'], 0) df['down'] = np.where(df['updown'] > 0.0, 0, df['updown']) # 11-4) 상승분 평균 AU, 하락분 평균 AD # simple moving average def get_average(updown, n): average = updown.rolling(n).mean() return average df['au'] = get_average(df['up'], n_rsi) df['ad'] = get_average(df['down'], n_rsi) # 11-5) RS : 상대강도 df['rs'] = df['au']/df['ad'].abs() # 11-6) RSI : 상대강도 지수 df['rsi'] = df['rs']/(1.0 + df['rs'])*100 print('\n','#11-6) ---') print(df) |
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 32 33 34 35 36 |
[ BINANCE ACCOUNT ACCESSED ] #11-6) --- time_open_utc open high low close volume ... up down au ad rs rsi 0 2022-12-31 16607.48 16644.09 16470.00 16542.40 114490.42864 ... 0.00 NaN NaN NaN NaN NaN 1 2023-01-01 16541.77 16628.00 16499.01 16616.75 96925.41374 ... 74.35 0.00 NaN NaN NaN NaN 2 2023-01-02 16617.17 16799.23 16548.70 16672.87 121888.57191 ... 56.12 0.00 NaN NaN NaN NaN 3 2023-01-03 16672.78 16778.40 16605.28 16675.18 159541.53733 ... 2.31 0.00 NaN NaN NaN NaN 4 2023-01-04 16675.65 16991.87 16652.66 16850.36 220362.18862 ... 175.18 0.00 NaN NaN NaN NaN 5 2023-01-05 16850.36 16879.82 16753.00 16831.85 163473.56641 ... 0.00 -18.51 NaN NaN NaN NaN 6 2023-01-06 16831.85 17041.00 16679.00 16950.65 207401.28415 ... 118.80 0.00 NaN NaN NaN NaN 7 2023-01-07 16950.31 16981.91 16908.00 16943.57 104526.56880 ... 0.00 -7.08 NaN NaN NaN NaN 8 2023-01-08 16943.83 17176.99 16911.00 17127.83 135155.89695 ... 184.26 0.00 67.891111 NaN NaN NaN 9 2023-01-09 17127.83 17398.80 17104.66 17178.26 266211.52723 ... 50.43 0.00 73.494444 -2.843333 25.847987 96.275326 10 2023-01-10 17179.04 17499.00 17146.34 17440.66 221382.42581 ... 262.40 0.00 94.388889 -2.843333 33.196561 97.075729 11 2023-01-11 17440.64 18000.00 17315.60 17943.26 262221.60653 ... 502.60 0.00 143.997778 -2.843333 50.644002 98.063667 12 2023-01-12 17943.26 19117.04 17892.05 18846.62 454568.32178 ... 903.36 0.00 244.114444 -2.843333 85.855021 98.848656 13 2023-01-13 18846.62 20000.00 18714.12 19930.01 368615.87823 ... 1083.39 0.00 345.026667 -2.843333 121.345838 99.182645 14 2023-01-14 19930.01 21258.00 19888.05 20954.92 393913.74951 ... 1024.91 0.00 458.905556 -0.786667 583.354520 99.828871 15 2023-01-15 20952.76 21050.74 20551.01 20871.50 178542.22549 ... 0.00 -83.42 445.705556 -10.055556 44.324309 97.793678 16 2023-01-16 20872.99 21474.05 20611.48 21185.65 293078.08262 ... 314.15 0.00 480.611111 -9.268889 51.852074 98.107927 17 2023-01-17 21185.65 21647.45 20841.31 21134.81 275407.74409 ... 0.00 -50.84 460.137778 -14.917778 30.844928 96.859782 18 2023-01-18 21132.29 21650.00 20407.15 20677.47 350916.01949 ... 0.00 -457.34 454.534444 -65.733333 6.914824 87.365481 19 2023-01-19 20677.47 21192.00 20659.19 21071.59 251385.84925 ... 394.12 0.00 469.170000 -65.733333 7.137475 87.711175 20 2023-01-20 21071.59 22755.93 20861.28 22667.21 338079.13659 ... 1595.62 0.00 590.616667 -65.733333 8.985041 89.985018 21 2023-01-21 22666.00 23371.80 22422.00 22783.55 346445.48432 ... 116.34 0.00 503.170000 -65.733333 7.654716 88.445606 22 2023-01-22 22783.35 23078.71 22292.37 22707.88 253577.75286 ... 0.00 -75.67 382.793333 -74.141111 5.163037 83.774235 23 2023-01-23 22706.02 23180.00 22500.00 22916.45 293588.37938 ... 208.57 0.00 292.088889 -74.141111 3.939635 79.755588 24 2023-01-24 22917.81 23162.20 22462.93 22632.89 293158.78254 ... 0.00 -283.56 292.088889 -96.378889 3.030631 75.189991 25 2023-01-25 22631.94 23816.73 22300.00 23060.94 346042.83223 ... 428.05 0.00 304.744444 -96.378889 3.161942 75.972754 26 2023-01-26 23060.42 23282.47 22850.01 23009.65 288924.43581 ... 0.00 -51.29 304.744444 -96.428889 3.160302 75.963285 27 2023-01-27 23009.65 23500.00 22534.88 23074.16 280833.86315 ... 64.51 0.00 311.912222 -45.613333 6.838181 87.241938 28 2023-01-28 23074.16 23189.00 22878.46 23022.60 148115.71085 ... 0.00 -51.56 268.121111 -51.342222 5.222234 83.928602 29 2023-01-29 23021.40 23492.00 22967.76 23219.78 69826.79025 ... 197.18 0.00 112.738889 -51.342222 2.195832 68.709243 [30 rows x 14 columns] |
마치며 …
이번 포스팅에서는 파이썬 바이낸스 API의 get_historical_klines() 함수로 시간, 시가, 고가, 저가, 종가 데이터를 가져온 후 판다스 데이터프레임을 이용하여 RSI를 구해 보았습니다.
pandas DataFrame의 shift() 함수, abs() 함수, rolling().mean() 함수, 넘파이의 np.where() 함수가 중요한 역할을 했습니다.
함께 참고하면 더 좋은 글 :
1. 바이낸스 코인거래소 API Key로 계좌에 접속하는 파이썬 프로그래밍
2. 파이썬 바이낸스 API로 시계열 데이터를 가져오는 파이썬 프로그래밍
3. 바이낸스 API 보안을 위한 환경 변수 설정 : 윈도우 10
4. 파이썬 바이낸스 API 시계열 데이터분석. 판다스 시간 처리
5. 파이썬 바이낸스 API로 차트 분석 : 판다스 이동평균선
6. 파이썬 프로그래밍 time 이해 : timestamp, UTC, KST
7. 파이썬 바이낸스 API로 차트 분석. 판다스 스토캐스틱
8. 바이낸스 비트코인 투자 백 테스팅. 파이썬 코인 투자 연습
9. 파이썬 프로그래밍 시작 (8) 자료구조(Data Structure) : 리스트
10. 파이썬 프로그래밍 시작
참고자료
[1] python-binance Docs >> get_historical_klines
[2] 치킨요정의 경제공부방, 주식 RSI 보조지표 개념 및 활용방법 정리