金融数据下载及管理
本示例展示了如何使用qteasy模块下载、管理及提取本地存储的金融数据 QTEASY提供了一套比较完善的金融数据下载及管理工具,可以通过tushare服务器下载相当广泛的金融数据,将数据存储在本地,并在需要的时候自动从本地提取数据用于策略的回测或策略运行。
本地数据源对象DataSource
在qteasy中定义了一个DataSource对象,这个对象定义了一个本地金融数据源,并提供了一系列内置的本地金融数据表和数据类型,用户可以直接通过各种数据类型的ID来直接读取相应的金融数据(前提是这些金融数据已经从网上下载并保存到了本地数据源中)。
大量常用的金融数据,例如’close’ ‘pe’都是预先定义并内置在qteasy中的,这些数据涵盖了相当广泛的范围,包括:
量价数据,如开盘价open、收盘价close、最高价high,交易量vol等等
财务指标数据,如市盈率pe,市净率pb
财务报表数据,如ebidta、ebit等等
公司基本信息数据,如管理层姓名、公司行业信息
上面的数据都是以“数据表”的形式内置并定义在系统中的,如果需要使用这些数据,必须首先下载数据至本地。DataSource对象定义了数据存储的方式和位置。qteasy定义了一个默认的数据源对象QT_DATA_SOURCE,在不特殊指明的情况下,qteasy所操作及使用的数据都在这个数据源中。
DataSource对象可以将数据保存为文件格式(csv、fth等),也可以将数据保存在mysql数据库中,鉴于金融数据的体量,建议将数据保存在数据库中。数据存储方式及存储位置可以在qteasy的configuration中设置。
DataSource的两种数据源类型
qt.DataSource(source_type, file_type='fth', file_loc='qteasy/data/', host='localhost', port=3306, user=None, password=None, db='qt_db')
对于一个DataSource对象,用户可以选择将数据存储为不同的形式,也叫数据源。DataSource目前支持两种不同的数据源:
db: 数据库,数据存储在mysql/Maria DB数据库中,通过建立数据库连接来访问
file: 文件,数据以文件的形式存储在指定的文件夹中,支持csv、hdf5以及feather三种文件格式
鉴于金融数据的数据量较大(例如,所有股票的日K线历史数据有超过一千万行数据,分钟级K线的数据量更加庞大),推荐使用mysql数据库来存储数据,如果使用本地文件存储数据,数据交换的效率将会很低。
使用下面的参数建立一个连接到本地数据库的DataSource对象:
import qteasy as qt
ds_db = qt.DataSource(source_type='db', host='localhost', port=3306, user='user', password='password', db='qt_db')
可以通过connection_type属性了解DataSource对象的连接性质
print(ds_db.connection_type)
ds_db
db:mysql://localhost@3306/qt_db
DataSource('db', 'localhost', 3306)
使用下面的参数可以建立一个使用本地文件夹的DataSource对象
import qteasy as qt
ds_csv = qt.DataSource(source_type='file', file_loc='src/data', file_type='csv')
print(ds_csv.connection_type)
ds_csv
file://csv@qt_root/qteasy/data
DataSource('file', 'qteasy/data', 'csv')
使用qt.configuration可以查看当前的配置变量,使用qt.QT_DATA_SOURCE可以查看当前数据源的类型和参数
qt.configuration(config_key='local_data_source, local_data_file_type, local_data_file_path', default=False)
qt.QT_DATA_SOURCE
No. Config-Key Cur Val
-----------------------------------------
1 local_data_source database
2 local_data_file_type csv
3 local_data_file_path qteasy/data/
DataSource('db', 'localhost', 3306)
历史数据类型
qteasy可以管理多种不同的数据类型,自动下载这些类型的数据并储存在本地,供交易策略调用。每一种数据都有一个内置的数据id(data_id),根据这个data_id,用户可以查看、读取、下载相应的数据。
qt.find_history_data(s, match_description=False, fuzzy=False, freq=None, asset_type=None, match_threshold=0.85,)
qt.find_history_data()可以查找qteasy内置的所有数据类型,列出数据的id,资产类型和频率,以及数据的详细说明。
使用qt.get_history_data()并将找到的数据id作为参数传入,则可以直接查看已经下载的历史数据
import qteasy as qt
qt.find_history_data('pe')
输出如下:
matched following history data,
use "qt.get_history_data()" to load these historical data by its data_id:
------------------------------------------------------------------------
freq asset table desc
data_id
initial_pe d E new_share 新股上市信息 - 发行市盈率
pe d IDX index_indicator 指数技术指标 - 市盈率
pe d E stock_indicator 股票技术指标 - 市盈率(总市值/净利润, 亏损的PE为空)
pe_2 d E stock_indicator2 股票技术指标 - 动态市盈率
========================================================================
import qteasy as qt
qt.get_history_data('pe', '000001.SZ', start="20220101", end="20220201")
Out[16]:
{'000001.SZ':
pe
2022-01-04 11.1761
2022-01-05 11.5048
2022-01-06 11.4847
2022-01-07 11.5384
2022-01-10 11.5317
2022-01-11 11.6792
2022-01-12 11.4042
2022-01-13 11.3908
2022-01-14 10.9547
2022-01-17 10.8809
2022-01-18 11.0822
2022-01-19 11.0688
2022-01-20 11.6256
2022-01-21 11.6390
2022-01-24 11.5384
2022-01-25 11.3036
2022-01-26 11.1694
2022-01-27 10.9346
2022-01-28 10.6193
2022-01-31 10.6193
2022-02-01 10.6193}
检查本地数据源的数据
使用qt.get_table_overview()可以查看当前数据源中已经下载的数据量
当数据量较大时,需要花费几分钟时间分析所有的数据,并打印本地数据源中数据表的数据量、占用磁盘空间以及数据范围
本地数据存储在若干张数据表中,也可以通过qt.get_table_info()来获取某一张数据表的详细信息
包括数据表的主键类型和取值范围以外,还包括各数据列的名称、含义和数据类型
qt.get_table_info(table_name, data_source=None, verbose=True)
获取一张数据表的信息,包括数据量(数据行数),占用磁盘空间大小、数据主键的名称及数据范围
如果设置verbose=True,还可以查看数据表中的数据列完整信息,包括列名、数据类型和说明
qt.get_table_overview(data_source=None)
统计数据源中所有数据表的数据量并打印总览
使用qt.get_table_info()可以获取一张数据表的信息:
qt.get_table_info('stock_15min', verbose=True)
<stock_15min>, 15.85GB/100.9M records on disc
primary keys:
-----------------------------------
1: ts_code: *<CRITICAL>*
<unknown> entries
starts: 000001.SZ, end: 689009.SH
2: trade_time:
<unknown> entries
starts: 20090105, end: 20220323
columns of table:
------------------------------------
columns dtypes remarks
0 ts_code varchar(20) 证券代码
1 trade_time datetime 交易日期时间
2 open float 开盘价
3 high float 最高价
4 low float 最低价
5 close float 收盘价
6 vol double 成交量(股)
7 amount double 成交额(元)
使用qt.get_table_overview()可以检查并显示DataSource中保存的所有本地数据的总览
qt.get_table_overview()
Analyzing local data source tables... depending on size of tables, it may take a few minutes
[########################################]62/62-100.0% Analyzing completed!or>>>>>ht>or>>
db:mysql://localhost@3306/ts_db
Following tables contain local data, to view complete list, print returned DataFrame
Has_data Size_on_disk Record_count Record_start Record_end
table
trade_calendar True 2.5MB 76K 1990-10-12 2022-12-31
stock_basic True 1.5MB 5K None None
stock_names True 2.4MB 13K 1990-12-10 2022-03-21
index_basic True 4.5MB 11K None None
fund_basic True 8.3MB 17K None None
future_basic True 2.5MB 7K None None
opt_basic True 4.5MB 10K None None
stock_15min True 15.85GB 100.9M 20090105 20220323
stock_30min True 6.66GB 38.9M 20090105 20220321
stock_hourly True 3.41GB 38.3M 20090105 20220318
stock_daily True 1.57GB 12.1M 1990-12-19 2022-03-22
stock_weekly True 217.9MB 2.4M 1990-12-21 2022-03-18
stock_monthly True 87.7MB 638K 1990-12-31 2022-02-28
index_15min True 2.07GB 17.6M 20090105 20220323
index_30min True 1.12GB 7.6M 20090105 20220318
index_hourly True 602.0MB 7.1M 20090105 20220113
index_daily True 357.0MB 2.2M 1990-12-19 2022-03-23
index_weekly True 56.6MB 611K 1991-07-05 2022-03-18
index_monthly True 22.5MB 139K 1991-07-31 2022-02-28
fund_hourly True 16KB 0 None None
fund_daily True 165.3MB 1.6M 1998-04-07 2022-03-22
fund_nav True 973.0MB 15.0M 2000-01-07 2022-03-22
fund_share True 69.7MB 1.1M 1998-03-27 2022-03-18
fund_manager True 84.7MB 40K 2000-02-22 2022-03-18
future_daily True 384.0MB 2.0M 1995-04-17 2022-03-23
options_daily True 753.0MB 5.3M 2015-02-09 2022-03-23
stock_adj_factor True 688.0MB 11.0M 1990-12-19 2022-03-23
fund_adj_factor True 112.7MB 1.9M 1998-04-07 2022-03-23
stock_indicator True 2.31GB 11.6M 1999-01-01 2022-03-23
stock_indicator2 True 988.0MB 4.8M 2017-06-14 2022-03-23
index_indicator True 5.5MB 45K 2004-01-02 2022-03-23
index_weight True 841.9MB 10.5M 2005-04-08 2022-03-17
income True 94.8MB 189K 1990-12-31 2021-12-31
balance True 130.0MB 172K 1989-12-31 2021-12-31
cashflow True 111.9MB 186K 1998-12-31 2021-12-31
financial True 373.0MB 152K 1989-12-31 2021-12-31
forecast True 50.6MB 86K 1998-12-31 2022-12-31
express True 4.5MB 23K 2004-12-31 2021-12-31
HistoryPanel 与 get_history_data
在 qteasy 2.x 中,qt.get_history_data() 的推荐用法是直接返回 HistoryPanel:
import qteasy as qt
hp = qt.get_history_data(
htypes='open, high, low, close, vol',
shares='000300.SH,000905.SH',
start='20230101',
end='20231231',
)
print(hp)
HistoryPanel 是一个三维数据容器,维度含义为:
axis 0(shares):标的列表,例如股票或指数代码;
axis 1(hdates):时间轴,每一行对应一个时间点(如交易日或分钟);
axis 2(htypes):历史数据类型,例如
open、high、low、close、vol等。
使用 hp[...] 按轴切片时,结果类型为 子 HistoryPanel(带正确的轴标签),不再直接得到 ndarray。需要裸矩阵时请使用 hp['close'].values 或 hp['close'].to_numpy(copy=True);具名切片与默认拷贝行为见 hp.subpanel(..., copy=True)。
研究向布尔掩码与后续带 mask= 的 API 可使用 hp.where(condition):返回与 hp.values 同形的 dtype=bool 数组(不改变 hp),详见 HistoryPanel API 参考 与教程 使用 HistoryPanel 操作和分析历史数据。
自 2.2.8 起还可:合法标识符列名用只读属性(如 hp.close,等价 hp['close']);比较运算(如 hp.close > 100、两列子面板比较)得到 numpy 布尔数组,可直接作为 hp.where(...) 的输入;按 交易日(时间轴) 筛选可用 hp.loc[key](等价 hp[:, :, key],与 pandas 仅类比)。边界说明见 API 页「列属性访问、比较与 loc」与教程 §6.1。
这样,策略与可视化都可以在同一份结构化数据上工作,避免重复转换。
当你已有 DataFrame 或字典形式的数据时,可以使用
qt.dataframe_to_hp() 将其适配为 HistoryPanel,再复用同一套 API。
从 HistoryPanel 到可视化
HistoryPanel 提供统一的可视化入口 hp.plot(),根据面板中已有的 htypes
自动选择合适的图表类型(K 线、成交量、MACD 或普通折线),并支持多标的对比:
import qteasy as qt
hp = qt.get_history_data(
htypes='open, high, low, close, vol',
shares='000300.SH',
start='20230101',
end='20231231',
)
# 静态 K 线 + 成交量
hp.plot(interactive=False)
# 交互式 K 线(在 Jupyter 中体验更好)
hp.plot(interactive=True)
HistoryPanel.plot 交互式可视化(Plotly)
当你使用 hp.plot(interactive=True) 时,qteasy 会使用 Plotly 生成交互式图表,支持缩放、平移与悬停查看数据。在 Notebook 中,如果你的环境支持 FigureWidget(通常需要安装 ipywidgets 与 anywidget),qteasy 会优先返回更完整的交互体验;否则会回退到 HTML 方式展示。你也可以通过 plotly_backend_app='auto'|'FigureWidget'|'html' 明确指定输出方式。
依赖与安装
基础交互(Plotly Figure):
pip install plotly
Notebook 更完整交互(FigureWidget + 回调):
pip install ipywidgets anywidget
注意:若未安装 Plotly,调用 interactive=True 会直接抛出英文错误提示(例如包含 “requires plotly” 的信息);这是为了让依赖缺失问题尽早暴露,避免生成一个不可交互的“空图”。
plotly_backend_app:输出方式与回退
plotly_backend_app 仅在 interactive=True 时生效:
plotly_backend_app='auto':在 Notebook 中优先使用 FigureWidget;否则回退到 HTML 包装;在脚本环境中也可能返回原始 Plotly Figure。plotly_backend_app='FigureWidget':强制使用 FigureWidget;若当前不是 Notebook 或缺少依赖会直接报错(英文提示)。plotly_backend_app='html':强制使用 HTML 包装;若当前不是 Notebook 也会直接报错(英文提示)。
关键交互能力(用户视角)
缩放/平移一致性:HTML 与 FigureWidget 在缩放/平移时遵循同一套 x 轴约束:保持最少可见 bar 数、越界时按 pan 语义平移回数据域。
顶部 OHLC 摘要:当面板中存在完整 OHLC 主图(蜡烛图)时,会显示顶部摘要;交互图初始为最后一根 bar,点击某根 bar 会更新摘要。无 K 线主图(例如仅 close 折线)时不显示该摘要区。
两标的 overlay:当你用
layout='overlay'对比两只标的时,点击某根 bar 会切换主次标的:主次透明度与线宽会联动更新;如果你启用了highlight,高亮点默认仅对当前主标的可见,并随主次切换。选中态十字交叉线:点击后在主价格图上显示选中态十字交叉线;缩放/平移时保持同步;当选中 bar 滚动出可见区域时会隐藏。
示例:最常用的两种交互调用
示例 1:单标的交互式 K 线
hp.plot(interactive=True, plotly_backend_app='auto')
示例 2:两标的 overlay + 高亮
hp2 = qt.get_history_data(
htypes='open, high, low, close, vol',
shares='000300.SH,000905.SH',
start='20230101',
end='20231231',
)
hp2.plot(
interactive=True,
layout='overlay',
highlight='max',
plotly_backend_app='html',
)
可视化层严格遵循“有什么画什么”原则:
只使用 HistoryPanel 中已经存在的列,不在绘图层计算新的指标;
是否绘制 K 线、成交量或 MACD,仅取决于面板中是否存在对应的 htypes。
典型 htypes 与默认图表类型的对应关系如下:
图表类型 |
依赖的 htype 示例 |
|---|---|
K 线 |
|
成交量 |
|
MACD |
|
折线图 |
其它任意一维序列(如 |
若需要 MA/布林带/MACD 等指标,应在 HistoryPanel 上调用相应方法
(例如 hp.kline.ma()、hp.kline.bbands()、hp.kline.macd()),
将结果列追加进面板后再调用 hp.plot()。
qt.candle 与 HistoryPanel 的关系
qt.candle() 是更高层的快捷入口,用于“一行代码画出某个标的的 K 线图”,
其内部逻辑可以概括为:
解析
stock、start、end等参数,从本地数据源取数;将价格数据适配为单标的
HistoryPanel;在 HistoryPanel 上追加用户需要的指标列(如 MA、布林带、MACD);
调用
hp.plot(...)绘制图表。
因此,你可以在保留现有 qt.candle 调用方式的同时,直接在 HistoryPanel 上
做更细粒度的控制。
常见用法示例:
import qteasy as qt
# 快速绘制日 K 线(内部走 HistoryPanel 可视化)
df = qt.candle(
stock='000300.SH',
start='2023-06-01',
end='2023-12-01',
asset_type='IDX',
plot_type='candle',
interactive=True,
)
print(df.head()) # df 为用于绘图的价格数据
其中 plot_type 的意义为:
'candle'/'c':使用 OHLC 绘制蜡烛图;'ohlc'/'o':行为与'candle'接近,仅作为轻量别名保留;'line'/'l':只绘制一维价格折线(通常为close);'none'/'n':只取数不绘图,直接返回DataFrame,方便你用 其它工具自行可视化。
Renko 图('renko' / 'r')在新版中已不再内置支持;若需要 Renko 图,
建议使用专门的技术分析或画图库。
获取历史数据,并将数据保存在DataSource中
如果DataSource中没有数据,那么qteasy将很难发挥所长,因此,首先需要将数据保存到DataSource中
DataSource类提供了_fetch_table_data_from_tushare()函数,来获取并存储历史数据到DataSource中,在这个函数的参数中可以直接给出一个DataFrame、一个csv文件名或excel文件名,同样也可以连接网络数据提供商的API获取数据。
使用DataSource对象获取、更新数据的方法包括:
DataSource.update_table_data()
检查输入的df,去掉不符合要求的列或行后,将数据合并到table中,包括以下步骤:
检查下载后的数据表的列名是否与数据表的定义相同,删除多余的列
如果datasource type是”db”,删除下载数据中与本地数据重复的部分,仅保留新增数据
如果datasource type是”file”,将下载的数据与本地数据合并并去重
DataSource.read_table_data()
通过本地文件获取数据,并保存到DataSource中:
下面的示例代码将存储在DataFrame中的数据保存在DataSource中
# stock_data 是事先准备好的股票价格数据,格式为pd.DataFrame
df = ds_csv._fetch_table_data_from_tushare(table='stock_basic', channel='df', df=stock_data)
ds_csv.update_table_data('stock_basic', df)
ds_csv.table_data_exists('stock_basic')
本地数据的获取和可视化
只要本地数据源中有了数据,就可以非常容易地获取这些数据,如果是量价数据,还可以非常容易地可视化(打印为K线图或价格曲线图)
股票或资产的基本信息数据
qt.get_basic_info(code_or_name: str, asset_types=None, match_full_name=False, printout=True, verbose=False)
获取一个股票或证券的基本信息,code_or_name可以是股票的代码,或者股票名称,默认情况下系统会进行全剧匹配查找匹配的证券,如‘000001’会匹配到多种不同的证券,所有匹配的证券都会被列出,除非在asset_type中指定一种或几种证券类型。
如果设置match_full_name=True,则会通过股票或基金的全名来模糊匹配证券
qt.get_stock_info(code_or_name: str, asset_types=None, match_full_name=False, printout=True, verbose=False)
get_basic_info()的别称
筛选股票代码
qt.filter_stocks(date: str = 'today', **kwargs)
根据发行日期、地区、行业、规模、指数成份等多种可用的信息筛选出一部分股票,打印出股票的信息
qt.filter_stock_codes(date: str = 'today', **kwargs)
根据发行日期、地区、行业、规模、指数成份等多种可用的信息筛选出一部分股票,返回股票的完整代码
提取金融历史数据
量价数据的可视化
qt.candle(stock=None, start=None, end=None, stock_data=None, asset_type=None, freq=None, plot_type='candle', interactive=True, data_source=None, **kwargs)
这个函数从本地数据源中提取股票的价格数据,并生成一张完整的动态高级K线图
示例:
查找证券的基本信息
使用qt.get_basic_info()获取证券的基本信息
在DataSource中准备好相关的金融数据后,还可以方便地查找证券的信息,通过证券代码(六位数字)或证券的名称搜索证券,并打印出详细信息。
使用证券名称搜索时,支持模糊查找或使用通配符:
例如,通过六位代码获取证券信息:
qt.get_basic_info('601728')
found 1 matches, matched codes are {'E': {'601728.SH': '中国电信'}, 'IDX': {}, 'FT': {}, 'FD': {}, 'OPT': {}, 'count': 1}
More information for asset type E:
------------------------------------------
ts_code 601728.SH
name 中国电信
area 北京
industry 电信运营
fullname 中国电信股份有限公司
list_status L
list_date 2021-08-20
-------------------------------------------
也可以直接通过证券名称来查找证券,模糊查找匹配多个证券,例如:
qt.get_basic_info('中国证券')
Too many matched codes 128, best matched are
{'E': {'000728.SZ': '国元证券'}, 'IDX': {'100630.CIC': '中金证券'}, 'FD': {'001552.OF': '天弘中证证券保险A'}}
pass "verbose=Ture" to view all matched assets
More information for asset type E:
------------------------------------------
ts_code 000728.SZ
name 国元证券
area 安徽
industry 证券
fullname 国元证券股份有限公司
list_status L
list_date 1997-06-16
-------------------------------------------
More information for asset type IDX:
------------------------------------------
ts_code 100630.CIC
name 中金证券
fullname 中金证券指数
publisher 中金公司
category 其他
list_date None
-------------------------------------------
More information for asset type FD:
------------------------------------------
ts_code 001552.OF
name 天弘中证证券保险A
management 天弘基金
custodian 国泰君安
fund_type 股票型
issue_date 2015-06-29
issue_amount 0.05
invest_type 被动指数型
type 契约型开放式
-------------------------------------------
通过证券名称匹配证券时,支持通过通配符查找:
qt.get_basic_info('中国?通')
found 2 matches, matched codes are {'E': {'600050.SH': '中国联通', '601698.SH': '中国卫通'}, 'IDX': {}, 'FD': {}, 'count': 2}
More information for asset type E:
------------------------------------------
ts_code 600050.SH 601698.SH
name 中国联通 中国卫通
area 北京 北京
industry 电信运营 电信运营
fullname 中国联合网络通信股份有限公司 中国卫通集团股份有限公司
list_status L L
list_date 2002-10-09 2019-06-28
-------------------------------------------
默认情况下,并不会查找证券的全名,如果有必要,可以匹配全名,例如:
# 使用‘贵州钢绳’为关键字搜索股票代码,不匹配全名时,找不到匹配的结果:
qt.get_basic_info('贵州钢绳')
结果如下:
found 0 matches, matched codes are {'E': {}, 'IDX': {}, 'FD': {}, 'count': 0}
# 然而如果设置了匹配全名`match_full_name=True`,则能够找到匹配的代码:
qt.get_basic_info('贵州钢绳', match_full_name=True)
结果如下:
found 1 matches, matched codes are {'E': {'600992.SH': '贵绳股份'}, 'IDX': {}, 'FD': {}, 'count': 1}
More information for asset type E:
------------------------------------------
ts_code 600992.SH
name 贵绳股份
area 贵州
industry 钢加工
fullname 贵州钢绳股份有限公司
list_status L
list_date 2004-05-14
-------------------------------------------
qt.filter_stocks被用来根据某些标准筛选股票,例如:
# 筛选2000年以后发行的HS300指数成份股
qt.filter_stocks(date = '20000101', index='000300.SH')
| symbol | name | area | industry | market | list_date | exchange | |
|---|---|---|---|---|---|---|---|
| ts_code | |||||||
| 000001.SZ | 000001 | 平安银行 | 深圳 | 银行 | 主板 | 1991-04-03 | SZSE |
| 000002.SZ | 000002 | 万科A | 深圳 | 全国地产 | 主板 | 1991-01-29 | SZSE |
| 000063.SZ | 000063 | 中兴通讯 | 深圳 | 通信设备 | 主板 | 1997-11-18 | SZSE |
| 000069.SZ | 000069 | 华侨城A | 深圳 | 旅游景点 | 主板 | 1997-09-10 | SZSE |
| 000100.SZ | 000100 | TCL科技 | 广东 | 元器件 | 主板 | 2004-01-30 | SZSE |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 603486.SH | 603486 | 科沃斯 | 江苏 | 家用电器 | 主板 | 2018-05-28 | SSE |
| 605499.SH | 605499 | 东鹏饮料 | 深圳 | 软饮料 | 主板 | 2021-05-27 | SSE |
| 688561.SH | 688561 | 奇安信-U | 北京 | 软件服务 | 科创板 | 2020-07-22 | SSE |
| 688599.SH | 688599 | 天合光能 | 江苏 | 电气设备 | 科创板 | 2020-06-10 | SSE |
| 688981.SH | 688981 | 中芯国际 | 上海 | 半导体 | 科创板 | 2020-07-16 | SSE |
397 rows × 7 columns













