Skip to content

Latest commit

 

History

History
149 lines (138 loc) · 7.87 KB

File metadata and controls

149 lines (138 loc) · 7.87 KB

jqcli 当前进度

更新时间:2026-04-25

已完成

  • 已创建项目虚拟环境 .venv,Python 版本为 3.13.13
  • 已实现基础 MVP:
    • auth status/logout/import-token/import-cookie/login
    • strategy ls/show/new/edit/rm
    • backtest 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: 41faea7d0299bc92c71364d9cd878259
      • attr_id: c8546c1d149c650ec420bbee2fe12637
      • name: 混合策略
      • 清洗后的列:["", "混合策略", "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 是编辑/删除/回测的真实主键。该命令被用户中断,结果不可用。
  • 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
      • nametypeupdated_atrun_countbacktest_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=...
      • 解析编辑页表单,输出 idsave_idbacktest_idname,可按需输出源码。
    • strategy new
      • 请求 /algorithm/index/new
      • 创建后调用 /algorithm/index/save 设置名称和源码。
      • 注意:聚宽列表页的 algorithmId 会随请求变化,命令返回会重新从列表按名称解析可用 id。
    • strategy edit
      • 先读取编辑页表单,再 POST /algorithm/index/save
      • 源码按前端逻辑 base64 编码,并提交 encrType=base64
    • strategy rm
      • 请求 /algorithm/index/del
      • 删除必须带 X-Requested-With: XMLHttpRequest 和列表页 Referer,否则返回 不合法请求
      • 删除时会从当前列表页解析 _algorithmId;如果列表页 id 变化,会回退到编辑页名称再匹配当前列表项。
    • backtest run
      • 请求 /algorithm/index/build
      • 返回包含聚宽的 backtestId_backtestId,CLI 输出为 idlist_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.py
      • scripts/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-022024-01-10
      • 初始资金:1000000
      • 提交返回:id=55544219list_id=1a5ed7cd1472a7df43824aefc9f2edebmode=backtest
      • 正式列表出现新记录:提交时间 2026-04-25 20:44:41,状态 done
      • 详情指标获取成功:algorithm_return=0.0053687416399999benchmark_return=0.00328947368421sharpe=3.7356032973192max_drawdown=0.0035792419084949
      • 测试记录已从正式回测列表删除成功。
  • 策略列表页引用的 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?...

重启后建议下一步

  1. 补强边界行为:
    • backtest rm 当前建议传 backtest ls 返回的 list_id;后续可增加详情 id 到列表 id 的自动解析。
    • backtest ls 的指标字段初始 HTML 里可能为 --,后续可调用 /algorithm/backtest/statsList 合并实时统计。
  2. 增加 README 命令示例和字段说明。
  3. 后续可补分页、文件夹策略同名冲突处理、更多错误码映射。

注意事项

  • 不要打印 .env、cookie、密码。
  • 真实接口调研时优先只读请求。
  • 删除、新建、保存等破坏性接口先确认参数和测试策略后再执行。
  • 上一个被中断的命令只是 HTML 解析探测,可能已被用户中断,无需依赖其结果。