遇到问题?先看这里!本文档收集了用户最常遇到的问题和解决方案。
- xtquant 相关 ← 🆕 常见问题
- 数据相关
- 配置相关 ← 🆕 新增章节
- QMT自动登录相关 ← 🆕 新增
- 代码转换相关
- 安装相关
- 运行相关
- 性能相关
- xqshare 相关
- 模块选择相关
这是最常见的错误!说明 xtquant 未正确安装或版本不兼容。
本项目需要特殊版本的 xtquant,不能使用 pip install xtquant 安装的官方版本!
为什么? 不同券商的 QMT 版本发布节奏不一致,xtquant 接口和行为存在差异。使用官方版本会导致:连接失败、字段缺失、接口不兼容。
方法 1:从 GitHub Releases 下载(推荐)
-
访问:https://github.com/quant-king299/EasyXT/releases/tag/v1.0.0
-
下载:
xtquant.rar -
解压到项目根目录(即下载的 EasyXT 项目文件夹)
说明:从 GitHub 下载的文件夹名为
EasyXT,项目根目录就是EasyXT/ -
验证安装:
python -c "from xtquant import xtdata; print('✓ OK')"
方法 2:一键下载并解压(PowerShell)
# 先进入项目根目录(EasyXT项目文件夹)
cd <你的项目路径>
$url = "https://github.com/quant-king299/EasyXT/releases/download/v1.0.0/xtquant.rar"
$dest = "$PWD\xtquant.rar"
Invoke-WebRequest -Uri $url -OutFile $dest -UseBasicParsing
# 解压(需要 7-Zip)
if (Test-Path "$env:ProgramFiles\7-Zip\7z.exe") {
& "$env:ProgramFiles\7-Zip\7z.exe" x -y "$dest" -o"$PWD"
}
Remove-Item $dest -ErrorAction SilentlyContinue
python easy_xt/check_xtquant.py方法 3:从 QMT 软件目录复制
如果已安装 QMT 客户端:
- 找到 QMT 安装目录,如:
D:\国金证券QMT交易端\userdata_mini\Python\ - 复制
xtquant文件夹到项目根目录(EasyXT项目文件夹)
运行诊断脚本:
python easy_xt/check_xtquant.py该脚本会自动检查:
- ✅ xtquant 模块能否导入
- ✅ xtquant.datacenter 能否导入(关键组件)
- ✅ xtquant.xtdata 能否导入
问题:XtQuant 不支持 Python 3.13!
支持版本:Python 3.6 - 3.12(推荐 3.11)
检查版本:
python --version
# 正确: Python 3.11.x
# 错误: Python 3.13.x解决方案:
如果系统默认是 Python 3.13,需要将 Python 3.11 设为默认:
- 按
Win + S搜索 "编辑系统环境变量" - 点击 "环境变量"
- 在 "用户变量" 的
Path中,将 Python 3.11 的路径移到最顶部:C:\Users\你的用户名\AppData\Local\Programs\Python\Python311\Scripts\ C:\Users\你的用户名\AppData\Local\Programs\Python\Python311\ - 删除 Python 3.13 的路径
- 重启终端,验证:
python --version
如果将 xtquant 解压到自定义目录(如 C:\xtquant_special),需设置环境变量:
setx XTQUANT_PATH "C:\xtquant_special"运行 rungui.py 后看到提示:
[时间] 本地数据管理组件已加载
[时间] 提示:首次使用请先下载数据
[时间] ℹ️ DuckDB数据库尚未创建,请先下载股票数据
不知道应该点击哪个按钮:
- 📥 下载A股数据
- 📜 补全历史数据
- 🔄 更新缺失数据
首次运行应该选择:📥 下载A股数据
| 功能 | 用途 | 使用场景 | 数据库状态 |
|---|---|---|---|
| 📥 下载A股数据 | 从零开始,自动获取全部A股列表并下载指定日期范围的数据 | 首次使用 | 数据库为空 |
| 📜 补全历史数据 | 补充指定日期之前的历史空白 | 发现历史数据缺失时 | 已有股票列表 |
| 🔄 更新缺失数据 | 智能检测并补充最新日期之后的所有缺失数据 | 日常更新数据 | 已有完整历史数据 |
📥 下载A股数据(首次使用必选)
- 功能:从零开始建立数据库
- 操作:
- 设置日期范围(建议首次:2024-01-01 ~ 今天)
- 点击「📥 下载A股数据」按钮
- 等待下载完成(首次可能需要几小时)
- 说明:
- ✅ 自动获取全部A股列表(约5000只股票)
- ✅ 创建DuckDB数据库和表结构
- ✅ 下载指定日期范围内的日线数据
- ⏰ 首次下载时间较长
📜 补全历史数据
- 功能:补充指定日期之前的历史空白
- 用途:发现历史数据有缺失时使用
- 说明:
- 需要数据库中已有股票列表
- 只会补充缺失的部分,已有数据不会被删除
- 适合修复历史数据空白期
🔄 更新缺失数据
- 功能:智能检测并补充最近缺失的数据
- 用途:日常更新推荐使用
- 说明:
- 自动检测每只股票的最新日期
- 补充从最新日期之后到今天缺失的所有数据
- 不管缺失1天还是100天,都会一并补全
首次运行: 📥 下载A股数据 → 从零开始建立数据库
日常使用: 🔄 更新缺失数据 → 补充最近几天的数据(推荐)
发现缺失: 📜 补全历史数据 → 修复历史数据空白期
- 数据存储位置:
D:/StockData/stock_data.ddb - 首次下载建议:
- 先下载1年数据测试(如2024-01-01 ~ 今天)
- 确认无误后再下载更早年份的数据
- 建议晚上睡觉前运行,避免交易时间影响速度
- 下载过程可以最小化窗口,不影响使用
- 数据来源:QMT本地数据(需要QMT已运行并登录)
DuckDB 是一个嵌入式数据库,类似于 SQLite,但专为分析查询(OLAP)优化。在本项目中,它用来把股票行情数据保存到本地文件(stock_data.ddb),回测时直接从本地文件读取,速度比每次从网络获取快 10-30 倍。
| 你的情况 | 是否需要 | 说明 |
|---|---|---|
| 只做实盘交易,不回测 | 不需要 | QMT 实时数据足够 |
| 偶尔跑几次回测 | 可选 | 不装也能跑,只是慢一些 |
| 频繁回测、调参、因子分析 | 强烈推荐 | 速度提升 10-30 倍 |
| 使用小市值策略 | 需要 | 策略依赖市值数据表 |
只需要满足以下任意一种条件即可:
- 方式A:有 Tushare Token(推荐,免费注册)— 不需要 QMT
- 方式B:有 QMT/miniQMT 环境 — 不需要 Tushare Token
- 方式C:两者都有 — 最灵活
无论哪种方式,都需要先安装 DuckDB:
pip install duckdb安装 duckdb(pip install duckdb)
|
v
选择下载方式
|
+---> 方式A:GUI 下载(推荐新手)
| python run_gui.py → "Tushare下载" 标签页
| 只需 Tushare Token,不需要 QMT
|
+---> 方式B:命令行下载
| python tools/setup_duckdb.py
| 需要 Tushare Token(市值数据)+ QMT(日线数据)
|
+---> 方式C:使用 QMT 本地数据
python run_gui.py → "数据管理" 标签页
需要 QMT/miniQMT 已启动
数据下载完成后,回测时会自动检测并使用 DuckDB,无需额外配置。
以下是从零开始的详细操作步骤,以最常用的 GUI 方式为例。
- 访问 https://tushare.pro ,点击右上角「注册」
- 用手机号注册(免费,注册即送积分)
- 登录后,进入「用户中心」→「接口Token」
- 复制一长串 Token(类似
1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab)
在项目根目录创建 .env 文件(如果还没有的话):
# Windows PowerShell
Copy-Item .env.example .env
# Windows CMD
copy .env.example .env
# 或者手动创建编辑 .env 文件,填入 Token:
TUSHARE_TOKEN=你的Token粘贴在这里验证配置:
python -c "from dotenv import load_dotenv; load_dotenv(); import os; print('Token OK:', os.getenv('TUSHARE_TOKEN')[:10]+'...') if os.getenv('TUSHARE_TOKEN') else print('Token 未配置')"python run_gui.py在 GUI 中:
- 切换到 "Tushare下载" 标签页
- 在 Token 输入框中粘贴你的 Token(如果
.env已配置会自动填入) - 点击 "测试连接" ,看到"连接成功"说明 Token 没问题
- 在 "快速下载" 子标签页中:
- 勾选 "日线行情"(回测必需的数据)
- 勾选 "市值数据"(小市值策略必需)
- 股票数量设为 100(新手先下 100 只试试)
- 数据年份设为 1 年(新手先下 1 年试试)
- 点击 "开始批量下载"
- 等待下载完成(100 只股票 1 年数据大约 5-15 分钟)
import duckdb
con = duckdb.connect('D:/StockData/stock_data.ddb', read_only=True)
# 查看有哪些表
tables = con.execute("SHOW TABLES").fetchall()
print("表列表:", [t[0] for t in tables])
# 查看日线数据概况
try:
result = con.execute("""
SELECT
COUNT(DISTINCT stock_code) as stocks,
MIN(date) as from_date,
MAX(date) as to_date,
COUNT(*) as records
FROM stock_daily
""").fetchone()
print(f"日线数据: {result[0]} 只股票, {result[1]} ~ {result[2]}, 共 {result[3]:,} 条")
except:
print("日线数据表为空")
# 查看市值数据概况
try:
result = con.execute("""
SELECT
COUNT(DISTINCT date) as days,
MIN(date) as from_date,
MAX(date) as to_date
FROM stock_market_cap
""").fetchone()
print(f"市值数据: {result[0]} 个交易日, {result[1]} ~ {result[2]}")
except:
print("市值数据表为空")
con.close()下载成功后,无需任何额外配置,回测和数据查询会自动使用 DuckDB:
from easyxt_backtest import DataManager, BacktestEngine
# 自动检测 DuckDB 路径
dm = DataManager()
engine = BacktestEngine(initial_cash=1000000, data_manager=dm)
# 开始回测
result = engine.run_backtest(strategy, '2024-01-01', '2024-12-31')
result.print_summary()Q: 下载报错"积分不足"怎么办?
A: Tushare 采用积分制。日线行情 daily 接口消耗较少积分,注册送的积分通常够下载几百只股票。如果不够,可以先减少下载数量(比如 50 只),或者到 Tushare 论坛做任务获取积分。
Q: 没有D盘怎么办?数据会存在哪里?
A: 系统会自动检测 D 盘、C 盘、E 盘。如果都不存在,会自动创建 D:/StockData/ 目录。你也可以通过环境变量自定义路径:
setx DUCKDB_PATH "C:/MyData/stock_data.ddb"Q: 数据下载到一半中断了怎么办? A: 直接重新下载。系统会自动跳过已有的数据,只下载缺失的部分。
Q: 我没有 QMT,能只用 Tushare 下载吗? A: 完全可以! GUI 的"Tushare下载"标签页只依赖 Tushare,不需要 QMT。这是新手最推荐的方式。
DuckDB 文件已经存在(D:/StockData/stock_data.ddb),但运行回测时代码找不到数据。
原因1:表名不匹配
旧版本教程可能引用了 stock_data 表,但实际表名是 stock_daily。
# 检查实际的表名
import duckdb
con = duckdb.connect('D:/StockData/stock_data.ddb', read_only=True)
tables = con.execute("SHOW TABLES").fetchall()
print([t[0] for t in tables])
con.close()原因2:回测日期范围没有重叠
如果你下载的是 2024 年的数据,但回测设置的是 2022 年,就会报"数据为空"。
# 检查数据库中的实际日期范围
import duckdb
con = duckdb.connect('D:/StockData/stock_data.ddb', read_only=True)
result = con.execute("SELECT MIN(date), MAX(date) FROM stock_daily").fetchone()
print(f"数据范围: {result[0]} ~ {result[1]}")
con.close()
# 回测日期应在此范围内原因3:DataManager 没有指向正确的路径
如果数据库不在默认路径,需要手动指定:
from easyxt_backtest import DataManager
# 自动检测(检查 D盘、C盘、E盘)
dm = DataManager()
# 手动指定
dm = DataManager(duckdb_path='你的实际路径/stock_data.ddb')原因4:数据库文件损坏
如果数据库文件损坏,删除后重新下载:
# 备份旧文件
ren "D:\StockData\stock_data.ddb" "stock_data.ddb.bak"
# 重新下载
python run_gui.py
# → "Tushare下载" → 重新下载IO Error: Cannot open file "D:\StockData\stock_data.ddb": 系统找不到指定的路径。
- 你还没有下载过数据(第一次使用项目)
- 数据库文件存放在其他盘符(C盘、E盘)
最推荐:用 GUI 下载一次数据
按照上方 第2节 的步骤操作。
或者:手动创建目录后使用 QMT 数据
如果你有 QMT,不需要 DuckDB 也能跑回测(只是速度慢一些)。系统会自动降级到 QMT 数据源。
错误1:Tushare连接失败
ConnectionError: Unable to connect to Tushare API
错误2:积分不足
API Error: 积分不足
错误3:下载速度慢或中断
TimeoutError: Request timeout
检查Token是否有效:
- 登录 Tushare Pro
- 进入「用户中心」→「接口Token」
- 确认Token没有过期
检查积分是否足够:
- 在Tushare网站查看账户积分
- 基础功能需要一定积分(注册后会获得初始积分)
- 高级功能需要更多积分(可能需要充值)
优化下载策略:
- 减少下载数量(GUI中:股票数量改为 10-50 只)
- 减少时间范围(GUI中:数据年份改为 1 年)
- 分批下载(多次运行,每次下载不同的股票)
使用其他数据源: 项目支持多种数据源,会自动降级:
DuckDB > QMT > Tushare > akshare > qstock
如果你有QMT终端,可以直接使用QMT本地数据,无需下载到DuckDB。
ValueError: TUSHARE_TOKEN not found in environment variables
检查.env文件:
-
确认
.env文件在项目根目录:miniqmt扩展/ ├── .env ← 这个文件 ├── easy_xt/ └── README.md -
检查文件内容格式:
# 正确格式(不加引号) TUSHARE_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # 错误格式 TUSHARE_TOKEN="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
-
验证环境变量:
python -c "from dotenv import load_dotenv; load_dotenv(); import os; print('Token OK') if os.getenv('TUSHARE_TOKEN') else print('Token 未配置')"
手动设置环境变量(永久):
# PowerShell
setx TUSHARE_TOKEN "你的Token"
# CMD
setx TUSHARE_TOKEN "你的Token"注意:设置后需要重启终端/IDE才能生效。
ERROR: 无法获取股票 ['000001.SZ'] 的数据。可能的原因:
1. 需要先在迅投客户端中下载历史数据
2. 股票代码错误
QMT刚安装时本地数据库为空,需要先下载历史数据。
方案一:使用项目的一键下载工具
cd tools
python download_all_stocks.py方案二:安装pytdx,自动降级到TDX
pip install pytdx安装后系统会自动使用通达信数据源,不需要QMT也能获取数据。
方案三:使用 DuckDB(推荐长期使用)
按照上方 第2节 下载 DuckDB 数据,彻底避免 QMT 数据管理问题。
[降级] 尝试使用 TDX 数据源...
[WARN] TDX 数据源失败: 时间范围内无数据: None - 20260414
或者
ERROR: 无法获取股票 ['000001.SZ'] 的数据。
TDX(通达信)对1分钟数据有最小count限制:count必须 ≥ 2
当你使用 count=1 获取1分钟数据时:
data = api.get_price(['000001.SZ'], period='1m', count=1) # ❌ 会失败TDX服务器认为请求的数据量太少,拒绝请求或返回空数据。
count = 数据条数,表示获取最近多少根K线:
| 周期 | count=5 的实际含义 | 时间范围 |
|---|---|---|
| 1d (日线) | 最近5个交易日 | 约1周 |
| 1m (1分钟) | 最近5个分钟 | 最近5分钟 |
| 5m (5分钟) | 最近5个5分钟 | 最近25分钟 |
| 1h (1小时) | 最近5个小时 | 最近5小时 |
方案一:自动调整(推荐,已修复) ✅
最新代码已经自动处理此问题:
# 即使你写 count=1,也会自动调整为 count=2
data = api.get_price(['000001.SZ'], period='1m', count=1)
# 输出:[INFO] TDX 1分钟数据最小count为2,已自动调整: 1 -> 2方案二:手动调整count值
# ✅ 正确:使用 count >= 2
data = api.get_price(['000001.SZ'], period='1m', count=2)
data = api.get_price(['000001.SZ'], period='1m', count=5)
data = api.get_price(['000001.SZ'], period='1m', count=10)
# ❌ 错误:count=1 会失败
data = api.get_price(['000001.SZ'], period='1m', count=1)方案三:使用更大的count值
对于1分钟数据,建议使用较大的count值:
# 推荐:获取最近10-20分钟的1分钟数据
data = api.get_price(['000001.SZ'], period='1m', count=10)
# 或
data = api.get_price(['000001.SZ'], period='1m', count=20)| 周期 | 最小count | 推荐count | 说明 |
|---|---|---|---|
| 1m | 2 | 10-20 | TDX有最小限制 |
| 5m | 1 | 5-10 | 无特殊限制 |
| 15m | 1 | 5-10 | 无特殊限制 |
| 30m | 1 | 5 | 无特殊限制 |
| 1h | 1 | 5 | 无特殊限制 |
| 1d | 1 | 5-100 | 根据需求 |
技术原因:
- 数据完整性:TDX服务器可能要求返回一定量的数据
- 性能优化:对于高频数据(如1分钟),服务器希望一次性返回更多
- 接口设计:某些API设计时就规定了最小请求量
只有1分钟数据有此限制:
- ✅ 5m、15m、30m、1h、1d 等周期可以使用
count=1 - ❌ 1m 数据必须使用
count>=2
当QMT没有分钟数据时,系统会自动降级到TDX:
[降级] 尝试使用 TDX 数据源...
[INFO] TDX 1分钟数据最小count为2,已自动调整: 1 -> 2 ← 自动调整
[OK] TDX 数据源获取成功
如果TDX也失败,会继续尝试Eastmoney:
[降级] 尝试使用 EASTMONEY 数据源...
[WARN] EASTMONEY 数据源失败: ...
使用了 tools/download_all_stocks.py 下载了全部A股数据,文件保存在 QMT 的 .DAT 格式中(如 userdata_mini/datadir/SZ/86400/000001.DAT),但想导入到 DuckDB(stock_data.ddb)并使用五维复权功能,不知道怎么操作。
download_all_stocks.py 只做了一件事:调用 xtdata.download_history_data() 把数据下载到 QMT 的 .DAT 本地文件。它不会自动把数据提取出来存到 DuckDB。
完整的下载流程应该是三步:
① xtdata.download_history_data() → 下载数据到 .DAT 文件
② xtdata.get_market_data_ex() → 从 .DAT 读取为 Python DataFrame
③ 写入 DuckDB + 五维复权 → 存入 stock_data.ddb
download_all_stocks.py 只做了第①步,缺少第②③步。
不需要手动转换 .DAT 文件! 直接使用 GUI 界面操作即可:
情况一:.DAT 文件已经下载好了(你之前运行过 download_all_stocks.py)
- 启动 GUI:
python run_gui.py - 切换到 "📊 数据管理" 标签页
- 点击 "🔄 更新缺失数据" 按钮
- 系统会通过 QMT API(
xtdata.get_market_data_ex())自动读取已有的 .DAT 文件,提取数据并存入 DuckDB
已经下载好的 .DAT 文件不会被浪费,QMT API 会直接从本地 .DAT 文件读取,不需要重新从网络下载。
情况二:还没有下载过数据,想一步到位
- 启动 GUI:
python run_gui.py - 切换到 "📊 数据管理" 标签页
- 设置日期范围(建议开始日期设为5年前)
- 点击 "📥 下载A股数据" 按钮
- 系统会自动完成:下载 → 读取 → 存入 DuckDB → 五维复权,一条龙搞定
情况三:只想下载单只股票
- 启动 GUI:
python run_gui.py - 切换到 "📊 数据管理" 标签页
- 在 "🎯 手动下载单个标的" 区域输入股票代码(如
000001.SZ) - 选择数据类型和日期范围
- 点击 "⬇️ 下载单个标的"
数据存入 DuckDB 后,在 "📈 数据查看器" 标签页可以切换五种复权方式查看数据:
| 复权类型 | 说明 | 用途 |
|---|---|---|
| 不复权 | 除权除息后的原始价格 | 看真实交易价格 |
| 前复权 | 以最新价格为基准调整历史 | 看K线图最常用 |
| 后复权 | 以上市首日为基准调整当前 | 计算真实收益率 |
| 等比前复权 | 几何平均消除除权跳空 | 连续K线 |
| 等比后复权 | 几何平均消除跳空 | 连续收益曲线 |
提示:不要使用
download_all_stocks.py下载数据,直接用 GUI 里的按钮就行,省时省力。
有用户反馈:既然回测基本都用前复权,为什么 DuckDB 只存不复权数据?每次都要先查 DuckDB 再调 QMT API 获取复权,是不是多了一步?DuckDB 还有什么用?
核心逻辑:原始数据不变,存本地;复权数据会变,用时再算。
不复权和复权是两条并行路径,不是串行的:
| 查询类型 | 数据来源 | 是否需要QMT |
|---|---|---|
| 不复权 | 直接读 DuckDB | 不需要 |
| 任何复权 | 直接调 QMT API | 需要 |
具体来说:
- 不复权:从 DuckDB 读取原始 OHLCV 数据,速度快,无需启动 QMT
- 前/后/等比前/等比后复权:直接调用 QMT API 的
get_market_data_ex(dividend_type=...)接口,QMT 实时计算并返回已复权数据
不存在"先从 DuckDB 取原始数据再本地做复权转换"的流程,所以没有"多绕一步"的问题。
复权数据有一个关键特性:每次新的除权除息发生后,所有历史数据的复权值都会变。
比如某股票在 2026 年 6 月派息,那么:
- 前复权:6 月之前所有历史价格都要重新计算
- 后复权:6 月之后所有价格都要重新计算
如果预存复权数据,就需要在每次除权除息后批量更新全量历史数据,维护成本高且容易出错。改为按需从 QMT API 获取,复权计算由 QMT 官方算法保证准确性,无需本地维护。
| 复权类型 | QMT参数 | 说明 | 典型用途 |
|---|---|---|---|
| 不复权 | none |
原始交易价格 | 看真实交易价、事件研究 |
| 前复权 | front |
以最新价为基准调整历史价格 | 技术分析、看K线图 |
| 后复权 | back |
以上市首日为基准调整当前价格 | 计算长期真实收益率 |
| 等比前复权 | front_ratio |
乘法因子调整历史价格 | 量化回测(推荐) |
| 等比后复权 | back_ratio |
乘法因子调整当前价格 | 复合收益曲线 |
等比复权与普通复权的区别:普通复权用加法(加回分红金额),等比复权用乘法(乘以比例因子)。等比复权能保证涨跌幅的连续性,是量化回测的推荐选择。
- 离线查看原始行情:不需要启动 QMT 就能浏览历史数据
- 数据完整性检测:对比本地已有数据,发现缺失时才触发在线补充
- 快速量价统计:不复权场景下的数据分析
- GUI 数据查看器的默认模式:
local_only=True时只展示本地数据,响应更快
目前是的。如果 QMT 未启动,系统会降级返回不复权的原始数据并给出提示。后续如果有"离线回测"需求,可以考虑增加一层复权结果缓存(按股票+日期范围缓存 QMT 返回的复权数据),按需填充,不会像之前那样预存全量复权列。
本项目主要有两个配置文件:
| 配置文件 | 路径 | 用途 |
|---|---|---|
| unified_config.json | config/unified_config.json |
主配置(QMT路径、交易参数等) |
| .env | 项目根目录 /.env |
环境变量(Token、Cookie等) |
Windows 最简单方法:
- 按
Win + R,输入notepad - 文件 → 打开
- 选择配置文件(
.env或config/unified_config.json) - 编辑并保存
如果 .env 不存在:
# Windows PowerShell
Copy-Item .env.example .env
# Windows CMD
copy .env.example .env错误:QMT 连接失败
解决方案:
编辑 config/unified_config.json,修改路径:
{
"settings": {
"account": {
"qmt_path": "D:\\\\国金QMT交易端模拟\\\\userdata_mini"
}
}
}\\\\ 或 /:
- ✅
"D:\\\\国金QMT交易端模拟\\\\userdata_mini" - ✅
"D:/国金QMT交易端模拟/userdata_mini" - ❌
"D:\国金QMT交易端模拟\userdata_mini"
验证配置:
from easy_xt.config import config
config.print_qmt_status()步骤 1:获取 Token
- 访问 https://tushare.pro 注册
- 登录后进入「用户中心」→「接口Token」
步骤 2:配置 Token
编辑项目根目录的 .env 文件:
TUSHARE_TOKEN=你的Token粘贴在这里验证:
python -c "from dotenv import load_dotenv; load_dotenv(); import os; print('✓ Token OK' if os.getenv('TUSHARE_TOKEN') else '✗ Token 未配置')"原因:PYTHONPATH 配置错误
VSCode 解决方案:
创建 .vscode/settings.json:
{
"python.envFile": "${workspaceFolder}/.env",
"python.analysis.extraPaths": ["${workspaceFolder}"]
}PyCharm 解决方案:
- Run → Edit Configurations
- 添加环境变量:
PYTHONPATH=项目根目录路径
Trae 解决方案:
在 Trae 终端中设置:
export PYTHONPATH="项目根目录路径:$PYTHONPATH"[10:52:22] 📥 开始下载可转债数据 (2016-04-16 ~ 2026-04-16)
[10:52:22] ✅ 获取到 648 只可转债
[10:56:45] 📊 进度: 500/648 | 成功: 4 | 失败: 496
[10:58:00] ✅ 下载完成! 总数: 648, 成功: 4, 失败: 644
可转债数据下载失败率高达99%,同时看到错误信息:
[WARN] TDX 数据源失败: 无法获取股票 ['123001.SZ'] 的TDX数据
ERROR:easy_xt.realtime_data.providers.eastmoney_provider:获取K线数据请求失败: ('Connection aborted.', RemoteDisconnected)可转债代码格式特殊:
- 123xxx.SZ(深交所可转债)
- 128xxx.SZ(深交所可转债)
- 110xxx.SH(上交所可转债)
- 113xxx.SH(上交所可转债)
数据源支持情况:
| 数据源 | 股票支持 | 可转债支持 | 说明 |
|---|---|---|---|
| QMT | ✅ 完全支持 | 需要特殊配置,部分券商不支持 | |
| TDX | ✅ 支持股票 | ❌ 不支持可转债 | 通达信主要支持股票和指数 |
| Eastmoney | ✅ 支持股票 | 网络不稳定,经常连接失败 |
三个降级阶段都失败:
-
QMT主数据源失败:
- QMT可能没有订阅可转债行情
- 券商QMT版本可能不支持可转债数据
- 可转债代码不在QMT的订阅列表中
-
TDX降级失败:
- TDX(通达信)不支持可转债数据
- 只支持股票、指数、期货等品种
-
Eastmoney降级失败:
- Eastmoney理论上支持可转债
- 但网络连接不稳定,经常超时
方案1:在QMT中订阅可转债行情(推荐)
- 打开QMT软件,登录交易账户
- 订阅可转债行情:
- 在QMT自选股中添加可转债代码
- 或使用QMT的"品种订阅"功能
- 验证订阅:
import easy_xt api = easy_xt.get_api() api.init_data() data = api.get_price(['123001.SZ'], period='1d', count=5) print(data)
- 重新运行"下载可转债数据"
方案2:使用Tushare下载可转债数据(推荐备选)
Tushare对可转债支持更好,数据更完整:
- 切换到GUI的"Tushare下载"标签页
- Tushare支持可转债数据
- 数据质量更好,来源更稳定
方案3:跳过可转债数据(快速解决)
如果你主要做股票量化,可转债数据不是必需的:
- 直接使用"下载A股数据"功能
- 后续需要可转债时再配置
如果看到'DataManager' object has no attribute 'get_stock_data'错误:
# 清除Python缓存
rm -rf "101因子/101因子分析平台/src/data_manager/__pycache__"
# 重启GUI
python run_gui.py可转债下载失败是正常现象,主要原因:
- ✅ QMT支持有限:需要特殊配置才能获取可转债数据
- ❌ TDX不支持:通达信只支持股票和指数
⚠️ Eastmoney不稳定:网络连接经常失败
推荐方案:
- 短期:使用Tushare下载可转债数据
- 长期:在QMT中订阅可转债行情
如果你只做股票量化,可以直接跳过可载数据下载,不影响股票策略的开发和回测。
完全可以独立运行,不需要安装 miniQMT!
聚宽转PTrade 模块(code_converter/)是一个纯代码转换工具,把聚宽的 API 语法翻译成 PTrade 的语法。它与 QMT/easy_xt 完全没有依赖关系。
| 问题 | 回答 |
|---|---|
| 需要 miniQMT 吗? | 不需要 |
| 需要 easy_xt 吗? | 不需要 |
| 需要 xtquant 吗? | 不需要 |
| 需要启动 QMT 客户端吗? | 不需要 |
| 转换后的代码在哪里运行? | 复制到 PTrade 平台运行 |
项目中的 QMT 相关模块(easy_xt、xtquant 等)是给 QMT 用户用的,和 PTrade 没有关系,可以忽略。
- 从 GitHub 下载项目代码
- 进入
code_converter文件夹 - 双击
run_converter.bat,弹出图形界面 - 选择你的聚宽策略 .py 文件,点击"开始转换"
- 点击"保存结果",将转换后的代码复制到 PTrade 平台运行
cd code_converter
python cli.py 你的聚宽策略.py -o ptrade策略.pycode_converter/代码转换学习-demo/ 目录提供了学习资料:
| 文件 | 说明 |
|---|---|
jq_code_demo.py |
聚宽策略示例代码 |
trans_PTrade.txt |
转换后的 PTrade 代码 |
check_before.txt |
转换前后的对比说明 |
聚宽一键迁移ptrade代码转换使用手册.docx |
完整的使用手册 |
注意:部分复杂的聚宽 API(如 get_fundamentals 的复杂 query)转换后可能需要手动微调,转换器会给出提示。
转换后的文件只有头部注释:
# 聚宽策略转Ptrade - BACKTEST版本
# 转换时间: 2026-04-09 22:19:28
# 转换器版本: v3.4
输入的聚宽策略文件内容为空。转换器读入空文件,自然只能输出头部信息。
确保输入文件包含有效的聚宽策略代码。一个有效的聚宽策略通常包含:
# 至少要有 initialize 和策略函数
def initialize(context):
set_benchmark('000300.XSHG')
run_daily(my_trade, time='9:30')
def my_trade(context):
stocks = get_all_securities().index.tolist()
for stock in stocks[:10]:
order_value(stock, 10000)TypeError: 'NoneType' object is not callable
ModuleNotFoundError: No module named 'duckdb'
AttributeError: 'DataManager' object has no attribute 'get_connection_status'
一键修复脚本(推荐)
# 1. 更新到最新代码
git pull origin main
# 2. 重新安装依赖
python -m pip install -r requirements.txt
# 3. 重新安装 easyxt_backtest
python -m pip uninstall easyxt_backtest -y
python -m pip install -e ./easyxt_backtest
# 4. 启动程序
python run_gui.py如果上面不行,试试完整重装:
# 删除虚拟环境
Remove-Item -Recurse -Force .venv
# 重新创建虚拟环境
python -m venv .venv
& .\.venv\Scripts\Activate.ps1
# 安装所有依赖
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
python -m pip install -e ./easyxt_backtest
# 启动程序
python run_gui.pyQ: pip 命令报错怎么办?
A: 使用 python -m pip 代替 pip:
# 如果这个报错
pip install xxx
# 改成这样
python -m pip install xxxQ: 提示 "ModuleNotFoundError: No module named 'duckdb'"?
A: 安装缺失的包:
python -m pip install duckdb pyarrowQ: 为什么本地能跑,GitHub 下载的代码不能跑?
A: 可能是版本不同步,运行 git pull origin main 更新到最新代码即可。
ReadTimeoutError: HTTPSConnectionPool read timeout
ERROR: Could not find a version that satisfies the requirement
使用国内镜像源:
pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt逐个安装依赖:
pip install pandas numpy PyQt5 duckdb streamlit
pip install -e ./easy_xtImportError: No module named 'PyQt5'
pip install PyQt5File "matplotlib\artist.py", line 72, in draw_wrapper
return draw(artist)
...
ymax = corners_rotated[:, 1].max()
File "numpy\_core\_methods.py", line 44, in amax
return umr_maximum(a, axis, None, out, keepdims, initial, where)
matplotlib找不到中文字体SimHei(黑体),导致绘制图表时出错。
使用项目提供的字体安装工具(推荐):
# 进入tools目录
cd tools
# 运行字体安装工具
python install_simhei_font.py
# 或者双击运行
.\install_simhei_font.bat安装工具会自动完成:
- ✓ 从Windows系统复制SimHei字体
- ✓ 安装到matplotlib字体目录
- ✓ 清除matplotlib缓存
- ✓ 验证字体安装
步骤1:复制字体文件
# 查找matplotlib字体目录
python -c "import matplotlib,os;print(os.path.join(os.path.dirname(matplotlib.__file__),'mpl-data','fonts','ttf'))"
# 复制字体(替换上面的路径)
$font_dir = "matplotlib字体目录路径"
Copy-Item "C:\Windows\Fonts\simhei.ttf" -Destination "$font_dir\simhei.ttf"步骤2:清除matplotlib缓存
python -c "import matplotlib,shutil;cache_dir=matplotlib.get_cachedir();shutil.rmtree(cache_dir,ignore_errors=True);print('缓存已清除')"步骤3:验证安装
python -c "import matplotlib.pyplot as plt;plt.rcParams['font.sans-serif']=['SimHei'];print('字体配置成功')"Q: 为什么会出现这个问题?
A: Windows系统自带SimHei字体,但matplotlib默认不会使用系统字体,需要手动配置。
Q: 安装工具提示找不到SimHei字体?
A: 检查Windows字体目录是否存在该字体:
Test-Path "C:\Windows\Fonts\simhei.ttf"如果返回False,说明系统缺少该字体,需要先安装SimHei字体。
Q: 安装后还是报错?
A: 重启Python程序或IDE,确保matplotlib重新加载字体配置。
ValueError: No data available for the specified date range
KeyError: 'STOCK_CODE not found'
检查数据是否存在:
import duckdb
con = duckdb.connect('D:/StockData/stock_data.ddb', read_only=True)
result = con.execute("SELECT COUNT(*), MIN(date), MAX(date) FROM stock_daily").fetchone()
print(f"数据量: {result[0]} 条, 范围: {result[1]} ~ {result[2]}")
con.close()确认股票代码格式:
- 正确:
000001.SZ,600000.SH - 错误:
000001,600000,sz000001
ConnectionError: 无法连接到交易账户
- 确保QMT客户端已启动并登录
- 确保账户有交易权限
- 确认
qmt_path配置正确
| 数据源 | 回测1000次耗时 | 推荐场景 |
|---|---|---|
| DuckDB | ~10秒 | 高频回测(推荐) |
| QMT本地 | ~30秒 | 实盘交易 |
| Tushare在线 | ~300秒 | 快速测试 |
安装并启用 DuckDB(效果最明显):
按照 第2节 下载 DuckDB 数据即可,回测时会自动使用。
from easyxt_backtest import DataManager
# 自动检测 DuckDB(无需手动指定路径)
dm = DataManager()使用向量化操作代替循环:
# 慢
for i in range(len(df)):
df.loc[i, 'ma5'] = df['close'].iloc[i-5:i].mean()
# 快
df['ma5'] = df['close'].rolling(5).mean()MemoryError: Unable to allocate array
# 分批处理
for batch in stock_batches:
data = load_batch(batch)
process(data)
# 及时释放
import gc
del large_dataframe
gc.collect()运行以下命令快速检查环境状态:
python -c "
import sys, os
from pathlib import Path
print('=' * 50)
print('EasyXT 环境快速检查')
print('=' * 50)
# 1. Python
print(f'[1] Python {sys.version_info.major}.{sys.version_info.minor}: ', end='')
print('OK' if sys.version_info >= (3, 8) else '建议升级到3.8+')
# 2. duckdb
try:
import duckdb; print('[2] duckdb: OK')
except: print('[2] duckdb: 未安装 (pip install duckdb)')
# 3. easy_xt
try:
from easy_xt import get_api; print('[3] easy_xt: OK')
except: print('[3] easy_xt: 未安装 (pip install -e ./easy_xt)')
# 4. DuckDB数据库
db_found = False
for p in ['D:/StockData/stock_data.ddb', 'C:/StockData/stock_data.ddb', 'E:/StockData/stock_data.ddb']:
if Path(p).exists():
size_mb = os.path.getsize(p) / 1024 / 1024
print(f'[4] DuckDB数据库: 找到 ({p}, {size_mb:.1f}MB)')
db_found = True; break
if not db_found:
print('[4] DuckDB数据库: 未找到 (运行 python run_gui.py 下载)')
# 5. Tushare Token
token = os.environ.get('TUSHARE_TOKEN', '')
if not token:
try:
with open('.env') as f:
for line in f:
if line.startswith('TUSHARE_TOKEN='):
token = line.split('=',1)[1].strip()
except: pass
print(f'[5] Tushare Token: {\"OK (\" + token[:10] + \"...)\" if token else \"未配置\"}')
print('=' * 50)
"A: xqshare 是一个远程客户端代理,让你在没有 Windows QMT 环境的情况下,通过远程服务器使用 QMT 的数据接口。
A: 不需要。xqshare 支持连接到已有的远程服务器。你也可以自己搭建服务器(需要 Windows + QMT 环境)。
A: 是的!通过 xqshare,Mac/Linux 用户也可以进行完整的股票交易操作。
A: xqshare 通过网络连接到远程服务器,性能取决于网络延迟。对于大多数量化策略,延迟是可以接受的。
根据需求选择:
- 只要API → 只安装
easy_xt - 要做回测 → 安装
easy_xt+easyxt_backtest - 因子研究 → 只使用
101因子平台(完全独立) - 学习量化 → 安装
easy_xt+ 看学习实例/ - 使用现成策略 → 安装
easy_xt+ 看strategies/
easy_xt:无依赖,可独立easyxt_backtest:可独立,不依赖101因子平台101因子平台:完全独立strategies、学习实例:依赖easy_xt
完全可以。easy_xt 设计为可独立使用的库:
from easy_xt import get_api
api = get_api()
data = api.get_price(['000001.SZ'], start='20240101', period='1d')不需要。101因子平台是完全独立的Web应用,可以单独使用。
建议路径:
- 阅读
学习实例/01_基础入门.py - 运行
学习实例/02_交易基础.py - 尝试
学习实例/04_策略回测.py - 需要时再学习其他模块
| 项目 | 定位 | 关系 |
|---|---|---|
| miniQMT | QMT官方Python接口 | EasyXT依赖的基础 |
| EasyXT | miniQMT的简化封装 | 本项目的核心库 |
| QMT官方 | 迅投QMT交易平台 | 底层交易软件 |
| 聚宽JoinQuant | 在线量化平台 | 通过JQ2PTrade可转换代码 |
| Backtrader | 通用回测框架 | easyxt_backtest是QMT专用版 |
- GitHub Issues: https://github.com/quant-king299/EasyXT/issues
- 微信公众号: 王者quant
- 知识星球: 获取一对一答疑服务
- 完整的错误信息
- 运行环境(Python版本、操作系统)
- 复现步骤
- 相关代码片段
最后更新: 2026-04-10