전에 언급했듯이 이번 시리즈를 위해 @roostermine 님께서 http://www.cryptodatadownload.com/data/northamerican/ 라고 하는 훌륭한 사이트를 알아봐주셨습니다. 이 사이트에 가보면 여러 거래소의 거래 기록이 모아져 있습니다. 저는 이곳에서 북미의 모든 거래소의 BTCUSD 기록을, Daily와 1-hourly 모두 다 다운받았습니다. 파이쏜 프로그램으로 웹에 있는 링크에서 파일을 직접 다운받을 수도 있을 것 같은데, 그 부분은 본 시리즈의 범위를 넘어서므로
(지금은 제가 그거 어떻게 하는 지 몰라서) 넘어가도록 하겠습니다.
이 사이트에서 제공되는 파일의 형태가 바로 Comma Separated Values 즉 CSV 파일입니다. 이름이 거창하긴 한데, 사실 별 거 없습니다. 텍스트 파일인데, 자료의 값들 사이가 오직 Comma (",") 로만 이뤄어 졌다는 뜻입니다. 그래서 지난 글 #00을 조금만 수정하면 됩니다.
더하여, 이제 데이타가 많아졌으므로, 데이타는 "Data"라고 하는 서브 폴더에 저장하도록 하겠습니다.
아래는 위 사이트에서 다운받은 CSV 파일을 읽어들이는 부분을 함수로 만든 것입니다.
import sys
import numpy as np
from datetime import datetime, timedelta
def conv2date(dateinfo):
"""
Date Format: YYYY-MM-DD HH-AM (or PM)
"""
return datetime.strptime(dateinfo,'%Y-%m-%d %I-%p')
def load_csv_data(fname):
"""
Input: file name with directory information
Assume that we already know the structure of csv file
Output: Time info, Prices, and Volumes: All togerther in a dictionary
"""
print(fname.split('/')[-1])
dates=[]; prices=[]; volumes=[]
## Read Text CSV File
with open(fname,'r') as f:
for i,line in enumerate(f):
if i==0:
print(line)
elif i==1:
headers=line.strip().split(',')
num=len(headers)
print(num,headers)
else:
words=line.strip().split(',')
if num!=len(words):
print(num,len(words),words)
sys.exit("Data entry is incomplete.")
dates.append(conv2date(words[0]))
prices.append(list(map(float,words[2:6])))
volumes.append([float(x) for x in words[6:]])
dates=np.asarray(dates)[::-1]
prices=np.asarray(prices)[::-1,:]
volumes=np.asarray(volumes)[::-1,:]
print(dates.shape,prices.shape,volumes.shape)
print( "Done to read a CSV file!")
return {'date':dates, 'prices':prices, 'volumes':volumes}
몇 가지 설명
그리고 위 함수를 포함해서 프로그램은 아래와 같습니다. (read_csv_data.py3.py)
###--- Main ---###
## Input File
in_dir='./Data/'
in_csv_fn=in_dir+'Bitfinex_BTCUSD_1h.csv'
data=load_csv_data(in_csv_fn)
print(data['date'][0],data['prices'][0],data['volumes'][0])
print(data['date'][-1],data['prices'][-1],data['volumes'][-1])
위 프로그램을 실행하면 다음과 같이 나옵니다.
>> python3 read_csv_data.py3.py
Bitfinex_BTCUSD_1h.csv
Timestamps are UTC timezone,https://www.CryptoDataDownload.com
8 ['Date', 'Symbol', 'Open', 'High', 'Low', 'Close', 'Volume BTC', 'Volume USD']
(15521,) (15521, 4) (15521, 2)
Done to read a CSV file!
2017-10-09 09:00:00 [ 4575.4 4589.5 4568.6 4585.7] [ 6.28890000e+02 2.87889786e+06]
2019-07-18 01:00:00 [ 9617.5 9813.1 9560.3 9748.7] [ 5.45670000e+02 5.28719882e+06]
자료를 읽어들였으니 여기에 #01에서 다뤘던 캔들스틱 그래프 부분을 붙여볼 수도 있겠는데, 여기선 이 자료로 조금 더 놀아보도록 하겠습니다.
위의 2개의 함수 부분은 공통이구요, 아래 실행시키는 부분을 약간 변형했습니다. 여기서는 Bitfinex와 Coinbase 이렇게 거래소 2군데의 자료를 불러와 서로 비교해보도록 하겠습니다.
"read_csv_data+simple_plot.py3.py"
###--- Main ---###
## Parameters
c_name="BTCUSD"
Exchanges=['Bitfinex','Coinbase']
## Input File
in_dir='./Data/'
data=[]
for ex_name in Exchanges:
in_csv_fn=in_dir+'{}_{}_1h.csv'.format(ex_name,c_name)
data.append(load_csv_data(in_csv_fn))
print(ex_name)
print(data[-1]['date'][0],data[-1]['prices'][0],data[-1]['volumes'][0])
print(data[-1]['date'][-1],data[-1]['prices'][-1],data[-1]['volumes'][-1])
print('\n')
### Check consistency between data
if data[0]['date'][-1] != data[1]['date'][-1]:
print('Time stamp is inconsistent',data[0]['date'][-1],data[1]['date'][-1])
sys.exit()
### Cut for last 10 days
xdate= data[0]['date'][-240:]
## Coinbase price - Bitfinex price
yprice_delta= data[1]['prices'][-240:,:]-data[0]['prices'][-240:,:]
###--- Plotting
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.ticker import AutoMinorLocator
##-- Page Setup --##
fig = plt.figure()
fig.set_size_inches(8.5,5) # Physical page size in inches, (lx,ly)
fig.subplots_adjust(left=0.05,right=0.95,top=0.92,bottom=0.05,hspace=0.35,wspace=0.15) ### Margins, etc.
##-- Title for the page --##
suptit="{} Price Difference [{} - {}]".format(c_name,Exchanges[1],Exchanges[0])
fig.suptitle(suptit,fontsize=15) #,ha='left',x=0.,y=0.98,stretch='semi-condensed')
cc=['r','g','b','y']
lname=['Open','High','Low','Close']
##-- Set up an axis --##
ax1 = fig.add_subplot(1,1,1) # (# of rows, # of columns, indicater from 1)
for i in range(4):
ax1.plot(xdate,yprice_delta[:,i],color=cc[i],lw=0.7,ls='-',label=lname[i])
print("{}: Mean={:.2f}, RMSD={:.3f}".format(lname[i],yprice_delta[:,i].mean(),np.sqrt(np.power(yprice_delta[:,i],2).mean())))
ax1.axhline(y=0.,color='0.5',lw=0.5,ls='--')
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%m-%d\n%Y'))
ax1.legend(loc='lower right',bbox_to_anchor=(0.97, 0.05),fontsize=11,ncol=2) # x and y relative location in ax1
##-- Seeing or Saving Pic --##
#- If want to see on screen -#
#plt.show()
#- If want to save to file
outdir = "./Pics/"
outfnm = outdir+"{}_price_diff.{}vs{}.png".format(c_name,Exchanges[1],Exchanges[0])
#fig.savefig(outfnm,dpi=100) # dpi: pixels per inch
fig.savefig(outfnm,dpi=180,bbox_inches='tight') # dpi: pixels per inch
몇 가지 설명
이 프로그램을 실행하면 다음과 같은 결과가 나옵니다.
>> python3 read_csv_data+simple_plot.py3.py
Bitfinex_BTCUSD_1h.csv
Timestamps are UTC timezone,https://www.CryptoDataDownload.com
8 ['Date', 'Symbol', 'Open', 'High', 'Low', 'Close', 'Volume BTC', 'Volume USD']
(15521,) (15521, 4) (15521, 2)
Done to read a CSV file!
Bitfinex
2017-10-09 09:00:00 [ 4575.4 4589.5 4568.6 4585.7] [ 6.28890000e+02 2.87889786e+06]
2019-07-18 01:00:00 [ 9617.5 9813.1 9560.3 9748.7] [ 5.45670000e+02 5.28719882e+06]
Coinbase_BTCUSD_1h.csv
Timestamps are UTC timezone,https://www.CryptoDataDownload.com
8 ['Date', 'Symbol', 'Open', 'High', 'Low', 'Close', 'Volume BTC', 'Volume USD']
(17919,) (17919, 4) (17919, 2)
Done to read a CSV file!
Coinbase
2017-07-01 11:00:00 [ 2505.56 2513.38 2495.12 2509.17] [ 1.14600000e+02 2.87000320e+05]
2019-07-18 01:00:00 [ 9630. 9829.78 9627.08 9795.28] [ 7.17030000e+02 6.97910252e+06]
Open: Mean=15.69, RMSD=26.041
High: Mean=20.48, RMSD=31.632
Low: Mean=11.19, RMSD=33.040
Close: Mean=15.98, RMSD=26.180
관련 글들
Matplotlib List
[Matplotlib] 00. Intro + 01. Page Setup
[Matplotlib] 02. Axes Setup: Subplots
[Matplotlib] 03. Axes Setup: Text, Label, and Annotation
[Matplotlib] 04. Axes Setup: Ticks and Tick Labels
[Matplotlib] 05. Plot Accessories: Grid and Supporting Lines
[Matplotlib] 06. Plot Accessories: Legend
[Matplotlib] 07. Plot Main: Plot
[Matplotlib] 08. Plot Main: Imshow
[Matplotlib] 09. Plot Accessary: Color Map (part1)
[Matplotlib] 10. Plot Accessary: Color Map (part2) + Color Bar
F2PY List
[F2PY] 01. Basic Example: Simple Gaussian 2D Filter
[F2PY] 02. Basic Example: Moving Average
[F2PY] 03. Advanced Example: Using OpenMP
Scipy+Numpy List
[SciPy] 1. Linear Regression (Application to Scatter Plot)
[SciPy] 2. Density Estimation (Application to Scatter Plot)
[Scipy+Numpy] 3. 2D Histogram + [Matplotlib] 11. Plot Main: Pcolormesh
Road to Finance
#00 Read Text File | #01 Draw CandleSticks | #02 Moving Average
#03 Read CSV data