历史绩效 API
默认地址为 http://127.0.0.1:8815,从 QPro 1.0.2608.904 起提供。查询已同步、已解析的历史账户资金、成交和日终持仓,并支持同步与解析结算数据。
初次使用请先阅读 历史绩效分析与导出;返回记录的完整定义见 历史绩效字段。收益率、回撤和胜率等指标由调用方根据业务口径计算。
接口总览
以下路径均相对于 http://127.0.0.1:8815。修改端口后,请同时替换示例地址。
方法 |
路径 |
作用及返回内容 |
|---|---|---|
|
|
检查本地数据库是否可用,返回 |
|
|
同步上游新增的结算事件,返回本次同步计数 |
|
|
解析本地待处理事件,返回本次处理计数 |
|
|
获取可选账户,返回 |
|
|
查询历史账户资金,返回 |
|
|
分页查询历史成交,返回 |
|
|
分页查询日终持仓,返回 |
成功响应使用统一结构:
{"code": 0, "message": "ok", "data": {}}
调用方应同时检查 HTTP 状态和业务码 code。这里的响应结构与其他本地服务的 {"ok": true} 不同。失败时 code 非零,message 说明原因,data 为空对象。
检查服务
GET /health 无请求参数:
$baseUrl = "http://127.0.0.1:8815"
Invoke-RestMethod "$baseUrl/health"
成功返回 HTTP 200:
{"code": 0, "message": "ok", "data": {"database": "ok"}}
该检查仅确认本地数据库可用,不检查上游连接,也不检查结算数据覆盖范围。数据库不可用时返回 HTTP 503、业务码 50301。
同步与解析结算数据
两个接口都使用 POST,调用时不发送请求体。它们会等待本次任务结束后返回;首次同步数据较多时,应给客户端设置较长的超时时间。
$baseUrl = "http://127.0.0.1:8815"
$sync = Invoke-RestMethod -Method Post -Uri "$baseUrl/settlements/sync" -TimeoutSec 600
$sync.data
if ($sync.code -ne 0 -or $sync.data.failed_count -gt 0) {
throw "本次同步存在失败,请检查返回信息后再继续"
}
$process = Invoke-RestMethod -Method Post -Uri "$baseUrl/settlements/process" -TimeoutSec 600
$process.data
if ($process.code -ne 0 -or $process.data.failed_count -gt 0) {
throw "本次解析存在失败,请检查返回信息和服务日志"
}
同步:POST /settlements/sync
获取当前登录身份可以访问的结算事件,将本地尚未保存的事件同步到本地。该接口不接收账户或日期筛选,也不会直接生成可查询的账户、成交和持仓记录;同步后需要调用解析接口。
响应示例中的计数均为示意值:
{
"code": 0,
"message": "ok",
"data": {
"remote_count": 120,
"existing_count": 100,
"synced_count": 18,
"failed_count": 2
}
}
字段 |
含义 |
|---|---|
|
本次从上游取得的去重后事件总数 |
|
同步开始时本地已有的事件总数 |
|
本次成功新增到本地的事件数 |
|
本次未成功同步的待同步事件数 |
同步按事件是否已存在判断新增,重复同步不会重新下载已有事件。未成功同步的事件可以在后续同步中再次尝试。以上计数是事件数,不是账户数、交易日数或成交笔数。
解析:POST /settlements/process
将本地尚未处理的结算事件解析为历史账户、成交和持仓记录。请求体留空,请勿发送 {}。
{
"code": 0,
"message": "ok",
"data": {"pending_count": 18, "processed_count": 17, "failed_count": 1}
}
字段 |
含义 |
|---|---|
|
本轮开始时待处理的事件数 |
|
本轮处理完成的事件数,包括不产生业务记录的跳过事件 |
|
本轮解析或写入失败的事件数 |
需要注意:
同步和解析共用任务锁,必须顺序执行。已有同步或解析任务运行时,新的任务请求立即返回 HTTP 409、业务码
40901。HTTP 200、
code = 0表示本次任务正常返回,仍需检查failed_count;部分事件失败不会必然导致整个请求失败。解析只处理尚未处理的事件。曾经解析失败的事件不会因再次调用解析接口而自动重试,因此本轮
failed_count = 0不代表历史失败已修复。请结合服务日志排查,当前 API 不提供重置失败状态的接口。多页查询期间应暂停刷新。接口不提供跨页数据快照;并发解析可能改变总数、记录内容或分页位置。
发现可查询的账户
GET /account-infos 无请求参数,返回已成功解析的账户集合:
$accountInfo = Invoke-RestMethod "http://127.0.0.1:8815/account-infos"
$accountInfo.data.accounts | Format-Table
响应示例中的账户为虚构数据:
{
"code": 0,
"message": "ok",
"data": {
"total": 1,
"accounts": [{"futures_company_name": "示例期货公司", "client_id": "000001"}]
}
}
账户由 futures_company_name``(期货公司名称)和 ``client_id``(客户号)共同标识,后续请求需原样使用这一对值。``client_id 不等于实时快照里的 user_key,也不能用资金账号 account_id 替代。客户号按字符串传递,保留前导零。
total 是账户总数,列表按期货公司名称、客户号升序排列。账户存在于此列表中,不保证选定的每个交易日都有资金、持仓或成交记录。无账户时返回 "total": 0, "accounts": []。
历史查询的通用参数
三个历史查询接口都使用 POST,设置 Content-Type: application/json; charset=utf-8,并发送一个 JSON 对象。参数放在请求体中,不是 URL 查询字符串。
{
"start_date": "2026-08-01",
"end_date": "2026-08-31",
"accounts": [{"futures_company_name": "示例期货公司", "client_id": "000001"}],
"limit": 1000,
"offset": 0
}
字段 |
类型 / 必填 |
说明 |
|---|---|---|
|
string / 是 |
起始交易日, |
|
string / 是 |
结束交易日, |
|
array / 是 |
至少包含一个账户对象;每项的期货公司名称和客户号都不能为空,重复账户自动去重 |
|
integer / 否 |
仅成交和持仓分页使用;省略或传 |
|
integer / 否 |
仅成交和持仓分页使用;默认 |
账户资金查询不分页,请省略 limit 和 offset;传入这两个字段不会限制账户资金返回行数。可以在 accounts 中加入多个账户对象,一次查询多个账户。
三个接口都会拒绝未知字段和请求体中的多个 JSON 值。目前没有按合约、品种、方向或数据来源筛选的请求参数;需要这些筛选时,应先取齐所选账户与日期范围内的记录,再在本地筛选。
data.total 是符合账户和日期条件的记录总数,不是当前页长度。无匹配数据时,记录数组返回 [],不会返回 null,也不作为请求错误。交易日由结算数据给出,不应把夜盘的自然日期自行当作结算交易日。
查询账户资金:POST /accounts/query
返回区间内的全部账户日记录,用于分析客户权益、出入金、手续费、可用资金和保证金。结果按 trading_day、futures_company_name、client_id 升序排列。
以下三类响应示例只展示部分业务字段,完整字段、类型和口径见 历史绩效字段;示例数值均为虚构。
{
"code": 0,
"message": "ok",
"data": {
"total": 1,
"accounts": [{
"trading_day": "2026-08-28",
"futures_company_name": "示例期货公司",
"client_id": "000001",
"source_type": "ObserveSettlement",
"currency": "CNY",
"balance_bf": 100000.0,
"deposit_withdrawal": 0.0,
"client_equity": 100800.0,
"commission": 200.0,
"margin_occupied": 20160.0,
"fund_available": 80640.0,
"risk_degree": 0.2
}]
}
}
查询成交:POST /trades/query
返回结算数据中的成交明细。按 trading_day、futures_company_name、client_id、exchange、trade_id、direction 升序排列后分页。该顺序不是盘中成交时间顺序;返回记录不包含成交时间戳或委托记录。
{
"code": 0,
"message": "ok",
"data": {
"total": 1,
"trades": [{
"trading_day": "2026-08-28",
"futures_company_name": "示例期货公司",
"client_id": "000001",
"source_type": "ObserveSettlement",
"exchange": "上期所",
"instrument_id": "rb2610",
"trade_id": "00001234",
"direction": "BUY",
"offset": "OPEN",
"hedge_type": "SPECULATION",
"price": 3200.0,
"volume": 2,
"commission": 6.4,
"realized_profit": 0.0,
"premium": null
}]
}
}
trade_id 不能单独作为跨账户、跨交易所的唯一标识。关联记录时,需要同时保留交易日、期货公司、客户号、交易所和方向。
查询持仓:POST /positions/query
返回日终持仓汇总,按 trading_day、futures_company_name、client_id、instrument_id、hedge_type 升序排列后分页。
{
"code": 0,
"message": "ok",
"data": {
"total": 1,
"positions": [{
"trading_day": "2026-08-28",
"futures_company_name": "示例期货公司",
"client_id": "000001",
"source_type": "ObserveSettlement",
"instrument_id": "rb2610",
"hedge_type": "SPECULATION",
"long_position": 2,
"short_position": 0,
"average_buy_price": 3200.0,
"average_sell_price": null,
"settlement_price": 3220.0,
"mtm_profit": 400.0,
"margin_occupied": 6440.0
}]
}
}
同一行可以同时包含买持仓和卖持仓;同一合约的不同投保类型可以分别返回。不要把每行当成一笔开仓,也不要将多个交易日的持仓手数相加解释为当前持仓。
错误码与排查
错误响应示例:
{"code": 40001, "message": "accounts must not be empty", "data": {}}
HTTP |
|
含义及处理方式 |
|---|---|---|
|
|
JSON、日期、账户或分页参数无效;检查字段名、类型和日期范围 |
|
|
已有同步或解析任务运行;等待任务结束再操作,不要并行刷新 |
|
|
同步时上游状态或响应异常;检查 QPro 登录状态、网络及服务日志 |
|
|
同步时上游超时;稍后再检查并重试 |
|
|
数据库或内部错误;检查服务日志 |
|
|
健康检查失败,本地数据库不可用 |
无法连接 8815 时,先检查版本、是否启用本地 API、是否完成重启登录,以及端口是否改动。账户列表为空时,先确认已执行同步和解析;有账户但区间无数据时,核对账户原值、交易日范围和结算数据覆盖情况。同步或解析的详细错误可在 analyse_server.log 中排查。