一、背景
文章版本: V1.0
介绍一下如何使用市面相对“免费”的价格获得中高频的股票、债券以及大宗商品市场的历史行情数据,除了baostock、akshare 常用的数据获取源以外,还有迅投旗下的QMT平台,本文记录一下从申请账号到数据下载、数据简单清洗、数据存储等方面,方便日后自己反复调用和回忆。
注:此文章更新与2024年2月份,对应的xtquant中xtdata的最后更新日期是2024-01-19
,此后的版本没有测试,但是对于这种数据下载的代码,官方不太会更新,最多是下载权限的更改。
二、怎么获取账号
我使用的是国金证券的股票账户,然后客户经理帮忙开的,有兴趣的可以联系自家的客户经理,每个券商的门槛都不一样。这样开通的迅投账号,数据权限包含了一部分的tick数据,和所有的其他周期的数据,基本足够了。
三、数据下载前的准备
- 下载xtquant压缩包xtquant
- 准备python运行环境
- 准备工程目录,将xtquant解压,作为库使用
- 登录
国金证券QMT交易端
,选择极简
模式
四、数据下载
以大宗商品为例,每个合约的代码,在官方文档中都有给出: 主力连续合约及加权
4.1 下载到本地
from xtquant_old import xtdata
stock_lists = ['rb2401.SF']
xtdata.download_history_data2(stock_lists,period='tick',start_time="20231208",end_time="20240208")
执行完后,数据会下载保存在本地,具体路径D:\国金证券QMT交易端\userdata_mini\datadir\SF\0\rb2405
4.2 加载本地数据进行处理
from xtquant_old import xtdata
stock_lists = ['rb2401.SF']
data = xtdata.get_market_data_ex([],stock_lists,period='tick')
下载完成的tick格式数据,大致如下,加载后为dict格式
{'rb2401.SF': time lastPrice ... settlementPrice transactionNum
20231208085900 1701997140500 3995.0 ... 0.0 0
20231208090000 1701997200500 3995.0 ... 0.0 0
20231208090001 1701997201000 3996.0 ... 0.0 0
20231208090001 1701997201500 3995.0 ... 0.0 0
20231208090002 1701997202000 3996.0 ... 0.0 0
... ... ... ... ... ...
20240115145343 1705301623000 3946.0 ... 0.0 0
20240115145346 1705301626000 3946.0 ... 0.0 0
20240115145349 1705301629000 3946.0 ... 0.0 0
20240115145920 1705301960500 3946.0 ... 0.0 0
20240115150000 1705302000500 3946.0 ... 3914.0 0
[431604 rows x 18 columns]}
字典中的DataFrame表头信息
'time' #时间戳
'lastPrice' #最新价
'open' #开盘价
'high' #最高价
'low' #最低价
'lastClose' #前收盘价
'amount' #成交总额
'volume' #成交总量
'pvolume' #原始成交总量
'stockStatus' #证券状态
'openInt' #持仓量
'lastSettlementPrice' #前结算
'settelementPrice' #今结算
'askPrice' #委卖价
'bidPrice' #委买价
'askVol' #委卖量
'bidVol' #委买量
'transactionNum' #成交笔数
4.3 数据清洗
下载得到的原始数据中包含的time
字段需要进行格式转换,便于处理,以及要对其中在非活跃交易段的数据进行剔除,整理为函数
import datetime
from xtquant import xtdata
def process_local_data(code,start_time,end_time):
data = xtdata.get_market_data_ex([], [code], period='1m',start_time=start_time,end_time=end_time)[code]
data = data[data.time !=0]
data['trade_time'] = data['time'].apply(lambda x: datetime.datetime.fromtimestamp(x / 1000.0)) # , cn_tz
data = data.sort_values(by="trade_time")
return data
process_local_data('rb2401.SF',start_time="20231208",end_time="20240208")
存在的问题: 在下载tick周期时,会出现错误数据,比如下面的例子,下载v2405
的数据时,会出现2027年的数据,明显有问题,这个暂时没有找到原因,等工作日后,我再联系官方咨询一下,如果有知道的也欢迎告诉我。
time ... trade_time
20231208085900 1701997140044 ... 2023-12-08 08:59:00.044
20231208085901 1701997141517 ... 2023-12-08 08:59:01.517
20231214103708 1702521428968 ... 2023-12-14 10:37:08.968
20231214103710 1702521430060 ... 2023-12-14 10:37:10.060
20231214103710 1702521430617 ... 2023-12-14 10:37:10.617
... ... ... ...
20721002034449 3242576689934 ... 2072-10-02 03:44:49.934
20721002034450 3242576690686 ... 2072-10-02 03:44:50.686
20721002034451 3242576691929 ... 2072-10-02 03:44:51.929
20721002034452 3242576692419 ... 2072-10-02 03:44:52.419
20721002034453 3242576693673 ... 2072-10-02 03:44:53.673
- [ ] 稍后更新其他清洗过程
五、TODO
- [ ] 成交量、成交时间等清洗
- [ ] 时间对齐
- [ ] 其他周期数据合成或下载
- [ ] 加权合约对比
- [ ] 主力合约抽取
- [ ] 合约拼接