数字量化系统之数字货币行情数据获取及分析
加密货币行情数据获取及分析。
一、获取数据
交易对的ticker数据获取
单个交易对的ticker数据获取及处理多个交易对的ticker数据获取及处理
交易对的K线数据数据获取
单个交易对的K线数据获取及处理多个交易对的K线数据获取及处理
工具模块
- 1、request
- 2、Pandas
- 3、datetime
我们这里以okex交易所提供的API接口为例,获取这两组数据,注意,这里因为GFW的关系无法直接访问,所以,需要使用代理科学上网。
二、代码实战
编辑器
我们使用 Pycharm 编辑器,Conda作为python的运行环境。

代码
main.py
# -*- coding:utf-8 -*-
"""
@author: Corwien
@file: main.py
@time: 19/11/30 20:18
"""
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
import pandas as pd
from datetime import datetime
# 如果数据多,会自动隐藏,这里设置不自动隐藏
pd.set_option('expand_frame_repr', False)
# ----------------- 代理相关 Begin -----------------
# 使用代理
# proxies = {'https': "socks5://root:W123456@167.179.117.142:10404"}
#proxies = {'https': "http://root:W123456@167.179.117.142:10404"}
# 这里的代理IP是从showdocsocks软件「复制终端代理命令」找到的
proxies = {'https': "http://127.0.0.1:1087", 'http': "http://127.0.0.1:1087"}
# ----------------- 代理相关 End -----------------
# HTTPS certificate warning(去掉https警告提示)
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
def get_single_ticker_data(symbol):
'''
单个交易对的ticker数据获取
'''
ticker_url = 'https://www.okex.com/api/v1/ticker.do?symbol={}'.format(symbol)
# 异常处理,api请求超时等问题,设置超时时间,防止程序阻塞
try:
res_obj = requests.get(ticker_url, timeout=5, verify=False, proxies=proxies) # 获取到的是一个对象
except Exception as e:
print('错误:', e)
return None
ticker_df = None
json_obj = res_obj.json()
if res_obj.status_code == 200:
if 'error_code' in res_obj:
print('错误码:{}'.format(json_obj['error_code']))
else:
raw_df = pd.DataFrame(json_obj) # json -> df
ticker_df = pd.DataFrame(index=[0], columns=['datetime', 'symbol'] + raw_df.index.tolist())
ticker_df['datetime'] = pd.to_datetime(datetime.utcnow())
ticker_df['symbol'] = symbol.replace('_', '/').upper()
ticker_df[raw_df.index.tolist()] = raw_df['ticker'].values
else:
print('状态码:{}'.format(res_obj.status_code))
return ticker_df
def get_tickers_data(symbols):
"""
多个交易对的数据获取和处理
:param symbols:
:return:
"""
tickers_df = pd.DataFrame()
for symbol in symbols:
ticker_df = get_single_ticker_data(symbol)
if ticker_df is None:
continue
tickers_df = tickers_df.append(ticker_df)
return tickers_df
def get_single_kline_data(symbol, kline_type='1min', size=20):
'''
单个交易对的K线数据获取
size 最大2000
'''
kline_url = 'https://www.okex.com/api/v1/kline.do?symbol={}&type={}&size={}'.format(symbol, kline_type, size)
# 异常处理,api请求超时等问题,设置超时时间,防止程序阻塞
try:
res_obj = requests.get(kline_url, timeout=5, verify=False, proxies=proxies) # 获取到的是一个对象
except Exception as e:
print('错误:', e)
return None
kline_df = None
json_obj = res_obj.json()
if res_obj.status_code == 200:
if 'error_code' in res_obj:
print('错误码:{}'.format(json_obj['error_code']))
else:
raw_df = pd.DataFrame(json_obj) # json ->
kline_df = raw_df.copy()
kline_df.columns = ['datetime', 'open', 'high', 'low', 'close', 'vol']
kline_df['datetime'] = pd.to_datetime(kline_df['datetime'], unit='ms')
kline_df['symbol'] = symbol.replace('_', '/').upper()
else:
print('状态码:{}'.format(res_obj.status_code))
return kline_df
def get_klines_data(symbols, kline_type='1min', size=5):
"""
多个交易对的K线数据获取和处理
:param symbols:
:return:
"""
klines_df = pd.DataFrame()
for symbol in symbols:
kline_df = get_single_kline_data(symbol, kline_type, size)
if kline_df is None:
continue
klines_df = klines_df.append(kline_df)
return klines_df
def main():
"""
主函数
"""
# 1.获取交易对的ticker信息
# 1.1获取单个交易对
#symbol = 'btc_usdt'
#ticker_df = get_single_ticker_data(symbol)
#print(ticker_df)
# 1.2 获取多个交易对的ticker数据
#symbols = ['btc_usdt', 'eth_usdt', 'eos_usdt']
#tickers_df = get_tickers_data(symbols)
#print(tickers_df)
# 2.获取交易对的K线信息
# 2.1 获取单个交易对K线
#symbol = 'btc_usdt'
#kline_df = get_single_kline_data(symbol, kline_type='1hour')
#print(kline_df)
# 2.2 多个交易对的K线数据获取及处理
symbols = ['btc_usdt', 'eth_usdt', 'eos_usdt', 'bch_usdt']
klines_df = get_klines_data(symbols)
print(klines_df)
if __name__ == '__main__':
main()
运行上边的代码,打印多个交易对的K线数据:
/Users/kaiyiwang/anaconda3/bin/python /Users/kaiyiwang/Code/quant/bitLearn/main.py
datetime open high low close vol symbol
0 2019-12-01 04:36:00 7283.9 7286.2 7283.8 7286.2 1.22558669 BTC/USDT
1 2019-12-01 04:37:00 7286.2 7290.6 7286.2 7288.5 16.87775011 BTC/USDT
2 2019-12-01 04:38:00 7289.7 7305.4 7289.7 7294 72.68640118 BTC/USDT
3 2019-12-01 04:39:00 7292.6 7322.9 7292.6 7316.1 188.53823 BTC/USDT
4 2019-12-01 04:40:00 7314.8 7314.8 7302.3 7308.9 5.07364692 BTC/USDT
0 2019-12-01 04:36:00 147.13 147.24 147.12 147.24 139.439291 ETH/USDT
1 2019-12-01 04:37:00 147.24 147.27 147.24 147.26 75.129606 ETH/USDT
2 2019-12-01 04:38:00 147.26 147.53 147.26 147.37 783.329827 ETH/USDT
3 2019-12-01 04:39:00 147.36 147.78 147.36 147.63 361.270089 ETH/USDT
4 2019-12-01 04:40:00 147.64 147.64 147.44 147.55 91.603368 ETH/USDT
0 2019-12-01 04:36:00 2.686 2.687 2.686 2.687 426.5304 EOS/USDT
1 2019-12-01 04:37:00 2.687 2.688 2.687 2.687 773.2268 EOS/USDT
2 2019-12-01 04:38:00 2.687 2.693 2.687 2.69 26926.8609 EOS/USDT
3 2019-12-01 04:39:00 2.69 2.692 2.69 2.692 2153.2226 EOS/USDT
4 2019-12-01 04:40:00 2.692 2.692 2.69 2.692 2329.0641 EOS/USDT
0 2019-12-01 04:36:00 211.36 211.51 211.36 211.51 5.4225 BCH/USDT
1 2019-12-01 04:37:00 211.51 211.51 211.35 211.45 40.0456 BCH/USDT
2 2019-12-01 04:38:00 211.52 211.79 211.46 211.54 68.4088 BCH/USDT
3 2019-12-01 04:39:00 211.57 211.92 211.57 211.9 20.8741 BCH/USDT
4 2019-12-01 04:40:00 211.83 211.83 211.63 211.74 9.0196 BCH/USDT
Process finished with exit code 0
我们已经可以成功获取Okex提供的行情数据了,但是可以看到上边的代码写的不够好,不够清爽简洁,对于通用的代码,我们可以直接将其抽出来放到工具文件中,然后在 main.py 中直接引入即可。
代码优化
将 main.py 中获取数据的方法都抽到帮助文件cyptocoin_data_utils.py:
# -*- coding:utf-8 -*-
"""
@author: Corwien
@file: cyptocoin_data_utils.py
@time: 19/12/1 12:47
"""
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
import pandas as pd
from datetime import datetime
# ----------------- 代理相关 Begin -----------------
# 使用代理
# proxies = {'https': "socks5://root:W123456@167.179.117.142:10404"}
#proxies = {'https': "http://root:W123456@167.179.117.142:10404"}
# 这里的代理IP是从showdocsocks软件「复制终端代理命令」找到的
proxies = {'https': "http://127.0.0.1:1087", 'http': "http://127.0.0.1:1087"}
# ----------------- 代理相关 End -----------------
# HTTPS certificate warning(去掉https警告提示)
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
def get_single_ticker_data(symbol):
'''
单个交易对的ticker数据获取
'''
ticker_url = 'https://www.okex.com/api/v1/ticker.do?symbol={}'.format(symbol)
# 异常处理,api请求超时等问题,设置超时时间,防止程序阻塞
try:
res_obj = requests.get(ticker_url, timeout=5, verify=False, proxies=proxies) # 获取到的是一个对象
except Exception as e:
print('错误:', e)
return None
ticker_df = None
json_obj = res_obj.json()
if res_obj.status_code == 200:
if 'error_code' in res_obj:
print('错误码:{}'.format(json_obj['error_code']))
else:
raw_df = pd.DataFrame(json_obj) # json -> df
ticker_df = pd.DataFrame(index=[0], columns=['datetime', 'symbol'] + raw_df.index.tolist())
ticker_df['datetime'] = pd.to_datetime(datetime.utcnow())
ticker_df['symbol'] = symbol.replace('_', '/').upper()
ticker_df[raw_df.index.tolist()] = raw_df['ticker'].values
else:
print('状态码:{}'.format(res_obj.status_code))
return ticker_df
def get_tickers_data(symbols):
"""
多个交易对的数据获取和处理
:param symbols:
:return:
"""
tickers_df = pd.DataFrame()
for symbol in symbols:
ticker_df = get_single_ticker_data(symbol)
if ticker_df is None:
continue
tickers_df = tickers_df.append(ticker_df)
return tickers_df
def get_single_kline_data(symbol, kline_type='1min', size=20):
'''
单个交易对的K线数据获取
size 最大2000
'''
kline_url = 'https://www.okex.com/api/v1/kline.do?symbol={}&type={}&size={}'.format(symbol, kline_type, size)
# 异常处理,api请求超时等问题,设置超时时间,防止程序阻塞
try:
res_obj = requests.get(kline_url, timeout=5, verify=False, proxies=proxies) # 获取到的是一个对象
except Exception as e:
print('错误:', e)
return None
kline_df = None
json_obj = res_obj.json()
if res_obj.status_code == 200:
if 'error_code' in res_obj:
print('错误码:{}'.format(json_obj['error_code']))
else:
raw_df = pd.DataFrame(json_obj) # json ->
kline_df = raw_df.copy()
kline_df.columns = ['datetime', 'open', 'high', 'low', 'close', 'vol']
kline_df['datetime'] = pd.to_datetime(kline_df['datetime'], unit='ms')
kline_df['symbol'] = symbol.replace('_', '/').upper()
else:
print('状态码:{}'.format(res_obj.status_code))
return kline_df
def get_klines_data(symbols, kline_type='1min', size=5):
"""
多个交易对的K线数据获取和处理
:param symbols:
:return:
"""
klines_df = pd.DataFrame()
for symbol in symbols:
kline_df = get_single_kline_data(symbol, kline_type, size)
if kline_df is None:
continue
klines_df = klines_df.append(kline_df)
return klines_df
在 main.py 中引入上边的文件(包):
# -*- coding:utf-8 -*-
"""
@author: Corwien
@file: main.py
@time: 19/11/30 20:18
"""
import pandas as pd
import cyptocoin_data_utils as cdu
# 如果数据多,会自动隐藏,这里设置不自动隐藏
pd.set_option('expand_frame_repr', False)
def main():
"""
主函数
"""
# 1.获取交易对的ticker信息
# 1.1获取单个交易对
#symbol = 'btc_usdt'
#ticker_df = cdu.get_single_ticker_data(symbol)
#print(ticker_df)
# 1.2 获取多个交易对的ticker数据
#symbols = ['btc_usdt', 'eth_usdt', 'eos_usdt']
#tickers_df = cdu.get_tickers_data(symbols)
#print(tickers_df)
# 2.获取交易对的K线信息
# 2.1 获取单个交易对K线
#symbol = 'btc_usdt'
#kline_df = cdu.get_single_kline_data(symbol, kline_type='1hour')
#print(kline_df)
# 2.2 多个交易对的K线数据获取及处理
symbols = ['btc_usdt', 'eth_usdt', 'eos_usdt', 'bch_usdt']
klines_df = cdu.get_klines_data(symbols)
# 保存数据到本地
klines_df.to_csv('./cyptocoin_sample.csv', index=False) # index=False 去掉索引
print(klines_df)
if __name__ == '__main__':
main()
通过优化后,我们的项目是不是很简洁清晰很多。
保存数据到本地
# 保存数据到本地
klines_df.to_csv('./cyptocoin_sample.csv', index=False) # index=False 去掉索引
为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)