很多人听说了Qlib这个量化工具后,想去尝试,但卡在了第一步,不知道怎么下载数据,今天主要讲讲如何下载数据。
一、下载(静态数据包)
1.脚本代码下载
# download 1d
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --region cn
# download 1min
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/qlib_cn_1min --region cn --interval 1min
# 美股下载(源代码/Users/test1/Documents/code/my_develop/qlib/scripts/data_collector/yahoo/collector.py里找到的)
python scripts/get_data.py qlib_data --target_dir <qlib_data_1d_dir> --interval 1d
# 美股更新
python scripts/data_collector/yahoo/collector.py update_data_to_bin --qlib_data_1d_dir <qlib_data_1d_dir> --trading_date 2021-06-01
【最终还是需要以我实际运行的代码为准,我的qlib版本是0.9.7
】
这个A股数据经我实操,发现只能到2020年的数据,应该是官方静态数据包,用来做实验的。
2.实操-下载A股1d数据
我这里下载到自定义的路径了:
python scripts/get_data.py qlib_data --target_dir ../qlib_data/cn_data --region cn
3.实操-下载美股1d数据
如果你有多个不同来源的数据集,最好如下进行分开。
qlib_data/
├── cn_data_tushare/ # A股数据源(含更新)
├── cn_data_snapshot/ # 官方静态包(2020-09-25)
├── us_data_yahoo/ # 美股
└── hk_data_yahoo/ # 港股
我的代码:
# 美股下载
python scripts/get_data.py qlib_data --target_dir ../qlib_data/us_data_yahoo --interval 1d --region us
二、检查数据的健康状况
Qlib 提供了一个脚本来检查数据的运行状况。
检查要点如下:
- 检查 DataFrame 中是否缺少任何数据。
- 检查 OHLCV 列中是否有任何高于阈值的较大阶跃变化。
- 检查 DataFrame 中是否缺少任何必需的列 (OLHCV)。
- 检查 DataFrame 中是否缺少 'factor' 列。
我们可以执行以下命令来检查数据是否健康。
# for daily data
python scripts/check_data_health.py check_data --qlib_dir ~/.qlib/qlib_data/cn_data
# for 1min data
python scripts/check_data_health.py check_data --qlib_dir ~/.qlib/qlib_data/cn_data_1min --freq 1min
还可以修改这些参数:
- freq:数据频率。
- large_step_threshold_price:允许的最大价格变化
- large_step_threshold_volume:允许的最大音量变化。
- missing_data_num:允许数据为空的最大值。 ### 1.实操 - 数据健康 根据我的实际目录, > python scripts/check_data_health.py check_data --qlib_dir ../qlib_data/cn_data
(freq) test1@budas-MacBook-Pro qlib % ls
CHANGELOG.md LICENSE SECURITY.md pyproject.toml tests
CHANGES.rst MANIFEST.in build_docker_image.sh qlib
CODE_OF_CONDUCT.md Makefile docs scripts
Dockerfile README.md examples setup.py
(freq) test1@budas-MacBook-Pro qlib % python scripts/check_data_health.py check_data --qlib_dir ../qlib_data/cn_data
[25774:MainThread](2025-10-16 18:01:32,906) INFO - qlib.Initialization - [config.py:452] - default_conf: client.
[25774:MainThread](2025-10-16 18:01:34,294) INFO - qlib.Initialization - [__init__.py:75] - qlib successfully initialized based on client settings.
[25774:MainThread](2025-10-16 18:01:34,294) INFO - qlib.Initialization - [__init__.py:77] - data_path={'__DEFAULT_FREQ': PosixPath('/Users/test1/Documents/code/my_develop/qlib_data/cn_data')}
open close low high volume factor
instrument datetime
SH000905 2007-01-15 1881.467041 1986.538940 1881.467041 1986.538940 3.881263e+09 NaN
2007-01-16 1991.689941 2055.020020 1991.040039 2055.020020 4.807442e+09 NaN
2007-01-17 2064.290039 2035.650024 1992.540039 2093.889893 5.883289e+09 NaN
2007-01-18 2025.849976 2085.399902 2002.660034 2085.399902 5.094946e+09 NaN
2007-01-19 2097.500000 2159.639893 2097.500000 2159.649902 5.792517e+09 NaN
... ... ... ... ... ... ...
2020-09-21 6492.225098 6445.964844 6434.323730 6515.336914 1.260237e+10 NaN
2020-09-22 6392.024902 6358.651855 6341.483887 6462.975098 1.213059e+10 NaN
2020-09-23 6382.281250 6392.032715 6356.163574 6411.204590 9.504884e+09 NaN
2020-09-24 6353.693848 6244.638672 6243.282227 6354.682617 1.128015e+10 NaN
2020-09-25 6271.700684 6236.890625 6206.182129 6285.471680 8.779878e+09 NaN
[3285 rows x 6 columns]
2025-10-16 18:03:15.435 | INFO | __main__:check_required_columns:144 - ✅ The columns (OLHCV) are complete and not missing.
2025-10-16 18:03:15.820 | INFO | __main__:check_missing_factor:172 - ✅ The `factor` column already exists and is not empty.
Summary of data health check (3875 files checked):
-------------------------------------------------
2025-10-16 18:03:15.820 | WARNING | __main__:check_data:189 - There is missing data.
open high low close volume
instruments
SH000903 4 4 4 4 4
SH600000 3 3 3 3 3
SH600004 53 53 53 53 53
SH600006 96 96 96 96 96
SH600007 32 32 32 32 32
... ... ... ... ... ...
SZ300771 2 2 2 2 2
SZ300772 2 2 2 2 2
SZ300773 2 2 2 2 2
SZ300802 1 1 1 1 1
SH000905 0 0 0 0 0
[3613 rows x 5 columns]
2025-10-16 18:03:15.825 | WARNING | __main__:check_data:192 - The OHLCV column has large step changes.
col_name date pct_change
instruments
SH000300 volume 2016-01-08 3.216515
SH000903 volume 2016-01-08 3.425825
SH600000 volume 1999-12-15 1396.263672
SH600004 volume 2003-05-23 634.929382
SH600006 volume 1999-11-16 40.254677
... ... ... ...
SZ300869 open 2020-08-26 0.502253
SZ300869 high 2020-08-25 0.513636
SZ300869 low 2020-08-25 0.557708
SZ300877 high 2020-08-25 0.698236
SZ300877 close 2020-08-25 0.768708
[4744 rows x 3 columns]
2.分析
- 先打印基本信息段, 把 中证 500(SH000905)拉出来做样例展示, 2007-01-15 ~ 2020-09-25 共 3285 条日线 6 个字段:open / close / low / high / volume / factor 虽然factor 全为NaN,但没关系后面会计算。
- OLHCV 五列 没有整列缺失 factor 列存在。
- 警告一 缺失数据(Missing rows) 缺了多少根 bar。可能是因为停牌等原因,只要不是缺失过多,影响不大。
- 警告二 大幅跳变(Large step change) 每只股票,每列数据,每日波动超过 50 % 则表示异常跳变。
三、查看下载数据
1.查看A股数据
import qlib
from qlib.data import D
qlib.init(provider_uri="/Users/test1/Documents/code/my_develop/qlib_data/cn_data", region="cn")
symbol = "SH000905"
df = D.features(
instruments=[symbol],
fields=["$open", "$close", "$low", "$high", "$volume"],
start_time="2010-01-01",
end_time="2025-01-01"
)
if df.empty:
print(f"没有找到 {symbol} 的数据,请检查代码或时间范围。")
else:
print(f"{symbol} 数据共 {len(df)} 条记录。")
print(df.head())
print(df.tail())
df.to_csv(f"{symbol}_data.csv", encoding="utf-8-sig")
print("保存成功!")
provider_uri
路径要写对。
注意symbol
的格式,
另外 instruments=[symbol]
是一个list,可以传入多只股票等。
还可以结合我上一篇文章,获取股票列表等。
从我的执行记录可以看出,尾部的数据并没有真的到2025年(这是因为数据不全导致的),所以我们有时候需要进行打印、排查等。
2.查看美股数据
我们以苹果AAPL公司为例,上市时间为1980年,但我们的官方静态数据包只有2000年到2020年的数据。
下面我们运行代码,注意修改一些配置参数。
import qlib
from qlib.data import D
qlib.init(provider_uri="/Users/test1/Documents/code/my_develop/qlib_data/us_data_yahoo", region="us")
symbol = "AAPL"
df = D.features(
instruments=[symbol],
fields=["$open", "$close", "$low", "$high", "$volume"],
start_time="1980-01-01",
end_time="2025-01-01"
)
if df.empty:
print(f"没有找到 {symbol} 的数据,请检查代码或时间范围。")
else:
print(f"{symbol} 数据共 {len(df)} 条记录。")
print(df.head())
print(df.tail())
df.to_csv(f"{symbol}_data.csv", encoding="utf-8-sig")
print("保存成功!")
我们可以通过这种方式,检查数据是否充足。发现2020年之后的数据没有,这样引出下一节内容:更新数据。
四、更新数据
# 美股更新
python scripts/data_collector/yahoo/collector.py update_data_to_bin --qlib_data_1d_dir ../qlib_data/us_data_yahoo --trading_date 2019-01-01 --end_date 2022-01-01 --region us
# 指定美股
python scripts/data_collector/yahoo/collector.py update_data_to_bin --qlib_data_1d_dir ../qlib_data/us_data_yahoo --trading_date 2019-01-01 --end_date 2022-01-01 --region us --instruments AAPL,MSFT
但是很不幸,接口请求不通,可能需要其他方式。
结果:
(freq) test1@budas-MacBook-Pro qlib % python scripts/data_collector/yahoo/collector.py update_data_to_bin --qlib_data_1d_dir ../qlib_data/us_data_yahoo --trading_date 2019-01-01 --end_date 2022-01-01 --region us --instruments AAPL,MSFT
2025-10-17 14:40:09.386 | INFO | collector:get_instrument_list:266 - get US stock symbols......
2025-10-17 14:40:10.913 | WARNING | data_collector.utils:wrapper:558 - _get_eastmoney: 1 :request error
2025-10-17 14:40:14.190 | WARNING | data_collector.utils:wrapper:558 - _get_eastmoney: 2 :request error
2025-10-17 14:40:17.669 | WARNING | data_collector.utils:wrapper:558 - _get_eastmoney: 3 :request error
2025-10-17 14:40:20.949 | WARNING | data_collector.utils:wrapper:558 - _get_eastmoney: 4 :request error
2025-10-17 14:40:24.227 | WARNING | data_collector.utils:wrapper:558 - _get_eastmoney: 5 :request error
Traceback (most recent call last):
File "/Users/test1/Documents/code/my_develop/qlib/scripts/data_collector/yahoo/collector.py", line 1021, in <module>
fire.Fire(Run)
File "/Users/test1/py_env/freq/lib/python3.11/site-packages/fire/core.py", line 135, in Fire
component_trace = _Fire(component, args, parsed_flag_args, context, name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/test1/py_env/freq/lib/python3.11/site-packages/fire/core.py", line 468, in _Fire
component, remaining_args = _CallAndUpdateTrace(
^^^^^^^^^^^^^^^^^^^^
File "/Users/test1/py_env/freq/lib/python3.11/site-packages/fire/core.py", line 684, in _CallAndUpdateTrace
component = fn(*varargs, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/test1/Documents/code/my_develop/qlib/scripts/data_collector/yahoo/collector.py", line 988, in update_data_to_bin
self.download_data(delay=delay, start=trading_date, end=end_date, check_data_length=check_data_length)
File "/Users/test1/Documents/code/my_develop/qlib/scripts/data_collector/yahoo/collector.py", line 802, in download_data
super(Run, self).download_data(max_collector_count, delay, start, end, check_data_length, limit_nums)
File "/Users/test1/Documents/code/my_develop/qlib/scripts/data_collector/base.py", line 402, in download_data
_class(
File "/Users/test1/Documents/code/my_develop/qlib/scripts/data_collector/yahoo/collector.py", line 86, in __init__
super(YahooCollector, self).__init__(
File "/Users/test1/Documents/code/my_develop/qlib/scripts/data_collector/base.py", line 80, in __init__
self.instrument_list = sorted(set(self.get_instrument_list()))
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/test1/Documents/code/my_develop/qlib/scripts/data_collector/yahoo/collector.py", line 267, in get_instrument_list
symbols = get_us_stock_symbols() + [
^^^^^^^^^^^^^^^^^^^^^^
File "/Users/test1/Documents/code/my_develop/qlib/scripts/data_collector/utils.py", line 359, in get_us_stock_symbols
_all_symbols = _get_eastmoney() + _get_nasdaq() + _get_nyse()
^^^^^^^^^^^^^^^^
File "/Users/test1/Documents/code/my_develop/qlib/scripts/data_collector/utils.py", line 554, in wrapper
_result = func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/test1/Documents/code/my_develop/qlib/scripts/data_collector/utils.py", line 316, in _get_eastmoney
raise ValueError("request error")
ValueError: request error
另外,还有一种方法,就是先从别的地方下载数据,如何再转换成qlib格式。
参考:官网文档
Top comments (0)