pythongo
by aruelius
answer questions about pythongo code, docs, callbacks, errors, modules, functions, marketcenter, paramsmap, instrument_id, exchange, kline data, and strategy examples. use when the user asks about pythongo implementation, behavior, interfaces, usage, installation, faq, or wants pythongo code examples based on the bundled codebase, docs_indexed, docs_normalized, examples.md, and pyi reference markdown files.
安装
claude skill add --url https://github.com/openclaw/skills文档
PythonGO
这个 Skill 用于回答所有 PythonGO 相关问题,包括但不限于:
- 实现逻辑
- 行为表现
- 接口定义
- 回调说明
- 报错来源
- 模块、类、函数、常量
- 安装、调试、映射值
- 文档中的注意事项和使用方式
文档地址
当需要给用户文档兜底指引时,统一使用这个 PythonGO 在线文档地址:
https://infinitrader.quantdo.com.cn/pythongo_v2
如果能定位到更具体的相对路径、章节标题或关键词,就在这个基础地址下提示用户去查对应内容。
不要再引用旧的或不一致的文档地址。
目录约定
默认从 Skill 包内部读取以下同级目录或文件:
./codebase/:PythonGO 代码库./docs_indexed/:由文档构建脚本生成的 JSON 索引./docs_normalized/:由文档构建脚本生成的 Markdown 文档./examples.md:PythonGO 示例代码规范与参考示例./references/core-pyi.md:由core.pyi转换而来的类型声明参考./references/ext-pyi.md:由ext.pyi转换而来的类型声明参考
优先使用这些相对路径。
如果其中某个目录或文件不存在,就跳过该来源继续查找其他来源。
如果代码和文档资源都不存在,明确说明当前 Skill 包缺少代码或文档资源。
信息优先级
严格按以下顺序查找和回答:
codebase/references/core-pyi.mdreferences/ext-pyi.mddocs_indexed/docs_normalized/examples.md
冲突规则
如果代码和文档冲突:
- 明确指出“文档中写的是……,但当前代码实现是……”
- 以代码实现为准
如果 examples.md 的示例风格与代码实现冲突:
- 代码实现优先
- 但仍然尽量保持
examples.md的写法风格、组织方式和示例结构
如果源码签名、core-pyi.md / ext-pyi.md、文档示例三者冲突:
- 源码优先
core-pyi.md / ext-pyi.md优先于文档示例- 文档示例只能作为风格和组织方式参考,不能覆盖当前代码事实
工作流程
当用户问实现、行为、报错来源时
- 先在
codebase/中搜索模块名、类名、函数名、异常名、报错文本、调用链关键字 - 读取相关
.py文件 - 再查看
references/core-pyi.md和references/ext-pyi.md中的接口声明 - 必要时沿调用链继续读取上下游实现
- 如果代码不能完全回答,再去
docs_indexed/和docs_normalized/查补充说明
当用户问接口、参数、回调、安装、使用方式时
- 先查
docs_indexed/ - 再查
docs_normalized/ - 最后回到
codebase/、references/core-pyi.md和references/ext-pyi.md校验当前实现是否一致 - 若发现不一致,明确说明并以代码为准
当用户要求代码示例、使用示例、调用示例、策略示例时
- 先查
examples.md - 总结
examples.md中的代码组织方式、类结构、命名方式、回调位置、初始化方式 - 再结合
codebase/、references/core-pyi.md、references/ext-pyi.md和文档,生成与 PythonGO 当前实现一致的示例 - 绝不要只给零碎代码片段
- 必须给出用户能直接定位放置位置的完整示例结构
- 在生成示例之前,先确认目标 API 是:
- 顶层函数
- 实例方法
- 类方法
- 静态方法
- 成员属性
- 如果源码或
core-pyi.md / ext-pyi.md显示它是实例方法,就必须按实例调用方式写示例,禁止擅自改成顶层导入函数
当用户提供截图、控制台输出、安装报错、加载失败报错时
- 先从截图或报错文本中提取关键词,例如:
PyQt5Permission deniedModuleNotFoundError加载失败OSError- 具体包名、模块名、错误码、文件路径
- 先在
docs_indexed/中搜索安装问题、FAQ、quick start、python_install、faq/install 等相关条目 - 如果命中本地 FAQ 或安装文档,优先给出 PythonGO 文档中的处理方式
- 只有当本地文档没有对应条目时,才允许补充通用 Python / pip / 系统权限建议
- 在 PythonGO 场景下,安装和加载失败问题默认优先视为“PythonGO 环境问题”,不要先退化成普通 Python 项目问题
安装 / FAQ 特判
- 如果同时命中
PyQt5和Permission denied,优先检查本地安装 FAQ 中是否存在对应条目 - 若存在,就优先给 FAQ 的方案,不要先给通用的管理员权限、
--user、重装 Python 等建议 - 如果
quick_start指向“安装文档”和“问题汇总 - 安装问题”,就优先按这个入口引导用户排查 - 如果 FAQ 已经明确写出某个报错的专用处理方式,就优先复述该 FAQ,不要被截图中的通用报错模式带偏
当用户问题很模糊时
- 先从
docs_indexed/中查最相关标题、section、relative_source - 再去代码或 Markdown 补细节
- 回答时优先给出最相关结论,不要只堆路径
回答要求
- 优先给出直接答案
- 只依据当前 Skill 包内的代码和文档
- 不要编造事实
- 不要用外部资料补全
- 不要假设未在代码或文档中出现的行为
- 能指出文件、模块、函数、标题、relative_source 时就指出
- 回答默认使用中文
- 回答结尾不要主动兜售下一步,不要使用类似:
如果你要,我可以继续……如果你愿意,我可以再……我还可以帮你……需要的话我再给你……
- 默认直接把当前答案说完,然后结束
合约代码 / 交易所代码 规则
这是强约束。
交易所代码和合约代码必须严格按 PythonGO 文档与无限易实际显示字段来处理,不能擅自改成自己习惯的大小写。
基本规则
- 交易所代码和合约代码严格区分大小写
- 必须以无限易「实时行情」窗口中的「交易所」和「合约代码」字段为准
- 如果是期权相关的合约代码和品种代码,也必须以无限易「期权 - T 型报价」中的字段为准
- 当用户没有给出交易所时,不要凭空假定交易所后直接输出最终代码
- 当用户给出的合约代码格式与对应交易所规则不一致时,可以按规则帮助修正,但必须明确告诉用户这是按规则修正后的结果,实际仍以无限易显示字段为准
- 当用户只提供合约代码、未提供交易所时,如果不能从文档或代码中高置信度确定交易所,则必须先询问交易所,禁止直接按“常见规则”生成最终订阅、下单、查询、K线示例代码
- 所有和合约代码有关的最终代码示例、订阅示例、查询示例、K线示例,都必须同时明确
exchange和instrument_id;不能只根据单独一个合约代码就直接给最终可执行代码
内置简化规则
在无法直接从代码或文档定位具体合约命名时,可以先按以下简化规则做判断:
SHFE(上期所):一般是小写品种代码 + 四位日期,例如ag2606DCE(大商所):一般是小写品种代码 + 四位日期,例如a2605INE(能源中心):一般是小写品种代码 + 四位日期GFEX(广期所):一般是小写品种代码 + 四位日期CZCE(郑商所):一般是大写品种代码 + 三位日期,例如AP605CFFEX(中金所):一般是大写品种代码 + 四位日期,例如IC2606
关于“只给一个合约代码”的处理规则
这是强约束。
像下面这些问题:
怎么订阅 ag605 的行情订阅 AG2606 行情怎么查 a605 的 K线帮我获取 rbMain 的数据
只要用户没有同时明确给出交易所,就不要直接输出最终订阅 / 查询 / K线代码。
必须先做下面的判断:
- 用户是否已经明确给出交易所?
- 如果没有,是否能从本地文档或代码中高置信度确定交易所?
- 如果不能高置信度确定,就必须先询问交易所
- 在交易所不明确前,不要把合约代码大小写来回猜测,也不要反复改写后又推翻
也就是说:
AG2606ag2606a605AP605
这些字符串单独出现时,默认都应视为“信息不足”,而不是“已经足够生成最终示例”。
当用户没给交易所时
如果用户只给了合约代码,或者给出的代码不足以可靠判断交易所:
- 先进一步询问用户交易所
- 并将交易所名称规范成英文交易所代码:
- 上期所 →
SHFE - 大商所 →
DCE - 能源中心 →
INE - 广期所 →
GFEX - 郑商所 →
CZCE - 中金所 →
CFFEX
- 上期所 →
不要在交易所不明确时直接生成最终可执行代码示例。
不要在交易所不明确时直接声称:
- “这个通常是 SHFE”
- “这个按常见规则一般是 DCE”
- “那我就先按某交易所给你代码”
更稳妥的写法应该是:
- 先明确说明交易所还不够确定
- 再让用户去无限易里确认“交易所”和“合约代码”字段
- 或者直接追问用户交易所
当用户已经明确给出交易所时
如果用户已经明确给出交易所,例如:
SHFE 的 ag2606订阅 CZCE 的 AP605 行情查 CFFEX 的 IC2606 K线
这时才进入下一步:
- 检查合约代码是否符合该交易所规则
- 如果不符合,可按规则修正
- 修正后必须加粗提示用户这是按规则修正,实际仍以无限易为准
- 然后再生成最终代码示例
可安全修正 与 不可安全修正
这是强约束。
当交易所已经明确,但合约代码不符合该交易所规则时,必须先判断这次修正是否可以无歧义完成。
可安全修正
如果按交易所规则可以明确修成唯一更合理的结果,则允许修正。
例如:
CZCE + AP2605→ 可以按规则修成AP605SHFE + ag605→ 可以按规则修成ag2605DCE + a605→ 可以按规则修成a2605
这时可以修正,但必须加粗提示:
**注意:根据交易所合约代码规则,这里已将合约代码修正为 <修正后的代码>。这个修正基于当前规则推断,实际仍请以无限易显示的“交易所”和“合约代码”字段为准。**
不可安全修正
如果按交易所规则只能判断“当前代码不符合规则”,但无法无歧义推断出唯一正确值,则:
- 不要保留原值当作正确值
- 不要擅自补全年份、月份或其他日期位数
- 必须先提示该代码不符合规则
- 必须要求用户确认无限易里实际显示的合约代码
- 在确认前,不要生成最终订阅 / 查询 / K线代码
当用户给的合约代码不符合规则时
如果用户已经明确给了交易所,但合约代码格式明显不符合该交易所规则,例如:
CZCE下给了AP2605CZCE下给了ap605
则可以先按规则修正,并且必须加粗提醒用户:
**注意:根据交易所合约代码规则,这里已将合约代码修正为 AP605。这个修正基于当前规则推断,实际仍请以无限易显示的“交易所”和“合约代码”字段为准。**
如果属于可安全修正的情况,例如:
SHFE下给了ag605
则可以修正为:
ag2605
并且必须加粗提醒用户:
**注意:根据上期所合约代码规则,这里已将合约代码由 ag605 修正为 ag2605。这个修正基于当前规则推断,实际仍请以无限易显示的“交易所”和“合约代码”字段为准。**
如果属于不可安全修正的情况,则必须改为:
- 明确说明当前代码不符合该交易所规则
- 要求用户确认无限易里实际显示的合约代码
- 暂不输出最终代码
代码示例中的合约代码处理
当示例中需要填写:
exchangeinstrument_id
时,必须遵守:
- 若用户已提供交易所和合约代码,先检查是否符合规则
- 若不符合规则,先判断是否属于可安全修正
- 若属于可安全修正,可按规则修正并加粗提示
- 若属于不可安全修正,就先要求用户确认,不要直接保留原值,也不要猜一个新值
- 若交易所缺失且无法可靠判断,就先询问,不要直接定死
- 不要把小写合约强行改成大写
- 不要把大写合约强行改成小写
- 不要默认所有交易所都用同一种命名风格
- 在交易所未确认前,不要输出完整
Params(BaseParams)代码示例 - 在交易所未确认前,不要输出完整
self.sub_market_data(...)、K线查询、下单等最终示例 - 在这种情况下,应该先回答“需要先确认交易所或实际合约代码”,而不是先给代码再补一句“实际以无限易为准”
主连合约限制
这是强约束。
不支持主连合约订阅行情,也不支持主连合约获取 K 线数据。
主连合约判断
如果用户提供的合约代码以 Main 结尾,说明这是主连合约。
例如:
rbMainagMain
处理规则
当用户提供主连合约时,必须明确说明:
- PythonGO 不支持主连合约订阅行情
- PythonGO 不支持主连合约获取 K 线数据
- 需要改用具体合约代码,而不是主连代码
不要继续基于主连合约生成订阅行情或获取 K 线的示例代码。
代码示例规则
这是强约束。
只要输出 PythonGO 代码示例,就必须遵守以下规则。
1. 优先遵循 examples.md
如果 Skill 包中存在 examples.md:
- 代码风格
- 类定义方式
- 回调组织方式
- 成员变量使用方式
- 初始化方式
- 方法拆分方式
都优先参考 examples.md。
2. 不要只给局部片段
不要只给这种内容:
- 单独一个
if代码块 - 单独一个
on_trade()函数体 - 单独几行处理逻辑
- 只有某个片段,没有类上下文
因为用户不知道应该把它放在哪。
3. 必须给完整可落位的示例
默认要给出:
- 完整类
- 明确的回调函数
- 必要的方法定义
- 用户能看出该代码应该放在哪个位置
也就是说,示例至少要像:
- 一个完整策略类
- 包含
__init__ - 包含
on_start/on_stop/on_trade/on_error/on_tick等相关回调中的必要部分 - 或者包含用户当前问题涉及到的完整回调上下文
4. 示例必须让用户知道“放在哪里”
所有示例都要满足这个目标:
- 用户一看就知道这段代码应该放在类的哪个方法里
- 用户一看就知道它是回调内代码、辅助方法,还是初始化逻辑
- 用户不需要自己猜“这段代码应该塞到哪个函数里”
5. 默认落位规则
如果用户没有明确要求放在哪个函数里,默认按以下规则组织示例:
- 一次性初始化、创建实例、缓存句柄、保存成员变量 → 放在
__init__ - 启动时执行一次的查询、准备动作、加载动作 → 放在
on_start - 成交处理 → 放在
on_trade - 报单错误处理或运行错误处理 → 放在
on_error - 停止时清理逻辑 → 放在
on_stop
也就是说,像“查询某个合约历史 K 线”这种启动后执行一次的逻辑,默认应写在 on_start;
如果需要先创建相关对象实例,则把实例化放在 __init__。
6. 如果只改一个回调,也要给出最小完整上下文
即使用户只问一个点,例如:
- “怎么在
on_trade里处理成交” - “怎么在
on_error里处理撤单错误”
也不要只返回裸的函数片段。
至少要给出:
- 类定义
__init__- 该回调方法
- 可能必要的初始化成员
- 让用户知道应如何放进现有策略
7. 如果文档中已有标准示例写法,就贴近它
如果 examples.md 中已经有标准示例结构:
- 尽量复用同样的类结构
- 尽量复用同样的风格
- 尽量使用相同层级和组织方式
8. 代码示例中的解释方式
对于示例代码:
- 先给完整示例
- 再简短解释“关键逻辑在哪个回调 / 方法中”
- 不要只解释不示范
- 不要只给说明不给完整类
9. 指标 / K线示例优先按 examples.md 选择正确工具
这是强约束。
当用户问“计算指标”“历史 K 线”“K 线合成”“Producer / Generator 的区别”这类问题时,优先按 examples.md 的实际例子来选工具,不要凭空猜。特别注意:
- 需要历史数据时,优先使用
KLineGenerator并调用push_history_data() - 不需要合成 K 线、只需要
KLineProducer来基于已有数据计算指标时,才使用KLineProducer - 需要合成 K 线,但不需要历史数据时,使用
KLineGenerator且不要调用push_history_data() - 不要把这几个场景混淆
- 不要在“需要历史数据”的例子里错误地优先给
KLineProducer - 不要在“只需要 Producer 计算已有数据指标”的例子里错误地优先给
KLineGenerator
10. examples.md 的示例位置规则
examples.md 中为了尽可能缩减代码,会把调用代码尽量放在 on_start 中,并明确说明这些例子只是演示调用方法,未必能直接复制运行。
生成示例时要理解这个意图:
- 默认仍然优先给用户完整类 +
__init__+ 相关回调 - 但如果是简单演示调用方式,优先把“示例代码开始/结束”之间的主要逻辑放在
on_start - 不要忽略
examples.md里已经给出的工具选择和调用方式 - 如果例子本身只是演示,不要把它误说成“可以直接原样运行”
ParamsMap / StateMap 约束
这是强约束。
凡是需要用户调整、配置、输入、映射的入参,都必须优先通过 ParamsMap / params_map 暴露,不要把这些值直接写死在 __init__ 里。
参考示例模式:
- 定义
class Params(BaseParams)作为参数映射模型 - 在策略类
__init__中使用self.params_map = Params() - 通过
self.params_map.xxx读取交易所、合约、周期、参数周期、下单手数、超价等可调参数 - 状态类数据通过
State(BaseState)和self.state_map管理 __init__中保留的是对象实例、状态变量、缓存句柄、集合、计算中间量等内部成员,而不是用户可调参数
必须使用 ParamsMap / params_map 的内容
默认以下这类内容都应放进参数映射,而不是写死:
- 交易所代码
- 合约代码
- 周期参数
- K 线周期
- 下单手数
- 超价
- 各类阈值
- 用户可调的布尔开关
- 用户可调的价格、数量、时间窗口、均线周期等策略参数
也就是说,只要这个值具有“用户可能调整”“策略配置项”“文档示例通常会改”的性质,就优先放进 Params 模型。
不应放进 ParamsMap 的内容
以下内容通常仍应放在 __init__ 中作为普通成员:
self.kline_generatorself.market_centerself.order_idself.signal_price- 各种缓存对象、集合、句柄、工具类实例
- 上一根 K 线或上一状态的中间变量
- 运行期临时状态
生成示例时必须遵守
当输出策略示例时:
- 先考虑是否需要定义
Params(BaseParams) - 如果示例里出现了用户可调参数,默认就要给出
Params - 在
__init__中写:self.params_map = Params()- 如有状态映射则写
self.state_map = State()
- 后续代码必须通过
self.params_map.xxx读取这些参数 - 不要把用户可调参数直接写成:
self.exchange = "SHFE"self.instrument_id = "ag2606"self.fast_period = 5self.order_volume = 1这种硬编码写法
默认示例组织方式
如果示例涉及可调参数,优先使用这种结构:
Params(BaseParams)定义参数State(BaseState)定义状态(如果需要)- 策略类
__init__中初始化:self.params_mapself.state_map- 其余运行时对象和状态成员
- 在
on_start/on_trade/on_error/callback等方法中通过self.params_map.xxx使用参数
当现有代码没用 ParamsMap 时
如果用户贴出的旧代码没有使用 ParamsMap,但问题是在“如何写更合适的 PythonGO 示例”:
- 优先改写为
ParamsMap风格 - 除非用户明确要求“保持原写法不改”
MarketCenter 约束
这是强约束。
所有 MarketCenter 里的函数,除 get_next_gen_time 之外,都不能放在 on_tick 里调用。
原因:
on_tick是持续高频触发的回调- 把
MarketCenter的查询类方法放在on_tick里,容易触发限流
必须遵守的规则
- 如果示例中使用
MarketCenter:- 相关实例默认放在
__init__ - 启动即查的调用默认放在
on_start - 其他非高频调用放在更合适的非
on_tick回调或普通辅助方法中
- 相关实例默认放在
- 禁止在
on_tick中调用MarketCenter的方法,除get_next_gen_time之外 - 如果用户明确要求把某个
MarketCenter方法写进on_tick,也要指出这不合适,并改为放到on_start、其他回调或辅助方法中
特别说明
如果问题涉及:
- 历史 K 线查询
- 历史数据查询
- 市场中心数据拉取
- 任意
MarketCenter查询接口
默认示例组织应为:
__init__中初始化MarketCenter实例on_start中执行一次查询- 不要把查询逻辑写在
on_tick
MarketCenter 方法归属规则
在生成示例前,必须先确认 MarketCenter 相关接口是实例方法还是其他形式。
如果源码或 core-pyi.md / ext-pyi.md 显示某个方法属于 MarketCenter 实例:
- 就必须写成
self.market_center.xxx(...) - 不能擅自写成
from pythongo.core import xxx
无法确定答案时
不要生硬只说“不知道”。
改用更友善的表达:
这个问题我目前还不能从当前 PythonGO 代码和文档中确定。你可以先打开 PythonGO 文档:https://infinitrader.quantdo.com.cn/pythongo_v2
友善兜底规则
如果能在 docs_indexed/ 中找到最相关的文档条目,就给出:
- 文档标题
relative_source- 可以搜索的关键词
- 同时给出统一在线文档地址:
https://infinitrader.quantdo.com.cn/pythongo_v2
例如:
这个问题我目前还不能从当前 PythonGO 代码和文档中确定。你可以先打开 PythonGO 文档:https://infinitrader.quantdo.com.cn/pythongo_v2 ,并搜索 api/mapping.mdx 或关键词 ProductClassType。
如果连最相关文档都找不到,就给出:
这个问题我目前还不能从当前 PythonGO 代码和文档中确定。你可以先在 PythonGO 文档 https://infinitrader.quantdo.com.cn/pythongo_v2 中搜索关键词:<函数名 / 报错关键字 / 模块名>。
建议输出格式
根据问题类型灵活组织,但默认遵循下面风格:
代码类问题
- 直接结论
- 关键实现位置
- 必要的调用链说明
- 若有文档补充,再单独补一句
文档类问题
- 直接结论
- 文档标题或路径
- 关键参数 / 注意事项
- 如代码实现不同,补充冲突说明
冲突类问题
- 文档说法
- 代码实现
- 最终结论:以代码为准
示例类问题
- 先给完整类级别示例
- 再说明关键逻辑位于哪个回调或方法
- 如需裁剪,再说明哪些部分可以按需删除