好久之前听过vnpy,前两天看到还在更新,觉得可以研究一下。
主要是对其中的K线的UI
写期货回测最主要的是图形化的工具比较缺,都是用数字图表,不直观。前段时间用plot画图,发现画出来的都是静态的,且数据量多后慢的要死。
看起来这个UI画的K线要好很多,值得研究一下。
网上有说明vnpy可保存为sqlite和mongdb.
一开始用的是sqlite,原因是无需安装,直接用,按照说明下载对应的组件,因为数据源这块vnpy已经抽象出BaseDatabase,需要用到哪一种组件再实现对应的组件,sqlite实现为vnpy-sqlite
先把数据准备好:
图中表示的是RBL9的1分钟的数据,我们只需要将其转换为vnpy识别的格式,然后利用vnpy提供的接口即可实现数据存入sqlite,最终通过
save_bar_data(self, bars: List[BarData])
接口将数据存入,不过我在存入的时候遇到了不小的问题:
1)sqlite要求存入时间时是一个指定格式的字符串,而提供的组件还是按照datetime格式存入的,导致无论如何存不进去。后来没有办法,强行在存入时修改为字符串,存进去的格式如下:
然后发现存进去了,取的时候又是按照datetime格式取出来的,而且 取的时候用的是这个接口:
load_bar_data, 一定要求输入开始时间和结束时间,使用datetime转换出来的格式为2021-01-05 00:00:00,这个东西作为参数直接就获取不到数据。实在不想重头改到尾,放弃使用sqlite,考虑使用mongodb(网上能成功的我看了一下应该代码比较旧了,我拉取的代码为:
因此之前网上的所有的做法由于代码的变动都失效了。
改用mongodb的比较容易 ,直接到官网上下载mongodb-windows-x86_64-5.0.6-signed.msi,进行安装后运行即可。
然后在vnpy的运行目录加上mongo的配置:
至此,主要的工作就做完了,剩下的就是将表格中的数据与
BarData的数据对齐即可
由于datetime是一个时间数据,在表格中我们是用两个字段来表示的,这一步比较费点精神:
datetime_format = '%Y-%m-%d %H:%M'
t = data['时间'].astype('str')
data['时间'] = pd.to_datetime(data['日期'] + " " + t.str[:-2] + ":" + t.str[-2:], format=datetime_format)
del data['日期']
然后把字段名再进行对齐:
data.columns = ['exchange', 'symbol', 'datetime', 'open', 'high', 'low', 'close', 'volume', '成交额',
'open_interest', 'interval']
最后通过接口把数据存入mongdb即可:
# 封装函数
def move_df_to_mongodb(imported_data: pd.DataFrame):
bars = []
start = None
count = 0
for row in imported_data.itertuples():
bar = BarData(
symbol=row.symbol,
exchange=row.exchange,
datetime=row.datetime,
interval=row.interval,
volume=row.volume,
open_price=row.open,
high_price=row.high,
low_price=row.low,
close_price=row.close,
open_interest=row.open_interest,
gateway_name="DB",
)
bars.append(bar)
# do some statistics
count += 1
if not start:
start = bar.datetime
end = bar.datetime
# insert into database
mongo_manager.save_bar_data(bars)
print(f"Insert Bar: {count} from {start} - {end}")
注意,存的过程会报错,这个没有去深究,因为我确定已经存成功了:
后面回头看了下错误细节:
百度搜索一下,确认是由于pymongo从4.1开始移除了update等相关函数,所以需要安装早一点版本的,看了一下系统的确实安装了4.0.1的pymongo,查看 vnpy_mongodb-1.0.1源码,在setup.cfg中查找到依赖项:
将之前的pymongo删除,安装指定版本,再次运行save_data.py, 发现错误消失
存完了以后可以直接运行candle_chart中的run.py,如果没有数据,运行的效果图如下:
数据存入成功后运行的效果图如下:
最后附上save_data.py代码:
from vnpy.trader.constant import (Exchange, Interval)
import pandas as pd
from vnpy.trader.object import (BarData, TickData)
from vnpy_mongodb import Database
mongo_manager = Database()
# 封装函数
def move_df_to_mongodb(imported_data: pd.DataFrame):
bars = []
start = None
count = 0
for row in imported_data.itertuples():
bar = BarData(
symbol=row.symbol,
exchange=row.exchange,
datetime=row.datetime,
interval=row.interval,
volume=row.volume,
open_price=row.open,
high_price=row.high,
low_price=row.low,
close_price=row.close,
open_interest=row.open_interest,
gateway_name="DB",
)
bars.append(bar)
# do some statistics
count += 1
if not start:
start = bar.datetime
end = bar.datetime
# insert into database
mongo_manager.save_bar_data(bars)
print(f"Insert Bar: {count} from {start} - {end}")
if __name__ == "__main__":
# 读取需要入库的csv文件,该文件是用gbk编码
data = pd.read_csv('RBL9.csv', encoding='gbk')
# 将csv文件中 `市场代码`的 SC 替换成 Exchange.SHFE SHFE
data['市场代码'] = Exchange.SHFE
# 增加一列数据 `inteval`,且该列数据的所有值都是 Interval.MINUTE
data['interval'] = Interval.MINUTE
# 明确需要是float数据类型的列
float_columns = ['开', '高', '低', '收', '成交量', '持仓量']
for col in float_columns:
data[col] = data[col].astype('float')
datetime_format = '%Y-%m-%d %H:%M'
t = data['时间'].astype('str')
data['时间'] = pd.to_datetime(data['日期'] + " " + t.str[:-2] + ":" + t.str[-2:], format=datetime_format)
del data['日期']
data.columns = ['exchange', 'symbol', 'datetime', 'open', 'high', 'low', 'close', 'volume', '成交额',
'open_interest', 'interval']
move_df_to_mongodb(data)
最后感谢网上一个哥们的代码,很多做了参照,一下子找不到他的相关链接,后面找着了会补上参照的相关文章。