@zltquant/zlt-mcp 0.5.0-beta.0 → 0.5.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/config.json +8 -8
- package/package.json +1 -1
- package/zlt-mcp-proxy.bundle.cjs +45 -6
package/config.json
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
"name": "mcp-strategy-get-template-list",
|
|
24
|
-
"description": "
|
|
24
|
+
"description": "获取平台策略参数模板列表。创建策略前应先调用本工具,只能从实时返回的条目取 val 作为 templateItemVal,不要编造或硬编码模板标识。用户明确指定的模板优先;用户只说「推荐策略并回测」等委托选择请求时,agent 可根据返回的名称、说明和可用标签选择合适模板,无需再要求用户选择。没有其他偏好时,优先选择实时返回的带平台推荐标签且适合的日线模板;没有返回推荐标记时,若列表中存在且适合用户需求,可选择「均线择时」作为后备;否则从当前列表选择其他合适模板并简要说明理由。随后调用 mcp-create-strategy-with-template 创建。",
|
|
25
25
|
"inputSchema": {
|
|
26
26
|
"type": "object",
|
|
27
27
|
"properties": {
|
|
@@ -47,13 +47,13 @@
|
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
"name": "mcp-create-strategy-with-template",
|
|
50
|
-
"description": "
|
|
50
|
+
"description": "基于平台策略模板创建本地策略。先用 mcp-strategy-get-template-list 取实时列表,把所选条目的 val 填入 templateItemVal;templateVal 固定为 strategy。用户明确指定的模板优先;用户委托推荐时允许 agent 代选,无需再要求用户选择。名称默认用「模板名称+日期时间(YYMMDD-HHMM)」,允许用户修改;用户未指定名称时直接生成唯一名称——ZLTAF 对重名策略会静默不创建并返回空结果,本工具已将其转为明确的 ErrNo 10051,遇到就改用唯一名称重试,**切勿改为复用既有同名策略**。\n\n返回含 strategyId 与 localPath,请直接使用,不要再自行查询策略列表按名称猜测。",
|
|
51
51
|
"inputSchema": {
|
|
52
52
|
"type": "object",
|
|
53
53
|
"properties": {
|
|
54
54
|
"name": {
|
|
55
55
|
"type": "string",
|
|
56
|
-
"description": "
|
|
56
|
+
"description": "策略名称。默认使用“模板名称+日期时间(YYMMDD-HHMM)”生成唯一名称,允许用户修改;用户未指定名称时由 agent 直接生成,调用时传入该名称。"
|
|
57
57
|
},
|
|
58
58
|
"templateVal": {
|
|
59
59
|
"type": "string",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
},
|
|
66
66
|
"templateItemVal": {
|
|
67
67
|
"type": "string",
|
|
68
|
-
"description": "
|
|
68
|
+
"description": "用户选择或委托 agent 代选的模板 val,必须来自 mcp-strategy-get-template-list 实时返回的模板条目;不要编造或硬编码。用户明确指定的模板优先。"
|
|
69
69
|
},
|
|
70
70
|
"userId": {
|
|
71
71
|
"type": "string",
|
|
@@ -507,7 +507,7 @@
|
|
|
507
507
|
},
|
|
508
508
|
{
|
|
509
509
|
"name": "mcp-create-and-run-backtest",
|
|
510
|
-
"description": "创建并启动回测。strategyId 必须来自 mcp-create-strategy 返回的策略ID;runType 固定为 2
|
|
510
|
+
"description": "创建并启动回测。strategyId 必须来自 mcp-create-strategy 返回的策略ID;runType 固定为 2;已有配置基线时必须把本次 schema 支持的配置字段显式放入 runParams,再叠加用户明确要求;不要只传 strategyId 丢掉已有日期、资金、账户或费用。只有用户和配置都未提供周期时,才让 MCP 默认 end 为自然日 T-1、start 从 end 往前推半年;ZLTAF 按实际交易日执行,非交易日不产生行情或策略调用。run/create 失败直接报错,不要去复用策略里自动生成的 debug runId(建策略时已回显为 debugRunId,跑它等于跑创建那一刻的模板快照)。run/create 生成快照后,MCP 会在真正启动前拒绝 get_current_data().get(...) 这种当前对象不支持的访问。\n\n**返回 runId、codePath 和 attemptFence 后立即调用 mcp-wait(kind=backtest,id=runId)阻塞等待回测结束,不要用 mcp-get-backtest-state 轮询。CLI 创建命令启动的隐藏 guardian 会自行携带 attemptFence;任何后续显式 CLI call 或 MCP 重启后的调用,都必须把 codePath 和 attemptFence 一起传回 mcp-wait,避免把上一轮残留的 result.json 当成本轮错误;同一 MCP 会话内可省略。**\n\n日线类频率只可见到 context.previous_date:要用交易日 T 的收盘,end 必须设成 T 的下一个交易日;end 落在未来不报错但结果为空。展开见返回的 dailyVisibilityNote / endWarning。\n\n返回 Data 回显 resolvedStart/resolvedEnd/resolvedCapital——向用户汇报区间和初始资金时一律以这些字段为准,不要自行推算或臆测。evidence 给出 backtestId、实际 runDir、完整 effectiveRunParams 和代码快照 sourceSha256,后续结果必须与它对账。**基准不在此列**:回显的 requestedBenchmark 只是请求值,策略 initialize 里的 set_benchmark() 会覆盖它,收益产物里的「基准收益」按策略实际用的基准算。说基准是什么之前先读策略代码里的 set_benchmark,否则会把一只个股的涨跌报成指数的。\n\n**期货回测要同时改三处,少一处引擎就按股票跑**:runParams.marketIds 加上对应期货交易所(zj 中金所、zs 郑商所、ds 大商所、sq 上期所、gq 广期所),account_list 的 account_type 改成 2(实测用 6 直接废单),费率用 ratio_tpl_obj.future。合约代码形如 zjIM2605。基准保持默认 sz399300 即可,它对期货策略只是业绩比较基准。数据前置见 mcp-download-data:除行情外还必须有市场规则 mr。",
|
|
511
511
|
"inputSchema": {
|
|
512
512
|
"type": "object",
|
|
513
513
|
"properties": {
|
|
@@ -529,7 +529,7 @@
|
|
|
529
529
|
},
|
|
530
530
|
"runParams": {
|
|
531
531
|
"type": "object",
|
|
532
|
-
"description": "
|
|
532
|
+
"description": "回测参数。有 tradesetting.json 配置基线时显式传入 schema 支持的已有字段(日期、资金、账户、频率、市场、预加载、参数/费率模板),用户本次要求覆盖对应字段;账户现金与初始资金保持一致。仅无用户要求且无配置基线的字段采用 MCP 默认值。",
|
|
533
533
|
"properties": {
|
|
534
534
|
"account_list": {
|
|
535
535
|
"type": "array",
|
|
@@ -588,12 +588,12 @@
|
|
|
588
588
|
"start": {
|
|
589
589
|
"type": "string",
|
|
590
590
|
"format": "date",
|
|
591
|
-
"description": "回测开始日期,格式 YYYY-MM-DD
|
|
591
|
+
"description": "回测开始日期,格式 YYYY-MM-DD。用户要求优先,否则显式传已有配置的 start;两者都缺失时默认从 end 往前推半年。用户说近几天、近几月或近几年时按对应长度回推。"
|
|
592
592
|
},
|
|
593
593
|
"end": {
|
|
594
594
|
"type": "string",
|
|
595
595
|
"format": "date",
|
|
596
|
-
"description": "回测结束日期,格式 YYYY-MM-DD
|
|
596
|
+
"description": "回测结束日期,格式 YYYY-MM-DD。用户要求优先,否则显式传已有配置的 end;两者都缺失时默认使用 T-1。"
|
|
597
597
|
},
|
|
598
598
|
"freq": {
|
|
599
599
|
"type": "string",
|
package/package.json
CHANGED
package/zlt-mcp-proxy.bundle.cjs
CHANGED
|
@@ -23302,14 +23302,14 @@ function shapeToolResult(tool, args, result, session) {
|
|
|
23302
23302
|
session.activeBacktestRunIds.delete(args.runId);
|
|
23303
23303
|
}
|
|
23304
23304
|
const echoed = echoResolvedBacktestConfig(tool, args, result, session.backtestRunContexts);
|
|
23305
|
-
const guarded = applyBacktestResultGuards(
|
|
23305
|
+
const guarded = annotateBacktestOutcome(tool, applyBacktestResultGuards(
|
|
23306
23306
|
tool,
|
|
23307
23307
|
args,
|
|
23308
23308
|
echoed,
|
|
23309
23309
|
session.backtestPollStates,
|
|
23310
23310
|
session.backtestRunContexts,
|
|
23311
23311
|
session.activeBacktestRunIds
|
|
23312
|
-
);
|
|
23312
|
+
));
|
|
23313
23313
|
const activeChange = classifyActiveBacktestChange(tool, args, guarded);
|
|
23314
23314
|
if (activeChange) {
|
|
23315
23315
|
if (activeChange.active) session.activeBacktestRunIds.add(activeChange.runId);
|
|
@@ -23323,6 +23323,38 @@ function shapeToolResult(tool, args, result, session) {
|
|
|
23323
23323
|
const distilled = distillFactorDetectReport(tool, args, diagnosed);
|
|
23324
23324
|
return injectDebugRunId(tool, injectStrategyDocsHint(tool, distilled, session.docsPath));
|
|
23325
23325
|
}
|
|
23326
|
+
function backtestStatusNumber(status) {
|
|
23327
|
+
return typeof status === "number" || typeof status === "string" && status.trim() !== "" ? Number(status) : NaN;
|
|
23328
|
+
}
|
|
23329
|
+
function annotateBacktestOutcome(tool, result) {
|
|
23330
|
+
if (tool.name !== "mcp-get-backtest-state") return result;
|
|
23331
|
+
try {
|
|
23332
|
+
const parsed = JSON.parse(result.content[0]?.text ?? "");
|
|
23333
|
+
if (!isRecord2(parsed) || !isRecord2(parsed.Data)) return result;
|
|
23334
|
+
const data = parsed.Data;
|
|
23335
|
+
const status = backtestStatusNumber(data.status);
|
|
23336
|
+
const reconciled = parsed.ErrNo === 10043 && data.reconciledFrom === "result.json";
|
|
23337
|
+
const backtestOutcome = reconciled ? "failed" : status === 0 || status === 1 ? "running" : status === 2 ? "failed" : status === 3 ? "cancelled" : status === 4 ? "terminated" : status === 5 ? "completed" : "unknown";
|
|
23338
|
+
const isTerminal2 = backtestOutcome !== "running" && backtestOutcome !== "unknown";
|
|
23339
|
+
const message = typeof data.error_msg === "string" ? data.error_msg.trim() : "";
|
|
23340
|
+
return {
|
|
23341
|
+
...result,
|
|
23342
|
+
content: [{ type: "text", text: JSON.stringify({
|
|
23343
|
+
...parsed,
|
|
23344
|
+
Data: {
|
|
23345
|
+
...data,
|
|
23346
|
+
backtestOutcome,
|
|
23347
|
+
isTerminal: isTerminal2,
|
|
23348
|
+
evidenceSource: reconciled ? "current-attempt-result.json" : "ipc-state",
|
|
23349
|
+
nextAction: isTerminal2 ? "finalize-backtest" : backtestOutcome === "unknown" || data.waitStopped || data.pollingStopped ? "inspect-backtest-state" : "keep-waiting",
|
|
23350
|
+
...backtestOutcome === "failed" && !reconciled && (!message || /异常(?:退出|终止)|unexpected.*exit|exited unexpectedly/i.test(message)) ? { failureCause: "unknown" } : {}
|
|
23351
|
+
}
|
|
23352
|
+
}) }]
|
|
23353
|
+
};
|
|
23354
|
+
} catch {
|
|
23355
|
+
return result;
|
|
23356
|
+
}
|
|
23357
|
+
}
|
|
23326
23358
|
var ZLTAF_CONFIG_SEGMENTS = ["zltaf", "application-local.properties"];
|
|
23327
23359
|
var FALLBACK_FACTOR_PROJECT_PATH = ["Users", "factors"];
|
|
23328
23360
|
var factorProjectRootCache = /* @__PURE__ */ new Map();
|
|
@@ -24404,11 +24436,11 @@ function unreadableDownloadProgressError(uuid2) {
|
|
|
24404
24436
|
);
|
|
24405
24437
|
}
|
|
24406
24438
|
function unreadableBacktestStateError(runId) {
|
|
24407
|
-
return waitError(
|
|
24439
|
+
return annotateBacktestOutcome(BACKTEST_WAIT_POLL_IDENTITY, waitError(
|
|
24408
24440
|
10054,
|
|
24409
24441
|
"\u56DE\u6D4B\u72B6\u6001\u5E94\u7B54\u65E0\u6CD5\u89E3\u6790\uFF0C\u5DF2\u505C\u6B62\u7B49\u5F85\uFF1B\u8BF7\u7528 mcp-get-backtest-state \u590D\u67E5\u3002",
|
|
24410
24442
|
{ runId }
|
|
24411
|
-
);
|
|
24443
|
+
));
|
|
24412
24444
|
}
|
|
24413
24445
|
function factorWaitLane(executionId, session) {
|
|
24414
24446
|
let staleCount = 0;
|
|
@@ -24557,7 +24589,7 @@ function backtestWaitLane(runId, session, codePath, resultBaseline, attemptStart
|
|
|
24557
24589
|
return { verdict: "return", result: unreadableBacktestStateError(runId) };
|
|
24558
24590
|
}
|
|
24559
24591
|
const data = parsed.Data;
|
|
24560
|
-
const status =
|
|
24592
|
+
const status = backtestStatusNumber(data.status);
|
|
24561
24593
|
if (!Number.isFinite(status)) {
|
|
24562
24594
|
return { verdict: "return", result: unreadableBacktestStateError(runId) };
|
|
24563
24595
|
}
|
|
@@ -24598,7 +24630,10 @@ function backtestWaitLane(runId, session, codePath, resultBaseline, attemptStart
|
|
|
24598
24630
|
frozenCount = signature === lastSignature ? frozenCount + 1 : 0;
|
|
24599
24631
|
lastSignature = signature;
|
|
24600
24632
|
if (frozenCount >= WAIT_FROZEN_THRESHOLD) {
|
|
24601
|
-
return { verdict: "return", result:
|
|
24633
|
+
return { verdict: "return", result: annotateBacktestOutcome(
|
|
24634
|
+
BACKTEST_WAIT_POLL_IDENTITY,
|
|
24635
|
+
frozenBacktestResult(parsed, data)
|
|
24636
|
+
) };
|
|
24602
24637
|
}
|
|
24603
24638
|
const progress = typeof data.progress === "number" && Number.isFinite(data.progress) ? data.progress : 0;
|
|
24604
24639
|
return { verdict: "wait", progress };
|
|
@@ -27669,6 +27704,10 @@ function compactCliReceipt(tool, result, resultFile) {
|
|
|
27669
27704
|
"available",
|
|
27670
27705
|
"runtimeReady",
|
|
27671
27706
|
"backtestReady",
|
|
27707
|
+
"backtestOutcome",
|
|
27708
|
+
"isTerminal",
|
|
27709
|
+
"evidenceSource",
|
|
27710
|
+
"failureCause",
|
|
27672
27711
|
"nextAction",
|
|
27673
27712
|
"recommendedAction",
|
|
27674
27713
|
"error_code",
|