파이썬 바이낸스 API로 차트 분석. 판다스 스토캐스틱
파이썬 바이낸스 API로 코인 가격에 대한 시계열 데이터 분석을 쉽게 할 수 있습니다. 이번 포스팅에서도 캔들 차트를 이용합니다. 파이썬 바이낸스 API의 get_historical_klines() 함수로 시간, 시가, 고가, 저가, 종가 데이터를 가져온 후 판다스 데이터프레임을 이용하여 차트 보조지표 중 스토캐스틱 구하는 방법과 스토캐스틱의 활용법에 대해 알아보겠습니다.
글의 순서
스토캐스틱 오실레이터 (Stochastic Oscillator) 개념
스토캐스틱이 보여주는 과매수, 과매도 상태
스토캐스틱 종류
스토캐스틱 이용 방법
파이썬 코드 : 바이낸스 API, 판다스 데이터프레임을 이용한 스토캐스틱
스토캐스틱 오실레이터 (Stochastic Oscillator) 개념
스토캐스틱은 주가의 마감 가격(종가)가 어떤 기간 내에서 어느 곳에 있었는지를 나타내주는 보조지표입니다. 최근 n일간의 최고가와 최저가의 범위 내에서 현재 가격의 위치를 표시해 줍니다. 물론 지난 포스팅의 이동평균선처럼 코인 가격에도 적용 가능합니다. 스토캐스틱은 매수세가 강할 때 높은 위치에, 매도세가 강할 때는 낮은 위치에 형성됩니다.
예를 들어, 어떤 주식의 최근 5일간 최고가가 10000원, 최저가가 5000원이었고, 현재가가 9000원이라면 매수세가 강하며, 오르는 추세라는 것을 알 수 있습니다. 반대로 현재가가 6000원이라면 매도세가 강하고 내리는 추세인 것입니다.
이제는 현재가를 스토캐스틱으로 환산해 보겠습니다. 현재가 9000원은 80%입니다. 최고가와 최저가의 차이, 그러니까 가격 변동폭이 5000원이고, 현재가는 최저가로부터 4000원이 높은 위치이므로, 변동폭 대비 80%가 됩니다. 4000/5000 × 100(%) = 80%로부터 구할 수 있습니다. 만약 현재가가 6000원이라면 최저가로부터 1000원이 높은 위치이며, 1000/5000 × 100(%) = 20%가 됩니다.
스토캐스틱이 보여주는 과매수, 과매도 상태
현재가가 5일간의 구간에서 최고가인 10000원이라면, 스토캐스틱은 100%이니까 매수세가 가장 강한 경우입니다. 100%에 가까울수록 과매수 상태, 0%에 가까울수록 과매도 상태라고 판단할 수 있습니다. 그러니까 현재 가격이 어느 정도 위치에 있는지를 알 수 있게 해주는 지표입니다.
스토캐스틱 종류
2가지 종류가 있습니다. 하나는 Fast Stochastic, 다른 하나는 Slow Stochastic입니다. 패스트스토캐스틱은 주가의 변동이 자주 발생해서 단기매매, 빠른 매매에 유리한 지표입니다. 그런데, 패스트 스토캐스틱은 변동이 잦아서 투자 판단에 어려움이 있습니다. 이를 느리게 만든 것이 슬로 스토캐스틱입니다. 위의 ‘스토캐스틱 오실레이터 개념’ 에서 계산했던 스토캐스틱이 바로 Fast 스토캐스틱입니다.
▶스토캐스틱 %K = (현재가 – n일 중 최저가)/(n일 중 최고가 – n일 중 최저가) × 100
▶스토캐스틱 %D = m일 동안 %K의 평균
▶Slow %K = 스토캐스틱 %D
▶Slow %D = t 일 동안의 Slow %K 평균
여기서, n, m, t라는 날짜가 나왔는데요, 보통 (n, m, t) = (5, 3, 3), (10, 6, 6), (14, 3, 3), (20, 12, 12)의 4가지를 주로 사용합니다. (n-m-t) = (5-3-3)의 의미를 살펴보면, 먼저 최근 5일간의 최고점과 최저점을 이용하여 스토캐스틱 %K를 구합니다. 이렇게 구한 %K의 3일 동안의 평균으로 스토캐스틱 %D를, 3일 동안의 스토캐스틱 %D(=Slow %K) 평균으로 Slow %D를 구한다는 의미입니다.
스토캐스틱 이용 방법
차트 보조지표 스토캐스틱은 일정한 방향이 없는 박스권의 구간에서 효과적입니다. 보통 Slow %K선이 20이하의 과매도 구간까지 하락했다가, 다시 상승할 때를 매수 시점으로 보고, 80 이상의 과매수 구간까지 상승했다가 다시 하락할 때를 매도 신호로 봅니다.
좀 더 구체적으로 정리해보면 다음과 같습니다.
▶ 매수 : 스토캐스틱 20 이하, %K 선이 %D를 상향돌파
▶ 매도 : 스토캐스틱 80 이상, %K 선이 %D를 하향돌파
판다스 데이터프레임과 넘파이(numpy) 라는 파이썬 패키지를 함께 사용하면, 상향 또는 하향 돌파할 때의 교차점을 쉽게 찾아낼 수 있습니다.
아래는 numpy의 where 함수를 사용해서 두 스토캐스틱의 교차지점을 찾아내는 코드입니다. np.where(조건, 1, 0) 함수는 조건이 참일 때 1, 거짓일 때 0을 출력합니다. 그러니까 아래 코드는 %K가 %D 보다 위에 있을 때 1을 출력하게 합니다. 따라서 df[‘cross’] 열이 0이었다가 1로 바뀌는 시점이 바로 %K가 %D를 교차한 후 위로 올라가는 시점입니다.
1 |
df['cross'] = np.where(df['slow_k'] > df['slow_d'], 1, 0) |
파이썬 코드 : 바이낸스 API, 판다스 데이터프레임을 이용한 스토캐스틱
지금까지의 과정을 ‘판다스 데이터프레임을 이용한 이등평균선’ 파이썬 코드에 나타내었습니다. 지난 포스팅 파이썬 바이낸스 API 시계열 데이터분석. 판다스 시간 처리의 판다스로 시계열데이터 전처리 (바이낸스 차트 분석)라는 파이썬 코드에 스토캐스틱 부분을 덧붙인 코드입니다. 여기서는 스토캐스틱 부분만 출력하도록 했습니다. 스토캐스틱 계산 부분을 함수 get_stochastic_fast_k, get_stochastic_slow_k, get_stochastic_slow_d에서 확인해 보시기 바랍니다. 이동평균선 구할 때 사용했던 판다스 데이터프레임 함수인 rolling(n).mean()가 중요한 역할을 합니다.
스토캐스틱은 일정한 방향이 없는 박스권의 구간에서 효과적입니다. Slow %K와 Slow %D가 교차하는 지점이 중요한 의미를 지니며, 이 시점을 거래에 참고합니다.
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 |
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_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)) return utc_stt #02-0) simple moving average def get_sma(close, n): sma = close.rolling(n).mean() return sma #02-1) 스토캐스틱 Fast %K = ((현재가 - n기간 중 최저가) / (n기간 중 최고가 - n기간 중 최저가)) * 100 def get_stochastic_fast_k(high, low, close, n): fast_k = ((close - low.rolling(n).min()) / (high.rolling(n).max() - low.rolling(n).min())) * 100 return fast_k #02-2) 스토캐스틱 Slow %K = Fast %K의 m기간 이동평균(SMA) def get_stochastic_slow_k(fast_k, m): slow_k = fast_k.rolling(m).mean() return slow_k #02-3) Slow %D = Slow %K의 t기간 이동평균(SMA) def get_stochastic_slow_d(slow_k, t): slow_d = slow_k.rolling(t).mean() return slow_d #03) 현재시간 timestamp_now = time.time() utc_now = datetime.fromtimestamp(timestamp_now) #04) 바이낸스 API 시계열 데이터 수집 시점부터 현재까지의 bar 데이터(ohlcv 데이터) 획득 nbar = 30d utc_ref = get_time_stt(timestamp_now, '15m', nbar) utc_ref_str = datetime.strftime(utc_ref, '%Y-%m-%d %H:%M:%S') bars = client.get_historical_klines('BTCUSDT', '15m', 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_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 완성 df1 = df_t_stt.join(df_core) df = df1.join(df_t_end) #11) 스토캐스틱 기간 n = 5 m = 3 t = 3 #11-1) 스토캐스틱 Fast %K df['fast_k'] = get_stochastic_fast_k(df['high'], df['low'], df['close'], n) #11-2) 스토캐스틱 Slow %K = Fast %K의 m기간 이동평균(SMA) df['slow_k'] = get_stochastic_slow_k(df['fast_k'], m) #11-3) Slow %D = Slow %K의 t기간 이동평균(SMA) df['slow_d'] = get_stochastic_slow_d(df['slow_k'], t) #11-4) Slow %K와 Slow %D의 교차점 df['cross_sto'] = np.where(df['slow_k'] > df['slow_d'], 1, 0) 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 |
[ BINANCE ACCOUNT ACCESSED ] time_open_utc time_open open high low ... time_close_utc fast_k slow_k slow_d cross_sto 0 2023-01-26 05:30:00 1674711000000 23171.00 23179.16 23130.69 ... 2023-01-26 05:44:59.999 NaN NaN NaN 0 1 2023-01-26 05:45:00 1674711900000 23136.10 23172.07 23130.55 ... 2023-01-26 05:59:59.999 NaN NaN NaN 0 2 2023-01-26 06:00:00 1674712800000 23148.26 23164.11 23120.01 ... 2023-01-26 06:14:59.999 NaN NaN NaN 0 3 2023-01-26 06:15:00 1674713700000 23153.17 23155.38 22897.17 ... 2023-01-26 06:29:59.999 NaN NaN NaN 0 4 2023-01-26 06:30:00 1674714600000 23001.67 23061.63 22979.59 ... 2023-01-26 06:44:59.999 53.494805 NaN NaN 0 5 2023-01-26 06:45:00 1674715500000 23049.23 23091.24 23045.17 ... 2023-01-26 06:59:59.999 69.370680 NaN NaN 0 6 2023-01-26 07:00:00 1674716400000 23088.63 23096.78 23032.19 ... 2023-01-26 07:14:59.999 57.548513 60.137999 NaN 0 7 2023-01-26 07:15:00 1674717300000 23050.79 23057.79 23004.12 ... 2023-01-26 07:29:59.999 51.403896 59.441030 NaN 0 8 2023-01-26 07:30:00 1674718200000 23029.35 23046.79 22951.27 ... 2023-01-26 07:44:59.999 19.957391 42.969933 54.182987 0 9 2023-01-26 07:45:00 1674719100000 22979.58 23014.74 22957.10 ... 2023-01-26 07:59:59.999 10.624699 27.328662 43.246542 0 10 2023-01-26 08:00:00 1674720000000 22965.81 23026.36 22964.02 ... 2023-01-26 08:14:59.999 43.900763 24.827618 31.708738 0 11 2023-01-26 08:15:00 1674720900000 23014.48 23031.07 22944.30 ... 2023-01-26 08:29:59.999 30.575381 28.366948 26.841076 1 12 2023-01-26 08:30:00 1674721800000 22979.00 23028.00 22923.56 ... 2023-01-26 08:44:59.999 82.910006 52.462050 35.218872 1 13 2023-01-26 08:45:00 1674722700000 23025.90 23048.49 22999.10 ... 2023-01-26 08:59:59.999 64.283999 59.256462 46.695153 1 14 2023-01-26 09:00:00 1674723600000 23003.11 23036.69 23000.04 ... 2023-01-26 09:14:59.999 84.583367 77.259124 62.992545 1 15 2023-01-26 09:15:00 1674724500000 23028.55 23029.33 22945.64 ... 2023-01-26 09:29:59.999 35.788041 61.551802 66.022463 0 16 2023-01-26 09:30:00 1674725400000 22968.26 22981.23 22900.00 ... 2023-01-26 09:44:59.999 50.952926 57.108111 65.306346 0 17 2023-01-26 09:45:00 1674726300000 22976.68 23007.06 22955.26 ... 2023-01-26 09:59:59.999 47.612634 44.784534 54.481482 0 18 2023-01-26 10:00:00 1674727200000 22970.70 22988.65 22915.19 ... 2023-01-26 10:14:59.999 20.528203 39.697921 47.196855 0 19 2023-01-26 10:15:00 1674728100000 22927.21 22981.96 22879.39 ... 2023-01-26 10:29:59.999 65.586234 44.575690 43.019382 1 20 2023-01-26 10:30:00 1674729000000 22977.31 22995.72 22926.83 ... 2023-01-26 10:44:59.999 47.364299 44.492912 42.922174 1 21 2023-01-26 10:45:00 1674729900000 22939.86 22957.51 22850.01 ... 2023-01-26 10:59:59.999 56.829035 56.593189 48.553931 1 22 2023-01-26 11:00:00 1674730800000 22939.26 22946.82 22895.48 ... 2023-01-26 11:14:59.999 44.602292 49.598542 50.228214 0 23 2023-01-26 11:15:00 1674731700000 22915.55 22975.60 22909.12 ... 2023-01-26 11:29:59.999 75.080640 58.837322 55.009685 1 24 2023-01-26 11:30:00 1674732600000 22959.57 22980.41 22952.10 ... 2023-01-26 11:44:59.999 83.350491 67.677808 58.704557 1 25 2023-01-26 11:45:00 1674733500000 22970.86 22993.90 22947.31 ... 2023-01-26 11:59:59.999 99.332824 85.921318 70.812149 1 26 2023-01-26 12:00:00 1674734400000 22992.09 23033.00 22966.56 ... 2023-01-26 12:14:59.999 56.057301 79.580205 77.726444 1 27 2023-01-26 12:15:00 1674735300000 22972.57 23065.45 22962.20 ... 2023-01-26 12:29:59.999 84.072155 79.820760 81.774094 0 28 2023-01-26 12:30:00 1674736200000 23042.09 23132.99 23038.36 ... 2023-01-26 12:44:59.999 76.610297 72.246584 77.215850 0 29 2023-01-26 12:45:00 1674737100000 23089.56 23097.07 23081.03 ... 2023-01-26 12:59:59.999 78.258294 79.646915 77.238087 1 [30 rows x 13 columns] |
마치며 …
이번 포스팅에서는 파이썬 바이낸스 API의 get_historical_klines() 함수로 시간, 시가, 고가, 저가, 종가 데이터를 가져온 후 판다스 데이터프레임을 이용하여 차트 보조지표 스토캐스틱을 구해 보았습니다.
pandas DataFrame의 rolling().mean() 함수로 스토캐스틱을 쉽게 구했고, 넘파이의 where 함수를 이용해서 Slow %K, Slow %D의 교차지점을 알아내는 방법도 확인하였습니다. 판다스 데이터프레임에서 쓰는 함수 2개를 기억해주시기 바랍니다.
함께 참고하면 더 좋은 글 :
1. 바이낸스 코인거래소 API Key로 계좌에 접속하는 파이썬 프로그래밍
2. 파이썬 바이낸스 API로 시계열 데이터를 가져오는 파이썬 프로그래밍
3. 바이낸스 API 보안을 위한 환경 변수 설정 : 윈도우 10
4. 파이썬 바이낸스 API 시계열 데이터분석. 판다스 시간 처리
5. 파이썬 바이낸스 API로 차트 분석 : 판다스 이동평균선
6. 파이썬 프로그래밍 time 이해 : timestamp, UTC, KST
7. API와 파이썬 데이터 분석
8. 시계열 데이터 전처리 결과 확인 : pandas DataFrame
9. 파이썬 프로그래밍 시작 (8) 자료구조(Data Structure) : 리스트
10. 파이썬 프로그래밍 시작
참고자료
[1] python-binance Docs >> get_historical_klines
[2] WENDYS(2019), [Python] pandas 주식정보로 스토캐스틱(Stochastic Oscillator) 구하기