lit-forge-mcp 0.3.0 → 0.4.1

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 (84) hide show
  1. package/README.md +17 -7
  2. package/dist/lib/__tests__/correlation.test.d.ts +1 -0
  3. package/dist/lib/__tests__/correlation.test.js +53 -0
  4. package/dist/lib/__tests__/correlation.test.js.map +1 -0
  5. package/dist/lib/__tests__/quartile.test.d.ts +1 -0
  6. package/dist/lib/__tests__/quartile.test.js +148 -0
  7. package/dist/lib/__tests__/quartile.test.js.map +1 -0
  8. package/dist/lib/__tests__/rankings.test.d.ts +1 -0
  9. package/dist/lib/__tests__/rankings.test.js +67 -0
  10. package/dist/lib/__tests__/rankings.test.js.map +1 -0
  11. package/dist/lib/__tests__/sessions.test.d.ts +1 -0
  12. package/dist/lib/__tests__/sessions.test.js +47 -0
  13. package/dist/lib/__tests__/sessions.test.js.map +1 -0
  14. package/dist/lib/__tests__/sma.test.d.ts +1 -0
  15. package/dist/lib/__tests__/sma.test.js +26 -0
  16. package/dist/lib/__tests__/sma.test.js.map +1 -0
  17. package/dist/lib/__tests__/thermometer.test.d.ts +1 -0
  18. package/dist/lib/__tests__/thermometer.test.js +120 -0
  19. package/dist/lib/__tests__/thermometer.test.js.map +1 -0
  20. package/dist/lib/__tests__/yield-spread.test.d.ts +1 -0
  21. package/dist/lib/__tests__/yield-spread.test.js +46 -0
  22. package/dist/lib/__tests__/yield-spread.test.js.map +1 -0
  23. package/dist/lib/correlation.d.ts +3 -0
  24. package/dist/lib/correlation.js +77 -0
  25. package/dist/lib/correlation.js.map +1 -0
  26. package/dist/lib/fangplus.d.ts +7 -0
  27. package/dist/lib/fangplus.js +19 -0
  28. package/dist/lib/fangplus.js.map +1 -0
  29. package/dist/lib/indicators.d.ts +1 -0
  30. package/dist/lib/indicators.js +36 -1
  31. package/dist/lib/indicators.js.map +1 -1
  32. package/dist/lib/mag7.d.ts +7 -0
  33. package/dist/lib/mag7.js +13 -0
  34. package/dist/lib/mag7.js.map +1 -0
  35. package/dist/lib/market-types.d.ts +22 -6
  36. package/dist/lib/market-types.js +1 -0
  37. package/dist/lib/market-types.js.map +1 -1
  38. package/dist/lib/performance.d.ts +3 -0
  39. package/dist/lib/performance.js +43 -0
  40. package/dist/lib/performance.js.map +1 -0
  41. package/dist/lib/quartile.d.ts +24 -0
  42. package/dist/lib/quartile.js +128 -0
  43. package/dist/lib/quartile.js.map +1 -0
  44. package/dist/lib/rankings.d.ts +7 -0
  45. package/dist/lib/rankings.js +29 -0
  46. package/dist/lib/rankings.js.map +1 -0
  47. package/dist/lib/sectors.d.ts +7 -0
  48. package/dist/lib/sectors.js +62 -0
  49. package/dist/lib/sectors.js.map +1 -0
  50. package/dist/lib/sessions.d.ts +14 -0
  51. package/dist/lib/sessions.js +50 -0
  52. package/dist/lib/sessions.js.map +1 -0
  53. package/dist/lib/sma.d.ts +2 -0
  54. package/dist/lib/sma.js +33 -0
  55. package/dist/lib/sma.js.map +1 -0
  56. package/dist/lib/thermometer.d.ts +13 -0
  57. package/dist/lib/thermometer.js +118 -0
  58. package/dist/lib/thermometer.js.map +1 -0
  59. package/dist/lib/yahoo.d.ts +2 -0
  60. package/dist/lib/yahoo.js +76 -16
  61. package/dist/lib/yahoo.js.map +1 -1
  62. package/dist/lib/yield-spread.d.ts +6 -0
  63. package/dist/lib/yield-spread.js +20 -0
  64. package/dist/lib/yield-spread.js.map +1 -0
  65. package/dist/tools/get-market-sessions.d.ts +2 -0
  66. package/dist/tools/get-market-sessions.js +27 -0
  67. package/dist/tools/get-market-sessions.js.map +1 -0
  68. package/dist/tools/get-market-snapshot.js +7 -5
  69. package/dist/tools/get-market-snapshot.js.map +1 -1
  70. package/dist/tools/get-market-thermometer.d.ts +2 -0
  71. package/dist/tools/get-market-thermometer.js +47 -0
  72. package/dist/tools/get-market-thermometer.js.map +1 -0
  73. package/dist/tools/get-performance-ranking.d.ts +2 -0
  74. package/dist/tools/get-performance-ranking.js +75 -0
  75. package/dist/tools/get-performance-ranking.js.map +1 -0
  76. package/dist/tools/get-sector-heatmap.d.ts +2 -0
  77. package/dist/tools/get-sector-heatmap.js +34 -0
  78. package/dist/tools/get-sector-heatmap.js.map +1 -0
  79. package/dist/tools/get-yield-spread.d.ts +2 -0
  80. package/dist/tools/get-yield-spread.js +41 -0
  81. package/dist/tools/get-yield-spread.js.map +1 -0
  82. package/dist/tools/index.js +13 -0
  83. package/dist/tools/index.js.map +1 -1
  84. package/package.json +6 -3
@@ -0,0 +1,62 @@
1
+ // 米株セクター ETF(State Street Sector SPDR、11 銘柄)。
2
+ // 各セクターの前日比をコンパクトなヒートマップで表示し、米株市場の解像度を上げる。
3
+ // /today では INDICATORS(27 銘柄)と並行して別セクションで取得・表示する。
4
+ export const SECTOR_ETFS = [
5
+ {
6
+ symbol: "XLK",
7
+ name: "テクノロジー",
8
+ description: "Apple / Microsoft / Nvidia など。AI・半導体・SaaS",
9
+ },
10
+ {
11
+ symbol: "XLF",
12
+ name: "金融",
13
+ description: "JPMorgan / Bank of America など。銀行・保険・証券",
14
+ },
15
+ {
16
+ symbol: "XLV",
17
+ name: "ヘルスケア",
18
+ description: "UnitedHealth / J&J / Eli Lilly など。製薬・医療機器",
19
+ },
20
+ {
21
+ symbol: "XLY",
22
+ name: "一般消費財",
23
+ description: "Amazon / Tesla / McDonald's など。景気敏感セクター",
24
+ },
25
+ {
26
+ symbol: "XLP",
27
+ name: "生活必需品",
28
+ description: "P&G / Coca-Cola / Walmart など。ディフェンシブ",
29
+ },
30
+ {
31
+ symbol: "XLE",
32
+ name: "エネルギー",
33
+ description: "ExxonMobil / Chevron など。原油価格と連動",
34
+ },
35
+ {
36
+ symbol: "XLI",
37
+ name: "資本財",
38
+ description: "Boeing / Caterpillar / GE など。製造業・防衛",
39
+ },
40
+ {
41
+ symbol: "XLU",
42
+ name: "公益",
43
+ description: "電力・ガス・水道。低 β のディフェンシブ",
44
+ },
45
+ {
46
+ symbol: "XLB",
47
+ name: "素材",
48
+ description: "化学・鉱業・金属。Linde / Sherwin-Williams など",
49
+ },
50
+ {
51
+ symbol: "XLRE",
52
+ name: "不動産",
53
+ description: "REIT 中心。金利感応度が高い",
54
+ },
55
+ {
56
+ symbol: "XLC",
57
+ name: "通信",
58
+ description: "Meta / Alphabet / Netflix など。メディア・通信",
59
+ },
60
+ ];
61
+ export const SECTOR_SYMBOLS = SECTOR_ETFS.map((s) => s.symbol);
62
+ //# sourceMappingURL=sectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sectors.js","sourceRoot":"","sources":["../../src/lib/sectors.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,2CAA2C;AAC3C,kDAAkD;AAUlD,MAAM,CAAC,MAAM,WAAW,GAAyB;IAC/C;QACE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,2CAA2C;KACzD;IACD;QACE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,wCAAwC;KACtD;IACD;QACE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,2CAA2C;KACzD;IACD;QACE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,yCAAyC;KACvD;IACD;QACE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,sCAAsC;KACpD;IACD;QACE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,iCAAiC;KAC/C;IACD;QACE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,qCAAqC;KACnD;IACD;QACE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,uBAAuB;KACrC;IACD;QACE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,sCAAsC;KACpD;IACD;QACE,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,kBAAkB;KAChC;IACD;QACE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,sCAAsC;KACpD;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAsB,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ export type MarketSession = {
2
+ id: "tokyo" | "london" | "ny" | "shanghai";
3
+ label: string;
4
+ openHourJst: number;
5
+ closeHourJst: number;
6
+ };
7
+ export declare const MARKET_SESSIONS: readonly MarketSession[];
8
+ export type SessionStatus = {
9
+ session: MarketSession;
10
+ state: "open" | "closed" | "pre-open";
11
+ hoursUntilOpen?: number;
12
+ hoursUntilClose?: number;
13
+ };
14
+ export declare function getSessionStatuses(now?: Date): SessionStatus[];
@@ -0,0 +1,50 @@
1
+ // 主要市場の取引時間帯を JST 基準で判定する純関数。
2
+ // 東京・ロンドン・ニューヨーク・上海の取引時間を JST 換算してオープン/クローズ判定する。
3
+ // 祝日や臨時休場までは追わない(運営許容範囲)。
4
+ // 通常取引時間(JST、サマータイム未考慮)。
5
+ // 東京: 9:00-15:30 JST
6
+ // 上海: 10:30-16:00 JST
7
+ // ロンドン: 17:00-25:30 JST(17:00-翌1:30)— UTC 8:00-16:30
8
+ // NY: 22:30-29:00 JST(22:30-翌5:00)— UTC 13:30-20:00
9
+ export const MARKET_SESSIONS = [
10
+ { id: "tokyo", label: "東京", openHourJst: 9, closeHourJst: 15.5 },
11
+ { id: "shanghai", label: "上海", openHourJst: 10.5, closeHourJst: 16 },
12
+ { id: "london", label: "ロンドン", openHourJst: 17, closeHourJst: 25.5 },
13
+ { id: "ny", label: "NY", openHourJst: 22.5, closeHourJst: 29 },
14
+ ];
15
+ // JST 時刻(now)から各市場のステータスを判定。
16
+ // open: 取引中、pre-open: 30 分以内にオープン、closed: それ以外。
17
+ export function getSessionStatuses(now = new Date()) {
18
+ const jstMs = now.getTime() + 9 * 3600 * 1000;
19
+ const jst = new Date(jstMs);
20
+ const dayOfWeek = jst.getUTCDay(); // 0=日, 6=土(JST 換算で)
21
+ const isWeekend = dayOfWeek === 0 || dayOfWeek === 6;
22
+ // 現在時刻を「24h 換算の小数」で表現(例: 22:30 → 22.5)。
23
+ // 翌日にまたがるセッションは現在時刻 + 24 とも比較できるよう dual で持つ。
24
+ const hour = jst.getUTCHours() + jst.getUTCMinutes() / 60;
25
+ return MARKET_SESSIONS.map((s) => {
26
+ if (isWeekend) {
27
+ // 週末は基本クローズ(厳密には金曜深夜の NY セッション越境はあるが省略)
28
+ return { session: s, state: "closed" };
29
+ }
30
+ // 取引時間判定(hour と hour+24 の両方をチェック)
31
+ let state = "closed";
32
+ let hoursUntilOpen;
33
+ let hoursUntilClose;
34
+ const candidates = [hour, hour + 24];
35
+ for (const h of candidates) {
36
+ if (h >= s.openHourJst && h < s.closeHourJst) {
37
+ state = "open";
38
+ hoursUntilClose = s.closeHourJst - h;
39
+ return { session: s, state, hoursUntilClose };
40
+ }
41
+ const delta = s.openHourJst - h;
42
+ if (delta > 0 && delta <= 0.5) {
43
+ state = "pre-open";
44
+ hoursUntilOpen = delta;
45
+ }
46
+ }
47
+ return { session: s, state, hoursUntilOpen, hoursUntilClose };
48
+ });
49
+ }
50
+ //# sourceMappingURL=sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../src/lib/sessions.ts"],"names":[],"mappings":"AAAA,8BAA8B;AAC9B,iDAAiD;AACjD,0BAA0B;AAU1B,yBAAyB;AACzB,qBAAqB;AACrB,sBAAsB;AACtB,qDAAqD;AACrD,oDAAoD;AACpD,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE;IAChE,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE;IACpE,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;IACpE,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE;CAC/D,CAAC;AAWF,6BAA6B;AAC7B,gDAAgD;AAChD,MAAM,UAAU,kBAAkB,CAAC,MAAY,IAAI,IAAI,EAAE;IACvD,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;IAC9C,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5B,MAAM,SAAS,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,oBAAoB;IACvD,MAAM,SAAS,GAAG,SAAS,KAAK,CAAC,IAAI,SAAS,KAAK,CAAC,CAAC;IACrD,wCAAwC;IACxC,6CAA6C;IAC7C,MAAM,IAAI,GAAG,GAAG,CAAC,WAAW,EAAE,GAAG,GAAG,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC;IAC1D,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAiB,EAAE;QAC9C,IAAI,SAAS,EAAE,CAAC;YACd,wCAAwC;YACxC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;QACzC,CAAC;QACD,kCAAkC;QAClC,IAAI,KAAK,GAA2B,QAAQ,CAAC;QAC7C,IAAI,cAAkC,CAAC;QACvC,IAAI,eAAmC,CAAC;QACxC,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QACrC,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,IAAI,CAAC,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC;gBAC7C,KAAK,GAAG,MAAM,CAAC;gBACf,eAAe,GAAG,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC;gBACrC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC;YAChD,CAAC;YACD,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC;YAChC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,IAAI,GAAG,EAAE,CAAC;gBAC9B,KAAK,GAAG,UAAU,CAAC;gBACnB,cAAc,GAAG,KAAK,CAAC;YACzB,CAAC;QACH,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC;IAChE,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function rollingSMA(values: readonly number[], window: number): (number | null)[];
2
+ export declare function lastSMA(values: readonly number[], window: number): number | null;
@@ -0,0 +1,33 @@
1
+ // 単純移動平均(SMA)の計算純関数。
2
+ // PeriodChart の 50 日 / 200 日線オーバーレイ、quartile.ts の 200 日線クロス検出、
3
+ // rankings.ts の期間別パフォーマンス計算などで共通利用する。
4
+ // 配列に対する N 期間 SMA を返す。先頭 N-1 個は null(データ不足)。
5
+ export function rollingSMA(values, window) {
6
+ if (window <= 0)
7
+ return values.map(() => null);
8
+ const out = [];
9
+ let sum = 0;
10
+ for (let i = 0; i < values.length; i++) {
11
+ sum += values[i];
12
+ if (i >= window)
13
+ sum -= values[i - window];
14
+ if (i >= window - 1) {
15
+ out.push(sum / window);
16
+ }
17
+ else {
18
+ out.push(null);
19
+ }
20
+ }
21
+ return out;
22
+ }
23
+ // 末尾 N 期間の SMA 単一値。データ不足は null。
24
+ export function lastSMA(values, window) {
25
+ if (values.length < window || window <= 0)
26
+ return null;
27
+ let sum = 0;
28
+ for (let i = values.length - window; i < values.length; i++) {
29
+ sum += values[i];
30
+ }
31
+ return sum / window;
32
+ }
33
+ //# sourceMappingURL=sma.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sma.js","sourceRoot":"","sources":["../../src/lib/sma.ts"],"names":[],"mappings":"AAAA,qBAAqB;AACrB,+DAA+D;AAC/D,sCAAsC;AAEtC,6CAA6C;AAC7C,MAAM,UAAU,UAAU,CACxB,MAAyB,EACzB,MAAc;IAEd,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAC/C,MAAM,GAAG,GAAsB,EAAE,CAAC;IAClC,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;QACjB,IAAI,CAAC,IAAI,MAAM;YAAE,GAAG,IAAI,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;QAC3C,IAAI,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,gCAAgC;AAChC,MAAM,UAAU,OAAO,CACrB,MAAyB,EACzB,MAAc;IAEd,IAAI,MAAM,CAAC,MAAM,GAAG,MAAM,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACvD,IAAI,GAAG,GAAG,CAAC,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5D,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,GAAG,MAAM,CAAC;AACtB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { Snapshot } from "./market-types.js";
2
+ export type ThermometerComponent = {
3
+ label: string;
4
+ value: number | null;
5
+ bias: string;
6
+ };
7
+ export type ThermometerResult = {
8
+ score: number;
9
+ level: "risk-on" | "neutral" | "risk-off";
10
+ components: ThermometerComponent[];
11
+ };
12
+ export declare function computeThermometer(snapshot: Snapshot): ThermometerResult | null;
13
+ export declare function computeThermometerHistory(snapshot: Snapshot, days?: number): number[];
@@ -0,0 +1,118 @@
1
+ // マーケット温度計:複数指標を組み合わせて 0〜100 のリスクオン/オフ合成スコアを返す。
2
+ // 数値の意味は「リスクオン度」(=積極的にリスク資産が買われている度合い)。
3
+ // 高い (>= 70) → リスクオン優勢、低い (<= 30) → リスクオフ優勢、中間 → 中立。
4
+ //
5
+ // あくまで個々の指標の現在値を線形マッピングして平均する素朴な合成で、
6
+ // 「これを根拠に売買せよ」という投資シグナルではない(YMYL 配慮)。
7
+ // 算出式・ラベルは事実ベースに留め、UI 側でも「投資助言ではなく俯瞰用」と明示する。
8
+ // 値を 0..100 にクリップ
9
+ function clamp01(x) {
10
+ return Math.max(0, Math.min(100, x));
11
+ }
12
+ function getQuote(snapshot, symbol) {
13
+ const q = snapshot.quotes[symbol];
14
+ if (!q || "error" in q)
15
+ return null;
16
+ return q;
17
+ }
18
+ // VIX:低いほどリスクオン。10 → 100、30 → 0 で線形マッピング。
19
+ // (20 が中立 50 になるよう設計)
20
+ function vixScore(snapshot) {
21
+ const q = getQuote(snapshot, "^VIX");
22
+ if (!q)
23
+ return null;
24
+ const v = q.price;
25
+ return clamp01(((30 - v) / 20) * 100);
26
+ }
27
+ // S&P 500 前日比:+1.5% で 100、-1.5% で 0、0% で 50。
28
+ function spxScore(snapshot) {
29
+ const q = getQuote(snapshot, "^GSPC");
30
+ if (!q)
31
+ return null;
32
+ return clamp01(((q.changePercent + 1.5) / 3) * 100);
33
+ }
34
+ // 米10年金利:金利上昇 = リスクオン側に振れることが多い(景気期待)が、過熱で逆相関にもなる。
35
+ // ここでは前日比 bp で評価:+10bp で 100、-10bp で 0、0bp で 50。
36
+ function tnxScore(snapshot) {
37
+ const q = getQuote(snapshot, "^TNX");
38
+ if (!q)
39
+ return null;
40
+ return clamp01(((q.changeBp + 10) / 20) * 100);
41
+ }
42
+ // ドル指数 DXY:上昇は一般にリスクオフ(質への逃避)。前日比 -0.5% で 100、+0.5% で 0、0% で 50。
43
+ function dxyScore(snapshot) {
44
+ const q = getQuote(snapshot, "DX-Y.NYB");
45
+ if (!q)
46
+ return null;
47
+ return clamp01(((-q.changePercent + 0.5) / 1) * 100);
48
+ }
49
+ // /today 上部に出すマーケット温度計の合成スコアを返す。
50
+ // 取得できた成分の平均で算出する(欠損成分は無視)。全成分欠損なら null。
51
+ export function computeThermometer(snapshot) {
52
+ const components = [
53
+ { label: "VIX (株式ボラ)", value: vixScore(snapshot), bias: "低いほどリスクオン" },
54
+ { label: "S&P 500 前日比", value: spxScore(snapshot), bias: "上昇でリスクオン" },
55
+ { label: "米10年金利前日比", value: tnxScore(snapshot), bias: "上昇でリスクオン寄り" },
56
+ { label: "ドル指数前日比", value: dxyScore(snapshot), bias: "下落でリスクオン" },
57
+ ];
58
+ const valid = components
59
+ .map((c) => c.value)
60
+ .filter((v) => v !== null);
61
+ if (valid.length === 0)
62
+ return null;
63
+ const score = valid.reduce((a, b) => a + b, 0) / valid.length;
64
+ const level = score >= 70 ? "risk-on" : score <= 30 ? "risk-off" : "neutral";
65
+ return { score, level, components };
66
+ }
67
+ // 任意の VIX 価格 / SPX・DXY 前日比% / TNX bp から合成スコアを計算(履歴算出用)。
68
+ function scoreFromValues(vixPrice, spxPct, tnxBp, dxyPct) {
69
+ const parts = [];
70
+ if (typeof vixPrice === "number")
71
+ parts.push(clamp01(((30 - vixPrice) / 20) * 100));
72
+ if (typeof spxPct === "number")
73
+ parts.push(clamp01(((spxPct + 1.5) / 3) * 100));
74
+ if (typeof tnxBp === "number")
75
+ parts.push(clamp01(((tnxBp + 10) / 20) * 100));
76
+ if (typeof dxyPct === "number")
77
+ parts.push(clamp01(((-dxyPct + 0.5) / 1) * 100));
78
+ if (parts.length === 0)
79
+ return null;
80
+ return parts.reduce((a, b) => a + b, 0) / parts.length;
81
+ }
82
+ // 過去 N 日の温度計合成スコアを日足配列から逆算する。
83
+ // closes1y を持つ 4 銘柄(^VIX, ^GSPC, ^TNX, DX-Y.NYB)の close 配列を入力に取り、
84
+ // 各日 i について closes[i] と closes[i-1] から prev-day 比を計算してスコア化。
85
+ // 戻り値は末尾が「最新日」、長さは days (データ点不足は number[] が短くなる)。
86
+ export function computeThermometerHistory(snapshot, days = 30) {
87
+ const get1y = (symbol) => {
88
+ const q = snapshot.quotes[symbol];
89
+ if (!q || "error" in q)
90
+ return null;
91
+ return q.closes1y && q.closes1y.length > 1 ? q.closes1y : null;
92
+ };
93
+ const vix = get1y("^VIX");
94
+ const spx = get1y("^GSPC");
95
+ const tnx = get1y("^TNX");
96
+ const dxy = get1y("DX-Y.NYB");
97
+ // 共通する有効長を取る(最も短い配列に合わせる、ただし null は無視)
98
+ const lens = [vix, spx, tnx, dxy]
99
+ .filter((a) => a !== null)
100
+ .map((a) => a.length);
101
+ if (lens.length === 0)
102
+ return [];
103
+ const minLen = Math.min(...lens);
104
+ // i=1 から minLen-1 までスコア化(i=0 は前日が無い)
105
+ const start = Math.max(1, minLen - days);
106
+ const out = [];
107
+ for (let i = start; i < minLen; i++) {
108
+ const vixPrice = vix ? vix[i] : null;
109
+ const spxPct = spx && spx[i - 1] !== 0 ? ((spx[i] - spx[i - 1]) / spx[i - 1]) * 100 : null;
110
+ const tnxBp = tnx ? (tnx[i] - tnx[i - 1]) * 100 : null;
111
+ const dxyPct = dxy && dxy[i - 1] !== 0 ? ((dxy[i] - dxy[i - 1]) / dxy[i - 1]) * 100 : null;
112
+ const s = scoreFromValues(vixPrice, spxPct, tnxBp, dxyPct);
113
+ if (s !== null)
114
+ out.push(s);
115
+ }
116
+ return out;
117
+ }
118
+ //# sourceMappingURL=thermometer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"thermometer.js","sourceRoot":"","sources":["../../src/lib/thermometer.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,8 @@ export declare class YahooFinanceError extends Error {
4
4
  readonly status: number;
5
5
  constructor(symbol: string, status: number, message?: string);
6
6
  }
7
+ export declare function fetchHistorical(symbol: string): Promise<number[]>;
7
8
  export declare function fetchQuoteForIndicator(indicator: Indicator): Promise<QuoteResult>;
8
9
  export declare function fetchQuoteBySymbol(symbol: string): Promise<Quote>;
9
10
  export declare function fetchSnapshot(): Promise<Snapshot>;
11
+ export declare function fetchSubsetSnapshot(symbols: readonly string[]): Promise<Record<string, QuoteResult>>;
package/dist/lib/yahoo.js CHANGED
@@ -1,8 +1,9 @@
1
1
  // Yahoo Finance v8 chart API ラッパー(MCP server 用)。
2
- // Web 側の app/lib/market/yahoo.ts と同期管理。
3
2
  // Node 18+ の global fetch を使用、依存追加なし。
3
+ // v0.4 で Snapshot を Record<symbol, QuoteResult> 型に変更し、52w 高安・当日高安・出来高・
4
+ // 1y close 配列(fetchHistorical)を取得できるよう拡張。
4
5
  import { INDICATORS } from "./indicators.js";
5
- const UA = "Mozilla/5.0 (compatible; lit-forge-mcp/0.3; +https://lit-forge.com/)";
6
+ const UA = "Mozilla/5.0 (compatible; lit-forge-mcp/0.4; +https://github.com/noblabs/lit-forge-mcp)";
6
7
  const TIMEOUT_MS = 4000;
7
8
  export class YahooFinanceError extends Error {
8
9
  symbol;
@@ -46,20 +47,58 @@ async function fetchRaw(symbol) {
46
47
  const changePercent = previousClose !== 0 ? (change / previousClose) * 100 : 0;
47
48
  const changeBp = change * 100;
48
49
  const fetchedAt = new Date(meta.regularMarketTime ? meta.regularMarketTime * 1000 : Date.now()).toISOString();
50
+ const sparkline = (result.indicators.quote?.[0]?.close ?? []).filter((v) => typeof v === "number");
49
51
  return {
50
52
  symbol,
51
53
  displayName: symbol,
52
54
  category: "fx",
55
+ unit: "",
53
56
  price,
54
57
  previousClose,
55
58
  change,
56
59
  changePercent,
57
60
  changeBp,
58
- unit: "",
59
61
  fetchedAt,
62
+ sparkline,
63
+ fiftyTwoWeekHigh: typeof meta.fiftyTwoWeekHigh === "number" ? meta.fiftyTwoWeekHigh : undefined,
64
+ fiftyTwoWeekLow: typeof meta.fiftyTwoWeekLow === "number" ? meta.fiftyTwoWeekLow : undefined,
65
+ dayHigh: typeof meta.regularMarketDayHigh === "number"
66
+ ? meta.regularMarketDayHigh
67
+ : undefined,
68
+ dayLow: typeof meta.regularMarketDayLow === "number"
69
+ ? meta.regularMarketDayLow
70
+ : undefined,
71
+ volume: typeof meta.regularMarketVolume === "number"
72
+ ? meta.regularMarketVolume
73
+ : undefined,
60
74
  };
61
75
  }
62
- // indicator のメタを Quote に上書きして返す。
76
+ // 任意 ticker 1y 日足 close 配列を取得(PERFORMANCE_SYMBOLS 等の分析用)。
77
+ export async function fetchHistorical(symbol) {
78
+ const url = `https://query1.finance.yahoo.com/v8/finance/chart/${encodeURIComponent(symbol)}` +
79
+ `?range=1y&interval=1d`;
80
+ let res;
81
+ try {
82
+ res = await fetch(url, {
83
+ headers: { "User-Agent": UA, Accept: "application/json" },
84
+ signal: AbortSignal.timeout(TIMEOUT_MS),
85
+ });
86
+ }
87
+ catch (e) {
88
+ const msg = e instanceof Error ? e.message : "fetch failed";
89
+ throw new YahooFinanceError(symbol, 0, `Yahoo Finance ${symbol} (hist): ${msg}`);
90
+ }
91
+ if (!res.ok)
92
+ throw new YahooFinanceError(symbol, res.status);
93
+ const data = (await res.json());
94
+ const result = data.chart.result?.[0];
95
+ if (!result) {
96
+ const desc = data.chart.error?.description ?? "empty result";
97
+ throw new YahooFinanceError(symbol, 0, `Yahoo Finance ${symbol} (hist): ${desc}`);
98
+ }
99
+ return (result.indicators.quote?.[0]?.close ?? []).filter((v) => typeof v === "number");
100
+ }
101
+ // indicator のメタ(displayName / category / unit)を Quote に上書き。
63
102
  function applyMeta(quote, indicator) {
64
103
  return {
65
104
  ...quote,
@@ -77,7 +116,7 @@ export async function fetchQuoteForIndicator(indicator) {
77
116
  catch (primaryErr) {
78
117
  if (!indicator.fallback) {
79
118
  const m = primaryErr instanceof Error ? primaryErr.message : "unknown";
80
- return { symbol: indicator.symbol, error: m };
119
+ return { error: m };
81
120
  }
82
121
  try {
83
122
  const quote = await fetchRaw(indicator.fallback);
@@ -86,7 +125,7 @@ export async function fetchQuoteForIndicator(indicator) {
86
125
  catch (fallbackErr) {
87
126
  const m1 = primaryErr instanceof Error ? primaryErr.message : "primary";
88
127
  const m2 = fallbackErr instanceof Error ? fallbackErr.message : "fallback";
89
- return { symbol: indicator.symbol, error: `${m1} / ${m2}` };
128
+ return { error: `${m1} / ${m2}` };
90
129
  }
91
130
  }
92
131
  }
@@ -94,17 +133,38 @@ export async function fetchQuoteForIndicator(indicator) {
94
133
  export async function fetchQuoteBySymbol(symbol) {
95
134
  return fetchRaw(symbol);
96
135
  }
97
- // 9 銘柄を並列取得して Snapshot を返す。
136
+ // INDICATORS(28 銘柄)を並列取得して Snapshot を返す。
137
+ // quotes は Record<symbol, QuoteResult>。Web 側と同型。
98
138
  export async function fetchSnapshot() {
99
- const results = await Promise.allSettled(INDICATORS.map((ind) => fetchQuoteForIndicator(ind)));
100
- const quotes = results.map((r, i) => {
101
- if (r.status === "fulfilled")
102
- return r.value;
103
- return {
104
- symbol: INDICATORS[i].symbol,
105
- error: r.reason instanceof Error ? r.reason.message : "unknown",
106
- };
107
- });
139
+ const settled = await Promise.allSettled(INDICATORS.map(async (ind) => [ind.symbol, await fetchQuoteForIndicator(ind)]));
140
+ const quotes = {};
141
+ for (const r of settled) {
142
+ if (r.status === "fulfilled") {
143
+ const [symbol, q] = r.value;
144
+ quotes[symbol] = q;
145
+ }
146
+ }
108
147
  return { fetchedAt: new Date().toISOString(), quotes };
109
148
  }
149
+ // 任意 symbol リストを並列取得(sectors / mag7 / fangplus 等のサブセット用)。
150
+ export async function fetchSubsetSnapshot(symbols) {
151
+ const settled = await Promise.allSettled(symbols.map(async (s) => {
152
+ try {
153
+ const quote = await fetchRaw(s);
154
+ return [s, quote];
155
+ }
156
+ catch (err) {
157
+ const m = err instanceof Error ? err.message : "fetch failed";
158
+ return [s, { error: m }];
159
+ }
160
+ }));
161
+ const out = {};
162
+ for (const r of settled) {
163
+ if (r.status === "fulfilled") {
164
+ const [symbol, q] = r.value;
165
+ out[symbol] = q;
166
+ }
167
+ }
168
+ return out;
169
+ }
110
170
  //# sourceMappingURL=yahoo.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"yahoo.js","sourceRoot":"","sources":["../../src/lib/yahoo.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"yahoo.js","sourceRoot":"","sources":["../../src/lib/yahoo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { Snapshot } from "./market-types.js";
2
+ export type YieldSpread = {
3
+ spread: number;
4
+ spreadChangeBp: number;
5
+ };
6
+ export declare function computeYieldSpread(snapshot: Snapshot): YieldSpread | null;
@@ -0,0 +1,20 @@
1
+ // 米イールドカーブの傾き(^TNX - ^FVX)を計算する純関数。
2
+ // 「今日のテーマ」やヘッダー脇のコンパクト表示で「米10y-5y スプレッド」を出すために使う。
3
+ //
4
+ // スプレッドは bp(ベーシスポイント、1bp = 0.01%)。プラスは順イールド(10y > 5y)。
5
+ function getQuote(snapshot, symbol) {
6
+ const q = snapshot.quotes[symbol];
7
+ if (!q || "error" in q)
8
+ return null;
9
+ return q;
10
+ }
11
+ export function computeYieldSpread(snapshot) {
12
+ const tnx = getQuote(snapshot, "^TNX");
13
+ const fvx = getQuote(snapshot, "^FVX");
14
+ if (!tnx || !fvx)
15
+ return null;
16
+ const spread = tnx.price - fvx.price;
17
+ const spreadChange = (tnx.change ?? 0) - (fvx.change ?? 0);
18
+ return { spread, spreadChangeBp: spreadChange * 100 };
19
+ }
20
+ //# sourceMappingURL=yield-spread.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yield-spread.js","sourceRoot":"","sources":["../../src/lib/yield-spread.ts"],"names":[],"mappings":"AAAA,oCAAoC;AACpC,kDAAkD;AAClD,EAAE;AACF,uDAAuD;AAWvD,SAAS,QAAQ,CAAC,QAAkB,EAAE,MAAc;IAClD,MAAM,CAAC,GAA4B,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3D,IAAI,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,CAAC,CAAC;AACX,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,QAAkB;IACnD,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvC,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAC9B,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;IACrC,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;IAC3D,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,YAAY,GAAG,GAAG,EAAE,CAAC;AACxD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type LitForgeTool } from "./types.js";
2
+ export declare const getMarketSessionsTool: LitForgeTool;
@@ -0,0 +1,27 @@
1
+ // 主要市場(東京・上海・ロンドン・NY)の現在の取引時間ステータスを返す。
2
+ // AI が「今は NY が動いている時間」「東京はもうすぐオープン」のような時間軸の context を取れる。
3
+ import { getSessionStatuses } from "../lib/sessions.js";
4
+ import { jsonReply } from "./types.js";
5
+ export const getMarketSessionsTool = {
6
+ name: "get_market_sessions",
7
+ title: "主要市場の取引時間ステータス",
8
+ description: "東京(9:00-15:30 JST)/ 上海(10:30-16:00 JST)/ ロンドン(17:00-25:30 JST)/ NY(22:30-29:00 JST)の現在の取引時間ステータス(open / pre-open / closed)を返します。土日は全て closed。サマータイムや臨時休場は未対応の概算。",
9
+ inputSchema: {},
10
+ handler: async () => {
11
+ const statuses = getSessionStatuses();
12
+ return jsonReply({
13
+ now: new Date().toISOString(),
14
+ sessions: statuses.map((s) => ({
15
+ id: s.session.id,
16
+ label: s.session.label,
17
+ state: s.state,
18
+ openHourJst: s.session.openHourJst,
19
+ closeHourJst: s.session.closeHourJst,
20
+ hoursUntilOpen: s.hoursUntilOpen,
21
+ hoursUntilClose: s.hoursUntilClose,
22
+ })),
23
+ note: "通常営業時間ベースの概算。祝日・臨時休場は反映されません。",
24
+ });
25
+ },
26
+ };
27
+ //# sourceMappingURL=get-market-sessions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-market-sessions.js","sourceRoot":"","sources":["../../src/tools/get-market-sessions.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,0DAA0D;AAE1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAqB,MAAM,YAAY,CAAC;AAE1D,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IACjD,IAAI,EAAE,qBAAqB;IAC3B,KAAK,EAAE,gBAAgB;IACvB,WAAW,EACT,kKAAkK;IACpK,WAAW,EAAE,EAAE;IACf,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC;QACtC,OAAO,SAAS,CAAC;YACf,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC7B,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC7B,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE;gBAChB,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK;gBACtB,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,WAAW,EAAE,CAAC,CAAC,OAAO,CAAC,WAAW;gBAClC,YAAY,EAAE,CAAC,CAAC,OAAO,CAAC,YAAY;gBACpC,cAAc,EAAE,CAAC,CAAC,cAAc;gBAChC,eAAe,EAAE,CAAC,CAAC,eAAe;aACnC,CAAC,CAAC;YACH,IAAI,EAAE,+BAA+B;SACtC,CAAC,CAAC;IACL,CAAC;CACF,CAAC"}
@@ -1,20 +1,22 @@
1
- // 主要マクロ指標 9 銘柄(為替・株・金利・コモディティ)の現在値・前日比を一括取得。
2
- // /today ページと同等情報を Claude Desktop / Cursor から呼べる。
1
+ // 主要マクロ指標 28 銘柄(為替・株・金利・コモディティ・暗号資産)の現在値・前日比を一括取得。
2
+ // Claude Desktop / Cursor 等の MCP クライアントから呼べる。
3
+ // v0.4 で 9 → 28 銘柄に拡張、出力形式は Record<symbol, QuoteResult>。
3
4
  import { fetchSnapshot } from "../lib/yahoo.js";
4
5
  import { errorReply, jsonReply } from "./types.js";
5
6
  export const getMarketSnapshotTool = {
6
7
  name: "get_market_snapshot",
7
8
  title: "主要マクロ指標スナップショット",
8
- description: "USD/JPY・EUR/JPY・日経平均・TOPIX・S&P 500・NASDAQ 100・米10年債利回り・金・原油 WTI の現在値と前日比を Yahoo Finance から取得します。lit-forge.com/today と同等の情報。約 1 時間遅れの参考値で、投資助言ではありません。",
9
+ description: "USD/JPY・EUR/JPY・GBP/JPY・AUD/JPY・EUR/USD・CHF/JPY・ドル指数・日経平均・TOPIX・NY ダウ・S&P 500・NASDAQ・VIX・NYSE FANG+・SOX・DAX・FTSE・上海総合・ハンセン・KOSPI・SENSEX・米10年/5年金利・金・原油・銅・ビットコイン・イーサリアム の主要 28 指標の現在値と前日比を Yahoo Finance から取得します。約 1 時間遅れの参考値で、投資助言ではありません。",
9
10
  inputSchema: {},
10
11
  handler: async () => {
11
12
  try {
12
13
  const snapshot = await fetchSnapshot();
13
- const successCount = snapshot.quotes.filter((q) => !("error" in q)).length;
14
+ const entries = Object.entries(snapshot.quotes);
15
+ const successCount = entries.filter(([, q]) => !("error" in q)).length;
14
16
  return jsonReply({
15
17
  fetchedAt: snapshot.fetchedAt,
16
18
  successCount,
17
- totalCount: snapshot.quotes.length,
19
+ totalCount: entries.length,
18
20
  quotes: snapshot.quotes,
19
21
  note: "データは Yahoo Finance より取得(約 1 時間遅れ)。投資助言ではなく情報集約。",
20
22
  });
@@ -1 +1 @@
1
- {"version":3,"file":"get-market-snapshot.js","sourceRoot":"","sources":["../../src/tools/get-market-snapshot.ts"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,kDAAkD;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAqB,MAAM,YAAY,CAAC;AAEtE,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IACjD,IAAI,EAAE,qBAAqB;IAC3B,KAAK,EAAE,iBAAiB;IACxB,WAAW,EACT,uJAAuJ;IACzJ,WAAW,EAAE,EAAE;IACf,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,aAAa,EAAE,CAAC;YACvC,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAC3E,OAAO,SAAS,CAAC;gBACf,SAAS,EAAE,QAAQ,CAAC,SAAS;gBAC7B,YAAY;gBACZ,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM;gBAClC,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,IAAI,EAAE,iDAAiD;aACxD,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,UAAU,CACf,kCACE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SACnC,EAAE,CACH,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
1
+ {"version":3,"file":"get-market-snapshot.js","sourceRoot":"","sources":["../../src/tools/get-market-snapshot.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,8CAA8C;AAC9C,yDAAyD;AAEzD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,SAAS,EAAqB,MAAM,YAAY,CAAC;AAEtE,MAAM,CAAC,MAAM,qBAAqB,GAAiB;IACjD,IAAI,EAAE,qBAAqB;IAC3B,KAAK,EAAE,iBAAiB;IACxB,WAAW,EACT,4OAA4O;IAC9O,WAAW,EAAE,EAAE;IACf,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,aAAa,EAAE,CAAC;YACvC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAChD,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CACjC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAC3B,CAAC,MAAM,CAAC;YACT,OAAO,SAAS,CAAC;gBACf,SAAS,EAAE,QAAQ,CAAC,SAAS;gBAC7B,YAAY;gBACZ,UAAU,EAAE,OAAO,CAAC,MAAM;gBAC1B,MAAM,EAAE,QAAQ,CAAC,MAAM;gBACvB,IAAI,EAAE,iDAAiD;aACxD,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,UAAU,CACf,kCACE,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SACnC,EAAE,CACH,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { type LitForgeTool } from "./types.js";
2
+ export declare const getMarketThermometerTool: LitForgeTool;