上篇文章,我们讲了回测系统的总体架构。后续会逐步把每个核心组件拆解开来说明。本篇要讲述的是数据获取——Datafeed。为了安装和理解系统简单,我们不使用数据库,而是直接以csv的形式存储数据。 Datafeed需要传入两个参数,data_path是本地存储目录,source是指明下载数据的地方,默认是从quandl下载美股数据。 实现交易数据获取,这里考虑最简化用户环境,暂不使用数据库,直接按年保存至本地csv。 datafeed.py
class DataFeed(object):
def __init__(self,data_path,source='quandl'):
self.data_path = data_path
self.source = source
实现获取数据的接口是downloadorget_data,如果本地已存在,则直接读取对应的csv; 如果没有,则从云端下载。为了实现方便,我们把数据按年存储,这样,就算给定的回测周期不同,也有大量可以复用,不必从头从云端下载。
def download_or_get_data(self,codes,from_year,to_year,authToken=None):
#目录是否存在,如果不存在,则创建
if not os.path.exists(self.data_path):
logger.info("Creating %s directory" % (self.data_path))
os.mkdir(self.data_path)
all = {}
for code in codes:
all_code = []
for year in range(from_year, to_year + 1):
all_code.append(self.__fetch_data(code,year))
df_code = pd.concat(all_code, axis=0)
all[code] = df_code.sort_index()
self.data = all
return all
_fetchdata是获取一个code某一年的数据。如果本地存在该csv文件,则直接读取,否则从云端下载。
def __fetch_data(self,code,year):
fileName = os.path.join(self.data_path, "%s-%d-quandl.csv" % (code, year))
if not os.path.exists(fileName):
logger.info("Downloading %d to %s" % (year, fileName))
if self.source == 'quandl':
self.__fetch_from_quanl(code,year,fileName)
df = pd.read_csv(fileName).copy()
df.index = df['Date']
return df
_fetchfrom_quanl实现从quanl下载对应code的交易数据,code可以美股代码,比如AAPL,AMZN等。
def __fetch_from_quanl(self,code,year,file_name,authToken=None):
download_daily_bars('WIKI', code, year, file_name, authToken)
后续可以扩展加上A股,BTC等数据源。 代码在github上开源ailabx