investdesk-quotes 0.3.0 → 0.4.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.
@@ -80,9 +80,20 @@ export async function listPlatformNames() {
80
80
  }
81
81
  return map;
82
82
  }
83
- /** 把价格写回「最新持仓」的「最新价格」字段(写入后「最新市值」公式自动重算) */
83
+ /**
84
+ * 把行情写回「最新持仓」:
85
+ * 最新价格 / 昨收价 / 日涨跌幅(%)
86
+ * 「最新市值」「日盈亏」是公式字段,写完后自动重算。
87
+ */
84
88
  export async function updateLatestPrices(updates) {
85
89
  if (updates.length === 0)
86
90
  return 0;
87
- return getBackend().batchUpdateRecords(HOLDINGS_TABLE, updates.map((update) => ({ recordId: update.recordId, fields: { 最新价格: update.price } })));
91
+ return getBackend().batchUpdateRecords(HOLDINGS_TABLE, updates.map((update) => {
92
+ const fields = { 最新价格: update.price };
93
+ if (update.previousPrice != null)
94
+ fields.昨收价 = update.previousPrice;
95
+ if (update.changePct != null)
96
+ fields['日涨跌幅(%)'] = update.changePct;
97
+ return { recordId: update.recordId, fields };
98
+ }));
88
99
  }
@@ -12,7 +12,7 @@ const DEFAULT_TIMEOUT_MS = 10_000;
12
12
  * 网络或接口异常则抛错,由调用方重试。
13
13
  */
14
14
  export async function fetchFundNav(code, timeoutMs = DEFAULT_TIMEOUT_MS) {
15
- const url = `${ENDPOINT}?fundCode=${encodeURIComponent(code)}&pageIndex=1&pageSize=1`;
15
+ const url = `${ENDPOINT}?fundCode=${encodeURIComponent(code)}&pageIndex=1&pageSize=2`;
16
16
  const controller = new AbortController();
17
17
  const timer = setTimeout(() => controller.abort(), timeoutMs);
18
18
  try {
@@ -26,16 +26,19 @@ export async function fetchFundNav(code, timeoutMs = DEFAULT_TIMEOUT_MS) {
26
26
  if (!res.ok)
27
27
  throw new Error(`东财净值 HTTP ${res.status}`);
28
28
  const payload = (await res.json());
29
- const row = payload.Data?.LSJZList?.[0];
29
+ const rows = payload.Data?.LSJZList ?? [];
30
+ const row = rows[0];
30
31
  if (!row?.DWJZ || !row.FSRQ)
31
32
  return null;
32
33
  const nav = Number(row.DWJZ);
33
34
  if (!Number.isFinite(nav) || nav <= 0)
34
35
  return null;
35
36
  const pct = Number(row.JZZZL);
37
+ const prevNav = Number(rows[1]?.DWJZ);
36
38
  return {
37
39
  code,
38
40
  nav,
41
+ previousNav: Number.isFinite(prevNav) && prevNav > 0 ? prevNav : null,
39
42
  date: row.FSRQ,
40
43
  changePct: Number.isFinite(pct) ? pct : null,
41
44
  };
@@ -87,6 +87,7 @@ export async function fetchQuotes(targets, options = {}) {
87
87
  name: target.name || q.name,
88
88
  price: q.price,
89
89
  changePct: q.changePct,
90
+ previousPrice: Number.isFinite(q.prevClose) && q.prevClose > 0 ? q.prevClose : null,
90
91
  tradeTime: q.tradeTime,
91
92
  source: 'tencent',
92
93
  });
@@ -125,6 +126,7 @@ export async function fetchQuotes(targets, options = {}) {
125
126
  name: target.name,
126
127
  price: nav.nav,
127
128
  changePct: nav.changePct,
129
+ previousPrice: nav.previousNav,
128
130
  tradeTime: nav.date,
129
131
  source: 'eastmoney-fund',
130
132
  });
package/dist/sync.js CHANGED
@@ -20,6 +20,8 @@ export async function syncPortfolioPrices(options = {}) {
20
20
  const updates = [...byRecord.entries()].map(([recordId, quote]) => ({
21
21
  recordId,
22
22
  price: quote.price,
23
+ previousPrice: quote.previousPrice,
24
+ changePct: quote.changePct,
23
25
  }));
24
26
  const written = await updateLatestPrices(updates);
25
27
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "investdesk-quotes",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "A 股与场外公募基金行情查询 + 飞书多维表格持仓读写的 MCP 服务。可装进豆包工作 / Claude Desktop 等支持 MCP 的 AI 宿主。",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -43,4 +43,4 @@
43
43
  "@types/node": "^26.6.5",
44
44
  "typescript": "^7.0.2"
45
45
  }
46
- }
46
+ }