TROUBLESHOOTING
Optopsy 报错排查:先看报错原文,再动手
Optopsy 的问题分成两类:报错的(好办,报错原文会直接指向原因)和不报错但结果不对的(难办,需要你主动验证)。本页把两类都按「原文 → 原因 → 修复」列清楚。
- 最高频首要原因:Python 不在 3.12–3.13,pip 装到了另一套 legacy 包。
- 第二高频:Pydantic 严格类型校验——
raw=1、min_bid_ask=5都会被拒。 - 第三高频:数据里没有
delta列,导致任何策略都选不出合约。 - 最难发现的一类:不报错,但结果偏少或偏乐观(列号错位、日期不匹配、无成本假设)。
Optopsy 报错怎么分诊:三步定位方法
| 顺序 | 先问自己 |
|---|---|
| 1 | 报错了吗?报了就直接查原文(下表第 1–4 类) |
| 2 | 没报错但结果为空?查缺列、区间、价差、DTE 四项 |
| 3 | 有结果但觉得不对?先确认装的是现代版,再检查列号与成本假设 |
ERROR TABLE
Optopsy 七类报错场景说明:原文、原因与修复动作
下表前四类是「会报错」的,后三类是「不报错但结果不对」的。按你的现象对号入座。
| # | 你看到的原文 / 现象 | 原因 | 怎么确认 | 修复动作 |
|---|---|---|---|---|
| 1 | AttributeError: module 'optopsy' has no attribute 'simulate'(或 TargetRange、rsi_below) | Python 不在 3.12–3.13,pip 装到了另一套 legacy 2.2.0 包 | python -c "import optopsy as op; print(len(op.__all__))",现代版是 160 | 用 Python 3.12 或 3.13 建虚拟环境后重装;详见安装与版本页 |
| 2 | Pydantic 校验错误,提示某个字段类型不符 | 布尔参数必须是真正的 bool、浮点参数必须是 float、整型参数拒绝 float/bool | 看报错里的字段名与约束描述 | raw=True 而不是 raw=1;min_bid_ask=5.0 而不是 5 |
| 3 | KeyError 指向某个列名 | 数据里缺这一列,或列名大小写/下划线不一致 | 打印 df.columns.tolist() 与 8 个必需列对照 | 补列或改名;csv_data() 场景下检查是不是列号填错 |
| 4 | ModuleNotFoundError: No module named 'pyarrow'(调用读缓存函数时) | 只装了核心库,没装 [data] | 看报错是否提到 pyarrow / parquet | pip install "optopsy[data]" |
| 5 | 什么错都没报,但结果一行都没有 | 缺 delta 列、Delta 区间过窄、min_bid_ask 过高,或 DTE 超出数据范围 | 按逐腿 Delta 页的七步排查表逐项验证 | 放宽 Delta 区间与 bid-ask 阈值,或扩大数据时间范围 |
| 6 | 结果有,但明显偏少 | 四个过滤条件(DTE / 价差 / Delta 区间 / 有多腿缺报价)叠加收窄 | 逐腿单独跑一次单腿策略,确认每条腿都有候选 | 放宽最难满足的那一腿;四腿策略尤其注意翼腿 |
| 7 | 结果有,但看起来太好 | 默认不收手续费 + 默认用中间价成交(最乐观) | 检查调用里有没有设 commission 与 slippage | 至少设一次真实费率,并用 slippage='spread' 跑一次保守对照 |
第 1 类为本机 pip 解析与 wheel 内容实测;第 2–4 类依据官方参数文档的类型校验说明与依赖说明;第 5–7 类依据官方空结果排查清单与默认值文档。
一条通用建议:把 python -c "import optopsy as op; print(len(op.__all__))" 当成你的首要排查命令。它能在 3 秒内排除掉最高频的那一类问题——包装错了。
LEGACY PACKAGE DIAGNOSIS
Optopsy 装错包专项:怎么用三行代码确认、两步修好
这类问题最容易被误判成「自己的代码写错了」。先做确认,再动手改。
第 1、2 步的判据来自本机对两个 wheel 的实际内容比对(采集 2026-09-23)。
python -c "import optopsy as op; print(len(op.__all__))"
现代版(2.3.0)的 __all__ 长度是 160。如果你拿到的是一个明显更小的数字,说明装到了 legacy 包。不要用 op.__version__ 判断——2.3.0 的包内部写的仍是 2.2.0,这会把你带偏。
预期输出:现代版输出 160
python -c "import optopsy as op; print(hasattr(op,'simulate'), hasattr(op,'TargetRange'), hasattr(op,'rsi_below'))"
这三个名字分别代表模拟器、逐腿 Delta 类型与信号系统。legacy 包三者都没有。
预期输出:现代版输出 True True True
python -c "import sys; print(sys.executable)"
pip -V
两条命令里的路径应指向同一个虚拟环境。指向不同环境时,你可能是「在 A 环境装、在 B 环境跑」。
预期输出:两处路径的虚拟环境目录一致
python3.12 -m venv .venv
.venv\\Scripts\\activate # Windows
pip install optopsy
python -c "import optopsy as op; print(len(op.__all__))"
换到 3.12 或 3.13 的解释器重建虚拟环境,重新安装后再跑一遍第 1 步。运行时要确认 len(op.__all__) 已经变成 160。
预期输出:输出 160,且此前的 AttributeError 消失
为什么 legacy 包更「安静」
它同样是合法的 PyPI 包,pip 会正常安装并提示成功。它的问题不是装不上,而是装上了一套 API 完全不同的代码。所以报错直到你首次调用现代 API 时才出现。
如果你只能待在 3.11 及以下
那么官方的现代版就用不了。这时有两条现实路径:①升级本机 Python 到 3.12/3.13;②改用其他不限定版本的期权工具。本站不建议在 legacy 包上硬套官方文档的写法。
SILENT PROBLEMS
Optopsy 不报错的四类问题:比报错更值得警惕
下面四类不会给你任何提示,只会让结果的可靠度下降。它们的共同特征是:有输出,但输出不是你以为的那回事。
| 问题 | 为什么不会报错 | 症状 | 自查方法 |
|---|---|---|---|
csv_data() 列号填错 | 参数是整数索引,任何整数都是合法的,pandas 不会校验语义 | 买价变成行权价、Delta 变成别的东西,结果看起来有模有样但完全不对 | 导入后立刻 describe() 关键列:delta 应在 0–1,strike 应是价格量级 |
| 期权链与信号的日期匹配不上 | 日期粒度不同(日期 vs 时间戳)时,合并是静默失败的,不抛异常 | 加了 entry_dates 后结果突然变少或为空 | 打印两边的日期范围与粒度;必要时用 normalize_dates() 在匹配边界统一 |
| 默认不收手续费、默认中间价成交 | 这些都是合法的默认值,库没有理由拒绝 | 结果比加了成本后好看很多 | 显式设置 commission 并用 slippage='spread' 跑一次对照 |
缺 high/low 时用 close 兜底 | 官方有意设计的容错,只在文档末尾一句提示过 | 技术指标信号数值与你在别处算的对不上,入场日集合随之偏移 | 检查股票数据有没有 high / low 列 |
第 1 类依据 csv_data() 的整数索引设计;第 2 类依据 timestamps.py 的模块说明;第 3 类依据官方默认值文档;第 4 类依据官方 entry-signals 文档末尾的提示。
这四类问题的处置方式都一样:把隐式假设变成显式检查。上手时多花五分钟做一次数据体检与成本设置,能省掉后面几小时的方向性误判。
PARAMETER ERRORS
Optopsy 参数校验错误说明:严格类型其实更安全
Optopsy 用 Pydantic 做严格校验,报错信息会指出字段名与约束。下表是最容易踩的六种。
| 你写的 | 报错原因 | 应该写成 | 适用场景 | 注意点 |
|---|---|---|---|---|
raw=1 | 布尔参数必须是真正的 bool | raw=True | 想拿逐笔明细时 | 这是最常踩的一个,来自其他库的习惯 |
min_bid_ask=5 | 浮点参数必须是 float | min_bid_ask=5.0 | 想设置 5 美元的价差下限 | 注意单位是美元,不是百分比 |
max_entry_dte=45.0 | 整型参数拒绝 float | max_entry_dte=45 | 设置 DTE 上限 | 同理不能写 True |
stop_loss=0.5 | 止损必须为负 | stop_loss=-0.5 | 给卖方策略加保护 | 方向写反会被校验拦下,这是好事 |
take_profit=-0.5 | 止盈必须为正 | take_profit=0.5 | 锁定利润 | 同上 |
front_dte_max=60, back_dte_min=50 | 跨字段规则:前月 DTE 上界必须小于后月 DTE 下界 | front_dte_max=40, back_dte_min=50 | 日历与对角策略 | 这是日历类独有的交叉校验,普通策略没有 |
依据官方 parameters 文档「Strict Parameter Validation」一节与 api-reference 的类型说明整理。
ENVIRONMENT
Optopsy 环境类问题:Windows、虚拟环境与依赖
路径与中文目录
在 Windows 上,数据文件放在含中文或空格的路径下时,某些读取方式可能失败。稳妥做法是把工作目录设在纯 ASCII 路径下,或改用绝对路径传参。这与 Optopsy 无关,但对整个 pandas 生态都适用。
虚拟环境混用
最常见的「装了却 import 不到」是环境混用:用 A 环境的 pip 装、用 B 环境的 python 跑。用 sys.executable 与 pip -V 两条命令对比路径即可确认。
依赖冲突
界面层([ui])会拉 Chainlit、LiteLLM、SQLAlchemy、plotly 等一大堆包,与既有项目冲突的概率明显高于核心库。只做回测就装核心库。
pandas 版本
官方要求 pandas 2.0+ 与 numpy 1.26+。如果你的环境里是更早的 pandas,部分 DataFrames 行为可能不一致。以官方 getting-started 的要求为准。
| 现象 | 最可能的原因 | 确认命令 | 处置 |
|---|---|---|---|
import optopsy 就失败 | 装在了另一个解释器或环境 | python -c "import sys; print(sys.executable)" | 在同一环境内重装 |
| 安装过程卡在编译某个依赖 | 依赖需要编译或网络受限 | 看 pip 输出卡在哪一步 | 用国内镜像或预编译 wheel;必要时只装核心库 |
[ui] 安装后命令找不到 | 入口脚本不在 PATH(虚拟环境未激活) | where optopsy-chat / which optopsy-chat | 激活虚拟环境后重试,或用 python -m 方式调用 |
| 读缓存函数报缺模块 | 没装 [data] | 看报错是否提到 pyarrow | pip install "optopsy[data]" |
| 数据下载命令无输出 | 没有配置 EODHD_API_KEY | 检查环境变量是否存在 | 配置 Key,或改用自建 CSV |
| 跑测试或大批量回测很慢 | 期权链数据量本身就大 | 看 DataFrame 行数与列数 | 用 start_date / end_date 与 min_bid_ask 尽早缩小候选 |
依据官方依赖说明与本项目对仓库 pyproject.toml(含 optional-dependencies 与 project.scripts)的核验整理。
排查到这里还没解决的话,建议先退一步:用一个最小的 CSV(几行数据、8 个必需列齐备)跑一次 long_calls。最小复现能跑通,说明问题在你的数据形状上;跑不通,说明问题在环境上。这一步能省下大量猜测时间。
FAQ
Optopsy 报错排查常见问题
为什么 AttributeError 出现在调用时而不是安装时?
因为那是另一套「合法的包」。PyPI 上的 2.2.0 与 2.3.0 都是可正常安装的发布版本,pip 不会报错;只有当你调用现代版特有的 API(simulate、TargetRange、信号函数)时,attribute 不存在的问题才暴露出来。确认方法见本页专项诊断。
怎么一眼判断我装的是不是现代版?
跑 python -c "import optopsy as op; print(len(op.__all__))":现代版是 160。不要用 op.__version__,因为 2.3.0 的包内部写的是 2.2.0,会把判断带偏。
结果为空但完全不报错,最该先查什么?
先查两件事:①数据里有没有 delta 列且值在 0–1;②leg*_delta 的区间是否比数据里 Delta 的实际分布更窄。这两条覆盖了绝大多数空结果。逐腿 Delta页有完整的七步排查表。
为什么 raw=1 会报错?
参数用 Pydantic 做严格校验,布尔参数必须是真正的 bool 类型。官方文档专门用警告框说明了这一点,同类还有 min_bid_ask=5 必须写成 5.0、整型参数不接受 45.0。严格校验虽然多一步,但能避免大量静默错误。
没有 volume 列会报错吗?
默认不会。只有当你启用 slippage='liquidity' 时才会因为缺 volume(或 open_interest)而失败。用 mid、spread 或 per_leg 都不需要成交量列。
日历策略报参数交叉校验错误怎么办?
这是日历与对角策略独有的跨字段规则:front_dte_min ≤ front_dte_max、back_dte_min ≤ back_dte_max,并且front_dte_max 必须小于 back_dte_min。按报错提示把前月区间收窄或把后月区间推远即可。
排查了半天还是不行,最短路径是什么?
构造一个最小样本:几行数据、8 个必需列齐备(delta 有效),跑一次 op.long_calls(data)。跑得通说明问题在数据形状或参数上;跑不通说明问题在环境或包装错上。把变量降到最少是最高效的排查方式。本站也不提供针对具体券商或数据源的定制支持。