@8btc/finance-assistant-mcp 0.0.56 → 0.0.58
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/dist/index.cjs +640 -592
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -9,6 +9,7 @@ const sse_js = require("@modelcontextprotocol/sdk/server/sse.js");
|
|
|
9
9
|
const express = require("express");
|
|
10
10
|
const streamableHttp_js = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
11
11
|
const cors = require("cors");
|
|
12
|
+
const z = require("zod");
|
|
12
13
|
const jsxRuntime = require("react/jsx-runtime");
|
|
13
14
|
const ReactDOMServer = require("react-dom/server");
|
|
14
15
|
const echarts = require("echarts");
|
|
@@ -17,7 +18,6 @@ const tailwindMerge = require("tailwind-merge");
|
|
|
17
18
|
const dayjs = require("dayjs");
|
|
18
19
|
const react = require("react");
|
|
19
20
|
const qrcode_react = require("qrcode.react");
|
|
20
|
-
const zod = require("zod");
|
|
21
21
|
const winston = require("winston");
|
|
22
22
|
const zodToJsonSchema$1 = require("zod-to-json-schema");
|
|
23
23
|
const fs = require("fs");
|
|
@@ -45,7 +45,7 @@ function _interopNamespaceDefault(e) {
|
|
|
45
45
|
}
|
|
46
46
|
const echarts__namespace = /* @__PURE__ */ _interopNamespaceDefault(echarts);
|
|
47
47
|
const d3__namespace = /* @__PURE__ */ _interopNamespaceDefault(d3);
|
|
48
|
-
const version = "0.0.
|
|
48
|
+
const version = "0.0.58";
|
|
49
49
|
const pkgJSON = {
|
|
50
50
|
version
|
|
51
51
|
};
|
|
@@ -1326,169 +1326,169 @@ const renderChapter7$2 = (data) => {
|
|
|
1326
1326
|
const seg = ReactDOMServer.renderToString(/* @__PURE__ */ jsxRuntime.jsx(Chapter7$2, { data }));
|
|
1327
1327
|
return renderFullHtml(seg);
|
|
1328
1328
|
};
|
|
1329
|
-
const top_news =
|
|
1330
|
-
|
|
1331
|
-
title:
|
|
1332
|
-
link:
|
|
1333
|
-
content:
|
|
1334
|
-
summary:
|
|
1335
|
-
timestamp:
|
|
1336
|
-
source:
|
|
1337
|
-
tag:
|
|
1338
|
-
insight:
|
|
1329
|
+
const top_news = z.z.array(
|
|
1330
|
+
z.z.object({
|
|
1331
|
+
title: z.z.string().describe("新闻标题"),
|
|
1332
|
+
link: z.z.string().describe("新闻链接"),
|
|
1333
|
+
content: z.z.string().describe("新闻内容,大模型访问链接获得"),
|
|
1334
|
+
summary: z.z.string().describe("新闻总结,大模型总结"),
|
|
1335
|
+
timestamp: z.z.number().describe("时间戳"),
|
|
1336
|
+
source: z.z.string().describe("新闻源"),
|
|
1337
|
+
tag: z.z.array(z.z.string()).describe("新闻标签"),
|
|
1338
|
+
insight: z.z.string().describe("详细解读。大模型总结")
|
|
1339
1339
|
}).describe("最热新闻")
|
|
1340
1340
|
);
|
|
1341
1341
|
const newsSchema = {
|
|
1342
|
-
report_type:
|
|
1343
|
-
report_time:
|
|
1344
|
-
data_period_start:
|
|
1345
|
-
data_period_end:
|
|
1346
|
-
overview:
|
|
1347
|
-
opportunities_and_risks:
|
|
1348
|
-
focus_points:
|
|
1349
|
-
risk_factors:
|
|
1342
|
+
report_type: z.z.enum(["market", "industry", "stock"]),
|
|
1343
|
+
report_time: z.z.string().describe("报告时间"),
|
|
1344
|
+
data_period_start: z.z.string().describe("数据开始时间"),
|
|
1345
|
+
data_period_end: z.z.string().describe("数据结束时间}"),
|
|
1346
|
+
overview: z.z.string().describe("总体描述,大模型总结"),
|
|
1347
|
+
opportunities_and_risks: z.z.string().describe("机会与风险,大模型总结"),
|
|
1348
|
+
focus_points: z.z.string().describe("关注点,大模型总结"),
|
|
1349
|
+
risk_factors: z.z.string().describe("风险点,大模型总结"),
|
|
1350
1350
|
top_news,
|
|
1351
|
-
news_statistics:
|
|
1352
|
-
summary:
|
|
1353
|
-
news_count_12h:
|
|
1354
|
-
news_count_24h:
|
|
1355
|
-
total_news_count:
|
|
1356
|
-
keywords:
|
|
1357
|
-
heat_index:
|
|
1358
|
-
heat_comment:
|
|
1359
|
-
social_media_summary:
|
|
1360
|
-
sentiment_distribution:
|
|
1361
|
-
negative_pct:
|
|
1362
|
-
value:
|
|
1363
|
-
comment:
|
|
1351
|
+
news_statistics: z.z.object({
|
|
1352
|
+
summary: z.z.string().describe("总结"),
|
|
1353
|
+
news_count_12h: z.z.number(),
|
|
1354
|
+
news_count_24h: z.z.number(),
|
|
1355
|
+
total_news_count: z.z.number(),
|
|
1356
|
+
keywords: z.z.array(z.z.string()).describe("关键字"),
|
|
1357
|
+
heat_index: z.z.number(),
|
|
1358
|
+
heat_comment: z.z.string().describe("热度描述"),
|
|
1359
|
+
social_media_summary: z.z.string().describe("社交数据总结"),
|
|
1360
|
+
sentiment_distribution: z.z.object({
|
|
1361
|
+
negative_pct: z.z.object({
|
|
1362
|
+
value: z.z.number(),
|
|
1363
|
+
comment: z.z.string().describe("描述")
|
|
1364
1364
|
}),
|
|
1365
|
-
neutral_pct:
|
|
1366
|
-
value:
|
|
1367
|
-
comment:
|
|
1365
|
+
neutral_pct: z.z.object({
|
|
1366
|
+
value: z.z.number(),
|
|
1367
|
+
comment: z.z.string().describe("描述")
|
|
1368
1368
|
}),
|
|
1369
|
-
positive_pct:
|
|
1370
|
-
value:
|
|
1371
|
-
comment:
|
|
1369
|
+
positive_pct: z.z.object({
|
|
1370
|
+
value: z.z.number(),
|
|
1371
|
+
comment: z.z.string().describe("描述")
|
|
1372
1372
|
})
|
|
1373
1373
|
})
|
|
1374
1374
|
}),
|
|
1375
|
-
market_sentiment:
|
|
1376
|
-
value:
|
|
1377
|
-
comment:
|
|
1375
|
+
market_sentiment: z.z.object({
|
|
1376
|
+
value: z.z.number(),
|
|
1377
|
+
comment: z.z.string()
|
|
1378
1378
|
}).optional(),
|
|
1379
|
-
stock_sentiment:
|
|
1380
|
-
value:
|
|
1381
|
-
comment:
|
|
1379
|
+
stock_sentiment: z.z.object({
|
|
1380
|
+
value: z.z.number(),
|
|
1381
|
+
comment: z.z.string()
|
|
1382
1382
|
}).optional(),
|
|
1383
|
-
industry_sentiment:
|
|
1384
|
-
value:
|
|
1385
|
-
comment:
|
|
1383
|
+
industry_sentiment: z.z.object({
|
|
1384
|
+
value: z.z.number(),
|
|
1385
|
+
comment: z.z.string()
|
|
1386
1386
|
}).optional(),
|
|
1387
|
-
market:
|
|
1388
|
-
industry_impact:
|
|
1389
|
-
bullish_industries:
|
|
1390
|
-
|
|
1391
|
-
sector:
|
|
1392
|
-
score:
|
|
1393
|
-
reason:
|
|
1387
|
+
market: z.z.object({
|
|
1388
|
+
industry_impact: z.z.object({
|
|
1389
|
+
bullish_industries: z.z.array(
|
|
1390
|
+
z.z.object({
|
|
1391
|
+
sector: z.z.string(),
|
|
1392
|
+
score: z.z.number(),
|
|
1393
|
+
reason: z.z.string()
|
|
1394
1394
|
})
|
|
1395
1395
|
),
|
|
1396
|
-
bearish_industries:
|
|
1397
|
-
|
|
1398
|
-
sector:
|
|
1399
|
-
score:
|
|
1400
|
-
reason:
|
|
1396
|
+
bearish_industries: z.z.array(
|
|
1397
|
+
z.z.object({
|
|
1398
|
+
sector: z.z.string(),
|
|
1399
|
+
score: z.z.number(),
|
|
1400
|
+
reason: z.z.string()
|
|
1401
1401
|
})
|
|
1402
1402
|
)
|
|
1403
1403
|
}),
|
|
1404
|
-
asset_class_impact:
|
|
1405
|
-
a_share:
|
|
1406
|
-
impact:
|
|
1407
|
-
performance:
|
|
1408
|
-
reason:
|
|
1404
|
+
asset_class_impact: z.z.object({
|
|
1405
|
+
a_share: z.z.object({
|
|
1406
|
+
impact: z.z.string(),
|
|
1407
|
+
performance: z.z.string(),
|
|
1408
|
+
reason: z.z.string()
|
|
1409
1409
|
}),
|
|
1410
|
-
hk_share:
|
|
1411
|
-
impact:
|
|
1412
|
-
performance:
|
|
1413
|
-
reason:
|
|
1410
|
+
hk_share: z.z.object({
|
|
1411
|
+
impact: z.z.string(),
|
|
1412
|
+
performance: z.z.string(),
|
|
1413
|
+
reason: z.z.string()
|
|
1414
1414
|
}),
|
|
1415
|
-
us_share:
|
|
1416
|
-
impact:
|
|
1417
|
-
performance:
|
|
1418
|
-
reason:
|
|
1415
|
+
us_share: z.z.object({
|
|
1416
|
+
impact: z.z.string(),
|
|
1417
|
+
performance: z.z.string(),
|
|
1418
|
+
reason: z.z.string()
|
|
1419
1419
|
})
|
|
1420
1420
|
})
|
|
1421
1421
|
}),
|
|
1422
|
-
industry:
|
|
1423
|
-
subsector_impact:
|
|
1424
|
-
bullish_subsectors:
|
|
1425
|
-
|
|
1426
|
-
subsector:
|
|
1427
|
-
score:
|
|
1428
|
-
reason:
|
|
1422
|
+
industry: z.z.object({
|
|
1423
|
+
subsector_impact: z.z.object({
|
|
1424
|
+
bullish_subsectors: z.z.array(
|
|
1425
|
+
z.z.object({
|
|
1426
|
+
subsector: z.z.string(),
|
|
1427
|
+
score: z.z.number(),
|
|
1428
|
+
reason: z.z.string()
|
|
1429
1429
|
})
|
|
1430
1430
|
),
|
|
1431
|
-
bearish_subsectors:
|
|
1432
|
-
|
|
1433
|
-
subsector:
|
|
1434
|
-
score:
|
|
1435
|
-
reason:
|
|
1431
|
+
bearish_subsectors: z.z.array(
|
|
1432
|
+
z.z.object({
|
|
1433
|
+
subsector: z.z.string(),
|
|
1434
|
+
score: z.z.number(),
|
|
1435
|
+
reason: z.z.string()
|
|
1436
1436
|
})
|
|
1437
1437
|
)
|
|
1438
1438
|
}),
|
|
1439
|
-
industry_asset_linkage:
|
|
1440
|
-
a_share:
|
|
1441
|
-
impact:
|
|
1442
|
-
industry_performance:
|
|
1443
|
-
reason:
|
|
1439
|
+
industry_asset_linkage: z.z.object({
|
|
1440
|
+
a_share: z.z.object({
|
|
1441
|
+
impact: z.z.string(),
|
|
1442
|
+
industry_performance: z.z.string(),
|
|
1443
|
+
reason: z.z.string()
|
|
1444
1444
|
}),
|
|
1445
|
-
hk_share:
|
|
1446
|
-
impact:
|
|
1447
|
-
industry_performance:
|
|
1448
|
-
reason:
|
|
1445
|
+
hk_share: z.z.object({
|
|
1446
|
+
impact: z.z.string(),
|
|
1447
|
+
industry_performance: z.z.string(),
|
|
1448
|
+
reason: z.z.string()
|
|
1449
1449
|
}),
|
|
1450
|
-
us_share:
|
|
1451
|
-
impact:
|
|
1452
|
-
industry_performance:
|
|
1453
|
-
reason:
|
|
1450
|
+
us_share: z.z.object({
|
|
1451
|
+
impact: z.z.string(),
|
|
1452
|
+
industry_performance: z.z.string(),
|
|
1453
|
+
reason: z.z.string()
|
|
1454
1454
|
})
|
|
1455
1455
|
})
|
|
1456
1456
|
}),
|
|
1457
|
-
professional_insights:
|
|
1458
|
-
|
|
1459
|
-
message:
|
|
1460
|
-
weight:
|
|
1461
|
-
comment:
|
|
1457
|
+
professional_insights: z.z.array(
|
|
1458
|
+
z.z.object({
|
|
1459
|
+
message: z.z.string(),
|
|
1460
|
+
weight: z.z.string(),
|
|
1461
|
+
comment: z.z.string()
|
|
1462
1462
|
})
|
|
1463
1463
|
),
|
|
1464
|
-
capital_flows:
|
|
1465
|
-
northbound_comment:
|
|
1466
|
-
southbound_comment:
|
|
1467
|
-
industry_flow_comment:
|
|
1464
|
+
capital_flows: z.z.object({
|
|
1465
|
+
northbound_comment: z.z.string(),
|
|
1466
|
+
southbound_comment: z.z.string(),
|
|
1467
|
+
industry_flow_comment: z.z.string()
|
|
1468
1468
|
}),
|
|
1469
|
-
expectation_analysis:
|
|
1470
|
-
historical_analogy:
|
|
1471
|
-
domestic_expectation:
|
|
1472
|
-
overseas_expectation:
|
|
1473
|
-
global_market_linkage:
|
|
1474
|
-
usa:
|
|
1475
|
-
europe:
|
|
1476
|
-
asia:
|
|
1469
|
+
expectation_analysis: z.z.object({
|
|
1470
|
+
historical_analogy: z.z.string(),
|
|
1471
|
+
domestic_expectation: z.z.string(),
|
|
1472
|
+
overseas_expectation: z.z.string(),
|
|
1473
|
+
global_market_linkage: z.z.object({
|
|
1474
|
+
usa: z.z.string(),
|
|
1475
|
+
europe: z.z.string(),
|
|
1476
|
+
asia: z.z.string()
|
|
1477
1477
|
})
|
|
1478
1478
|
}),
|
|
1479
|
-
summary:
|
|
1480
|
-
general_comment:
|
|
1481
|
-
policy_comment:
|
|
1482
|
-
fundamental_comment:
|
|
1483
|
-
strategy_suggestion:
|
|
1479
|
+
summary: z.z.object({
|
|
1480
|
+
general_comment: z.z.string(),
|
|
1481
|
+
policy_comment: z.z.string(),
|
|
1482
|
+
fundamental_comment: z.z.string(),
|
|
1483
|
+
strategy_suggestion: z.z.string()
|
|
1484
1484
|
}),
|
|
1485
|
-
risk_summary:
|
|
1486
|
-
macro_risk:
|
|
1487
|
-
policy_risk:
|
|
1488
|
-
inflation_risk:
|
|
1485
|
+
risk_summary: z.z.object({
|
|
1486
|
+
macro_risk: z.z.string(),
|
|
1487
|
+
policy_risk: z.z.string(),
|
|
1488
|
+
inflation_risk: z.z.string()
|
|
1489
1489
|
})
|
|
1490
1490
|
};
|
|
1491
|
-
|
|
1491
|
+
z.z.object({
|
|
1492
1492
|
...newsSchema
|
|
1493
1493
|
});
|
|
1494
1494
|
const logger = winston.createLogger({
|
|
@@ -1512,7 +1512,7 @@ const logger = winston.createLogger({
|
|
|
1512
1512
|
]
|
|
1513
1513
|
});
|
|
1514
1514
|
const zodToJsonSchema = (schema) => {
|
|
1515
|
-
return zodToJsonSchema$1.zodToJsonSchema(
|
|
1515
|
+
return zodToJsonSchema$1.zodToJsonSchema(z.z.object(schema), {
|
|
1516
1516
|
rejectedAdditionalProperties: void 0,
|
|
1517
1517
|
$refStrategy: "none"
|
|
1518
1518
|
});
|
|
@@ -1814,6 +1814,13 @@ const tool$5 = {
|
|
|
1814
1814
|
};
|
|
1815
1815
|
const toolHandler$5 = async (args) => {
|
|
1816
1816
|
try {
|
|
1817
|
+
const result = z.object(newsSchema).safeParse(args);
|
|
1818
|
+
if (!result.success) {
|
|
1819
|
+
throw new types_js.McpError(
|
|
1820
|
+
types_js.ErrorCode.InvalidParams,
|
|
1821
|
+
`Invalid parameters: ${result.error.message}`
|
|
1822
|
+
);
|
|
1823
|
+
}
|
|
1817
1824
|
logger.info(`start: ${(/* @__PURE__ */ new Date()).getTime()}`);
|
|
1818
1825
|
logger.info(args);
|
|
1819
1826
|
const resp = generateFinancialNewsHtml({
|
|
@@ -2746,89 +2753,91 @@ const renderChapter5$4 = (data) => {
|
|
|
2746
2753
|
return renderFullHtml(seg);
|
|
2747
2754
|
};
|
|
2748
2755
|
const fundamentalSchema = {
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2756
|
+
core_thesis: z.z.string().describe("核心观点"),
|
|
2757
|
+
core_thesis_desc: z.z.string().describe("核心观点阐述"),
|
|
2758
|
+
roe_takeaway: z.z.string().describe("roe 指标解读核心要点"),
|
|
2759
|
+
roe_takeaway_desc: z.z.string().describe("roe 指标解读核心要点阐述"),
|
|
2760
|
+
gp_margin_takeaway: z.z.string().describe("毛利率 指标解读核心要点"),
|
|
2761
|
+
gp_margin_takeaway_desc: z.z.string().describe("毛利率 指标解读核心要点阐述"),
|
|
2762
|
+
yoy_ni_takeaway: z.z.string().describe("增长率 指标解读核心要点"),
|
|
2763
|
+
yoy_ni_takeaway_desc: z.z.string().describe("增长率 指标解读核心要点阐述"),
|
|
2764
|
+
pe_takeaway: z.z.string().describe("市盈率 指标解读核心要点"),
|
|
2765
|
+
pe_takeaway_desc: z.z.string().describe("市盈率 指标解读核心要点阐述"),
|
|
2766
|
+
cfo_takeaway: z.z.string().describe("经营性现金净流量 指标解读核心要点"),
|
|
2767
|
+
cfo_takeaway_desc: z.z.string().describe("经营性现金净流量 指标解读核心要点阐述"),
|
|
2768
|
+
main_risks: z.z.string().describe("主要风险"),
|
|
2769
|
+
primary_stock_holder: z.z.string().describe("主要股东"),
|
|
2770
|
+
free_float_characteristics: z.z.string().describe("流通盘特征"),
|
|
2771
|
+
stock_holder_analyze: z.z.string().describe("前十大股东分析"),
|
|
2772
|
+
roe_review: z.z.string(),
|
|
2773
|
+
gp_margin_review: z.z.string(),
|
|
2774
|
+
revenue_review: z.z.string(),
|
|
2775
|
+
balance_review: z.z.string().describe("财务结构点评"),
|
|
2776
|
+
cash_flow_ratio: z.z.number().describe("现金流点评"),
|
|
2777
|
+
peg_review: z.z.string().describe("peg 点评"),
|
|
2778
|
+
industry_trends_commentary: z.z.string().describe("行业趋势展望"),
|
|
2779
|
+
pe_list: z.z.array(
|
|
2780
|
+
z.z.object({
|
|
2781
|
+
code: z.z.string().describe("股票代码"),
|
|
2782
|
+
name: z.z.string().describe("股票简称"),
|
|
2783
|
+
ttm: z.z.number().describe("TTM市盈率"),
|
|
2784
|
+
ttm_review: z.z.string().describe("估值点评")
|
|
2785
|
+
})
|
|
2786
|
+
).describe("市盈率列表"),
|
|
2787
|
+
raw_data_path: z.z.string().describe("数据存储地址,**这很重要**")
|
|
2788
|
+
};
|
|
2789
|
+
z.z.object({
|
|
2790
|
+
...fundamentalSchema,
|
|
2791
|
+
// 本地json解析
|
|
2792
|
+
title: z.z.string().describe("报告名称"),
|
|
2793
|
+
generation_time: z.z.string().describe("生成时间"),
|
|
2794
|
+
logo: z.z.string().optional().describe("logo"),
|
|
2795
|
+
code: z.z.string().describe("股票代码"),
|
|
2796
|
+
market: z.z.string().describe("市场"),
|
|
2797
|
+
name: z.z.string().describe("上市公司名称"),
|
|
2798
|
+
data_period_start: z.z.string().describe("数据周期起始点"),
|
|
2799
|
+
data_period_end: z.z.string().describe("数据周期结束点}"),
|
|
2800
|
+
industry: z.z.string().describe("行业"),
|
|
2801
|
+
curr_price: z.z.number().describe("当前股价"),
|
|
2802
|
+
curr_change: z.z.number().describe("涨跌额"),
|
|
2803
|
+
curr_pct_chg: z.z.number().optional().describe("涨跌幅度"),
|
|
2804
|
+
roe: z.z.number().describe("ROE指标"),
|
|
2805
|
+
gp_margin: z.z.number().describe("毛利率指标"),
|
|
2806
|
+
yoy_ni: z.z.number().describe("增长率指标"),
|
|
2807
|
+
pe: z.z.number().describe("市盈率指标"),
|
|
2808
|
+
cfo: z.z.number().describe("经营性现金净流量"),
|
|
2809
|
+
stock_holder_list: z.z.array(
|
|
2810
|
+
z.z.object({
|
|
2811
|
+
name: z.z.string(),
|
|
2812
|
+
type: z.z.string(),
|
|
2813
|
+
shares: z.z.number(),
|
|
2814
|
+
shares_ratio: z.z.number(),
|
|
2815
|
+
change: z.z.union([z.z.string(), z.z.number()]),
|
|
2816
|
+
change_ratio: z.z.string()
|
|
2790
2817
|
})
|
|
2791
2818
|
).describe("股东列表"),
|
|
2792
|
-
financial_trend_indicators:
|
|
2793
|
-
|
|
2794
|
-
date:
|
|
2795
|
-
roe:
|
|
2796
|
-
gp_margin:
|
|
2797
|
-
revenue:
|
|
2819
|
+
financial_trend_indicators: z.z.array(
|
|
2820
|
+
z.z.object({
|
|
2821
|
+
date: z.z.string(),
|
|
2822
|
+
roe: z.z.number(),
|
|
2823
|
+
gp_margin: z.z.number(),
|
|
2824
|
+
revenue: z.z.number()
|
|
2798
2825
|
})
|
|
2799
2826
|
),
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
code: zod.z.string().describe("股票代码"),
|
|
2813
|
-
name: zod.z.string().describe("股票简称"),
|
|
2814
|
-
ttm: zod.z.number().describe("TTM市盈率"),
|
|
2815
|
-
ttm_review: zod.z.string().describe("估值点评")
|
|
2816
|
-
})
|
|
2817
|
-
).describe("市盈率列表"),
|
|
2818
|
-
peg: zod.z.number().describe("PEG"),
|
|
2819
|
-
peg_review: zod.z.string().describe("peg 点评"),
|
|
2820
|
-
industry_trends_commentary: zod.z.string().describe("行业趋势展望"),
|
|
2821
|
-
major_holdings_review: zod.z.string().describe("重点持仓机构点评"),
|
|
2822
|
-
institutional_holdings_structure_review: zod.z.string().describe("机构持仓点评"),
|
|
2823
|
-
institutional_holdings_structure: zod.z.array(
|
|
2824
|
-
zod.z.object({
|
|
2825
|
-
type: zod.z.string().describe("机构类型"),
|
|
2826
|
-
ratio: zod.z.number().describe("占比")
|
|
2827
|
+
cagr_3y: z.z.number().describe("三年复合增长率"),
|
|
2828
|
+
liability_to_asset: z.z.number().describe("资产负债率"),
|
|
2829
|
+
current_ratio: z.z.number().describe("流动比率"),
|
|
2830
|
+
cash_ratio: z.z.number().describe("现金比率"),
|
|
2831
|
+
cfo_to_np: z.z.number().describe("经营现金流/净利润"),
|
|
2832
|
+
peg: z.z.number().describe("PEG"),
|
|
2833
|
+
major_holdings_review: z.z.string().describe("重点持仓机构点评"),
|
|
2834
|
+
institutional_holdings_structure_review: z.z.string().describe("机构持仓点评"),
|
|
2835
|
+
institutional_holdings_structure: z.z.array(
|
|
2836
|
+
z.z.object({
|
|
2837
|
+
type: z.z.string().describe("机构类型"),
|
|
2838
|
+
ratio: z.z.number().describe("占比")
|
|
2827
2839
|
})
|
|
2828
2840
|
)
|
|
2829
|
-
};
|
|
2830
|
-
zod.z.object({
|
|
2831
|
-
...fundamentalSchema
|
|
2832
2841
|
});
|
|
2833
2842
|
const tool$4 = {
|
|
2834
2843
|
name: "generate_fundamental_pdf",
|
|
@@ -2837,10 +2846,21 @@ const tool$4 = {
|
|
|
2837
2846
|
};
|
|
2838
2847
|
const toolHandler$4 = async (args) => {
|
|
2839
2848
|
try {
|
|
2849
|
+
const result = z.object(fundamentalSchema).safeParse(args);
|
|
2850
|
+
if (!result.success) {
|
|
2851
|
+
throw new types_js.McpError(
|
|
2852
|
+
types_js.ErrorCode.InvalidParams,
|
|
2853
|
+
`Invalid parameters: ${result.error.message}`
|
|
2854
|
+
);
|
|
2855
|
+
}
|
|
2840
2856
|
logger.info(`start: ${(/* @__PURE__ */ new Date()).getTime()}`);
|
|
2841
2857
|
logger.info(args);
|
|
2858
|
+
const jsonData = await getJsonDataIfExists(args.raw_data_path, {});
|
|
2859
|
+
logger.info(`readFile `, args.raw_data_path);
|
|
2860
|
+
logger.info(jsonData);
|
|
2842
2861
|
const resp = generateFundamentalHtml({
|
|
2843
|
-
...args
|
|
2862
|
+
...args,
|
|
2863
|
+
...jsonData
|
|
2844
2864
|
});
|
|
2845
2865
|
const pdfUrl = await generatePDF({
|
|
2846
2866
|
list: resp,
|
|
@@ -3996,187 +4016,187 @@ const renderChapter7$1 = (data) => {
|
|
|
3996
4016
|
const seg = ReactDOMServer.renderToString(/* @__PURE__ */ jsxRuntime.jsx(Chapter7$1, { data }));
|
|
3997
4017
|
return renderFullHtml(seg);
|
|
3998
4018
|
};
|
|
3999
|
-
const kline_daily$1 =
|
|
4000
|
-
|
|
4001
|
-
time:
|
|
4002
|
-
open:
|
|
4003
|
-
close:
|
|
4004
|
-
high:
|
|
4005
|
-
low:
|
|
4006
|
-
pct_chg:
|
|
4007
|
-
vol:
|
|
4008
|
-
amount:
|
|
4019
|
+
const kline_daily$1 = z.z.array(
|
|
4020
|
+
z.z.object({
|
|
4021
|
+
time: z.z.string().describe("时间"),
|
|
4022
|
+
open: z.z.number().describe("开盘价"),
|
|
4023
|
+
close: z.z.number().describe("收盘价"),
|
|
4024
|
+
high: z.z.number().describe("最高价"),
|
|
4025
|
+
low: z.z.number().describe("最低价"),
|
|
4026
|
+
pct_chg: z.z.number().describe("涨跌幅"),
|
|
4027
|
+
vol: z.z.number().describe("成交量"),
|
|
4028
|
+
amount: z.z.number().describe("成交额")
|
|
4009
4029
|
})
|
|
4010
4030
|
);
|
|
4011
4031
|
const marketTrendSchema = {
|
|
4012
|
-
report_time:
|
|
4013
|
-
data_period_start:
|
|
4014
|
-
data_period_end:
|
|
4015
|
-
core_comment:
|
|
4016
|
-
important_indices:
|
|
4017
|
-
|
|
4018
|
-
name:
|
|
4019
|
-
code:
|
|
4020
|
-
open:
|
|
4021
|
-
trade:
|
|
4022
|
-
high:
|
|
4023
|
-
low:
|
|
4024
|
-
change:
|
|
4025
|
-
pct_chg:
|
|
4026
|
-
vol:
|
|
4027
|
-
amount:
|
|
4028
|
-
summary:
|
|
4032
|
+
report_time: z.z.string().describe("报告时间"),
|
|
4033
|
+
data_period_start: z.z.string().describe("数据开始时间"),
|
|
4034
|
+
data_period_end: z.z.string().describe("数据结束时间"),
|
|
4035
|
+
core_comment: z.z.string().describe("核心综述"),
|
|
4036
|
+
important_indices: z.z.array(
|
|
4037
|
+
z.z.object({
|
|
4038
|
+
name: z.z.string().describe("指数名称"),
|
|
4039
|
+
code: z.z.string().describe("指数代码"),
|
|
4040
|
+
open: z.z.number().describe("开盘价"),
|
|
4041
|
+
trade: z.z.number().describe("最新价"),
|
|
4042
|
+
high: z.z.number().describe("最高价"),
|
|
4043
|
+
low: z.z.number().describe("最低价"),
|
|
4044
|
+
change: z.z.number().describe("涨跌额"),
|
|
4045
|
+
pct_chg: z.z.number().describe("涨跌幅"),
|
|
4046
|
+
vol: z.z.number().describe("成交量"),
|
|
4047
|
+
amount: z.z.number().describe("成交额"),
|
|
4048
|
+
summary: z.z.string().describe("具体描述")
|
|
4029
4049
|
})
|
|
4030
4050
|
).describe("重要指数"),
|
|
4031
|
-
depth_description:
|
|
4032
|
-
description:
|
|
4033
|
-
bull_description:
|
|
4034
|
-
bear_description:
|
|
4035
|
-
summary:
|
|
4051
|
+
depth_description: z.z.object({
|
|
4052
|
+
description: z.z.string().describe("深入分析内容"),
|
|
4053
|
+
bull_description: z.z.string().describe("多头描述"),
|
|
4054
|
+
bear_description: z.z.string().describe("空头描述"),
|
|
4055
|
+
summary: z.z.string().describe("总结")
|
|
4036
4056
|
}).describe("深度描述"),
|
|
4037
|
-
sentiment:
|
|
4038
|
-
up_stock_count:
|
|
4039
|
-
down_stock_count:
|
|
4040
|
-
up_down_summary:
|
|
4041
|
-
limit_up_count:
|
|
4042
|
-
limit_down_count:
|
|
4043
|
-
up_down_limit_summary:
|
|
4044
|
-
summary:
|
|
4057
|
+
sentiment: z.z.object({
|
|
4058
|
+
up_stock_count: z.z.number().describe("上涨数量"),
|
|
4059
|
+
down_stock_count: z.z.number().describe("下跌数量"),
|
|
4060
|
+
up_down_summary: z.z.string().describe("涨跌总结"),
|
|
4061
|
+
limit_up_count: z.z.number().describe("涨停数量"),
|
|
4062
|
+
limit_down_count: z.z.number().describe("跌停数量"),
|
|
4063
|
+
up_down_limit_summary: z.z.string().describe("涨跌停总结"),
|
|
4064
|
+
summary: z.z.string().describe("整体总结")
|
|
4045
4065
|
}).describe("市场情绪"),
|
|
4046
|
-
capital_flows:
|
|
4047
|
-
northbound:
|
|
4048
|
-
northbound_summary:
|
|
4049
|
-
southbound:
|
|
4050
|
-
southbound_summary:
|
|
4051
|
-
inflow_board_rank:
|
|
4052
|
-
|
|
4053
|
-
name:
|
|
4054
|
-
money:
|
|
4066
|
+
capital_flows: z.z.object({
|
|
4067
|
+
northbound: z.z.number().describe("北向金额"),
|
|
4068
|
+
northbound_summary: z.z.string().describe("北向资金总结"),
|
|
4069
|
+
southbound: z.z.number().describe("南向金额"),
|
|
4070
|
+
southbound_summary: z.z.string().describe("南向资金总结"),
|
|
4071
|
+
inflow_board_rank: z.z.array(
|
|
4072
|
+
z.z.object({
|
|
4073
|
+
name: z.z.string().describe("板块名称"),
|
|
4074
|
+
money: z.z.number().describe("金额")
|
|
4055
4075
|
})
|
|
4056
4076
|
).describe("流入板块排名"),
|
|
4057
|
-
inflow_board_summary:
|
|
4058
|
-
outflow_board_rank:
|
|
4059
|
-
|
|
4060
|
-
name:
|
|
4061
|
-
money:
|
|
4077
|
+
inflow_board_summary: z.z.string().describe("流入板块总结"),
|
|
4078
|
+
outflow_board_rank: z.z.array(
|
|
4079
|
+
z.z.object({
|
|
4080
|
+
name: z.z.string().describe("板块名称"),
|
|
4081
|
+
money: z.z.number().describe("金额")
|
|
4062
4082
|
})
|
|
4063
4083
|
).describe("流出板块排名"),
|
|
4064
|
-
outflow_board_summary:
|
|
4084
|
+
outflow_board_summary: z.z.string().describe("流出板块总结")
|
|
4065
4085
|
}).describe("资金流向"),
|
|
4066
|
-
market_valuation:
|
|
4067
|
-
PE:
|
|
4068
|
-
PB:
|
|
4069
|
-
PE_PB_description:
|
|
4070
|
-
volatility:
|
|
4071
|
-
volatility_description:
|
|
4086
|
+
market_valuation: z.z.object({
|
|
4087
|
+
PE: z.z.number().describe("市盈率"),
|
|
4088
|
+
PB: z.z.number().describe("市净率"),
|
|
4089
|
+
PE_PB_description: z.z.string().describe("市盈率/市净率整体描述"),
|
|
4090
|
+
volatility: z.z.number().describe("波动率"),
|
|
4091
|
+
volatility_description: z.z.string().describe("波动率描述")
|
|
4072
4092
|
}).describe("市场估值"),
|
|
4073
|
-
periods_analyze:
|
|
4074
|
-
daily_trend_summary:
|
|
4075
|
-
weekly_trend_summary:
|
|
4076
|
-
monthly_trend_summary:
|
|
4077
|
-
support:
|
|
4078
|
-
support_description:
|
|
4079
|
-
resistance:
|
|
4080
|
-
resistance_description:
|
|
4081
|
-
momentum_summary:
|
|
4082
|
-
energy_summary:
|
|
4083
|
-
volatility_summary:
|
|
4084
|
-
kline_daily_file:
|
|
4093
|
+
periods_analyze: z.z.object({
|
|
4094
|
+
daily_trend_summary: z.z.string().describe("日线趋势总结"),
|
|
4095
|
+
weekly_trend_summary: z.z.string().describe("周线趋势总结"),
|
|
4096
|
+
monthly_trend_summary: z.z.string().describe("月线趋势总结"),
|
|
4097
|
+
support: z.z.number().describe("支撑位"),
|
|
4098
|
+
support_description: z.z.string().describe("支撑位描述"),
|
|
4099
|
+
resistance: z.z.number().describe("压力位"),
|
|
4100
|
+
resistance_description: z.z.string().describe("压力位描述"),
|
|
4101
|
+
momentum_summary: z.z.string().describe("动能总结"),
|
|
4102
|
+
energy_summary: z.z.string().describe("能量总结"),
|
|
4103
|
+
volatility_summary: z.z.string().describe("波动性总结"),
|
|
4104
|
+
kline_daily_file: z.z.string().describe("k线数据存储的地址,**这很重要**:不要workspace的地址")
|
|
4085
4105
|
}).describe("周期分析"),
|
|
4086
|
-
industries_info:
|
|
4087
|
-
industries_rank:
|
|
4088
|
-
|
|
4089
|
-
name:
|
|
4090
|
-
pct_chg:
|
|
4106
|
+
industries_info: z.z.object({
|
|
4107
|
+
industries_rank: z.z.array(
|
|
4108
|
+
z.z.object({
|
|
4109
|
+
name: z.z.string().describe("行业名称"),
|
|
4110
|
+
pct_chg: z.z.number().describe("涨跌幅")
|
|
4091
4111
|
})
|
|
4092
4112
|
).describe("行业排名"),
|
|
4093
|
-
strong_industries:
|
|
4094
|
-
classification_summary:
|
|
4095
|
-
|
|
4096
|
-
industries:
|
|
4097
|
-
summary:
|
|
4113
|
+
strong_industries: z.z.object({
|
|
4114
|
+
classification_summary: z.z.array(
|
|
4115
|
+
z.z.object({
|
|
4116
|
+
industries: z.z.string().describe("行业名词及涨跌幅"),
|
|
4117
|
+
summary: z.z.string().describe("总结")
|
|
4098
4118
|
})
|
|
4099
4119
|
).describe("强势行业分类总结")
|
|
4100
4120
|
}).describe("强势行业"),
|
|
4101
|
-
weak_industries:
|
|
4102
|
-
classification_summary:
|
|
4103
|
-
|
|
4104
|
-
industries:
|
|
4105
|
-
summary:
|
|
4121
|
+
weak_industries: z.z.object({
|
|
4122
|
+
classification_summary: z.z.array(
|
|
4123
|
+
z.z.object({
|
|
4124
|
+
industries: z.z.string().describe("行业名词及涨跌幅"),
|
|
4125
|
+
summary: z.z.string().describe("总结")
|
|
4106
4126
|
})
|
|
4107
4127
|
).describe("弱势行业分类总结")
|
|
4108
4128
|
}).describe("弱势行业"),
|
|
4109
|
-
main_theme:
|
|
4110
|
-
growth_VS_value:
|
|
4111
|
-
large_cap_VS_small_cap:
|
|
4129
|
+
main_theme: z.z.string().describe("主线逻辑描述"),
|
|
4130
|
+
growth_VS_value: z.z.string().describe("成长vs价值"),
|
|
4131
|
+
large_cap_VS_small_cap: z.z.string().describe("大盘vs小盘")
|
|
4112
4132
|
}).describe("行业信息"),
|
|
4113
|
-
impact_factor:
|
|
4114
|
-
|
|
4115
|
-
type:
|
|
4116
|
-
summary:
|
|
4117
|
-
strength:
|
|
4118
|
-
direction:
|
|
4133
|
+
impact_factor: z.z.array(
|
|
4134
|
+
z.z.object({
|
|
4135
|
+
type: z.z.string().describe("类型|宏观|政策"),
|
|
4136
|
+
summary: z.z.string().describe("描述"),
|
|
4137
|
+
strength: z.z.string().describe("强度"),
|
|
4138
|
+
direction: z.z.string().describe("方向")
|
|
4119
4139
|
})
|
|
4120
4140
|
).describe("影响因素"),
|
|
4121
|
-
comprehensive_assessment:
|
|
4122
|
-
macro:
|
|
4123
|
-
external:
|
|
4124
|
-
summary:
|
|
4141
|
+
comprehensive_assessment: z.z.object({
|
|
4142
|
+
macro: z.z.string().describe("宏观评估"),
|
|
4143
|
+
external: z.z.string().describe("外部评估"),
|
|
4144
|
+
summary: z.z.string().describe("总结")
|
|
4125
4145
|
}).describe("综合评估"),
|
|
4126
|
-
risk_point:
|
|
4127
|
-
|
|
4128
|
-
risk_category:
|
|
4129
|
-
except_event:
|
|
4130
|
-
summary:
|
|
4146
|
+
risk_point: z.z.array(
|
|
4147
|
+
z.z.object({
|
|
4148
|
+
risk_category: z.z.string().describe("风险类别"),
|
|
4149
|
+
except_event: z.z.array(z.z.string()).describe("预期可能发生的事件"),
|
|
4150
|
+
summary: z.z.string().describe("发生概率和可能的影响总结")
|
|
4131
4151
|
})
|
|
4132
4152
|
).describe("风险点"),
|
|
4133
|
-
scenarios:
|
|
4134
|
-
negative:
|
|
4135
|
-
probability:
|
|
4136
|
-
prerequisites:
|
|
4137
|
-
signal:
|
|
4138
|
-
target:
|
|
4153
|
+
scenarios: z.z.object({
|
|
4154
|
+
negative: z.z.object({
|
|
4155
|
+
probability: z.z.string().describe("概率"),
|
|
4156
|
+
prerequisites: z.z.string().describe("发生的条件"),
|
|
4157
|
+
signal: z.z.string().describe("发生的信号"),
|
|
4158
|
+
target: z.z.string().describe("达成的目标")
|
|
4139
4159
|
}).describe("负向情景"),
|
|
4140
|
-
neutral:
|
|
4141
|
-
probability:
|
|
4142
|
-
prerequisites:
|
|
4143
|
-
signal:
|
|
4144
|
-
target:
|
|
4160
|
+
neutral: z.z.object({
|
|
4161
|
+
probability: z.z.string().describe("概率"),
|
|
4162
|
+
prerequisites: z.z.string().describe("发生的条件"),
|
|
4163
|
+
signal: z.z.string().describe("发生的信号"),
|
|
4164
|
+
target: z.z.string().describe("达成的目标")
|
|
4145
4165
|
}).describe("中性情景"),
|
|
4146
|
-
positive:
|
|
4147
|
-
probability:
|
|
4148
|
-
prerequisites:
|
|
4149
|
-
signal:
|
|
4150
|
-
target:
|
|
4166
|
+
positive: z.z.object({
|
|
4167
|
+
probability: z.z.string().describe("概率"),
|
|
4168
|
+
prerequisites: z.z.string().describe("发生的条件"),
|
|
4169
|
+
signal: z.z.string().describe("发生的信号"),
|
|
4170
|
+
target: z.z.string().describe("达成的目标")
|
|
4151
4171
|
}).describe("正向情景")
|
|
4152
4172
|
}).describe("情景分析"),
|
|
4153
|
-
investment_strategy:
|
|
4154
|
-
market_positioning:
|
|
4155
|
-
core_driving:
|
|
4156
|
-
summary:
|
|
4157
|
-
detail:
|
|
4173
|
+
investment_strategy: z.z.object({
|
|
4174
|
+
market_positioning: z.z.string().describe("当前市场定位"),
|
|
4175
|
+
core_driving: z.z.object({
|
|
4176
|
+
summary: z.z.string().describe("总结"),
|
|
4177
|
+
detail: z.z.array(z.z.string()).describe("驱动项详情")
|
|
4158
4178
|
}).describe("核心驱动")
|
|
4159
4179
|
}).describe("投资策略"),
|
|
4160
|
-
outlook:
|
|
4161
|
-
up_outlook:
|
|
4162
|
-
up_outlook_description:
|
|
4163
|
-
down_outlook:
|
|
4164
|
-
down_outlook_description:
|
|
4165
|
-
overall_comment:
|
|
4180
|
+
outlook: z.z.object({
|
|
4181
|
+
up_outlook: z.z.string().describe("上涨前景"),
|
|
4182
|
+
up_outlook_description: z.z.string().describe("上涨前景描述"),
|
|
4183
|
+
down_outlook: z.z.string().describe("下跌前景"),
|
|
4184
|
+
down_outlook_description: z.z.string().describe("下跌前景描述"),
|
|
4185
|
+
overall_comment: z.z.string().describe("总体判断")
|
|
4166
4186
|
}).describe("市场展望"),
|
|
4167
|
-
core_summary:
|
|
4168
|
-
strategy:
|
|
4169
|
-
investment_direction:
|
|
4170
|
-
underweight_board:
|
|
4171
|
-
investment_style:
|
|
4172
|
-
asset_allocation_rate:
|
|
4173
|
-
stock:
|
|
4174
|
-
cash:
|
|
4175
|
-
bond:
|
|
4187
|
+
core_summary: z.z.object({
|
|
4188
|
+
strategy: z.z.string().describe("建议策略"),
|
|
4189
|
+
investment_direction: z.z.string().describe("投资方向"),
|
|
4190
|
+
underweight_board: z.z.string().describe("回避板块"),
|
|
4191
|
+
investment_style: z.z.string().describe("投资风格"),
|
|
4192
|
+
asset_allocation_rate: z.z.object({
|
|
4193
|
+
stock: z.z.string().describe("股票占比"),
|
|
4194
|
+
cash: z.z.string().describe("现金占比"),
|
|
4195
|
+
bond: z.z.string().describe("债券占比")
|
|
4176
4196
|
}).describe("资产配置占比")
|
|
4177
4197
|
}).describe("核心总结")
|
|
4178
4198
|
};
|
|
4179
|
-
|
|
4199
|
+
z.z.object({
|
|
4180
4200
|
...marketTrendSchema,
|
|
4181
4201
|
periods_analyze: marketTrendSchema.periods_analyze.extend({
|
|
4182
4202
|
kline_daily: kline_daily$1
|
|
@@ -4189,6 +4209,13 @@ const tool$3 = {
|
|
|
4189
4209
|
};
|
|
4190
4210
|
const toolHandler$3 = async (args) => {
|
|
4191
4211
|
try {
|
|
4212
|
+
const result = z.object(marketTrendSchema).safeParse(args);
|
|
4213
|
+
if (!result.success) {
|
|
4214
|
+
throw new types_js.McpError(
|
|
4215
|
+
types_js.ErrorCode.InvalidParams,
|
|
4216
|
+
`Invalid parameters: ${result.error.message}`
|
|
4217
|
+
);
|
|
4218
|
+
}
|
|
4192
4219
|
logger.info(`start: ${(/* @__PURE__ */ new Date()).getTime()}`);
|
|
4193
4220
|
logger.info(args);
|
|
4194
4221
|
const kline_daily2 = await getJsonDataIfExists(
|
|
@@ -5268,85 +5295,85 @@ const renderEnd$2 = (data) => {
|
|
|
5268
5295
|
const seg = ReactDOMServer.renderToString(/* @__PURE__ */ jsxRuntime.jsx(End$2, { data }));
|
|
5269
5296
|
return renderFullHtml(seg);
|
|
5270
5297
|
};
|
|
5271
|
-
const pick_list =
|
|
5272
|
-
|
|
5273
|
-
stock_code:
|
|
5274
|
-
market:
|
|
5275
|
-
name:
|
|
5276
|
-
total_score:
|
|
5277
|
-
base_score:
|
|
5278
|
-
technology_score:
|
|
5279
|
-
trend_score:
|
|
5280
|
-
news_score:
|
|
5281
|
-
reason:
|
|
5282
|
-
vol:
|
|
5283
|
-
price:
|
|
5284
|
-
total:
|
|
5285
|
-
pct:
|
|
5298
|
+
const pick_list = z.z.array(
|
|
5299
|
+
z.z.object({
|
|
5300
|
+
stock_code: z.z.string(),
|
|
5301
|
+
market: z.z.string(),
|
|
5302
|
+
name: z.z.string(),
|
|
5303
|
+
total_score: z.z.number(),
|
|
5304
|
+
base_score: z.z.number(),
|
|
5305
|
+
technology_score: z.z.number(),
|
|
5306
|
+
trend_score: z.z.number(),
|
|
5307
|
+
news_score: z.z.number(),
|
|
5308
|
+
reason: z.z.string(),
|
|
5309
|
+
vol: z.z.number(),
|
|
5310
|
+
price: z.z.number(),
|
|
5311
|
+
total: z.z.number(),
|
|
5312
|
+
pct: z.z.number()
|
|
5286
5313
|
})
|
|
5287
5314
|
);
|
|
5288
|
-
const industry_list =
|
|
5289
|
-
|
|
5290
|
-
industry_name:
|
|
5291
|
-
industry_pct:
|
|
5315
|
+
const industry_list = z.z.array(
|
|
5316
|
+
z.z.object({
|
|
5317
|
+
industry_name: z.z.string(),
|
|
5318
|
+
industry_pct: z.z.number()
|
|
5292
5319
|
})
|
|
5293
5320
|
);
|
|
5294
5321
|
const portfolioSchema = {
|
|
5295
|
-
generation_time:
|
|
5296
|
-
data_period_start:
|
|
5297
|
-
data_period_end:
|
|
5298
|
-
expected_cash:
|
|
5299
|
-
fact_cash:
|
|
5322
|
+
generation_time: z.z.string().describe("生成时间"),
|
|
5323
|
+
data_period_start: z.z.string().describe("数据周期起始点"),
|
|
5324
|
+
data_period_end: z.z.string().describe("数据周期结束点}"),
|
|
5325
|
+
expected_cash: z.z.number().describe("预期投资金额"),
|
|
5326
|
+
fact_cash: z.z.number().describe("实际投资金额"),
|
|
5300
5327
|
pick_list,
|
|
5301
|
-
industry_review:
|
|
5328
|
+
industry_review: z.z.string().describe("行业分配点评"),
|
|
5302
5329
|
industry_list,
|
|
5303
|
-
backtest_period:
|
|
5304
|
-
base_index:
|
|
5305
|
-
backtest_cash:
|
|
5306
|
-
backtest_total_return:
|
|
5307
|
-
backtest_total_return_review:
|
|
5308
|
-
backtest_final_value:
|
|
5309
|
-
backtest_final_value_review:
|
|
5310
|
-
backtest_volatility:
|
|
5311
|
-
backtest_volatility_review:
|
|
5312
|
-
backtest_max_drawdown:
|
|
5313
|
-
backtest_max_drawdown_review:
|
|
5314
|
-
backtest_sharpe_ratio:
|
|
5315
|
-
backtest_sharpe_ratio_review:
|
|
5316
|
-
positive_return_months_review:
|
|
5317
|
-
negative_return_months_review:
|
|
5318
|
-
annualized_return:
|
|
5319
|
-
annualized_return_review:
|
|
5320
|
-
highest_month:
|
|
5321
|
-
highest_month_review:
|
|
5322
|
-
lowest_month:
|
|
5323
|
-
lowest_month_review:
|
|
5324
|
-
backtest_nav_per_share_daily_path:
|
|
5325
|
-
backtest_income_per_monthly_path:
|
|
5326
|
-
hold_review:
|
|
5327
|
-
summary:
|
|
5328
|
-
backtest_nav_per_share_review:
|
|
5329
|
-
investment_style:
|
|
5330
|
-
risk_level:
|
|
5330
|
+
backtest_period: z.z.string().describe("回测时间跨度"),
|
|
5331
|
+
base_index: z.z.string().describe("回测基准指数"),
|
|
5332
|
+
backtest_cash: z.z.number(),
|
|
5333
|
+
backtest_total_return: z.z.number(),
|
|
5334
|
+
backtest_total_return_review: z.z.string(),
|
|
5335
|
+
backtest_final_value: z.z.number(),
|
|
5336
|
+
backtest_final_value_review: z.z.string(),
|
|
5337
|
+
backtest_volatility: z.z.number(),
|
|
5338
|
+
backtest_volatility_review: z.z.string(),
|
|
5339
|
+
backtest_max_drawdown: z.z.number(),
|
|
5340
|
+
backtest_max_drawdown_review: z.z.string(),
|
|
5341
|
+
backtest_sharpe_ratio: z.z.number(),
|
|
5342
|
+
backtest_sharpe_ratio_review: z.z.string(),
|
|
5343
|
+
positive_return_months_review: z.z.string(),
|
|
5344
|
+
negative_return_months_review: z.z.string(),
|
|
5345
|
+
annualized_return: z.z.number(),
|
|
5346
|
+
annualized_return_review: z.z.string(),
|
|
5347
|
+
highest_month: z.z.number(),
|
|
5348
|
+
highest_month_review: z.z.string(),
|
|
5349
|
+
lowest_month: z.z.number(),
|
|
5350
|
+
lowest_month_review: z.z.string(),
|
|
5351
|
+
backtest_nav_per_share_daily_path: z.z.string().describe("每日净值存储的地址,**这很重要**"),
|
|
5352
|
+
backtest_income_per_monthly_path: z.z.string().describe("月收益存储的地址,**这很重要**"),
|
|
5353
|
+
hold_review: z.z.string(),
|
|
5354
|
+
summary: z.z.string(),
|
|
5355
|
+
backtest_nav_per_share_review: z.z.string(),
|
|
5356
|
+
investment_style: z.z.string(),
|
|
5357
|
+
risk_level: z.z.enum([
|
|
5331
5358
|
"保守型 / 防御型(Conservative / Defensive)",
|
|
5332
5359
|
"均衡 / 稳健型(Balanced / Moderate)",
|
|
5333
5360
|
"激进型 / 成长型(Aggressive / Growth)"
|
|
5334
5361
|
])
|
|
5335
5362
|
};
|
|
5336
|
-
|
|
5363
|
+
z.z.object({
|
|
5337
5364
|
...portfolioSchema,
|
|
5338
|
-
backtest_nav_per_share_daily:
|
|
5339
|
-
|
|
5340
|
-
time:
|
|
5341
|
-
portfolio:
|
|
5342
|
-
csi300:
|
|
5365
|
+
backtest_nav_per_share_daily: z.z.array(
|
|
5366
|
+
z.z.object({
|
|
5367
|
+
time: z.z.string(),
|
|
5368
|
+
portfolio: z.z.number(),
|
|
5369
|
+
csi300: z.z.number()
|
|
5343
5370
|
})
|
|
5344
5371
|
),
|
|
5345
|
-
backtest_income_per_monthly:
|
|
5346
|
-
|
|
5347
|
-
time:
|
|
5348
|
-
portfolio:
|
|
5349
|
-
csi300:
|
|
5372
|
+
backtest_income_per_monthly: z.z.array(
|
|
5373
|
+
z.z.object({
|
|
5374
|
+
time: z.z.string(),
|
|
5375
|
+
portfolio: z.z.number(),
|
|
5376
|
+
csi300: z.z.number()
|
|
5350
5377
|
})
|
|
5351
5378
|
)
|
|
5352
5379
|
});
|
|
@@ -5357,6 +5384,13 @@ const tool$2 = {
|
|
|
5357
5384
|
};
|
|
5358
5385
|
const toolHandler$2 = async (args) => {
|
|
5359
5386
|
try {
|
|
5387
|
+
const result = z.object(portfolioSchema).safeParse(args);
|
|
5388
|
+
if (!result.success) {
|
|
5389
|
+
throw new types_js.McpError(
|
|
5390
|
+
types_js.ErrorCode.InvalidParams,
|
|
5391
|
+
`Invalid parameters: ${result.error.message}`
|
|
5392
|
+
);
|
|
5393
|
+
}
|
|
5360
5394
|
logger.info(`start: ${(/* @__PURE__ */ new Date()).getTime()}`);
|
|
5361
5395
|
logger.info(args);
|
|
5362
5396
|
const backtest_nav_per_share_daily = await getJsonDataIfExists(
|
|
@@ -6235,93 +6269,93 @@ const renderEnd$1 = (data) => {
|
|
|
6235
6269
|
return renderFullHtml(seg);
|
|
6236
6270
|
};
|
|
6237
6271
|
const stockForecastSchema = {
|
|
6238
|
-
generation_time:
|
|
6239
|
-
data_period_start:
|
|
6240
|
-
data_period_end:
|
|
6241
|
-
code:
|
|
6242
|
-
market:
|
|
6243
|
-
name:
|
|
6244
|
-
trend_forecasting_review:
|
|
6245
|
-
history_data_path:
|
|
6246
|
-
predict_data_path:
|
|
6247
|
-
backtest_data_path:
|
|
6248
|
-
predict_7d_pct_chg:
|
|
6249
|
-
predict_7d_pct_chg_interpret:
|
|
6250
|
-
model_confidence_pct:
|
|
6251
|
-
model_confidence_pct_interpret:
|
|
6252
|
-
volatility_forecast_pct:
|
|
6253
|
-
volatility_forecast_pct_interpret:
|
|
6254
|
-
turning_point_signal_date:
|
|
6255
|
-
turning_point_signal_regime:
|
|
6256
|
-
turning_point_signal_interpret:
|
|
6257
|
-
buy_interval_left:
|
|
6258
|
-
buy_interval_right:
|
|
6259
|
-
buy_interval_confidence_pct:
|
|
6260
|
-
buy_interval_reason:
|
|
6261
|
-
buy_interval_reason_desc:
|
|
6262
|
-
hold_interval_left:
|
|
6263
|
-
hold_interval_right:
|
|
6264
|
-
hold_interval_confidence_pct:
|
|
6265
|
-
hold_interval_reason:
|
|
6266
|
-
hold_interval_reason_desc:
|
|
6267
|
-
sell_interval_left:
|
|
6268
|
-
sell_interval_right:
|
|
6269
|
-
sell_interval_confidence_pct:
|
|
6270
|
-
sell_interval_reason:
|
|
6271
|
-
sell_interval_reason_desc:
|
|
6272
|
-
backtest_review:
|
|
6273
|
-
short_term_accuracy:
|
|
6274
|
-
short_term_mae:
|
|
6275
|
-
short_term_review:
|
|
6276
|
-
middle_term_accuracy:
|
|
6277
|
-
middle_term_mae:
|
|
6278
|
-
middle_term_review:
|
|
6279
|
-
high_freq_accuracy:
|
|
6280
|
-
high_freq_mae:
|
|
6281
|
-
high_freq_review:
|
|
6282
|
-
bull_market_performance:
|
|
6283
|
-
bull_market_review:
|
|
6284
|
-
bear_market_performance:
|
|
6285
|
-
bear_market_review:
|
|
6286
|
-
env_adaptation_summary:
|
|
6287
|
-
risk:
|
|
6288
|
-
ada:
|
|
6289
|
-
ada_interpret:
|
|
6290
|
-
rmse:
|
|
6291
|
-
rmse_interpret:
|
|
6292
|
-
mae:
|
|
6293
|
-
mae_interpret:
|
|
6294
|
-
maximum_single_error:
|
|
6295
|
-
maximum_single_error_interpret:
|
|
6296
|
-
backtest_sample_size:
|
|
6297
|
-
backtest_sample_size_interpret:
|
|
6298
|
-
mpiw:
|
|
6299
|
-
mpiw_interpret:
|
|
6300
|
-
pic:
|
|
6301
|
-
pic_interpret:
|
|
6302
|
-
comprehensive_analysis_and_assessment:
|
|
6303
|
-
key_findings_and_conclusions:
|
|
6304
|
-
final_recommendations:
|
|
6305
|
-
data_path:
|
|
6306
|
-
};
|
|
6307
|
-
|
|
6272
|
+
generation_time: z.z.string().describe("生成时间"),
|
|
6273
|
+
data_period_start: z.z.string().describe("数据周期起始点"),
|
|
6274
|
+
data_period_end: z.z.string().describe("数据周期结束点}"),
|
|
6275
|
+
code: z.z.string().describe("股票代码"),
|
|
6276
|
+
market: z.z.string().describe("市场"),
|
|
6277
|
+
name: z.z.string().describe("上市公司名称"),
|
|
6278
|
+
trend_forecasting_review: z.z.string().describe("趋势预测综述"),
|
|
6279
|
+
history_data_path: z.z.string().optional().describe("历史数据路径"),
|
|
6280
|
+
predict_data_path: z.z.string().optional().describe("预测数据路径"),
|
|
6281
|
+
backtest_data_path: z.z.string().optional().describe("回测数据路径"),
|
|
6282
|
+
predict_7d_pct_chg: z.z.number().describe("未来7日预测涨跌幅"),
|
|
6283
|
+
predict_7d_pct_chg_interpret: z.z.string().describe("未来7日预测涨跌幅解读"),
|
|
6284
|
+
model_confidence_pct: z.z.number().describe("模型置信度"),
|
|
6285
|
+
model_confidence_pct_interpret: z.z.string().describe("模型置信度解读"),
|
|
6286
|
+
volatility_forecast_pct: z.z.number().describe("波动率预测"),
|
|
6287
|
+
volatility_forecast_pct_interpret: z.z.string().describe("波动率预测解读"),
|
|
6288
|
+
turning_point_signal_date: z.z.string().describe("拐点信号日期"),
|
|
6289
|
+
turning_point_signal_regime: z.z.string().describe("拐点信号市场制度"),
|
|
6290
|
+
turning_point_signal_interpret: z.z.string().describe("拐点信号解读"),
|
|
6291
|
+
buy_interval_left: z.z.number().describe("买入区间左端"),
|
|
6292
|
+
buy_interval_right: z.z.number().describe("买入区间右端"),
|
|
6293
|
+
buy_interval_confidence_pct: z.z.number().describe("买入区间置信度"),
|
|
6294
|
+
buy_interval_reason: z.z.string().describe("买入区间理由"),
|
|
6295
|
+
buy_interval_reason_desc: z.z.string().describe("买入区间描述"),
|
|
6296
|
+
hold_interval_left: z.z.number().describe("持有区间左端"),
|
|
6297
|
+
hold_interval_right: z.z.number().describe("持有区间右端"),
|
|
6298
|
+
hold_interval_confidence_pct: z.z.number().describe("持有区间置信度"),
|
|
6299
|
+
hold_interval_reason: z.z.string().describe("持有区间理由"),
|
|
6300
|
+
hold_interval_reason_desc: z.z.string().describe("持有区间描述"),
|
|
6301
|
+
sell_interval_left: z.z.number().describe("卖出区间左端"),
|
|
6302
|
+
sell_interval_right: z.z.number().describe("卖出区间右端"),
|
|
6303
|
+
sell_interval_confidence_pct: z.z.number().describe("卖出区间置信度"),
|
|
6304
|
+
sell_interval_reason: z.z.string().describe("卖出区间理由"),
|
|
6305
|
+
sell_interval_reason_desc: z.z.string().describe("卖出区间描述"),
|
|
6306
|
+
backtest_review: z.z.string().describe("回测表现综述"),
|
|
6307
|
+
short_term_accuracy: z.z.number().describe("短期预测准确度"),
|
|
6308
|
+
short_term_mae: z.z.number().describe("短期MAE"),
|
|
6309
|
+
short_term_review: z.z.string().describe("短期预测简述"),
|
|
6310
|
+
middle_term_accuracy: z.z.number().describe("中期预测准确度"),
|
|
6311
|
+
middle_term_mae: z.z.number().describe("中期MAE"),
|
|
6312
|
+
middle_term_review: z.z.string().describe("中期预测简述"),
|
|
6313
|
+
high_freq_accuracy: z.z.number().describe("高频预测准确度"),
|
|
6314
|
+
high_freq_mae: z.z.number().describe("高频MAE"),
|
|
6315
|
+
high_freq_review: z.z.string().describe("高频预测简述"),
|
|
6316
|
+
bull_market_performance: z.z.number().describe("牛市表现"),
|
|
6317
|
+
bull_market_review: z.z.string().describe("牛市期表现简述"),
|
|
6318
|
+
bear_market_performance: z.z.number().describe("熊市表现"),
|
|
6319
|
+
bear_market_review: z.z.string().describe("熊市期表现简述"),
|
|
6320
|
+
env_adaptation_summary: z.z.string().describe("环境适应性结论"),
|
|
6321
|
+
risk: z.z.string().describe("潜在风险与免责声明"),
|
|
6322
|
+
ada: z.z.number().describe("平均方向命中率"),
|
|
6323
|
+
ada_interpret: z.z.string().describe("平均方向命中率解读"),
|
|
6324
|
+
rmse: z.z.number().describe("均方根误差"),
|
|
6325
|
+
rmse_interpret: z.z.string().describe("均方根误差解读"),
|
|
6326
|
+
mae: z.z.number().describe("平均绝对误差"),
|
|
6327
|
+
mae_interpret: z.z.string().describe("平均绝对误差解读"),
|
|
6328
|
+
maximum_single_error: z.z.number().describe("最大单次误差"),
|
|
6329
|
+
maximum_single_error_interpret: z.z.string().describe("最大单次误差解读"),
|
|
6330
|
+
backtest_sample_size: z.z.number().describe("回测样本数量"),
|
|
6331
|
+
backtest_sample_size_interpret: z.z.string().describe("回测样本数量解读"),
|
|
6332
|
+
mpiw: z.z.number().describe("平均预测区间宽度"),
|
|
6333
|
+
mpiw_interpret: z.z.string().describe("平均预测区间宽度解读"),
|
|
6334
|
+
pic: z.z.number().describe("区间命中率"),
|
|
6335
|
+
pic_interpret: z.z.string().describe("区间命中率解读"),
|
|
6336
|
+
comprehensive_analysis_and_assessment: z.z.string().describe("综合研判"),
|
|
6337
|
+
key_findings_and_conclusions: z.z.string().describe("核心结论"),
|
|
6338
|
+
final_recommendations: z.z.string().describe("最终建议"),
|
|
6339
|
+
data_path: z.z.string().describe("数据存储的地址,**这很重要**:不要workspace的地址")
|
|
6340
|
+
};
|
|
6341
|
+
z.z.object({
|
|
6308
6342
|
...stockForecastSchema,
|
|
6309
|
-
history:
|
|
6310
|
-
|
|
6311
|
-
date:
|
|
6312
|
-
close_price:
|
|
6343
|
+
history: z.z.array(
|
|
6344
|
+
z.z.object({
|
|
6345
|
+
date: z.z.string().describe("日期"),
|
|
6346
|
+
close_price: z.z.number().describe("收盘价")
|
|
6313
6347
|
})
|
|
6314
6348
|
).describe("历史数据"),
|
|
6315
|
-
predict:
|
|
6316
|
-
|
|
6317
|
-
date:
|
|
6318
|
-
close_price:
|
|
6349
|
+
predict: z.z.array(
|
|
6350
|
+
z.z.object({
|
|
6351
|
+
date: z.z.string().describe("日期"),
|
|
6352
|
+
close_price: z.z.number().describe("收盘价")
|
|
6319
6353
|
})
|
|
6320
6354
|
).describe("预测数据"),
|
|
6321
|
-
backtest:
|
|
6322
|
-
|
|
6323
|
-
date:
|
|
6324
|
-
close_price:
|
|
6355
|
+
backtest: z.z.array(
|
|
6356
|
+
z.z.object({
|
|
6357
|
+
date: z.z.string().describe("日期"),
|
|
6358
|
+
close_price: z.z.number().describe("收盘价")
|
|
6325
6359
|
})
|
|
6326
6360
|
).describe("回测数据")
|
|
6327
6361
|
});
|
|
@@ -6332,6 +6366,13 @@ const tool$1 = {
|
|
|
6332
6366
|
};
|
|
6333
6367
|
const toolHandler$1 = async (args) => {
|
|
6334
6368
|
try {
|
|
6369
|
+
const result = z.z.object(stockForecastSchema).safeParse(args);
|
|
6370
|
+
if (!result.success) {
|
|
6371
|
+
throw new types_js.McpError(
|
|
6372
|
+
types_js.ErrorCode.InvalidParams,
|
|
6373
|
+
`Invalid parameters: ${result.error.message}`
|
|
6374
|
+
);
|
|
6375
|
+
}
|
|
6335
6376
|
logger.info(`start: ${(/* @__PURE__ */ new Date()).getTime()}`);
|
|
6336
6377
|
logger.info(args);
|
|
6337
6378
|
const data = await getJsonDataIfExists(args.data_path, {});
|
|
@@ -8889,122 +8930,122 @@ const generateTechIndicatorHtml = (data) => {
|
|
|
8889
8930
|
}
|
|
8890
8931
|
];
|
|
8891
8932
|
};
|
|
8892
|
-
const reportNotes =
|
|
8893
|
-
basic_info:
|
|
8894
|
-
trend_indicator_summary:
|
|
8895
|
-
momentum_indicator_summary:
|
|
8896
|
-
volatility_indicator_summary:
|
|
8897
|
-
volume_indicator_summary:
|
|
8898
|
-
overall_assessment:
|
|
8933
|
+
const reportNotes = z.z.object({
|
|
8934
|
+
basic_info: z.z.string().describe("该股票的基本情况,需要 llm 分析"),
|
|
8935
|
+
trend_indicator_summary: z.z.string().describe("根据趋势指标数据,需要 llm 提供综合结论"),
|
|
8936
|
+
momentum_indicator_summary: z.z.string().describe("根据动能指标数据,需要 llm 提供综合结论"),
|
|
8937
|
+
volatility_indicator_summary: z.z.string().describe("根据波动率指标,需要 llm 提供综合结论"),
|
|
8938
|
+
volume_indicator_summary: z.z.string().describe("根据量能分析指标,需要 llm 提供综合结论"),
|
|
8939
|
+
overall_assessment: z.z.string().describe("根据所有数据,需要 llm 提供整体评价")
|
|
8899
8940
|
});
|
|
8900
|
-
const kline_daily =
|
|
8901
|
-
|
|
8902
|
-
time:
|
|
8903
|
-
open:
|
|
8904
|
-
close:
|
|
8905
|
-
high:
|
|
8906
|
-
low:
|
|
8907
|
-
change:
|
|
8908
|
-
pct_chg:
|
|
8909
|
-
vol:
|
|
8910
|
-
amount:
|
|
8911
|
-
turn_over:
|
|
8912
|
-
obv_qfq:
|
|
8913
|
-
net_amount:
|
|
8914
|
-
buy_lg_amount:
|
|
8941
|
+
const kline_daily = z.z.array(
|
|
8942
|
+
z.z.object({
|
|
8943
|
+
time: z.z.string().describe("时间"),
|
|
8944
|
+
open: z.z.number().describe("开盘价"),
|
|
8945
|
+
close: z.z.number().describe("收盘价"),
|
|
8946
|
+
high: z.z.number().describe("最高价"),
|
|
8947
|
+
low: z.z.number().describe("最低价"),
|
|
8948
|
+
change: z.z.number().describe("涨跌额"),
|
|
8949
|
+
pct_chg: z.z.number().describe("涨跌幅"),
|
|
8950
|
+
vol: z.z.number().describe("成交量"),
|
|
8951
|
+
amount: z.z.number().describe("成交额"),
|
|
8952
|
+
turn_over: z.z.number().describe("换手率"),
|
|
8953
|
+
obv_qfq: z.z.number().describe("obv能量潮"),
|
|
8954
|
+
net_amount: z.z.number().describe("主力净流入"),
|
|
8955
|
+
buy_lg_amount: z.z.number().describe("大单净流入"),
|
|
8915
8956
|
// 均线
|
|
8916
|
-
ma5:
|
|
8917
|
-
ma10:
|
|
8918
|
-
ma20:
|
|
8919
|
-
ma60:
|
|
8920
|
-
ma250:
|
|
8957
|
+
ma5: z.z.number().describe("5日均线"),
|
|
8958
|
+
ma10: z.z.number().describe("10日均线"),
|
|
8959
|
+
ma20: z.z.number().describe("20日均线"),
|
|
8960
|
+
ma60: z.z.number().describe("60日均线"),
|
|
8961
|
+
ma250: z.z.number().describe("250日均线"),
|
|
8921
8962
|
// macd
|
|
8922
|
-
macd_dif:
|
|
8923
|
-
macd_dea:
|
|
8924
|
-
macd_histogram:
|
|
8963
|
+
macd_dif: z.z.number().describe("macd"),
|
|
8964
|
+
macd_dea: z.z.number().describe("macd"),
|
|
8965
|
+
macd_histogram: z.z.number().describe("macd 柱"),
|
|
8925
8966
|
// rsi
|
|
8926
|
-
rsi_6:
|
|
8927
|
-
rsi_12:
|
|
8928
|
-
rsi_24:
|
|
8967
|
+
rsi_6: z.z.number().describe("rsi6"),
|
|
8968
|
+
rsi_12: z.z.number().describe("rsi12"),
|
|
8969
|
+
rsi_24: z.z.number().describe("rsi24"),
|
|
8929
8970
|
// kdf
|
|
8930
|
-
kdj_k:
|
|
8931
|
-
kdj_d:
|
|
8932
|
-
kdj_j:
|
|
8971
|
+
kdj_k: z.z.number().describe("kdj_k"),
|
|
8972
|
+
kdj_d: z.z.number().describe("kdj_d"),
|
|
8973
|
+
kdj_j: z.z.number().describe("kdj_j"),
|
|
8933
8974
|
// atr
|
|
8934
|
-
atr14:
|
|
8975
|
+
atr14: z.z.number().describe("atr14"),
|
|
8935
8976
|
// boll
|
|
8936
|
-
boll_upper:
|
|
8937
|
-
boll_mid:
|
|
8938
|
-
boll_lower:
|
|
8977
|
+
boll_upper: z.z.number().describe("布林线上轨"),
|
|
8978
|
+
boll_mid: z.z.number().describe("布林线中轨"),
|
|
8979
|
+
boll_lower: z.z.number().describe("布林线下轨")
|
|
8939
8980
|
})
|
|
8940
8981
|
);
|
|
8941
|
-
const kline_indicator =
|
|
8942
|
-
open:
|
|
8943
|
-
high:
|
|
8944
|
-
swing:
|
|
8945
|
-
vol:
|
|
8946
|
-
pre_close:
|
|
8947
|
-
low:
|
|
8948
|
-
turn_over:
|
|
8949
|
-
amount:
|
|
8950
|
-
selling:
|
|
8951
|
-
buying:
|
|
8952
|
-
week52_high:
|
|
8953
|
-
week52_low:
|
|
8954
|
-
kline_summary:
|
|
8982
|
+
const kline_indicator = z.z.object({
|
|
8983
|
+
open: z.z.number().describe("开盘价"),
|
|
8984
|
+
high: z.z.number().describe("最高价"),
|
|
8985
|
+
swing: z.z.number().describe("振幅"),
|
|
8986
|
+
vol: z.z.number().describe("成交量"),
|
|
8987
|
+
pre_close: z.z.number().describe("昨收价"),
|
|
8988
|
+
low: z.z.number().describe("最低价"),
|
|
8989
|
+
turn_over: z.z.number().describe("换手率"),
|
|
8990
|
+
amount: z.z.number().describe("成交额"),
|
|
8991
|
+
selling: z.z.number().optional().describe("内盘"),
|
|
8992
|
+
buying: z.z.number().optional().describe("外盘"),
|
|
8993
|
+
week52_high: z.z.number().describe("52周高"),
|
|
8994
|
+
week52_low: z.z.number().describe("52周低"),
|
|
8995
|
+
kline_summary: z.z.string().describe("根据 kline 数据,需要 llm 总结")
|
|
8955
8996
|
});
|
|
8956
|
-
const trend_indicator =
|
|
8957
|
-
ma_summary:
|
|
8958
|
-
macd_summary:
|
|
8997
|
+
const trend_indicator = z.z.object({
|
|
8998
|
+
ma_summary: z.z.string().describe("根据ma数据,需要 llm 总结"),
|
|
8999
|
+
macd_summary: z.z.string().describe("根据 macd 数据,需要 llm 总结")
|
|
8959
9000
|
});
|
|
8960
|
-
const momentum_indicator =
|
|
8961
|
-
rsi_summary:
|
|
8962
|
-
kdj_summary:
|
|
8963
|
-
momentum_indicator_summary:
|
|
9001
|
+
const momentum_indicator = z.z.object({
|
|
9002
|
+
rsi_summary: z.z.string().describe("根据 rsi 数据,需要 llm 总结"),
|
|
9003
|
+
kdj_summary: z.z.string().describe("根据 kdj 数据,需要 llm 总结"),
|
|
9004
|
+
momentum_indicator_summary: z.z.string().describe("根据动能指标数据,需要 llm 提供综合结论")
|
|
8964
9005
|
});
|
|
8965
|
-
const volatility_indicator =
|
|
8966
|
-
hv30:
|
|
8967
|
-
bb_summary:
|
|
8968
|
-
risk_tips:
|
|
8969
|
-
volatility_indicator_summary:
|
|
9006
|
+
const volatility_indicator = z.z.object({
|
|
9007
|
+
hv30: z.z.number().describe("30日历史波动率"),
|
|
9008
|
+
bb_summary: z.z.string().describe("根据布林带数据, 需要 llm 总结"),
|
|
9009
|
+
risk_tips: z.z.string().describe("根据波动率指标,需要 llm 提供风险提示"),
|
|
9010
|
+
volatility_indicator_summary: z.z.string().describe("根据波动率指标,需要 llm 提供综合结论")
|
|
8970
9011
|
});
|
|
8971
|
-
const volume_indicator =
|
|
8972
|
-
volume_ratio:
|
|
8973
|
-
volume_trend:
|
|
8974
|
-
retail_sentiment:
|
|
8975
|
-
volume_indicator_summary:
|
|
9012
|
+
const volume_indicator = z.z.object({
|
|
9013
|
+
volume_ratio: z.z.number().optional().describe("量比"),
|
|
9014
|
+
volume_trend: z.z.string().describe("根据相关成交量数据,需要 llm 提供成交量趋势"),
|
|
9015
|
+
retail_sentiment: z.z.string().describe("散户情绪"),
|
|
9016
|
+
volume_indicator_summary: z.z.string().describe("根据量能分析指标,需要 llm 提供综合结论")
|
|
8976
9017
|
});
|
|
8977
|
-
const pattern_analysis =
|
|
8978
|
-
short_term:
|
|
8979
|
-
pattern_desc:
|
|
8980
|
-
short_resistance:
|
|
8981
|
-
short_support:
|
|
9018
|
+
const pattern_analysis = z.z.object({
|
|
9019
|
+
short_term: z.z.object({
|
|
9020
|
+
pattern_desc: z.z.string().describe("短期形态简述,需要 llm 提供"),
|
|
9021
|
+
short_resistance: z.z.number().describe("短期压力位"),
|
|
9022
|
+
short_support: z.z.number().describe("短期支撑位")
|
|
8982
9023
|
}),
|
|
8983
|
-
intermediate_term:
|
|
8984
|
-
pattern_desc:
|
|
8985
|
-
resistance:
|
|
8986
|
-
support:
|
|
9024
|
+
intermediate_term: z.z.object({
|
|
9025
|
+
pattern_desc: z.z.string().describe("中期形态简述,需要 llm 提供"),
|
|
9026
|
+
resistance: z.z.number().describe("中期压力位"),
|
|
9027
|
+
support: z.z.number().describe("中期支撑位")
|
|
8987
9028
|
}),
|
|
8988
|
-
long_term:
|
|
8989
|
-
pattern_desc:
|
|
8990
|
-
resistance:
|
|
8991
|
-
support:
|
|
9029
|
+
long_term: z.z.object({
|
|
9030
|
+
pattern_desc: z.z.string().describe("长期形态简述,需要 llm 提供"),
|
|
9031
|
+
resistance: z.z.number().describe("长期压力位"),
|
|
9032
|
+
support: z.z.number().describe("长期支撑位")
|
|
8992
9033
|
}),
|
|
8993
|
-
pattern_analysis_summary:
|
|
9034
|
+
pattern_analysis_summary: z.string().describe("需要 llm 提供综合形态分析")
|
|
8994
9035
|
});
|
|
8995
9036
|
const techIndicatorSchema = {
|
|
8996
|
-
title:
|
|
8997
|
-
generation_time:
|
|
8998
|
-
logo:
|
|
8999
|
-
code:
|
|
9000
|
-
market:
|
|
9001
|
-
name:
|
|
9002
|
-
industry:
|
|
9003
|
-
curr_price:
|
|
9004
|
-
curr_change:
|
|
9005
|
-
curr_pct_chg:
|
|
9006
|
-
data_period_start:
|
|
9007
|
-
data_period_end:
|
|
9037
|
+
title: z.z.string().describe("报告名称"),
|
|
9038
|
+
generation_time: z.z.string().describe("生成时间"),
|
|
9039
|
+
logo: z.z.string().optional().describe("logo"),
|
|
9040
|
+
code: z.z.string().describe("股票代码"),
|
|
9041
|
+
market: z.z.string().describe("市场"),
|
|
9042
|
+
name: z.z.string().describe("上市公司名称"),
|
|
9043
|
+
industry: z.z.string().describe("行业"),
|
|
9044
|
+
curr_price: z.z.number().describe("当前股价"),
|
|
9045
|
+
curr_change: z.z.number().describe("涨跌额"),
|
|
9046
|
+
curr_pct_chg: z.z.number().optional().describe("涨跌幅度"),
|
|
9047
|
+
data_period_start: z.z.string().describe("数据周期起始点"),
|
|
9048
|
+
data_period_end: z.z.string().describe("数据周期结束点}"),
|
|
9008
9049
|
report_notes: reportNotes,
|
|
9009
9050
|
kline_indicator,
|
|
9010
9051
|
trend_indicator,
|
|
@@ -9012,9 +9053,9 @@ const techIndicatorSchema = {
|
|
|
9012
9053
|
volatility_indicator,
|
|
9013
9054
|
volume_indicator,
|
|
9014
9055
|
pattern_analysis,
|
|
9015
|
-
kline_data_path:
|
|
9056
|
+
kline_data_path: z.z.string().describe("k线数据存储的地址,**这很重要**:不要workspace的地址")
|
|
9016
9057
|
};
|
|
9017
|
-
|
|
9058
|
+
z.z.object({
|
|
9018
9059
|
...techIndicatorSchema,
|
|
9019
9060
|
kline_daily
|
|
9020
9061
|
});
|
|
@@ -9025,6 +9066,13 @@ const tool = {
|
|
|
9025
9066
|
};
|
|
9026
9067
|
const toolHandler = async (args) => {
|
|
9027
9068
|
try {
|
|
9069
|
+
const result = z.object(techIndicatorSchema).safeParse(args);
|
|
9070
|
+
if (!result.success) {
|
|
9071
|
+
throw new types_js.McpError(
|
|
9072
|
+
types_js.ErrorCode.InvalidParams,
|
|
9073
|
+
`Invalid parameters: ${result.error.message}`
|
|
9074
|
+
);
|
|
9075
|
+
}
|
|
9028
9076
|
logger.info(`start: ${(/* @__PURE__ */ new Date()).getTime()}`);
|
|
9029
9077
|
logger.info(args);
|
|
9030
9078
|
const kline_daily2 = await getJsonDataIfExists(args.kline_data_path, []);
|