@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.
Files changed (2) hide show
  1. package/dist/index.cjs +640 -592
  2. 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.56";
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 = zod.z.array(
1330
- zod.z.object({
1331
- title: zod.z.string().describe("新闻标题"),
1332
- link: zod.z.string().describe("新闻链接"),
1333
- content: zod.z.string().describe("新闻内容,大模型访问链接获得"),
1334
- summary: zod.z.string().describe("新闻总结,大模型总结"),
1335
- timestamp: zod.z.number().describe("时间戳"),
1336
- source: zod.z.string().describe("新闻源"),
1337
- tag: zod.z.array(zod.z.string()).describe("新闻标签"),
1338
- insight: zod.z.string().describe("详细解读。大模型总结")
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: zod.z.enum(["market", "industry", "stock"]),
1343
- report_time: zod.z.string().describe("报告时间"),
1344
- data_period_start: zod.z.string().describe("数据开始时间"),
1345
- data_period_end: zod.z.string().describe("数据结束时间}"),
1346
- overview: zod.z.string().describe("总体描述,大模型总结"),
1347
- opportunities_and_risks: zod.z.string().describe("机会与风险,大模型总结"),
1348
- focus_points: zod.z.string().describe("关注点,大模型总结"),
1349
- risk_factors: zod.z.string().describe("风险点,大模型总结"),
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: zod.z.object({
1352
- summary: zod.z.string().describe("总结"),
1353
- news_count_12h: zod.z.number(),
1354
- news_count_24h: zod.z.number(),
1355
- total_news_count: zod.z.number(),
1356
- keywords: zod.z.array(zod.z.string()).describe("关键字"),
1357
- heat_index: zod.z.number(),
1358
- heat_comment: zod.z.string().describe("热度描述"),
1359
- social_media_summary: zod.z.string().describe("社交数据总结"),
1360
- sentiment_distribution: zod.z.object({
1361
- negative_pct: zod.z.object({
1362
- value: zod.z.number(),
1363
- comment: zod.z.string().describe("描述")
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: zod.z.object({
1366
- value: zod.z.number(),
1367
- comment: zod.z.string().describe("描述")
1365
+ neutral_pct: z.z.object({
1366
+ value: z.z.number(),
1367
+ comment: z.z.string().describe("描述")
1368
1368
  }),
1369
- positive_pct: zod.z.object({
1370
- value: zod.z.number(),
1371
- comment: zod.z.string().describe("描述")
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: zod.z.object({
1376
- value: zod.z.number(),
1377
- comment: zod.z.string()
1375
+ market_sentiment: z.z.object({
1376
+ value: z.z.number(),
1377
+ comment: z.z.string()
1378
1378
  }).optional(),
1379
- stock_sentiment: zod.z.object({
1380
- value: zod.z.number(),
1381
- comment: zod.z.string()
1379
+ stock_sentiment: z.z.object({
1380
+ value: z.z.number(),
1381
+ comment: z.z.string()
1382
1382
  }).optional(),
1383
- industry_sentiment: zod.z.object({
1384
- value: zod.z.number(),
1385
- comment: zod.z.string()
1383
+ industry_sentiment: z.z.object({
1384
+ value: z.z.number(),
1385
+ comment: z.z.string()
1386
1386
  }).optional(),
1387
- market: zod.z.object({
1388
- industry_impact: zod.z.object({
1389
- bullish_industries: zod.z.array(
1390
- zod.z.object({
1391
- sector: zod.z.string(),
1392
- score: zod.z.number(),
1393
- reason: zod.z.string()
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: zod.z.array(
1397
- zod.z.object({
1398
- sector: zod.z.string(),
1399
- score: zod.z.number(),
1400
- reason: zod.z.string()
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: zod.z.object({
1405
- a_share: zod.z.object({
1406
- impact: zod.z.string(),
1407
- performance: zod.z.string(),
1408
- reason: zod.z.string()
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: zod.z.object({
1411
- impact: zod.z.string(),
1412
- performance: zod.z.string(),
1413
- reason: zod.z.string()
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: zod.z.object({
1416
- impact: zod.z.string(),
1417
- performance: zod.z.string(),
1418
- reason: zod.z.string()
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: zod.z.object({
1423
- subsector_impact: zod.z.object({
1424
- bullish_subsectors: zod.z.array(
1425
- zod.z.object({
1426
- subsector: zod.z.string(),
1427
- score: zod.z.number(),
1428
- reason: zod.z.string()
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: zod.z.array(
1432
- zod.z.object({
1433
- subsector: zod.z.string(),
1434
- score: zod.z.number(),
1435
- reason: zod.z.string()
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: zod.z.object({
1440
- a_share: zod.z.object({
1441
- impact: zod.z.string(),
1442
- industry_performance: zod.z.string(),
1443
- reason: zod.z.string()
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: zod.z.object({
1446
- impact: zod.z.string(),
1447
- industry_performance: zod.z.string(),
1448
- reason: zod.z.string()
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: zod.z.object({
1451
- impact: zod.z.string(),
1452
- industry_performance: zod.z.string(),
1453
- reason: zod.z.string()
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: zod.z.array(
1458
- zod.z.object({
1459
- message: zod.z.string(),
1460
- weight: zod.z.string(),
1461
- comment: zod.z.string()
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: zod.z.object({
1465
- northbound_comment: zod.z.string(),
1466
- southbound_comment: zod.z.string(),
1467
- industry_flow_comment: zod.z.string()
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: zod.z.object({
1470
- historical_analogy: zod.z.string(),
1471
- domestic_expectation: zod.z.string(),
1472
- overseas_expectation: zod.z.string(),
1473
- global_market_linkage: zod.z.object({
1474
- usa: zod.z.string(),
1475
- europe: zod.z.string(),
1476
- asia: zod.z.string()
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: zod.z.object({
1480
- general_comment: zod.z.string(),
1481
- policy_comment: zod.z.string(),
1482
- fundamental_comment: zod.z.string(),
1483
- strategy_suggestion: zod.z.string()
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: zod.z.object({
1486
- macro_risk: zod.z.string(),
1487
- policy_risk: zod.z.string(),
1488
- inflation_risk: zod.z.string()
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
- zod.z.object({
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(zod.z.object(schema), {
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
- title: zod.z.string().describe("报告名称"),
2750
- generation_time: zod.z.string().describe("生成时间"),
2751
- logo: zod.z.string().optional().describe("logo"),
2752
- code: zod.z.string().describe("股票代码"),
2753
- market: zod.z.string().describe("市场"),
2754
- name: zod.z.string().describe("上市公司名称"),
2755
- data_period_start: zod.z.string().describe("数据周期起始点"),
2756
- data_period_end: zod.z.string().describe("数据周期结束点}"),
2757
- industry: zod.z.string().describe("行业"),
2758
- curr_price: zod.z.number().describe("当前股价"),
2759
- curr_change: zod.z.number().describe("涨跌额"),
2760
- curr_pct_chg: zod.z.number().optional().describe("涨跌幅度"),
2761
- core_thesis: zod.z.string().describe("核心观点"),
2762
- core_thesis_desc: zod.z.string().describe("核心观点阐述"),
2763
- roe: zod.z.number().describe("ROE指标"),
2764
- roe_takeaway: zod.z.string().describe("roe 指标解读核心要点"),
2765
- roe_takeaway_desc: zod.z.string().describe("roe 指标解读核心要点阐述"),
2766
- gp_margin: zod.z.number().describe("毛利率指标"),
2767
- gp_margin_takeaway: zod.z.string().describe("毛利率 指标解读核心要点"),
2768
- gp_margin_takeaway_desc: zod.z.string().describe("毛利率 指标解读核心要点阐述"),
2769
- yoy_ni: zod.z.number().describe("增长率指标"),
2770
- yoy_ni_takeaway: zod.z.string().describe("增长率 指标解读核心要点"),
2771
- yoy_ni_takeaway_desc: zod.z.string().describe("增长率 指标解读核心要点阐述"),
2772
- pe: zod.z.number().describe("市盈率指标"),
2773
- pe_takeaway: zod.z.string().describe("市盈率 指标解读核心要点"),
2774
- pe_takeaway_desc: zod.z.string().describe("市盈率 指标解读核心要点阐述"),
2775
- cfo: zod.z.number().describe("经营性现金净流量"),
2776
- cfo_takeaway: zod.z.string().describe("经营性现金净流量 指标解读核心要点"),
2777
- cfo_takeaway_desc: zod.z.string().describe("经营性现金净流量 指标解读核心要点阐述"),
2778
- main_risks: zod.z.string().describe("主要风险"),
2779
- primary_stock_holder: zod.z.string().describe("主要股东"),
2780
- free_float_characteristics: zod.z.string().describe("流通盘特征"),
2781
- stock_holder_analyze: zod.z.string().describe("前十大股东分析"),
2782
- stock_holder_list: zod.z.array(
2783
- zod.z.object({
2784
- name: zod.z.string(),
2785
- type: zod.z.string(),
2786
- shares: zod.z.number(),
2787
- shares_ratio: zod.z.number(),
2788
- change: zod.z.union([zod.z.string(), zod.z.number()]),
2789
- change_ratio: zod.z.string()
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: zod.z.array(
2793
- zod.z.object({
2794
- date: zod.z.string(),
2795
- roe: zod.z.number(),
2796
- gp_margin: zod.z.number(),
2797
- revenue: zod.z.number()
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
- roe_review: zod.z.string(),
2801
- gp_margin_review: zod.z.string(),
2802
- revenue_review: zod.z.string(),
2803
- cagr_3y: zod.z.number().describe("三年复合增长率"),
2804
- balance_review: zod.z.string().describe("财务结构点评"),
2805
- liability_to_asset: zod.z.number().describe("资产负债率"),
2806
- current_ratio: zod.z.number().describe("流动比率"),
2807
- cash_ratio: zod.z.number().describe("现金比率"),
2808
- cash_flow_ratio: zod.z.number().describe("现金流点评"),
2809
- cfo_to_np: zod.z.number().describe("经营现金流/净利润"),
2810
- pe_list: zod.z.array(
2811
- zod.z.object({
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 = zod.z.array(
4000
- zod.z.object({
4001
- time: zod.z.string().describe("时间"),
4002
- open: zod.z.number().describe("开盘价"),
4003
- close: zod.z.number().describe("收盘价"),
4004
- high: zod.z.number().describe("最高价"),
4005
- low: zod.z.number().describe("最低价"),
4006
- pct_chg: zod.z.number().describe("涨跌幅"),
4007
- vol: zod.z.number().describe("成交量"),
4008
- amount: zod.z.number().describe("成交额")
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: zod.z.string().describe("报告时间"),
4013
- data_period_start: zod.z.string().describe("数据开始时间"),
4014
- data_period_end: zod.z.string().describe("数据结束时间"),
4015
- core_comment: zod.z.string().describe("核心综述"),
4016
- important_indices: zod.z.array(
4017
- zod.z.object({
4018
- name: zod.z.string().describe("指数名称"),
4019
- code: zod.z.string().describe("指数代码"),
4020
- open: zod.z.number().describe("开盘价"),
4021
- trade: zod.z.number().describe("最新价"),
4022
- high: zod.z.number().describe("最高价"),
4023
- low: zod.z.number().describe("最低价"),
4024
- change: zod.z.number().describe("涨跌额"),
4025
- pct_chg: zod.z.number().describe("涨跌幅"),
4026
- vol: zod.z.number().describe("成交量"),
4027
- amount: zod.z.number().describe("成交额"),
4028
- summary: zod.z.string().describe("具体描述")
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: zod.z.object({
4032
- description: zod.z.string().describe("深入分析内容"),
4033
- bull_description: zod.z.string().describe("多头描述"),
4034
- bear_description: zod.z.string().describe("空头描述"),
4035
- summary: zod.z.string().describe("总结")
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: zod.z.object({
4038
- up_stock_count: zod.z.number().describe("上涨数量"),
4039
- down_stock_count: zod.z.number().describe("下跌数量"),
4040
- up_down_summary: zod.z.string().describe("涨跌总结"),
4041
- limit_up_count: zod.z.number().describe("涨停数量"),
4042
- limit_down_count: zod.z.number().describe("跌停数量"),
4043
- up_down_limit_summary: zod.z.string().describe("涨跌停总结"),
4044
- summary: zod.z.string().describe("整体总结")
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: zod.z.object({
4047
- northbound: zod.z.number().describe("北向金额"),
4048
- northbound_summary: zod.z.string().describe("北向资金总结"),
4049
- southbound: zod.z.number().describe("南向金额"),
4050
- southbound_summary: zod.z.string().describe("南向资金总结"),
4051
- inflow_board_rank: zod.z.array(
4052
- zod.z.object({
4053
- name: zod.z.string().describe("板块名称"),
4054
- money: zod.z.number().describe("金额")
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: zod.z.string().describe("流入板块总结"),
4058
- outflow_board_rank: zod.z.array(
4059
- zod.z.object({
4060
- name: zod.z.string().describe("板块名称"),
4061
- money: zod.z.number().describe("金额")
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: zod.z.string().describe("流出板块总结")
4084
+ outflow_board_summary: z.z.string().describe("流出板块总结")
4065
4085
  }).describe("资金流向"),
4066
- market_valuation: zod.z.object({
4067
- PE: zod.z.number().describe("市盈率"),
4068
- PB: zod.z.number().describe("市净率"),
4069
- PE_PB_description: zod.z.string().describe("市盈率/市净率整体描述"),
4070
- volatility: zod.z.number().describe("波动率"),
4071
- volatility_description: zod.z.string().describe("波动率描述")
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: zod.z.object({
4074
- daily_trend_summary: zod.z.string().describe("日线趋势总结"),
4075
- weekly_trend_summary: zod.z.string().describe("周线趋势总结"),
4076
- monthly_trend_summary: zod.z.string().describe("月线趋势总结"),
4077
- support: zod.z.number().describe("支撑位"),
4078
- support_description: zod.z.string().describe("支撑位描述"),
4079
- resistance: zod.z.number().describe("压力位"),
4080
- resistance_description: zod.z.string().describe("压力位描述"),
4081
- momentum_summary: zod.z.string().describe("动能总结"),
4082
- energy_summary: zod.z.string().describe("能量总结"),
4083
- volatility_summary: zod.z.string().describe("波动性总结"),
4084
- kline_daily_file: zod.z.string().describe("k线数据存储的地址,**这很重要**:不要workspace的地址")
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: zod.z.object({
4087
- industries_rank: zod.z.array(
4088
- zod.z.object({
4089
- name: zod.z.string().describe("行业名称"),
4090
- pct_chg: zod.z.number().describe("涨跌幅")
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: zod.z.object({
4094
- classification_summary: zod.z.array(
4095
- zod.z.object({
4096
- industries: zod.z.string().describe("行业名词及涨跌幅"),
4097
- summary: zod.z.string().describe("总结")
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: zod.z.object({
4102
- classification_summary: zod.z.array(
4103
- zod.z.object({
4104
- industries: zod.z.string().describe("行业名词及涨跌幅"),
4105
- summary: zod.z.string().describe("总结")
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: zod.z.string().describe("主线逻辑描述"),
4110
- growth_VS_value: zod.z.string().describe("成长vs价值"),
4111
- large_cap_VS_small_cap: zod.z.string().describe("大盘vs小盘")
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: zod.z.array(
4114
- zod.z.object({
4115
- type: zod.z.string().describe("类型|宏观|政策"),
4116
- summary: zod.z.string().describe("描述"),
4117
- strength: zod.z.string().describe("强度"),
4118
- direction: zod.z.string().describe("方向")
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: zod.z.object({
4122
- macro: zod.z.string().describe("宏观评估"),
4123
- external: zod.z.string().describe("外部评估"),
4124
- summary: zod.z.string().describe("总结")
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: zod.z.array(
4127
- zod.z.object({
4128
- risk_category: zod.z.string().describe("风险类别"),
4129
- except_event: zod.z.array(zod.z.string()).describe("预期可能发生的事件"),
4130
- summary: zod.z.string().describe("发生概率和可能的影响总结")
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: zod.z.object({
4134
- negative: zod.z.object({
4135
- probability: zod.z.string().describe("概率"),
4136
- prerequisites: zod.z.string().describe("发生的条件"),
4137
- signal: zod.z.string().describe("发生的信号"),
4138
- target: zod.z.string().describe("达成的目标")
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: zod.z.object({
4141
- probability: zod.z.string().describe("概率"),
4142
- prerequisites: zod.z.string().describe("发生的条件"),
4143
- signal: zod.z.string().describe("发生的信号"),
4144
- target: zod.z.string().describe("达成的目标")
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: zod.z.object({
4147
- probability: zod.z.string().describe("概率"),
4148
- prerequisites: zod.z.string().describe("发生的条件"),
4149
- signal: zod.z.string().describe("发生的信号"),
4150
- target: zod.z.string().describe("达成的目标")
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: zod.z.object({
4154
- market_positioning: zod.z.string().describe("当前市场定位"),
4155
- core_driving: zod.z.object({
4156
- summary: zod.z.string().describe("总结"),
4157
- detail: zod.z.array(zod.z.string()).describe("驱动项详情")
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: zod.z.object({
4161
- up_outlook: zod.z.string().describe("上涨前景"),
4162
- up_outlook_description: zod.z.string().describe("上涨前景描述"),
4163
- down_outlook: zod.z.string().describe("下跌前景"),
4164
- down_outlook_description: zod.z.string().describe("下跌前景描述"),
4165
- overall_comment: zod.z.string().describe("总体判断")
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: zod.z.object({
4168
- strategy: zod.z.string().describe("建议策略"),
4169
- investment_direction: zod.z.string().describe("投资方向"),
4170
- underweight_board: zod.z.string().describe("回避板块"),
4171
- investment_style: zod.z.string().describe("投资风格"),
4172
- asset_allocation_rate: zod.z.object({
4173
- stock: zod.z.string().describe("股票占比"),
4174
- cash: zod.z.string().describe("现金占比"),
4175
- bond: zod.z.string().describe("债券占比")
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
- zod.z.object({
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 = zod.z.array(
5272
- zod.z.object({
5273
- stock_code: zod.z.string(),
5274
- market: zod.z.string(),
5275
- name: zod.z.string(),
5276
- total_score: zod.z.number(),
5277
- base_score: zod.z.number(),
5278
- technology_score: zod.z.number(),
5279
- trend_score: zod.z.number(),
5280
- news_score: zod.z.number(),
5281
- reason: zod.z.string(),
5282
- vol: zod.z.number(),
5283
- price: zod.z.number(),
5284
- total: zod.z.number(),
5285
- pct: zod.z.number()
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 = zod.z.array(
5289
- zod.z.object({
5290
- industry_name: zod.z.string(),
5291
- industry_pct: zod.z.number()
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: zod.z.string().describe("生成时间"),
5296
- data_period_start: zod.z.string().describe("数据周期起始点"),
5297
- data_period_end: zod.z.string().describe("数据周期结束点}"),
5298
- expected_cash: zod.z.number().describe("预期投资金额"),
5299
- fact_cash: zod.z.number().describe("实际投资金额"),
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: zod.z.string().describe("行业分配点评"),
5328
+ industry_review: z.z.string().describe("行业分配点评"),
5302
5329
  industry_list,
5303
- backtest_period: zod.z.string().describe("回测时间跨度"),
5304
- base_index: zod.z.string().describe("回测基准指数"),
5305
- backtest_cash: zod.z.number(),
5306
- backtest_total_return: zod.z.number(),
5307
- backtest_total_return_review: zod.z.string(),
5308
- backtest_final_value: zod.z.number(),
5309
- backtest_final_value_review: zod.z.string(),
5310
- backtest_volatility: zod.z.number(),
5311
- backtest_volatility_review: zod.z.string(),
5312
- backtest_max_drawdown: zod.z.number(),
5313
- backtest_max_drawdown_review: zod.z.string(),
5314
- backtest_sharpe_ratio: zod.z.number(),
5315
- backtest_sharpe_ratio_review: zod.z.string(),
5316
- positive_return_months_review: zod.z.string(),
5317
- negative_return_months_review: zod.z.string(),
5318
- annualized_return: zod.z.number(),
5319
- annualized_return_review: zod.z.string(),
5320
- highest_month: zod.z.number(),
5321
- highest_month_review: zod.z.string(),
5322
- lowest_month: zod.z.number(),
5323
- lowest_month_review: zod.z.string(),
5324
- backtest_nav_per_share_daily_path: zod.z.string().describe("每日净值存储的地址,**这很重要**"),
5325
- backtest_income_per_monthly_path: zod.z.string().describe("月收益存储的地址,**这很重要**"),
5326
- hold_review: zod.z.string(),
5327
- summary: zod.z.string(),
5328
- backtest_nav_per_share_review: zod.z.string(),
5329
- investment_style: zod.z.string(),
5330
- risk_level: zod.z.enum([
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
- zod.z.object({
5363
+ z.z.object({
5337
5364
  ...portfolioSchema,
5338
- backtest_nav_per_share_daily: zod.z.array(
5339
- zod.z.object({
5340
- time: zod.z.string(),
5341
- portfolio: zod.z.number(),
5342
- csi300: zod.z.number()
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: zod.z.array(
5346
- zod.z.object({
5347
- time: zod.z.string(),
5348
- portfolio: zod.z.number(),
5349
- csi300: zod.z.number()
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: zod.z.string().describe("生成时间"),
6239
- data_period_start: zod.z.string().describe("数据周期起始点"),
6240
- data_period_end: zod.z.string().describe("数据周期结束点}"),
6241
- code: zod.z.string().describe("股票代码"),
6242
- market: zod.z.string().describe("市场"),
6243
- name: zod.z.string().describe("上市公司名称"),
6244
- trend_forecasting_review: zod.z.string().describe("趋势预测综述"),
6245
- history_data_path: zod.z.string().optional().describe("历史数据路径"),
6246
- predict_data_path: zod.z.string().optional().describe("预测数据路径"),
6247
- backtest_data_path: zod.z.string().optional().describe("回测数据路径"),
6248
- predict_7d_pct_chg: zod.z.number().describe("未来7日预测涨跌幅"),
6249
- predict_7d_pct_chg_interpret: zod.z.string().describe("未来7日预测涨跌幅解读"),
6250
- model_confidence_pct: zod.z.number().describe("模型置信度"),
6251
- model_confidence_pct_interpret: zod.z.string().describe("模型置信度解读"),
6252
- volatility_forecast_pct: zod.z.number().describe("波动率预测"),
6253
- volatility_forecast_pct_interpret: zod.z.string().describe("波动率预测解读"),
6254
- turning_point_signal_date: zod.z.string().describe("拐点信号日期"),
6255
- turning_point_signal_regime: zod.z.string().describe("拐点信号市场制度"),
6256
- turning_point_signal_interpret: zod.z.string().describe("拐点信号解读"),
6257
- buy_interval_left: zod.z.number().describe("买入区间左端"),
6258
- buy_interval_right: zod.z.number().describe("买入区间右端"),
6259
- buy_interval_confidence_pct: zod.z.number().describe("买入区间置信度"),
6260
- buy_interval_reason: zod.z.string().describe("买入区间理由"),
6261
- buy_interval_reason_desc: zod.z.string().describe("买入区间描述"),
6262
- hold_interval_left: zod.z.number().describe("持有区间左端"),
6263
- hold_interval_right: zod.z.number().describe("持有区间右端"),
6264
- hold_interval_confidence_pct: zod.z.number().describe("持有区间置信度"),
6265
- hold_interval_reason: zod.z.string().describe("持有区间理由"),
6266
- hold_interval_reason_desc: zod.z.string().describe("持有区间描述"),
6267
- sell_interval_left: zod.z.number().describe("卖出区间左端"),
6268
- sell_interval_right: zod.z.number().describe("卖出区间右端"),
6269
- sell_interval_confidence_pct: zod.z.number().describe("卖出区间置信度"),
6270
- sell_interval_reason: zod.z.string().describe("卖出区间理由"),
6271
- sell_interval_reason_desc: zod.z.string().describe("卖出区间描述"),
6272
- backtest_review: zod.z.string().describe("回测表现综述"),
6273
- short_term_accuracy: zod.z.number().describe("短期预测准确度"),
6274
- short_term_mae: zod.z.number().describe("短期MAE"),
6275
- short_term_review: zod.z.string().describe("短期预测简述"),
6276
- middle_term_accuracy: zod.z.number().describe("中期预测准确度"),
6277
- middle_term_mae: zod.z.number().describe("中期MAE"),
6278
- middle_term_review: zod.z.string().describe("中期预测简述"),
6279
- high_freq_accuracy: zod.z.number().describe("高频预测准确度"),
6280
- high_freq_mae: zod.z.number().describe("高频MAE"),
6281
- high_freq_review: zod.z.string().describe("高频预测简述"),
6282
- bull_market_performance: zod.z.number().describe("牛市表现"),
6283
- bull_market_review: zod.z.string().describe("牛市期表现简述"),
6284
- bear_market_performance: zod.z.number().describe("熊市表现"),
6285
- bear_market_review: zod.z.string().describe("熊市期表现简述"),
6286
- env_adaptation_summary: zod.z.string().describe("环境适应性结论"),
6287
- risk: zod.z.string().describe("潜在风险与免责声明"),
6288
- ada: zod.z.number().describe("平均方向命中率"),
6289
- ada_interpret: zod.z.string().describe("平均方向命中率解读"),
6290
- rmse: zod.z.number().describe("均方根误差"),
6291
- rmse_interpret: zod.z.string().describe("均方根误差解读"),
6292
- mae: zod.z.number().describe("平均绝对误差"),
6293
- mae_interpret: zod.z.string().describe("平均绝对误差解读"),
6294
- maximum_single_error: zod.z.number().describe("最大单次误差"),
6295
- maximum_single_error_interpret: zod.z.string().describe("最大单次误差解读"),
6296
- backtest_sample_size: zod.z.number().describe("回测样本数量"),
6297
- backtest_sample_size_interpret: zod.z.string().describe("回测样本数量解读"),
6298
- mpiw: zod.z.number().describe("平均预测区间宽度"),
6299
- mpiw_interpret: zod.z.string().describe("平均预测区间宽度解读"),
6300
- pic: zod.z.number().describe("区间命中率"),
6301
- pic_interpret: zod.z.string().describe("区间命中率解读"),
6302
- comprehensive_analysis_and_assessment: zod.z.string().describe("综合研判"),
6303
- key_findings_and_conclusions: zod.z.string().describe("核心结论"),
6304
- final_recommendations: zod.z.string().describe("最终建议"),
6305
- data_path: zod.z.string().describe("数据存储的地址,**这很重要**:不要workspace的地址")
6306
- };
6307
- zod.z.object({
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: zod.z.array(
6310
- zod.z.object({
6311
- date: zod.z.string().describe("日期"),
6312
- close_price: zod.z.number().describe("收盘价")
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: zod.z.array(
6316
- zod.z.object({
6317
- date: zod.z.string().describe("日期"),
6318
- close_price: zod.z.number().describe("收盘价")
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: zod.z.array(
6322
- zod.z.object({
6323
- date: zod.z.string().describe("日期"),
6324
- close_price: zod.z.number().describe("收盘价")
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 = zod.z.object({
8893
- basic_info: zod.z.string().describe("该股票的基本情况,需要 llm 分析"),
8894
- trend_indicator_summary: zod.z.string().describe("根据趋势指标数据,需要 llm 提供综合结论"),
8895
- momentum_indicator_summary: zod.z.string().describe("根据动能指标数据,需要 llm 提供综合结论"),
8896
- volatility_indicator_summary: zod.z.string().describe("根据波动率指标,需要 llm 提供综合结论"),
8897
- volume_indicator_summary: zod.z.string().describe("根据量能分析指标,需要 llm 提供综合结论"),
8898
- overall_assessment: zod.z.string().describe("根据所有数据,需要 llm 提供整体评价")
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 = zod.z.array(
8901
- zod.z.object({
8902
- time: zod.z.string().describe("时间"),
8903
- open: zod.z.number().describe("开盘价"),
8904
- close: zod.z.number().describe("收盘价"),
8905
- high: zod.z.number().describe("最高价"),
8906
- low: zod.z.number().describe("最低价"),
8907
- change: zod.z.number().describe("涨跌额"),
8908
- pct_chg: zod.z.number().describe("涨跌幅"),
8909
- vol: zod.z.number().describe("成交量"),
8910
- amount: zod.z.number().describe("成交额"),
8911
- turn_over: zod.z.number().describe("换手率"),
8912
- obv_qfq: zod.z.number().describe("obv能量潮"),
8913
- net_amount: zod.z.number().describe("主力净流入"),
8914
- buy_lg_amount: zod.z.number().describe("大单净流入"),
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: zod.z.number().describe("5日均线"),
8917
- ma10: zod.z.number().describe("10日均线"),
8918
- ma20: zod.z.number().describe("20日均线"),
8919
- ma60: zod.z.number().describe("60日均线"),
8920
- ma250: zod.z.number().describe("250日均线"),
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: zod.z.number().describe("macd"),
8923
- macd_dea: zod.z.number().describe("macd"),
8924
- macd_histogram: zod.z.number().describe("macd 柱"),
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: zod.z.number().describe("rsi6"),
8927
- rsi_12: zod.z.number().describe("rsi12"),
8928
- rsi_24: zod.z.number().describe("rsi24"),
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: zod.z.number().describe("kdj_k"),
8931
- kdj_d: zod.z.number().describe("kdj_d"),
8932
- kdj_j: zod.z.number().describe("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: zod.z.number().describe("atr14"),
8975
+ atr14: z.z.number().describe("atr14"),
8935
8976
  // boll
8936
- boll_upper: zod.z.number().describe("布林线上轨"),
8937
- boll_mid: zod.z.number().describe("布林线中轨"),
8938
- boll_lower: zod.z.number().describe("布林线下轨")
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 = zod.z.object({
8942
- open: zod.z.number().describe("开盘价"),
8943
- high: zod.z.number().describe("最高价"),
8944
- swing: zod.z.number().describe("振幅"),
8945
- vol: zod.z.number().describe("成交量"),
8946
- pre_close: zod.z.number().describe("昨收价"),
8947
- low: zod.z.number().describe("最低价"),
8948
- turn_over: zod.z.number().describe("换手率"),
8949
- amount: zod.z.number().describe("成交额"),
8950
- selling: zod.z.number().optional().describe("内盘"),
8951
- buying: zod.z.number().optional().describe("外盘"),
8952
- week52_high: zod.z.number().describe("52周高"),
8953
- week52_low: zod.z.number().describe("52周低"),
8954
- kline_summary: zod.z.string().describe("根据 kline 数据,需要 llm 总结")
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 = zod.z.object({
8957
- ma_summary: zod.z.string().describe("根据ma数据,需要 llm 总结"),
8958
- macd_summary: zod.z.string().describe("根据 macd 数据,需要 llm 总结")
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 = zod.z.object({
8961
- rsi_summary: zod.z.string().describe("根据 rsi 数据,需要 llm 总结"),
8962
- kdj_summary: zod.z.string().describe("根据 kdj 数据,需要 llm 总结"),
8963
- momentum_indicator_summary: zod.z.string().describe("根据动能指标数据,需要 llm 提供综合结论")
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 = zod.z.object({
8966
- hv30: zod.z.number().describe("30日历史波动率"),
8967
- bb_summary: zod.z.string().describe("根据布林带数据, 需要 llm 总结"),
8968
- risk_tips: zod.z.string().describe("根据波动率指标,需要 llm 提供风险提示"),
8969
- volatility_indicator_summary: zod.z.string().describe("根据波动率指标,需要 llm 提供综合结论")
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 = zod.z.object({
8972
- volume_ratio: zod.z.number().optional().describe("量比"),
8973
- volume_trend: zod.z.string().describe("根据相关成交量数据,需要 llm 提供成交量趋势"),
8974
- retail_sentiment: zod.z.string().describe("散户情绪"),
8975
- volume_indicator_summary: zod.z.string().describe("根据量能分析指标,需要 llm 提供综合结论")
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 = zod.z.object({
8978
- short_term: zod.z.object({
8979
- pattern_desc: zod.z.string().describe("短期形态简述,需要 llm 提供"),
8980
- short_resistance: zod.z.number().describe("短期压力位"),
8981
- short_support: zod.z.number().describe("短期支撑位")
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: zod.z.object({
8984
- pattern_desc: zod.z.string().describe("中期形态简述,需要 llm 提供"),
8985
- resistance: zod.z.number().describe("中期压力位"),
8986
- support: zod.z.number().describe("中期支撑位")
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: zod.z.object({
8989
- pattern_desc: zod.z.string().describe("长期形态简述,需要 llm 提供"),
8990
- resistance: zod.z.number().describe("长期压力位"),
8991
- support: zod.z.number().describe("长期支撑位")
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: zod.string().describe("需要 llm 提供综合形态分析")
9034
+ pattern_analysis_summary: z.string().describe("需要 llm 提供综合形态分析")
8994
9035
  });
8995
9036
  const techIndicatorSchema = {
8996
- title: zod.z.string().describe("报告名称"),
8997
- generation_time: zod.z.string().describe("生成时间"),
8998
- logo: zod.z.string().optional().describe("logo"),
8999
- code: zod.z.string().describe("股票代码"),
9000
- market: zod.z.string().describe("市场"),
9001
- name: zod.z.string().describe("上市公司名称"),
9002
- industry: zod.z.string().describe("行业"),
9003
- curr_price: zod.z.number().describe("当前股价"),
9004
- curr_change: zod.z.number().describe("涨跌额"),
9005
- curr_pct_chg: zod.z.number().optional().describe("涨跌幅度"),
9006
- data_period_start: zod.z.string().describe("数据周期起始点"),
9007
- data_period_end: zod.z.string().describe("数据周期结束点}"),
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: zod.z.string().describe("k线数据存储的地址,**这很重要**:不要workspace的地址")
9056
+ kline_data_path: z.z.string().describe("k线数据存储的地址,**这很重要**:不要workspace的地址")
9016
9057
  };
9017
- zod.z.object({
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, []);