更新时间:2026-04-25
- 已创建项目虚拟环境
.venv,Python 版本为3.13.13。 - 已实现基础 MVP:
auth status/logout/import-token/import-cookie/loginstrategy ls/show/new/edit/rmbacktest run/ls/show/rm--env-file和.env读取--non-interactive --format json- 统一错误码和 JSON 错误输出
- 已添加
.env和.env.example。 .env已加入.gitignore,避免提交真实账号密码。- 单元测试全量通过,最近一次结果为
58 passed。
.env中的账号密码已成功登录真实聚宽。- 登录接口已定位并接入:
- 登录页:
/user/login/index - 登录接口:
/user/login/doLogin - 表单字段:
CyLoginForm[username]CyLoginForm[pwd]- 登录页中的
window.tokenData.value
- 登录页:
auth login已改为真实登录,成功后保存 cookie 到本地配置。- 当前本地配置路径:
/Users/lxx/.config/jqcli/config.json
- 登录状态接口验证成功:
/user/index/isLogin- 返回
code: "00000",isLogin: 1
- 策略列表页可访问:
/algorithm/index/list
- 页面是服务端渲染 HTML,不是简单 JSON API。
- 策略列表 HTML 中观察到:
<tr class="algorithm_list">- 编辑链接:
/algorithm/index/edit?algorithmId=...&backtest=... - 回测列表链接:
/algorithm/backtest/list?algorithmId=...
- 2026-04-25 继续调研结果:
- 使用已保存 cookie 请求
/algorithm/index/list成功。 - 当前账号返回
10条策略列表行。 - 每行可用正则
r'<tr class="algorithm_list".*?</tr>'提取。 - 单行中至少有两个疑似 ID:
_algorithmId="...",在第一列 checkbox 容器上。- 编辑链接中的
algorithmId=...。
- 初步样例,注意不要把这些样例当作固定数据:
href_id:41faea7d0299bc92c71364d9cd878259attr_id:c8546c1d149c650ec420bbee2fe12637name:混合策略- 清洗后的列:
["", "混合策略", "Code", "2025-10-08 12:48:07", "0", "1", ""] - 第二条:
全天候ETF,类型Code,更新时间2025-07-01 11:18:21 - 第三条:
小市值混合,类型Code,更新时间2025-06-18 23:12:16
- 中断前正在尝试查看完整单条
<tr class="algorithm_list">...</tr>,用于确认哪个 ID 是编辑/删除/回测的真实主键。该命令被用户中断,结果不可用。
- 使用已保存 cookie 请求
- 2026-04-25 已落地
strategy ls真实接口:jqcli/api/client.py增加get_text(),用于读取服务端渲染 HTML。ApiClient使用trust_env=False,避免本机 SOCKS 代理环境变量导致socksio依赖错误。jqcli/api/strategy.py增加parse_strategy_list_html(html)。list_strategies()已改为请求/algorithm/index/list。- parser 当前输出字段:
id:编辑链接中的algorithmId,暂作为策略主 ID。internal_id:行内_algorithmId。name、type、updated_at、run_count、backtest_count。created_at暂为空字符串,因为列表页暂未确认该字段。
- 已用真实账号只读验证:
jqcli --env-file .env --format json strategy ls --limit 3- 返回 3 条策略,包括
混合策略、全天候ETF、小市值混合。
- 已添加 HTML parser 单元测试。
- 2026-04-25 已继续落地其余真实接口:
strategy show:- 请求
/algorithm/index/edit?algorithmId=... - 解析编辑页表单,输出
id、save_id、backtest_id、name,可按需输出源码。
- 请求
strategy new:- 请求
/algorithm/index/new - 创建后调用
/algorithm/index/save设置名称和源码。 - 注意:聚宽列表页的
algorithmId会随请求变化,命令返回会重新从列表按名称解析可用 id。
- 请求
strategy edit:- 先读取编辑页表单,再 POST
/algorithm/index/save。 - 源码按前端逻辑 base64 编码,并提交
encrType=base64。
- 先读取编辑页表单,再 POST
strategy rm:- 请求
/algorithm/index/del。 - 删除必须带
X-Requested-With: XMLHttpRequest和列表页Referer,否则返回不合法请求。 - 删除时会从当前列表页解析
_algorithmId;如果列表页 id 变化,会回退到编辑页名称再匹配当前列表项。
- 请求
backtest run:- 请求
/algorithm/index/build。 - 返回包含聚宽的
backtestId_和backtestId,CLI 输出为id和list_id。 - 默认发起正式回测:提交
backtest[type]=0,记录进入/algorithm/backtest/list。 - 保留编译运行模式:增加
--compile,提交backtest[type]=1,记录进入/algorithm/backtest/buildList。
- 请求
backtest ls:- 默认请求
/algorithm/backtest/list?algorithmId=...。 --compile请求/algorithm/backtest/buildList?algorithmId=...。- 解析
<tr class="backtest-tr">,输出详情 id、列表 id、源码 id、状态、区间、资金、频率和基础指标字段。
- 默认请求
backtest show:- 请求
/algorithm/backtest/detail?backtestId=... - 再请求
/algorithm/backtest/source和/algorithm/backtest/stats获取源码和指标。
- 请求
backtest rm:- 默认请求
/algorithm/backtest/del?type=0删除正式回测。 --compile请求/algorithm/backtest/del?type=1删除编译运行记录。- 已用正式回测列表中的
list_id验证删除成功。
- 默认请求
ApiClient默认发送X-Requested-With: XMLHttpRequest,写接口按需要补Referer。- 新增调研脚本:
scripts/inspect_joinquant_static.pyscripts/inspect_joinquant_page.py
- 真实写入验证:
- 创建、编辑、删除临时策略成功。
- 发起短区间回测成功,随后删除回测记录和临时策略成功。
- 2026-04-25 已确认回测两种服务端路径:
- 聚宽前端正式回测和编译运行都 POST
/algorithm/index/build,差异在backtest[type]。 - 正式回测按钮设置
type=0,使用/algorithm/backtest/list和删除type=0。 - 编译运行路径使用
type=1,使用/algorithm/backtest/buildList和删除type=1。 - 新增调研脚本:
scripts/inspect_backtest_flows.py。 - 真实正式回测验证:
- 策略:
全天候ETF - 策略 id:
8f345883a69b74cc456919ab1be76267 - 时间:
2024-01-02到2024-01-10 - 初始资金:
1000000 - 提交返回:
id=55544219,list_id=1a5ed7cd1472a7df43824aefc9f2edeb,mode=backtest - 正式列表出现新记录:提交时间
2026-04-25 20:44:41,状态done - 详情指标获取成功:
algorithm_return=0.0053687416399999,benchmark_return=0.00328947368421,sharpe=3.7356032973192,max_drawdown=0.0035792419084949 - 测试记录已从正式回测列表删除成功。
- 策略:
- 聚宽前端正式回测和编译运行都 POST
- 策略列表页引用的 JS:
https://cdn.joinquant.com/std/algorithm/js/list.min.js
- 从 JS 中发现的接口:
/algorithm/index/del/algorithm/index/save/algorithm/index/new/algorithm/index/AddFile?.../algorithm/index/AlgorithmToFile?.../algorithm/index/GetFileList?...
- 补强边界行为:
backtest rm当前建议传backtest ls返回的list_id;后续可增加详情 id 到列表 id 的自动解析。backtest ls的指标字段初始 HTML 里可能为--,后续可调用/algorithm/backtest/statsList合并实时统计。
- 增加 README 命令示例和字段说明。
- 后续可补分页、文件夹策略同名冲突处理、更多错误码映射。
- 不要打印
.env、cookie、密码。 - 真实接口调研时优先只读请求。
- 删除、新建、保存等破坏性接口先确认参数和测试策略后再执行。
- 上一个被中断的命令只是 HTML 解析探测,可能已被用户中断,无需依赖其结果。