xstock-mcp 1.0.0

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.
@@ -0,0 +1,90 @@
1
+ /**
2
+ * 测试 data/tencent.ts
3
+ * 运行:npx ts-node test/data-tencent.ts
4
+ */
5
+ import {
6
+ fetchAShareQuotes,
7
+ fetchHKQuotes,
8
+ fetchAShareKline,
9
+ fetchHKKline,
10
+ resolveASharePrefix,
11
+ } from "../src/data/tencent";
12
+
13
+ function section(title: string) {
14
+ console.log(`\n${"─".repeat(50)}`);
15
+ console.log(` ${title}`);
16
+ console.log("─".repeat(50));
17
+ }
18
+
19
+ async function main() {
20
+ // ── 1. 代码前缀识别 ───────────────────────────────
21
+ section("resolveASharePrefix");
22
+ const cases = [
23
+ ["600519", "sh"], // 上证(茅台)
24
+ ["000858", "sz"], // 深证(五粮液)
25
+ ["301060", "sz"], // 创业板
26
+ ["688001", "sh"], // 科创板
27
+ ["830001", "bj"], // 北交所
28
+ ["sh600519", "sh"], // 带前缀
29
+ ];
30
+ for (const [code, expected] of cases) {
31
+ const got = resolveASharePrefix(code);
32
+ const ok = got === expected ? "✓" : "✗";
33
+ console.log(` ${ok} ${code.padEnd(12)} → ${got} (expected ${expected})`);
34
+ }
35
+
36
+ // ── 2. A 股行情 ───────────────────────────────────
37
+ section("fetchAShareQuotes — 茅台 + 五粮液");
38
+ try {
39
+ const quotes = await fetchAShareQuotes(["600519", "000858"]);
40
+ for (const q of quotes) {
41
+ console.log(` ${q.name}(${q.code}) 价格=${q.price} 涨跌=${q.change} 涨跌幅=${q.changePercent}`);
42
+ }
43
+ } catch (e) {
44
+ console.error(" ERROR:", e);
45
+ }
46
+
47
+ // ── 3. A 股错误代码 ───────────────────────────────
48
+ section("fetchAShareQuotes — 错误代码");
49
+ try {
50
+ const quotes = await fetchAShareQuotes(["999999"]);
51
+ console.log(" 返回:", quotes.length === 0 ? "空数组(符合预期)" : JSON.stringify(quotes));
52
+ } catch (e) {
53
+ console.error(" ERROR:", e);
54
+ }
55
+
56
+ // ── 4. 港股行情 ───────────────────────────────────
57
+ section("fetchHKQuotes — 腾讯 + 阿里巴巴");
58
+ try {
59
+ const quotes = await fetchHKQuotes(["00700", "09988"]);
60
+ for (const q of quotes) {
61
+ console.log(` ${q.name}(${q.code}) 价格=${q.price} 涨跌幅=${q.changePercent}`);
62
+ }
63
+ } catch (e) {
64
+ console.error(" ERROR:", e);
65
+ }
66
+
67
+ // ── 5. A 股 K 线 ──────────────────────────────────
68
+ section("fetchAShareKline — 茅台日K");
69
+ try {
70
+ const bars = await fetchAShareKline("600519", "daily");
71
+ const last = bars[bars.length - 1];
72
+ console.log(` 共 ${bars.length} 条`);
73
+ console.log(` 最新一条: date=${last?.date} open=${last?.open} close=${last?.close} high=${last?.high} low=${last?.low}`);
74
+ } catch (e) {
75
+ console.error(" ERROR:", e);
76
+ }
77
+
78
+ // ── 6. 港股 K 线 ──────────────────────────────────
79
+ section("fetchHKKline — 腾讯日K");
80
+ try {
81
+ const bars = await fetchHKKline("00700", "daily");
82
+ const last = bars[bars.length - 1];
83
+ console.log(` 共 ${bars.length} 条`);
84
+ console.log(` 最新一条: date=${last?.date} open=${last?.open} close=${last?.close}`);
85
+ } catch (e) {
86
+ console.error(" ERROR:", e);
87
+ }
88
+ }
89
+
90
+ main().catch(console.error);
@@ -0,0 +1,84 @@
1
+ /**
2
+ * 测试 data/yahoo.ts
3
+ * 运行:npx ts-node test/data-yahoo.ts
4
+ */
5
+ import { fetchUSQuotes, fetchUSKlines, fetchStockProfile } from "../src/data/yahoo";
6
+
7
+ function section(title: string) {
8
+ console.log(`\n${"─".repeat(50)}`);
9
+ console.log(` ${title}`);
10
+ console.log("─".repeat(50));
11
+ }
12
+
13
+ async function main() {
14
+ // ── 1. 美股行情 ───────────────────────────────────
15
+ section("fetchUSQuotes — AAPL / NVDA / TSLA");
16
+ try {
17
+ const quotes = await fetchUSQuotes(["AAPL", "NVDA", "TSLA"]);
18
+ for (const q of quotes) {
19
+ console.log(
20
+ ` ${q.symbol.padEnd(6)} ${q.name.slice(0, 20).padEnd(22)}` +
21
+ ` $${q.price.toFixed(2).padStart(9)} ${q.changePercent.padStart(8)}` +
22
+ ` ${q.exchange}`
23
+ );
24
+ }
25
+ } catch (e) {
26
+ console.error(" ERROR:", e);
27
+ }
28
+
29
+ // ── 2. 错误 symbol ────────────────────────────────
30
+ section("fetchUSQuotes — 不存在的 symbol");
31
+ try {
32
+ const quotes = await fetchUSQuotes(["NOTEXIST999"]);
33
+ console.log(" 返回:", quotes.length === 0 ? "空数组(符合预期)" : JSON.stringify(quotes));
34
+ } catch (e) {
35
+ console.log(" 捕获到错误(符合预期):", (e as Error).message);
36
+ }
37
+
38
+ // ── 3. 美股日 K 线 ────────────────────────────────
39
+ section("fetchUSKlines — AAPL 最近 30 天日K");
40
+ try {
41
+ const end = new Date().toISOString().slice(0, 10);
42
+ const start = new Date(Date.now() - 30 * 86400_000).toISOString().slice(0, 10);
43
+ const bars = await fetchUSKlines("AAPL", start, end, "1d");
44
+ const last = bars[bars.length - 1];
45
+ console.log(` 共 ${bars.length} 条 (${start} ~ ${end})`);
46
+ console.log(` 最新: date=${last?.date} open=${last?.open?.toFixed(2)} close=${last?.close?.toFixed(2)} adjClose=${last?.adjClose?.toFixed(2)}`);
47
+ } catch (e) {
48
+ console.error(" ERROR:", e);
49
+ }
50
+
51
+ // ── 4. 美股周 K 线 ────────────────────────────────
52
+ section("fetchUSKlines — NVDA 最近 3 个月周K");
53
+ try {
54
+ const end = new Date().toISOString().slice(0, 10);
55
+ const start = new Date(Date.now() - 90 * 86400_000).toISOString().slice(0, 10);
56
+ const bars = await fetchUSKlines("NVDA", start, end, "1wk");
57
+ console.log(` 共 ${bars.length} 条`);
58
+ for (const b of bars.slice(-5)) {
59
+ console.log(` ${b.date} close=$${b.close.toFixed(2)}`);
60
+ }
61
+ } catch (e) {
62
+ console.error(" ERROR:", e);
63
+ }
64
+
65
+ // ── 5. 股票基本面 ──────────────────────────────────
66
+ section("fetchStockProfile — AAPL");
67
+ try {
68
+ const p = await fetchStockProfile("AAPL");
69
+ console.log(` 名称: ${p.name}`);
70
+ console.log(` 行业: ${p.sector} / ${p.industry}`);
71
+ console.log(` 国家: ${p.country}`);
72
+ console.log(` 市值: $${p.marketCap ? (p.marketCap / 1e12).toFixed(2) + "T" : "N/A"}`);
73
+ console.log(` PE: ${p.pe?.toFixed(2) ?? "N/A"}`);
74
+ console.log(` EPS: ${p.eps?.toFixed(2) ?? "N/A"}`);
75
+ console.log(` Beta: ${p.beta?.toFixed(2) ?? "N/A"}`);
76
+ console.log(` 52W High: $${p.fiftyTwoWeekHigh?.toFixed(2) ?? "N/A"}`);
77
+ console.log(` 52W Low: $${p.fiftyTwoWeekLow?.toFixed(2) ?? "N/A"}`);
78
+ console.log(` 网站: ${p.website ?? "N/A"}`);
79
+ } catch (e) {
80
+ console.error(" ERROR:", e);
81
+ }
82
+ }
83
+
84
+ main().catch(console.error);
package/tsconfig.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": ["ES2020"],
6
+ "types": ["node"],
7
+ "outDir": "./dist",
8
+ "rootDir": "./src",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true
12
+ },
13
+ "include": ["src/**/*"]
14
+ }