파이썬 바이낸스 API로 차트 분석 : 판다스 이동평균선

파이썬 바이낸스 API로 차트 분석 : 판다스 이동평균선

파이썬 바이낸스 API로 코인 가격에 대한 시계열 데이터 분석을 쉽게 할 수 있습니다. 이번 포스팅에서도 캔들 차트를 이용합니다. 파이썬 바이낸스 API의 get_historical_klines() 함수로 시간, 시가, 고가, 저가, 종가 데이터를 가져온 후 판다스 데이터프레임을 이용하여 이동평균선을 구하는 방법과 이동평균선의 활용법에 대해 알아보겠습니다.


글의 순서

이동평균선 (moving average line)
파이썬 바이낸스 API로 가져온 ohlcv 데이터와 이동평균선
판다스 데이터프레임에서 단순 이동평균선을 구하는 방법
단기, 장기 이동평균선 교차 시점으로 예측하는 추세 전환
파이썬 코드 : 판다스 데이터프레임을 이용한 이동평균선


이동평균선 (moving average line)

이동평균선은 주가나 외환의 기술적 분석에서 사용되는 지표입니다. 물론 코인 가격에도 적용할 수 있습니다. 이동평균선은 종가를 기준으로 계산하며, 짧은 시간 동안에 발생한 극심한 가격 변동을 보다 긴 시간에서의 변화로 바꿔주는 역할을 합니다. 그래서 추세를 확인할 수 있습니다. 주가 차트에서의 이동평균선은 일정기간의 주가를 합한 후 해당 기간으로 나눠서 구합니다.

예를 들어, 10일 이동평균선은 과거 10일 동안의 주가를 평균내서 표시하는 방법입니다. 주가는 예측할 수 없이 움직이지만, 평균을 내보면 방향성이 보이지 않을까?라는 가정으로부터 이동평균선이 나왔습니다.

이동평균선은 크게 3가지 정도로 나눌 수 있습니다. 각각 단순 이동평균 SMA(simple moving average), 지수 이동평균 EMA(exponetial moving average), 가중 이동평균 WMA(weighted moving average)입니다. 이번 포스팅에서는 단순 이동평균 SMA을 구해보겠습니다.



파이썬 바이낸스 API로 가져온 ohlcv 데이터와 이동평균선

파이썬 바이낸스 API는 코인 가격을 시계열 데이터로 쉽게 가져올 수 있도록 get_historical_klines() 함수를 제공합니다. get_historical_klines() 함수에 시작점, 끝점을 인자로 넘겨주면서 시계열 데이터 수집 구간을 정할 수 있는데, 만약 끝점을 넘겨주지 않으면 현재까지의 데이터를 가져옵니다. 인자로 넘겨 줄 시간 간격(시작점, 끝점)은 아래처럼 분(m, minute), 시간(h, hour), 일(d, day), 주(w, week), 월(M, month)로 구분할 수 있습니다.

# valid intervals – 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M

get_historical_klines() 함수의 출력값은 ohlcv라는 캔들 데이터 형태입니다. 여기서, o는 시작가(open), h는 최고가(high), l은 최저가(low), c는 종료가(close), 그리고 v는 총 거래량(volume)을 의미합니다. 캔들 차트로부터 특정 시간 간격에서 가격이 어떻게 변화했는지를 알 수 있고, 각 구간별로 이동평균선도 구할 수 있습니다.


판다스 데이터프레임에서 단순 이동평균선을 구하는 방법

시간 간격을 정해서 나온 ohlcv 데이터, 즉 캔들 데이터로 평균을 구합니다. 주식시장에서처럼 시간 간격을 1일이라고 가정해 보겠습니다. 각 날짜에서 종가가 아래의 리스트처럼 수집되었습니다.

prices = [10, 15, 13, 17, 12, 13, 14, …. ]

5일 이동평균선은 위 리스트에서 5개의 엘리먼트를 이용하여 구합니다. 그러니까 5일 이동평균선의 엘리먼트는 다음과 같이 5개의 엘리먼트를 평균하여 구합니다.
1번째 엘리먼트 : 없음
2번째 엘리먼트 : 없음
3번째 엘리먼트 : 없음
4번째 엘리먼트 : 없음
5번째 엘리먼트 : (10+15+13+17+12)/5
6번째 엘리먼트 : (15+13+17+12+13)/5
7번째 엘리먼트 : (13+17+12+13+14)/5


단기, 장기 이동평균선 교차 시점으로 예측하는 추세 전환

이동평균선은 시장의 추세를 보여줍니다. 5일 이동평균선과 10일 이동평균선이 있다면, 말 그대로 5일이 단기, 10일이 장기가 됩니다. 두 이동평균선이 교차하는 지점이 중요한 의미를 지니며, 이 시점을 거래에 참고합니다. 보통 단기 이동평균선이 장기 이동평균선 아래에 있다가 교차해서 위로 올라가는 시점을 매수 시점으로 봅니다.

판다스 데이터프레임과 넘파이(numpy) 라는 파이썬 패키지를 함께 사용하면, 단기 이동평균선과 장기 이동평균선의 교차점을 쉽게 찾아낼 수 있습니다. 참고로, 넘파이(numpy)는 행렬이나 수치 계산에 최적화되어 있어 데이터 분석에 유용하게 사용할 수 있는 라이브러리입니다.

아래는 numpy의 where 함수를 사용해서 두 이동평균선의 교차지점을 찾아내는 코드입니다. np.where(조건, 1, 0) 함수는 조건이 참일 때 1, 거짓일 때 0을 출력합니다. 그러니까 아래 코드는 단기 이동평균선이 장기 이동평균선보다 위에 있을 때 1을 출력하게 합니다. 따라서 df[‘cross’] 열이 0이었다가 1로 바뀌는 시점이 바로 5일 이동평균선이 10일 이동 평균선을 교차해서 위로 올라가는 시점입니다.

df['cross'] = np.where(df['sma5'] > df['sma10'], 1, 0)
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 == '4h':
        timestamp_stt = timestamp_now - nbar*4*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

#03) 현재시간
timestamp_now = time.time()
utc_now = datetime.fromtimestamp(timestamp_now)

#04) 시계열 데이터 수집 시점부터 현재까지의 bar 데이터(ohlcv 데이터) 획득 
nbar = 30
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) 5일, 10일 이동평균선
df['sma5'] = df['close'].rolling(5).mean()
df['sma10'] = df['close'].rolling(10).mean()

#12) 이동평균선 교차점
df['cross'] = np.where(df['sma5'] > df['sma10'], 1, 0)

print(df)

 [ BINANCE ACCOUNT ACCESSED ]

         time_open_utc      time_open      open      high       low  ...     time_close          time_close_utc       sma5      sma10  cross
0  2023-01-24 07:45:00  1674546300000  23059.83  23066.37  23006.98  ...  1674547199999 2023-01-24 07:59:59.999        NaN        NaN      0      
1  2023-01-24 08:00:00  1674547200000  23054.70  23069.00  23033.80  ...  1674548099999 2023-01-24 08:14:59.999        NaN        NaN      0      
2  2023-01-24 08:15:00  1674548100000  23042.69  23090.25  23042.24  ...  1674548999999 2023-01-24 08:29:59.999        NaN        NaN      0      
3  2023-01-24 08:30:00  1674549000000  23072.93  23089.11  23042.29  ...  1674549899999 2023-01-24 08:44:59.999        NaN        NaN      0      
4  2023-01-24 08:45:00  1674549900000  23078.19  23081.64  23045.00  ...  1674550799999 2023-01-24 08:59:59.999  23060.540        NaN      0      
5  2023-01-24 09:00:00  1674550800000  23052.67  23058.29  22825.00  ...  1674551699999 2023-01-24 09:14:59.999  23033.610        NaN      0      
6  2023-01-24 09:15:00  1674551700000  22920.56  22958.00  22886.87  ...  1674552599999 2023-01-24 09:29:59.999  23008.380        NaN      0      
7  2023-01-24 09:30:00  1674552600000  22918.25  22926.46  22770.00  ...  1674553499999 2023-01-24 09:44:59.999  22955.614        NaN      0      
8  2023-01-24 09:45:00  1674553500000  22809.93  22889.41  22801.86  ...  1674554399999 2023-01-24 09:59:59.999  22910.534        NaN      0      
9  2023-01-24 10:00:00  1674554400000  22852.21  22906.93  22846.12  ...  1674555299999 2023-01-24 10:14:59.999  22876.822  22968.681      0      
10 2023-01-24 10:15:00  1674555300000  22884.56  22924.88  22859.52  ...  1674556199999 2023-01-24 10:29:59.999  22875.984  22954.797      0      
11 2023-01-24 10:30:00  1674556200000  22915.24  22942.70  22897.81  ...  1674557099999 2023-01-24 10:44:59.999  22878.802  22943.591      0      
12 2023-01-24 10:45:00  1674557100000  22931.49  22941.08  22901.01  ...  1674557999999 2023-01-24 10:59:59.999  22897.318  22926.466      0      
13 2023-01-24 11:00:00  1674558000000  22902.51  22920.00  22870.00  ...  1674558899999 2023-01-24 11:14:59.999  22907.682  22909.108      0      
14 2023-01-24 11:15:00  1674558900000  22904.17  22930.38  22885.73  ...  1674559799999 2023-01-24 11:29:59.999  22915.280  22896.051      1      
15 2023-01-24 11:30:00  1674559800000  22923.22  22933.32  22900.00  ...  1674560699999 2023-01-24 11:44:59.999  22912.578  22894.281      1      
16 2023-01-24 11:45:00  1674560700000  22902.47  22926.75  22866.23  ...  1674561599999 2023-01-24 11:59:59.999  22909.812  22894.307      1      
17 2023-01-24 12:00:00  1674561600000  22917.11  22931.65  22882.09  ...  1674562499999 2023-01-24 12:14:59.999  22907.312  22902.315      1      
18 2023-01-24 12:15:00  1674562500000  22891.01  22999.72  22885.62  ...  1674563399999 2023-01-24 12:29:59.999  22925.616  22916.649      1      
19 2023-01-24 12:30:00  1674563400000  22994.94  23035.31  22966.31  ...  1674564299999 2023-01-24 12:44:59.999  22938.592  22926.936      1      
20 2023-01-24 12:45:00  1674564300000  22988.01  22990.13  22957.60  ...  1674565199999 2023-01-24 12:59:59.999  22951.072  22931.825      1      
21 2023-01-24 13:00:00  1674565200000  22963.20  23016.80  22958.22  ...  1674566099999 2023-01-24 13:14:59.999  22967.584  22938.698      1      
22 2023-01-24 13:15:00  1674566100000  23000.97  23012.68  22942.36  ...  1674566999999 2023-01-24 13:29:59.999  22980.808  22944.060      1      
23 2023-01-24 13:30:00  1674567000000  22957.52  22975.00  22785.01  ...  1674567899999 2023-01-24 13:44:59.999  22946.818  22936.217      1      
24 2023-01-24 13:45:00  1674567900000  22827.04  22883.00  22816.79  ...  1674568799999 2023-01-24 13:59:59.999  22921.318  22929.955      0      
25 2023-01-24 14:00:00  1674568800000  22860.37  22946.55  22803.74  ...  1674569699999 2023-01-24 14:14:59.999  22915.900  22933.486      0      
26 2023-01-24 14:15:00  1674569700000  22937.04  22939.69  22800.01  ...  1674570599999 2023-01-24 14:29:59.999  22886.210  22926.897      0      
27 2023-01-24 14:30:00  1674570600000  22853.65  22886.40  22711.00  ...  1674571499999 2023-01-24 14:44:59.999  22863.616  22922.212      0      
28 2023-01-24 14:45:00  1674571500000  22843.16  22961.18  22803.40  ...  1674572399999 2023-01-24 14:59:59.999  22870.200  22908.509      0      
29 2023-01-24 15:00:00  1674572400000  22859.10  22880.52  22750.01  ...  1674573299999 2023-01-24 15:14:59.999  22862.280  22891.799      0      

댓글 남기기