A 股量化环境搭建:4 个 conda 环境的安装步骤
akshare + akquant + PyBroker + vnpy.alpha + VeighNa Studio。Windows 11 + conda 26.5.3,2026 年 9 月实际操作记录。
环境规划
装 4 个环境,互相隔离:
| 环境 | Python | 装什么 | 用途 | 体积 |
|---|---|---|---|---|
| quant | 3.12 | akshare + yfinance + akquant + quantstats | 取数、分析、回测、出报告 | 970 MB |
| pybroker | 3.12 | lib-pybroker + akshare + quantstats | 策略置信区间检验 | 781 MB |
| vnpy-alpha | 3.12 | vnpyalpha + jupyterlab + akshare | 机器学习选股 | 2.4 GB |
| veighna_studio | 3.13 | 官方发行版(50 个 vnpy 模块) | 实盘交易 | 1.9 GB |
为什么分开装
三处依赖冲突决定的:
1. numba 卡 numpy 上限
numba 0.67.0 → numpy<2.6
akquant → numpy>=2.2.2(无上限)
PyBroker 依赖 numba。装进 quant 会让整个环境的 numpy 被压在 2.6 以下。单独装,quant 保持无上限。
2. peewee 版本区间不相交
vnpy_sqlite / vnpy_mysql / vnpy_postgresql → peewee >= 3.17.9
empyrical-reloaded(alphalens 依赖) → peewee < 3.17.4
交集为空。所以 vnpy[alpha] 不能装进 VeighNa Studio------pip 不会报错,它会默默把 peewee 降到 3.17.3,然后 vnpy 的数据库层失效(SQLite 是默认库)。
3. alphalens 卡 pandas 上限
alphalens-reloaded → pandas<3.0
所以 vnpy-alpha 环境的 pandas 是 2.3.3,而另外两个是 3.0.5。
准备工作
conda 路径
Anaconda 装在 D:\anaconda3,但新建环境默认落在 C:\用户目录\.conda\envs,跟 Anaconda 装哪无关。查看:
bash
conda config --show envs_dirs
conda 不在 PATH
conda init 注册的是 shell 函数,不是把 conda.exe 加进 PATH。交互式 PowerShell 里 conda activate 能用,脚本里就报「不是内部或外部命令」。
所以本文命令全部用绝对路径:
bash
D:\anaconda3\Scripts\conda.exe create -n myenv python=3.12 -y
C:\Users\你的用户名\.conda\envs\myenv\python.exe -m pip install 包名
中文乱码
Windows 控制台默认 GBK,打印 akshare 返回的中文列名会乱码。执行时加环境变量:
bash
set PYTHONIOENCODING=utf-8
装之前先 dry-run
bash
python.exe -m pip install --dry-run 包名
完整跑一遍依赖解算,输出会装哪些包、哪些被升降级,但不写磁盘。装 quantstats 之前我跑的结果:
Would install contourpy-1.3.3 cycler-0.12.1 fonttools-4.64.0 kiwisolver-1.5.1
matplotlib-3.11.1 pillow-12.3.0 pyparsing-3.3.2 quantstats-0.0.81 scipy-1.18.1 seaborn-0.13.2
10 个新包,现有的 akshare / akquant / pandas / numpy 都没出现在列表里,说明不会动它们。
导出成 JSON 可以进一步分析,比如找出需要现场编译的 sdist:
bash
pip install --dry-run --ignore-installed --report out.json 包名
python
import json
r = json.load(open("out.json", encoding="utf-8"))
for it in r["install"]:
fn = it.get("download_info", {}).get("url", "").rsplit("/", 1)[-1]
if fn.endswith((".tar.gz", ".zip")):
print("需编译:", it["metadata"]["name"], it["metadata"]["version"])
单独测试某个 sdist 能不能构建:
bash
pip wheel "包名==版本" --no-deps -w 临时目录
构建成功的 wheel 进 pip 缓存,正式安装时直接复用。
环境一:quant
安装
bash
D:\anaconda3\Scripts\conda.exe create -n quant python=3.12 -y
bash
C:\Users\你的用户名\.conda\envs\quant\python.exe -m pip install akshare yfinance akquant quantstats
Python 选 3.12:akshare 要求 >=3.11,Anaconda base 自带的版本通常太新(我的是 3.14),量化库还没适配。
装完 60 个包。
| 包 | 版本 | 说明 |
|---|---|---|
| akshare | 1.18.94 | A 股数据主力,免费无 token |
| yfinance | 1.7.0 | 美股/全球行情 |
| akquant | 0.3.57 | 回测框架,Rust 内核,内置 103 个 TA 指标,A 股/期货/期权交易规则原生支持 |
| quantstats | 0.0.81 | 绩效分析,一行出 HTML 报告 |
这四个包的依赖声明里没有任何上限约束,numpy/pandas 可以自由升级。后面那些会引入上限的工具不要往这里装。
akquant 有 7 个 extras,上面的命令一个都没装:
[ml] sklearn+torch [quantstats] [plot] plotly
[full] = ml+plot+quantstats [signal-redis] [dev] [docs]
需要的话按需加,比如 pip install "akquant[quantstats,plot]"。
验证
python
import akshare as ak, pandas as pd, quantstats as qs
px = ak.stock_zh_a_daily(symbol="sh600519", start_date="20240101", adjust="qfq")
px["date"] = pd.to_datetime(px["date"])
ret = px.set_index("date")["close"].pct_change().dropna()
bm = ak.stock_zh_index_daily(symbol="sh000300")
bm["date"] = pd.to_datetime(bm["date"])
bmr = bm.set_index("date")["close"].pct_change().dropna()
bmr = bmr[bmr.index.isin(ret.index)]
print("Sharpe:", qs.stats.sharpe(ret))
print("最大回撤:", qs.stats.max_drawdown(ret))
print("Beta:", qs.stats.greeks(ret, bmr)["beta"])
qs.reports.html(ret, benchmark=bmr, output="report.html")
生成的 HTML 含净值曲线、回撤、月度收益热力图和 50+ 指标。
注意 quantstats 默认用 yfinance 取基准指数,国内网络下不稳,显式传 benchmark= 参数用 akshare 的数据。
环境二:pybroker
安装
bash
D:\anaconda3\Scripts\conda.exe create -n pybroker python=3.12 -y
bash
C:\Users\你的用户名\.conda\envs\pybroker\python.exe -m pip install lib-pybroker akshare quantstats
PyPI 上的包名是 lib-pybroker ,不是 pybroker;import 时写 import pybroker。
akshare 不是 PyBroker 的依赖,但它的 AKShare 数据源运行时要 import,不装会 ImportError。
装完 75 个包,含 numba 0.67.0、llvmlite 0.49.0、optuna 4.9.0。
用法
PyBroker 跟其他回测框架的区别是 bootstrap 置信区间------不只给点估计,还给区间。
python
from pybroker import Strategy, StrategyConfig
from pybroker.ext.data import AKShare
def my_strategy(ctx):
if len(ctx.close) < 21: return
ma20 = ctx.close[-20:].mean()
if not ctx.long_pos():
if ctx.close[-1] < ma20 * 0.97:
ctx.buy_shares = ctx.calc_target_shares(0.33)
elif ctx.close[-1] > ma20 * 1.03:
ctx.sell_shares = ctx.long_pos().shares
if __name__ == "__main__": # Windows 上必须,原因见「常见报错」
cfg = StrategyConfig(initial_cash=1_000_000, bootstrap_samples=500)
st = Strategy(AKShare(), "20220101", "20260904", cfg)
st.add_execution(my_strategy, ["600519", "000001", "601318"])
res = st.backtest(calc_bootstrap=True, adjust="qfq")
print(res.metrics_df)
print(res.bootstrap.conf_intervals)
print(res.bootstrap.drawdown_conf)
上面这段代码的实测输出(2022-01 至 2026-09,三只股票):
点估计 总收益 +6.87% 最大回撤 -29.34% 胜率 58.2% 交易 55 次
Profit Factor 1.15(总盈利 53.3 万 / 总亏损 46.4 万)
Bootstrap Sharpe 97.5% 区间 [-0.039, 0.074] 跨过零
PF 97.5% 区间 [ 0.863, 1.269] 下界跌破 1
最大回撤 99.9% 置信度 -62.0% 是回测所见的 2.1 倍
点估计已经不好看了,bootstrap 进一步说明:Sharpe 的区间跨零、Profit Factor 下界跌破 1,意味着这个策略赚钱与否在统计上无法区分于随机;而真实世界的回撤可能到 -62%,是回测里那个 -29% 的两倍多。
换一组股票结果会完全不同------这也正是为什么要看区间不看点估计。
它的 AKShare 数据源内置了降级,东财失败自动切腾讯源:
python
try:
return akshare.stock_zh_a_hist(...) # 东财
except (ConnectionError, KeyError, requests.RequestException):
if period != "daily": raise
return akshare.stock_zh_a_hist_tx(...) # 腾讯
只有日线有降级,周线直接抛异常。
它不带机器学习库
sklearn / xgboost / lightgbm / torch 全部不装。PyBroker 是「自带模型」设计,pybroker.model() 只提供注册机制。要跑 ML 策略自己装:
bash
C:\Users\你的用户名\.conda\envs\pybroker\python.exe -m pip install scikit-learn lightgbm
两者只有 numpy 下限,不会破坏 numba 的 numpy<2.6。
环境三:vnpy-alpha
vn.py 从 4.0 开始带了个 vnpy.alpha 模块,做多因子机器学习:内置 Alpha158(158 个价量因子)和 Alpha101 两套数据集,配 LightGBM / Lasso / MLP 三个模型。
它是 vnpy 的子模块,但跟实盘那套完全独立------这个环境不装任何券商接口,只做研究。
安装
从 GitHub Releases 下载 vnpy 4.4.0 源码,解压到本地。
bash
D:\anaconda3\Scripts\conda.exe create -n vnpy-alpha python=3.12 -y
bash
C:\Users\你的用户名\.conda\envs\vnpy-alpha\python.exe -m pip install -e "D:\你的路径\vnpy-4.4.0[alpha]"
bash
C:\Users\你的用户名\.conda\envs\vnpy-alpha\python.exe -m pip install jupyterlab akshare
装完 159 个包,2.4 GB。大头是 torch(安装后 539 MB,下载包 118 MB)和 PySide6 全家桶(安装后 485 MB)------PySide6 是 Qt 图形界面,做因子研究一行都用不到,但 vnpy 核心硬依赖它,绕不过去。
三点说明:
用源码而不是 pip install vnpy :源码里有 examples/alpha_research/,含 6 个研究流程 notebook(Alpha101、LightGBM、Lasso、MLP),这些不在 pip 包里。
用 -e(editable) :site-packages 链到源码目录,改源码立即生效,examples/ 就在旁边。验证:
python
import vnpy
print(vnpy.__file__) # 应指向源码路径
[alpha] 不能省。这是 pyproject.toml 里定义的可选依赖组:
toml
alpha = ["polars>=1.26.0", "scipy>=1.15.2", "alphalens-reloaded>=0.4.5",
"scikit-learn>=1.6.1", "lightgbm>=4.6.0", "torch>=2.6.0", "pyarrow>=19.0.1"]
不写的话 torch/lightgbm 一个都不装,import vnpy.alpha 直接失败。
别用官方 install.bat :它最后一行是 pip install .,不带 [alpha]。
[dev] 不用装 :hatchling 和 babel 在 build-system.requires 里,pip 构建时自动在隔离环境获取;stubs 只服务静态类型检查。
数据从哪来
官方取数 notebook 用米筐 RQData 和迅投 XT,都是付费源。用 akshare 自己灌。
AlphaLab 的数据格式是普通 parquet,不是自研二进制:
lab/
├── daily/{代码}.{SSE|SZSE}.parquet
├── component/ (指数成分,可选)
└── dataset/ model/ signal/
桥接代码:
python
import akshare as ak, pandas as pd
from vnpy.trader.constant import Exchange, Interval
from vnpy.trader.object import BarData
from vnpy.alpha import AlphaLab
lab = AlphaLab("./lab/a_share")
code = "600519"
df = ak.stock_zh_a_daily(
symbol=("sh" if code.startswith("6") else "sz") + code,
start_date="20180101", adjust="qfq")
df["date"] = pd.to_datetime(df["date"]) # 见「常见报错」第 6 条
ex = Exchange.SSE if code.startswith("6") else Exchange.SZSE
bars = [BarData(
symbol=code, exchange=ex, datetime=r.date.to_pydatetime(),
interval=Interval.DAILY,
open_price=float(r.open), high_price=float(r.high),
low_price=float(r.low), close_price=float(r.close),
volume=float(r.volume),
turnover=float(r.amount), # 见「常见报错」第 7 条
gateway_name="AK",
) for r in df.itertuples()]
lab.save_bar_data(bars)
之后是标准流程:
python
df = lab.load_bar_df(vt_symbols, Interval.DAILY, start, end, 100)
dataset = Alpha158(df, train_period=..., valid_period=..., test_period=...)
dataset.add_processor("learn", partial(process_drop_na, names=["label"]))
dataset.add_processor("learn", partial(process_cs_norm, names=["label"], method="zscore"))
dataset.prepare_data(max_workers=4) # filters 可选,不用指数成分也能跑
dataset.process_data()
model = LgbModel(seed=42)
model.fit(dataset)
pre = model.predict(dataset, Segment.TEST)
三个模型的调用方式不同
vnpy.alpha 只实现了三个模型:
python
# LightGBM ------ 原生支持 NaN,直接用
model = LgbModel(seed=42)
# Lasso ------ 必须先填 NaN,否则报 ValueError: Input X contains NaN
dataset.add_processor("infer", partial(process_fill_na, fill_value=0))
model = LassoModel()
# MLP ------ 必须传 input_size,还要额外的归一化处理器
dataset.add_processor("infer", partial(process_robust_zscore_norm,
fit_start_time=fs, fit_end_time=fe))
dataset.add_processor("infer", partial(process_fill_na, fill_value=0, fill_label=False))
model = MlpModel(input_size=158, hidden_sizes=(256,), lr=0.002,
optimizer="adam", n_epochs=8000, batch_size=8192,
weight_decay=0.0002, seed=42)
股票池要够大
我用 38 只股票测试时,show_signal_performance() 报错:
Dropped 100.0% entries from factor data: 2.5% in forward returns computation
and 97.5% in binning phase
ValueError: No objects to concatenate
这个函数内部硬编码 quantiles=10,38 只分 10 档每档不到 4 只,样本不足被全丢。
绕开可视化直接算 IC 也没意义:IC 均值 +0.0197、标准差 0.2536、ICIR 0.0776、IC>0 占比 50.7%。IC 是横截面相关系数,38 只股票的单日估计噪声太大。横截面因子研究用 300 只量级。
三个升级陷阱
pip list --outdated 会列出这些,但不能升:
| 包 | 现版本 | 原因 |
|---|---|---|
| PySide6(含 Addons/Essentials/shiboken6) | 6.8.2.1 | vnpy 硬锁 pyside6==6.8.2.1 |
| peewee | 3.17.3 | empyrical-reloaded 要 peewee<3.17.4 |
| pandas | 2.3.3 | alphalens-reloaded 要 pandas<3.0 |
环境四:veighna_studio
用官方发行版,不用 conda 装。下载 veighna_studio-4.4.0.exe(507 MB)安装即可。
为什么不用 pip 装
pip install vnpy → 46 个包,vnpy_* 模块只有 vnpy 自己一个
VeighNa Studio → 50 个 vnpy_* 模块
vn.py 是模块化架构,github.com/vnpy/vnpy 只是框架核心,每个券商接口、每个交易 App 都是独立的仓库和独立的 PyPI 包,核心包一个都不带。
而且所有带 C++ 编译的券商网关,Windows wheel 只有 cp313:
| 模块 | Windows wheel |
|---|---|
| vnpy_ctp | 仅 cp313 |
| vnpy_mini | 仅 cp313 |
| vnpy_femas | 仅 cp313 |
| vnpy_sec | 无 wheel,仅 sdist |
Studio 捆绑 Python 3.13.8 就是这个原因。想用 conda 复刻,得建 3.13 环境再手动装 38 个包。
和 conda 冲突吗
conda 环境不受影响,但它会改系统 PATH,这点要知道。
实测结果:
① 会往系统 PATH 加两条(安装时自动加的,向导里没给选项):
[Machine PATH 第 15、16 位]
D:\CodeEnv\veighna_studio
D:\CodeEnv\veighna_studio\Scripts
后果是:全新 shell 里敲 python 会解析到 Studio 的 Python 3.13,而不是你的 conda 环境。
bash
C:\> where python
D:\CodeEnv\veighna_studio\python.exe
C:\Users\你的用户名\AppData\Local\Microsoft\WindowsApps\python.exe
② 没有写 Python 注册表 :HKLM\SOFTWARE\Python\PythonCore 下只有 Anaconda 那一条(3.14),Studio 没有注册自己。
③ conda 环境完全不受影响 :conda env list 正常,各环境 pip check 全绿。
原因是 conda 的 conda activate 是 profile 里注册的 shell 函数,不看 PATH;而且激活后 conda 会把环境路径 prepend 到 PATH 最前面,顺序上压过 Studio。
实际影响 :只影响不 activate 任何环境时的裸 python 命令。如果你的脚本依赖裸 python,装 Studio 后行为会变。用绝对路径或者先 conda activate 就不受影响。
装之前建议存个 PATH 快照,方便对比和还原:
bash
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v Path > path-before.txt
注意:查 PATH 要看注册表 (持久化的值),不能看当前进程的
%PATH%。已经启动的进程持有的是旧快照,安装程序改了 PATH 也不会反映进去------我第一次就是这么查错的。
vnpy.alpha 在 Studio 里不可用
官方发行版没带 [alpha] extra,缺 polars/torch/lightgbm/sklearn/alphalens。强行装会触发前面说的 peewee 冲突,破坏数据库层。要用 alpha 走 vnpy-alpha 环境。
常见报错速查
1. conda 不是内部或外部命令
conda init 注册的是 shell 函数不是 PATH 条目。用绝对路径 D:\anaconda3\Scripts\conda.exe。
2. 中文输出乱码 Ӫҵ������
Windows 控制台 GBK 编码。设 PYTHONIOENCODING=utf-8,或写 UTF-8 文件再读。
3. 东方财富接口全部连不上
ConnectionError: ('Connection aborted.', RemoteDisconnected('Remote end closed
connection without response'))
影响所有 *_em 接口:stock_zh_a_hist、stock_zh_a_spot_em、stock_individual_info_em、stock_news_em 等。
如果机器上有接管 DNS 的代理软件,域名可能被路由到境外出口后被拒。自查:
python
import socket
print(socket.gethostbyname("push2his.eastmoney.com"))
# 返回 198.18.x.x 说明 DNS 被接管
改用非东财源,这套组合够完成一份完整的基本面分析:
| 维度 | 接口 | 源 |
|---|---|---|
| 日线行情 | stock_zh_a_daily(symbol="sh600519", adjust="qfq") |
新浪,需 sh/sz 前缀 |
| 全市场快照 | stock_zh_a_spot() |
新浪,较慢 |
| 指数 | stock_zh_index_daily(symbol="sh000300") |
新浪 |
| 财务摘要 | stock_financial_abstract_ths(symbol="600519", indicator="按报告期") |
同花顺,25 列全给 |
| 三大报表 | stock_financial_report_sina(stock="sh600519", symbol="资产负债表") |
新浪 |
| 财务指标 | stock_financial_analysis_indicator(symbol="600519", start_year="2020") |
新浪 |
| 估值 PE/PB | stock_zh_valuation_baidu(symbol="600519", indicator="市盈率(TTM)", period="近五年") |
百度 |
| 十大股东 | stock_main_stock_holder(stock="600519") |
新浪 |
| 主营业务 | stock_zyjs_ths(symbol="600519") |
同花顺 |
| 分红 | stock_fhps_detail_ths(symbol="600519") |
同花顺 |
两个字段细节:stock_financial_abstract_ths 的缺失值是字符串 "False",金额是 "1.15亿" / "3622.32万" 格式需自己解析;stock_main_stock_holder 的日期列名是「截至日期」不是「截止日期」。
4. 装 akshare 卡在 Building wheel for jsonpath
jsonpath 是 akshare 的依赖,只有 10 KB 源码包没有预编译版本,setup.py 用了 3.12 已移除的 distutils,靠 setuptools 垫片构建。会停几秒,正常现象。
5. 跑回测炸出几十个进程
RuntimeError: An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.
MemoryError
ImportError: DLL load failed while importing _multiarray_umath: 页面文件太小,无法完成操作。
Windows 用 spawn 创建子进程会重新导入主模块,模块顶层有启动进程的代码就会无限递归。那些 MemoryError 和 DLL load failed 是内存被撑爆的连带症状,不是 numpy 装坏了。
脚本加守卫:
python
def main():
...
if __name__ == "__main__":
main()
6. 'datetime.date' object has no attribute 'to_pydatetime'
ak.stock_zh_a_daily() 返回的 date 列是原生 datetime.date,不是 pandas Timestamp。先转换:
python
df["date"] = pd.to_datetime(df["date"])
7. 成交额和换手率写反(不报错)
akshare 的列:
['date', 'open', 'high', 'low', 'close', 'volume', 'amount', 'outstanding_share', 'turnover']
amount 是成交额,turnover 是换手率。而 vnpy 的 BarData.turnover 指成交额。
python
turnover=float(r.amount) # 正确
turnover=float(r.turnover) # 错误,但不报错
程序照常跑完,成交额相关的因子全算错。
8. 升级 pydantic_core 后 pydantic 用不了
pydantic 2.13.5 → pydantic-core==2.46.5
是等号锁定。pip 只解算你要装的包,不会拦你,装完就破坏了这个锁。
pip list --outdated 里的传递依赖不要单独升级,要升就升上游的包。
9. pip install pybroker 装到别的包
PyPI 上的包名是 lib-pybroker。import 时才是 import pybroker。
10. 查 PATH 要看注册表,不能看 %PATH%
装完 VeighNa Studio 后我查了一遍 PATH,显示没被改动,结论写错了。
原因是用 echo %PATH% 查的是当前进程的 PATH,而这个 shell 在安装之前就启动了,持有的是旧快照。安装程序改的是注册表,已运行的进程感知不到。
正确查法:
bash
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment" /v Path
reg query "HKCU\Environment" /v Path
Studio 确实往系统 PATH 加了两条,所以裸 python 会指向它的 Python 3.13。
装完的验收
结构检查
bash
python.exe -m pip check
输出 No broken requirements found. 算过。
存快照方便回滚:
bash
python.exe -m pip freeze > env-lock.txt
python.exe -m pip install -r env-lock.txt --force-reinstall # 回滚
功能验证
import 成功不代表能用,要实际调用。我给 quant 跑了 13 项:4 个 akshare 接口、yfinance 取数、akquant 的指标和类、quantstats 的 4 个指标 + HTML 生成,加一个跨库联动(akshare 取数 → pandas 计算 → quantstats 出报告)。
vnpy-alpha 跑了完整链路:数据写入 → 读回 → 158 因子计算 → 三个模型训练 → 预测输出。
最终结果
quant akshare + yfinance + akquant + quantstats 无上限约束
pybroker PyBroker + numba + optuna numpy<2.6
vnpy-alpha vnpy.alpha + torch + lightgbm + alphalens pandas<3.0 / peewee<3.17.4 / pyside6==6.8.2.1
veighna_studio 官方发行版 50 个模块 独立 Python 3.13,会改系统 PATH
总计约 6 GB。
版本号、报错信息、测试结果均来自 2026 年 9 月实际操作。环境:Windows 11 + conda 26.5.3 + Python 3.12/3.13。