바이낸스 비트코인 투자 백 테스팅. 파이썬 코인 투자 연습
실감나는 데이터로 파이썬을 익히는 중입니다. 이번에는 바이낸스 비트코인 투자 연습을 해보겠습니다. 파이썬 바이낸스 API로 비트코인 캔들 데이터를 가지고 온 후, 파이썬 판다스로 변동성 돌파 전략을 백 테스팅 해 보는 것이 이 포스팅의 목적입니다.
글의 순서
변동성 돌파 전략
변동성 돌파전략 백 테스팅 : 2022년 12월 바이낸스 비트코인 시계열 데이터
파이썬 코드 : 바이낸스 API, 판다스로 변동성 돌파 전략 백 테스팅
변동성 돌파 전략 (Volatility Break-out strategy)
원리가 간단하고, 코드로 구현하기 쉬워서 많은 분들이 변동성 돌파 전략을 자동 투자 알고리즘으로 고려하고 있습니다. 변동성 돌파 전략은 많은 주식 HTS(Home Trading System)에서 Wiliams %R, Wiliams A/D라는 보조지표로 만들어져 있기도 합니다.
변동성 돌파 전략을 개발한 래리 윌리암스는 하루 단위의 캔들 차트를 이용합니다. 전날의 캔들에서 최고가(high)와 최저가(low)의 차이인 Range를 가져온 후, 오늘 시가에 Range의 K배가 되었을 때 매수하는 기법입니다. 매도 시점은 다음 날이며, 매도 가격은 시작가입니다. K배라고 말씀드렸는데요. 윌리암스는 0.5를 추천합니다.
예를 들어보겠습니다.
관심 있는 주식의 어제 최고가가 5천원, 최저가가 4천원이었고, 오늘 시작가가 4500으로 시작했다면, 그 주식이 얼마가 되었을 때 사야 할까요? K를 0.5라고 가정하면, 오늘 시가보다 어제 Range의 50% 만큼 올랐을 때 매수하는 것이므로,
4500 + (5000-4000) × 0.5 = 5000 으로부터
5천원이 되었을 때 매수한다는 것을 알 수 있습니다.
변동성 돌파전략 백 테스팅 과정 : 2022년 12월 바이낸스 비트코인 시계열 데이터
백 테스팅은 과거의 데이터를 바탕으로 특정 알고리즘의 유효성을 판단하거나, 거래 전략을 수립하는데 가장 유용하게 쓸 수 있는 방법입니다. 다만 거래 조건 들을 시험해 보기 위해서는 결과에 영향을 미치는 변수들을 입력 값으로 처리할 수 있게 해줘야 합니다. 이번 포스팅에서는 K 값을 입력으로 처리할 수 있도록 하였습니다.
(1) 파이썬 바이낸스 API로 12월 한 달 동안의 캔들 데이터 가져오기
파이썬 바이낸스 API의 get_historical_klines() 함수로 코인 가격을 시계열 데이터로 쉽게 가져올 수 있습니다. 이 함수의 출력값은 ohlcv라는 캔들 데이터 형태입니다. 여기서, o는 시작가(open), h는 최고가(high), l은 최저가(low), c는 종료가(close), 그리고 v는 총 거래량(volume)을 의미합니다. 시작가를 시가, 최고가를 고가, 최저가를 저가, 종료가를 종가라고도 부릅니다.
(2) 하루 단위의 Range 계산 : Range = 최고가 – 최처가
하루 단위로 고가와 저가의 차이인 Range를 구합니다. 우리말로 Range는 범위인데, 말 그대로 가격이 움직인 범위를 말합니다.
(3) 당일 매수 가격 계산 : price_buy = Range × K
하루 단위의 매수 가격을 계산합니다. 이 포스팅에서는 K값을 0.5로 설정하고 계산해 보겠습니다. 이 K 값은 우리가 설정하기 나름인 값입니다. 시장 상황에 따라 이익을 얻을 수 있는 K값은 달라집니다.
오늘 매수 가격을 구할 때 어제의 변동성(Range × K)을 사용합니다. 그래서 어제의 변동성(volatility)이 오늘로 오도록 판다스 shift 함수를 사용하여 하루씩 밀었습니다.
(4) 당일 이익 계산 : 이익(profit) = 종가(close) – 매수가(price_buy)
종료가에서 매수 가격을 빼면 그날의 이익이 됩니다. 만약 종료가가 매수가 보다 낮다면 손해를 본 것입니다. 원래 변동성 돌파 전략에서는 어제 사고 오늘 시작가에 파는데, 이 포스팅에서는 백 테스팅을 간단하게 하기 위해 그날의 종가에 파는 것으로 하였습니다.
(5) 한 달 동안의 이익 계산
하루 하루 이익의 총합. 2022년 12월 1일부터 5일까지의 데이터는 변동성 돌파 전략 백 테스팅 결과가 이익이 아니라 손해임을 보여주고 있습니다.
※ 참고로, 이 포스팅에서는 거래 수수료를 0%로 가정하고 계산하였습니다
파이썬 코드 : 바이낸스 API, 판다스로 변동성 돌파 전략 백 테스팅
지금까지의 과정을 ‘판다스 변동성 돌파 전략 백 테스팅’ 파이썬 코드에 나타내었습니다. 앞에서 설명한 변동성 돌파전략 구현 과정을 옮긴 것입니다. 데이터를 가져오는 기간을 입력할 수 있도록 하였으며, K값도 입력으로 처리할 수 있게 하여 K값의 변화에 따라 전체 이익이 어떻게 변하는 지 확인할 수 있도록 하였습니다.
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 |
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) 시계열 데이터 수집 : 2022.12.01 ~ 12.05 tstt_utc = '2022-12-01 00:00:00' tend_utc = '2022-12-05 23:59:59' bars = client.get_historical_klines('BTCUSDT', '1d', tstt_utc, tend_utc, limit=1000) #03) ohlcv 데이터를 판다스 데이터프레임에 저장 df_core = pd.DataFrame(bars) #04) ohlcv 데이터만 추출 for i in bars: del i[7:] df_core = pd.DataFrame(bars) #05) 데이터프레임 열 이름 붙여주기 df_core = pd.DataFrame(bars, columns=['time_open','open','high','low','close','volume','time_close']) #06) 데이터프레임 열 type을 실수형으로 변환 df_core = df_core.astype({'open' : 'float', 'high' : 'float', 'low' : 'float', 'close' : 'float', 'volume' : 'float'}) print('\n','#06) ---') print(df_core) #07) 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)) #08) 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']) #09) UTC 데이터를 추가하여 pandas DataFrame 완성 df1 = df_t_stt.join(df_core) df = df1.join(df_t_end) print('\n','#10) ---') print(df) # ====== 판다스로 변동성 돌파전략 구현 ====== # 입력값 예: K = 0.5 K = 0.5 #10) Range = 최고가 - 최처가 : Range = high - low df['range'] = df['high'] - df['low'] #11) 돌파할 변동성 volat = Range * K df['volat'] = df['range']*K #12) 오늘 매수가 = 오늘 시작가 + 어제 Range * K #12-1) volat 데이터 다음 날로 밀기 df['volat'] = df['volat'].shift(1) #12-2) 매수 목표가 df['price_buy'] = df['open'] + df['volat'] print('\n', df) #13) 이익 계산 price_sell_target = [] price_sell = [] profit = [] # price_st : price_sell_target # row[11] : price_buy, # row[2] : open, # row[3] : high, # row[5] : close print('#13) row operation') for idx, row in df.iterrows(): if(row[11] > row[2] and row[11] < row[3]): price_st = row[5] price_sell_target.append(price_st) print(idx, price_sell_target[idx]) price_sell.append(row[5]) profit.append(row[5]-row[11]) else: price_sell_target.append(0.0) price_sell.append(0.0) profit.append(0.0) df_profit_pre = zip(t_stt, price_sell_target, price_sell, profit) df_profit = pd.DataFrame(df_profit_pre, columns=['Dates','Price_sell_target','Price_sell','profit']) print('\n', df_profit) #14) 이익 총합 print('\n #14) total profit :', df_profit.profit.sum()) |
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 |
[ BINANCE ACCOUNT ACCESSED ] #06) --- time_open open high low close volume time_close 0 1669852800000 17165.53 17324.00 16855.01 16977.37 232818.18218 1669939199999 1 1669939200000 16978.00 17105.73 16787.85 17092.74 202372.20620 1670025599999 2 1670025600000 17092.13 17188.98 16858.74 16885.20 154542.57306 1670111999999 3 1670112000000 16885.20 17202.84 16878.25 17105.70 178619.13387 1670198399999 4 1670198400000 17106.65 17424.25 16867.00 16966.35 233703.29225 1670284799999 #10) --- time_open_utc time_open open high low close volume time_close time_close_utc 0 2022-12-01 1669852800000 17165.53 17324.00 16855.01 16977.37 232818.18218 1669939199999 2022-12-01 23:59:59.999 1 2022-12-02 1669939200000 16978.00 17105.73 16787.85 17092.74 202372.20620 1670025599999 2022-12-02 23:59:59.999 2 2022-12-03 1670025600000 17092.13 17188.98 16858.74 16885.20 154542.57306 1670111999999 2022-12-03 23:59:59.999 3 2022-12-04 1670112000000 16885.20 17202.84 16878.25 17105.70 178619.13387 1670198399999 2022-12-04 23:59:59.999 4 2022-12-05 1670198400000 17106.65 17424.25 16867.00 16966.35 233703.29225 1670284799999 2022-12-05 23:59:59.999 time_open_utc time_open open high low ... time_close time_close_utc range volat price_buy 0 2022-12-01 1669852800000 17165.53 17324.00 16855.01 ... 1669939199999 2022-12-01 23:59:59.999 468.99 NaN NaN 1 2022-12-02 1669939200000 16978.00 17105.73 16787.85 ... 1670025599999 2022-12-02 23:59:59.999 317.88 234.495 17212.495 2 2022-12-03 1670025600000 17092.13 17188.98 16858.74 ... 1670111999999 2022-12-03 23:59:59.999 330.24 158.940 17251.070 3 2022-12-04 1670112000000 16885.20 17202.84 16878.25 ... 1670198399999 2022-12-04 23:59:59.999 324.59 165.120 17050.320 4 2022-12-05 1670198400000 17106.65 17424.25 16867.00 ... 1670284799999 2022-12-05 23:59:59.999 557.25 162.295 17268.945 [5 rows x 12 columns] #13) row operation 3 17105.7 4 16966.35 Dates Price_sell_target Price_sell profit 0 2022-12-01 0.00 0.00 0.000 1 2022-12-02 0.00 0.00 0.000 2 2022-12-03 0.00 0.00 0.000 3 2022-12-04 17105.70 17105.70 55.380 4 2022-12-05 16966.35 16966.35 -302.595 #14) total profit : -247.21500000000015 |
마치며 …
이번 포스팅에서는 판다스 데이터프레임을 바이낸스 비트코인 투자 연습으로 익혀보았습니다. 파이썬 바이낸스 API로 비트코인 캔들 데이터를 가지고 온 후, 파이썬 판다스로 변동성 돌파 전략을 백 테스팅 하였습니다. 이번 포스팅에서는 변동성 돌파 전략의 효과도 보셨겠지만, 무엇보다 데이터 분석에 유용하게 쓸 수 있는 판다스 데이터프레임의 열 계산 방법에 익숙해지셨길 바랍니다.
함께 참고하면 더 좋은 글 :
1. 바이낸스 비트코인 변동성 돌파전략 백 테스팅 결과
2. 바이낸스 코인거래소 API Key로 계좌에 접속하는 파이썬 프로그래밍
3. 파이썬 바이낸스 API로 시계열 데이터를 가져오는 파이썬 프로그래밍
4. 바이낸스 API 보안을 위한 환경 변수 설정 : 윈도우 10
5. 파이썬 바이낸스 API 시계열 데이터분석. 판다스 시간 처리
6. 파이썬 바이낸스 API로 차트 분석 : 판다스 이동평균선
7. 파이썬 프로그래밍 time 이해 : timestamp, UTC, KST
8. API와 파이썬 데이터 분석
9. 시계열 데이터 전처리 결과 확인 : pandas DataFrame
10. 파이썬 프로그래밍 시작 (8) 자료구조(Data Structure) : 리스트
11. 파이썬 프로그래밍 시작
참고자료
[1] python-binance Docs >> get_historical_klines
[2] 조코딩 JoCoding, 하락장에서도 수익나는 비트코인 자동매매 완성하기