opencandle 0.1.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.
- package/LICENSE +21 -0
- package/README.md +150 -0
- package/dist/analysts/orchestrator.d.ts +9 -0
- package/dist/analysts/orchestrator.js +100 -0
- package/dist/analysts/orchestrator.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +122 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.js +76 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/infra/browser.d.ts +27 -0
- package/dist/infra/browser.js +102 -0
- package/dist/infra/browser.js.map +1 -0
- package/dist/infra/cache.d.ts +18 -0
- package/dist/infra/cache.js +42 -0
- package/dist/infra/cache.js.map +1 -0
- package/dist/infra/http-client.d.ts +13 -0
- package/dist/infra/http-client.js +54 -0
- package/dist/infra/http-client.js.map +1 -0
- package/dist/infra/index.d.ts +5 -0
- package/dist/infra/index.js +6 -0
- package/dist/infra/index.js.map +1 -0
- package/dist/infra/open-url.d.ts +1 -0
- package/dist/infra/open-url.js +29 -0
- package/dist/infra/open-url.js.map +1 -0
- package/dist/infra/opencandle-paths.d.ts +11 -0
- package/dist/infra/opencandle-paths.js +48 -0
- package/dist/infra/opencandle-paths.js.map +1 -0
- package/dist/infra/rate-limiter.d.ts +7 -0
- package/dist/infra/rate-limiter.js +38 -0
- package/dist/infra/rate-limiter.js.map +1 -0
- package/dist/memory/index.d.ts +5 -0
- package/dist/memory/index.js +5 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/preference-extractor.d.ts +6 -0
- package/dist/memory/preference-extractor.js +88 -0
- package/dist/memory/preference-extractor.js.map +1 -0
- package/dist/memory/retrieval.d.ts +8 -0
- package/dist/memory/retrieval.js +61 -0
- package/dist/memory/retrieval.js.map +1 -0
- package/dist/memory/sqlite.d.ts +5 -0
- package/dist/memory/sqlite.js +95 -0
- package/dist/memory/sqlite.js.map +1 -0
- package/dist/memory/storage.d.ts +47 -0
- package/dist/memory/storage.js +124 -0
- package/dist/memory/storage.js.map +1 -0
- package/dist/onboarding/state.d.ts +8 -0
- package/dist/onboarding/state.js +31 -0
- package/dist/onboarding/state.js.map +1 -0
- package/dist/pi/opencandle-extension.d.ts +2 -0
- package/dist/pi/opencandle-extension.js +205 -0
- package/dist/pi/opencandle-extension.js.map +1 -0
- package/dist/pi/session.d.ts +10 -0
- package/dist/pi/session.js +28 -0
- package/dist/pi/session.js.map +1 -0
- package/dist/pi/setup.d.ts +10 -0
- package/dist/pi/setup.js +357 -0
- package/dist/pi/setup.js.map +1 -0
- package/dist/pi/tool-adapter.d.ts +5 -0
- package/dist/pi/tool-adapter.js +17 -0
- package/dist/pi/tool-adapter.js.map +1 -0
- package/dist/prompts/workflow-prompts.d.ts +9 -0
- package/dist/prompts/workflow-prompts.js +202 -0
- package/dist/prompts/workflow-prompts.js.map +1 -0
- package/dist/providers/alpha-vantage.d.ts +4 -0
- package/dist/providers/alpha-vantage.js +122 -0
- package/dist/providers/alpha-vantage.js.map +1 -0
- package/dist/providers/coingecko.d.ts +3 -0
- package/dist/providers/coingecko.js +53 -0
- package/dist/providers/coingecko.js.map +1 -0
- package/dist/providers/fear-greed.d.ts +2 -0
- package/dist/providers/fear-greed.js +26 -0
- package/dist/providers/fear-greed.js.map +1 -0
- package/dist/providers/fred.d.ts +2 -0
- package/dist/providers/fred.js +37 -0
- package/dist/providers/fred.js.map +1 -0
- package/dist/providers/index.d.ts +7 -0
- package/dist/providers/index.js +8 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/reddit.d.ts +9 -0
- package/dist/providers/reddit.js +69 -0
- package/dist/providers/reddit.js.map +1 -0
- package/dist/providers/sec-edgar.d.ts +9 -0
- package/dist/providers/sec-edgar.js +59 -0
- package/dist/providers/sec-edgar.js.map +1 -0
- package/dist/providers/yahoo-finance.d.ts +17 -0
- package/dist/providers/yahoo-finance.js +231 -0
- package/dist/providers/yahoo-finance.js.map +1 -0
- package/dist/routing/classify-intent.d.ts +2 -0
- package/dist/routing/classify-intent.js +147 -0
- package/dist/routing/classify-intent.js.map +1 -0
- package/dist/routing/defaults.d.ts +7 -0
- package/dist/routing/defaults.js +26 -0
- package/dist/routing/defaults.js.map +1 -0
- package/dist/routing/entity-extractor.d.ts +3 -0
- package/dist/routing/entity-extractor.js +130 -0
- package/dist/routing/entity-extractor.js.map +1 -0
- package/dist/routing/index.d.ts +5 -0
- package/dist/routing/index.js +5 -0
- package/dist/routing/index.js.map +1 -0
- package/dist/routing/slot-resolver.d.ts +15 -0
- package/dist/routing/slot-resolver.js +120 -0
- package/dist/routing/slot-resolver.js.map +1 -0
- package/dist/routing/types.d.ts +51 -0
- package/dist/routing/types.js +2 -0
- package/dist/routing/types.js.map +1 -0
- package/dist/system-prompt.d.ts +1 -0
- package/dist/system-prompt.js +49 -0
- package/dist/system-prompt.js.map +1 -0
- package/dist/tool-kit.d.ts +19 -0
- package/dist/tool-kit.js +20 -0
- package/dist/tool-kit.js.map +1 -0
- package/dist/tools/fundamentals/company-overview.d.ts +7 -0
- package/dist/tools/fundamentals/company-overview.js +40 -0
- package/dist/tools/fundamentals/company-overview.js.map +1 -0
- package/dist/tools/fundamentals/comps.d.ts +22 -0
- package/dist/tools/fundamentals/comps.js +110 -0
- package/dist/tools/fundamentals/comps.js.map +1 -0
- package/dist/tools/fundamentals/dcf.d.ts +46 -0
- package/dist/tools/fundamentals/dcf.js +184 -0
- package/dist/tools/fundamentals/dcf.js.map +1 -0
- package/dist/tools/fundamentals/earnings.d.ts +7 -0
- package/dist/tools/fundamentals/earnings.js +33 -0
- package/dist/tools/fundamentals/earnings.js.map +1 -0
- package/dist/tools/fundamentals/financials.d.ts +7 -0
- package/dist/tools/fundamentals/financials.js +37 -0
- package/dist/tools/fundamentals/financials.js.map +1 -0
- package/dist/tools/fundamentals/sec-filings.d.ts +8 -0
- package/dist/tools/fundamentals/sec-filings.js +40 -0
- package/dist/tools/fundamentals/sec-filings.js.map +1 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/index.js +51 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/macro/fear-greed.d.ts +5 -0
- package/dist/tools/macro/fear-greed.js +26 -0
- package/dist/tools/macro/fear-greed.js.map +1 -0
- package/dist/tools/macro/fred-data.d.ts +8 -0
- package/dist/tools/macro/fred-data.js +34 -0
- package/dist/tools/macro/fred-data.js.map +1 -0
- package/dist/tools/market/crypto-history.d.ts +8 -0
- package/dist/tools/market/crypto-history.js +32 -0
- package/dist/tools/market/crypto-history.js.map +1 -0
- package/dist/tools/market/crypto-price.d.ts +7 -0
- package/dist/tools/market/crypto-price.js +42 -0
- package/dist/tools/market/crypto-price.js.map +1 -0
- package/dist/tools/market/search-ticker.d.ts +6 -0
- package/dist/tools/market/search-ticker.js +33 -0
- package/dist/tools/market/search-ticker.js.map +1 -0
- package/dist/tools/market/stock-history.d.ts +9 -0
- package/dist/tools/market/stock-history.js +35 -0
- package/dist/tools/market/stock-history.js.map +1 -0
- package/dist/tools/market/stock-quote.d.ts +7 -0
- package/dist/tools/market/stock-quote.js +32 -0
- package/dist/tools/market/stock-quote.js.map +1 -0
- package/dist/tools/options/greeks.d.ts +14 -0
- package/dist/tools/options/greeks.js +65 -0
- package/dist/tools/options/greeks.js.map +1 -0
- package/dist/tools/options/option-chain.d.ts +9 -0
- package/dist/tools/options/option-chain.js +61 -0
- package/dist/tools/options/option-chain.js.map +1 -0
- package/dist/tools/portfolio/correlation.d.ts +10 -0
- package/dist/tools/portfolio/correlation.js +122 -0
- package/dist/tools/portfolio/correlation.js.map +1 -0
- package/dist/tools/portfolio/predictions.d.ts +49 -0
- package/dist/tools/portfolio/predictions.js +171 -0
- package/dist/tools/portfolio/predictions.js.map +1 -0
- package/dist/tools/portfolio/risk-analysis.d.ts +12 -0
- package/dist/tools/portfolio/risk-analysis.js +113 -0
- package/dist/tools/portfolio/risk-analysis.js.map +1 -0
- package/dist/tools/portfolio/tracker.d.ts +10 -0
- package/dist/tools/portfolio/tracker.js +125 -0
- package/dist/tools/portfolio/tracker.js.map +1 -0
- package/dist/tools/portfolio/watchlist.d.ts +10 -0
- package/dist/tools/portfolio/watchlist.js +120 -0
- package/dist/tools/portfolio/watchlist.js.map +1 -0
- package/dist/tools/sentiment/news-sentiment.d.ts +7 -0
- package/dist/tools/sentiment/news-sentiment.js +57 -0
- package/dist/tools/sentiment/news-sentiment.js.map +1 -0
- package/dist/tools/sentiment/reddit-sentiment.d.ts +8 -0
- package/dist/tools/sentiment/reddit-sentiment.js +37 -0
- package/dist/tools/sentiment/reddit-sentiment.js.map +1 -0
- package/dist/tools/technical/backtest.d.ts +26 -0
- package/dist/tools/technical/backtest.js +190 -0
- package/dist/tools/technical/backtest.js.map +1 -0
- package/dist/tools/technical/indicators.d.ts +23 -0
- package/dist/tools/technical/indicators.js +212 -0
- package/dist/tools/technical/indicators.js.map +1 -0
- package/dist/types/fundamentals.d.ts +44 -0
- package/dist/types/fundamentals.js +2 -0
- package/dist/types/fundamentals.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/macro.d.ts +24 -0
- package/dist/types/macro.js +14 -0
- package/dist/types/macro.js.map +1 -0
- package/dist/types/market.d.ts +41 -0
- package/dist/types/market.js +2 -0
- package/dist/types/market.js.map +1 -0
- package/dist/types/options.d.ts +33 -0
- package/dist/types/options.js +2 -0
- package/dist/types/options.js.map +1 -0
- package/dist/types/portfolio.d.ts +44 -0
- package/dist/types/portfolio.js +2 -0
- package/dist/types/portfolio.js.map +1 -0
- package/dist/types/sentiment.d.ts +24 -0
- package/dist/types/sentiment.js +2 -0
- package/dist/types/sentiment.js.map +1 -0
- package/dist/workflows/compare-assets.d.ts +3 -0
- package/dist/workflows/compare-assets.js +14 -0
- package/dist/workflows/compare-assets.js.map +1 -0
- package/dist/workflows/index.d.ts +4 -0
- package/dist/workflows/index.js +4 -0
- package/dist/workflows/index.js.map +1 -0
- package/dist/workflows/options-screener.d.ts +3 -0
- package/dist/workflows/options-screener.js +22 -0
- package/dist/workflows/options-screener.js.map +1 -0
- package/dist/workflows/portfolio-builder.d.ts +3 -0
- package/dist/workflows/portfolio-builder.js +26 -0
- package/dist/workflows/portfolio-builder.js.map +1 -0
- package/dist/workflows/types.d.ts +4 -0
- package/dist/workflows/types.js +2 -0
- package/dist/workflows/types.js.map +1 -0
- package/package.json +97 -0
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { getOverview, getFinancials } from "../../providers/alpha-vantage.js";
|
|
3
|
+
import { getQuote } from "../../providers/yahoo-finance.js";
|
|
4
|
+
import { getConfig } from "../../config.js";
|
|
5
|
+
export function computeDCF(params) {
|
|
6
|
+
const { freeCashFlow, growthRate, discountRate, terminalGrowth, years, netDebt, sharesOutstanding } = params;
|
|
7
|
+
// Project future cash flows (mid-year convention: discount at year-0.5)
|
|
8
|
+
const projectedCashFlows = [];
|
|
9
|
+
for (let y = 1; y <= years; y++) {
|
|
10
|
+
const fcf = freeCashFlow * (1 + growthRate) ** y;
|
|
11
|
+
const pv = fcf / (1 + discountRate) ** (y - 0.5); // mid-year convention
|
|
12
|
+
projectedCashFlows.push({ year: y, fcf, presentValue: pv });
|
|
13
|
+
}
|
|
14
|
+
// Terminal value (Gordon Growth Model), discounted at full year (end of projection)
|
|
15
|
+
const finalFCF = freeCashFlow * (1 + growthRate) ** years;
|
|
16
|
+
const terminalValue = (finalFCF * (1 + terminalGrowth)) / (discountRate - terminalGrowth);
|
|
17
|
+
const pvTerminal = terminalValue / (1 + discountRate) ** years;
|
|
18
|
+
// Enterprise value
|
|
19
|
+
const sumPVs = projectedCashFlows.reduce((s, cf) => s + cf.presentValue, 0);
|
|
20
|
+
const enterpriseValue = sumPVs + pvTerminal;
|
|
21
|
+
// Equity value → per share
|
|
22
|
+
const equityValue = enterpriseValue - netDebt;
|
|
23
|
+
const intrinsicValue = equityValue / sharesOutstanding;
|
|
24
|
+
// Sensitivity table: vary growth ±2% and discount ±2%
|
|
25
|
+
const sensitivityTable = [];
|
|
26
|
+
for (let gDelta = -0.02; gDelta <= 0.02; gDelta += 0.01) {
|
|
27
|
+
for (let dDelta = -0.02; dDelta <= 0.02; dDelta += 0.01) {
|
|
28
|
+
const g = growthRate + gDelta;
|
|
29
|
+
const d = discountRate + dDelta;
|
|
30
|
+
if (d <= terminalGrowth || d <= 0 || g < 0)
|
|
31
|
+
continue;
|
|
32
|
+
const sensResult = computeDCFSimple(freeCashFlow, g, d, terminalGrowth, years, netDebt, sharesOutstanding);
|
|
33
|
+
sensitivityTable.push({ growthRate: g, discountRate: d, intrinsicValue: sensResult });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Validation warnings (inspired by Anthropic financial plugins + Dexter)
|
|
37
|
+
const warnings = [];
|
|
38
|
+
const tvPctOfEV = pvTerminal / enterpriseValue;
|
|
39
|
+
if (tvPctOfEV > 0.85) {
|
|
40
|
+
warnings.push(`Terminal value is ${(tvPctOfEV * 100).toFixed(0)}% of enterprise value (typical: 40-80%). The valuation is heavily dependent on terminal assumptions.`);
|
|
41
|
+
}
|
|
42
|
+
const spreadPct = discountRate - terminalGrowth;
|
|
43
|
+
if (spreadPct < 0.02) {
|
|
44
|
+
warnings.push(`Terminal growth (${(terminalGrowth * 100).toFixed(1)}%) is very close to discount rate (${(discountRate * 100).toFixed(1)}%). Small changes in assumptions will produce large swings in value.`);
|
|
45
|
+
}
|
|
46
|
+
if (discountRate < 0.05 || discountRate > 0.20) {
|
|
47
|
+
warnings.push(`Discount rate of ${(discountRate * 100).toFixed(1)}% is outside typical WACC range (5-20%).`);
|
|
48
|
+
}
|
|
49
|
+
if (growthRate > 0.20) {
|
|
50
|
+
warnings.push(`Growth rate of ${(growthRate * 100).toFixed(1)}% exceeds 20%. High growth is difficult to sustain — consider a multi-stage model.`);
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
intrinsicValue,
|
|
54
|
+
enterpriseValue,
|
|
55
|
+
terminalValue,
|
|
56
|
+
netDebt,
|
|
57
|
+
projectedCashFlows,
|
|
58
|
+
assumptions: {
|
|
59
|
+
fcf: freeCashFlow,
|
|
60
|
+
growthRate,
|
|
61
|
+
discountRate,
|
|
62
|
+
terminalGrowth,
|
|
63
|
+
years,
|
|
64
|
+
},
|
|
65
|
+
sensitivityTable,
|
|
66
|
+
warnings,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function computeDCFSimple(fcf, g, d, tg, years, debt, shares) {
|
|
70
|
+
let sumPV = 0;
|
|
71
|
+
for (let y = 1; y <= years; y++) {
|
|
72
|
+
sumPV += (fcf * (1 + g) ** y) / (1 + d) ** (y - 0.5); // mid-year convention
|
|
73
|
+
}
|
|
74
|
+
const finalFCF = fcf * (1 + g) ** years;
|
|
75
|
+
const tv = (finalFCF * (1 + tg)) / (d - tg);
|
|
76
|
+
const pvTV = tv / (1 + d) ** years;
|
|
77
|
+
return (sumPV + pvTV - debt) / shares;
|
|
78
|
+
}
|
|
79
|
+
export function computeNetDebt(f) {
|
|
80
|
+
if (f.totalDebt != null && f.cashAndEquivalents != null) {
|
|
81
|
+
return f.totalDebt - f.cashAndEquivalents;
|
|
82
|
+
}
|
|
83
|
+
// Fallback: totalLiabilities - totalAssets (negative means net cash position)
|
|
84
|
+
return f.totalLiabilities - f.totalAssets;
|
|
85
|
+
}
|
|
86
|
+
const params = Type.Object({
|
|
87
|
+
symbol: Type.String({ description: "Stock ticker symbol (e.g. AAPL, MSFT)" }),
|
|
88
|
+
growth_rate: Type.Optional(Type.Number({ description: "Annual FCF growth rate as decimal (e.g. 0.10 for 10%). If omitted, estimated from historical data." })),
|
|
89
|
+
discount_rate: Type.Optional(Type.Number({ description: "Discount rate / WACC as decimal (default: 0.10 for 10%)" })),
|
|
90
|
+
terminal_growth: Type.Optional(Type.Number({ description: "Terminal growth rate as decimal (default: 0.03 for 3%)" })),
|
|
91
|
+
projection_years: Type.Optional(Type.Number({ description: "Years to project forward (default: 5)" })),
|
|
92
|
+
});
|
|
93
|
+
export const dcfTool = {
|
|
94
|
+
name: "compute_dcf",
|
|
95
|
+
label: "DCF Valuation",
|
|
96
|
+
description: "Compute a Discounted Cash Flow (DCF) intrinsic value estimate for a stock. Uses free cash flow, growth projections, and a discount rate to estimate what the stock is worth. Returns intrinsic value per share, margin of safety vs current price, and a sensitivity table.",
|
|
97
|
+
parameters: params,
|
|
98
|
+
async execute(toolCallId, args) {
|
|
99
|
+
const symbol = args.symbol.toUpperCase();
|
|
100
|
+
const config = getConfig();
|
|
101
|
+
if (!config.alphaVantageApiKey) {
|
|
102
|
+
throw new Error("Alpha Vantage API key not configured. Set ALPHA_VANTAGE_API_KEY or add ~/.opencandle/config.json.");
|
|
103
|
+
}
|
|
104
|
+
const [overview, financials, quote] = await Promise.all([
|
|
105
|
+
getOverview(symbol, config.alphaVantageApiKey),
|
|
106
|
+
getFinancials(symbol, config.alphaVantageApiKey),
|
|
107
|
+
getQuote(symbol),
|
|
108
|
+
]);
|
|
109
|
+
const latestFCF = financials[0]?.freeCashFlow ?? 0;
|
|
110
|
+
if (latestFCF <= 0) {
|
|
111
|
+
return {
|
|
112
|
+
content: [{ type: "text", text: `${symbol} has negative or zero free cash flow ($${latestFCF.toLocaleString()}). DCF is not meaningful for companies without positive FCF.` }],
|
|
113
|
+
details: null,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// Estimate growth from historical FCF if not provided
|
|
117
|
+
let growthRate = args.growth_rate ?? 0.10;
|
|
118
|
+
if (!args.growth_rate && financials.length >= 2) {
|
|
119
|
+
const olderFCF = financials[1]?.freeCashFlow;
|
|
120
|
+
if (olderFCF && olderFCF > 0) {
|
|
121
|
+
growthRate = Math.max(0.02, Math.min(0.25, (latestFCF - olderFCF) / olderFCF));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const discountRate = args.discount_rate ?? 0.10;
|
|
125
|
+
const terminalGrowth = args.terminal_growth ?? 0.03;
|
|
126
|
+
const years = args.projection_years ?? 5;
|
|
127
|
+
const sharesOutstanding = quote.price > 0 ? overview.marketCap / quote.price : 1;
|
|
128
|
+
const netDebt = financials[0] ? computeNetDebt(financials[0]) : 0;
|
|
129
|
+
const result = computeDCF({
|
|
130
|
+
freeCashFlow: latestFCF,
|
|
131
|
+
growthRate,
|
|
132
|
+
discountRate,
|
|
133
|
+
terminalGrowth,
|
|
134
|
+
years,
|
|
135
|
+
netDebt: Math.max(0, netDebt),
|
|
136
|
+
sharesOutstanding,
|
|
137
|
+
});
|
|
138
|
+
const marginOfSafety = (result.intrinsicValue - quote.price) / result.intrinsicValue;
|
|
139
|
+
const upside = (result.intrinsicValue - quote.price) / quote.price;
|
|
140
|
+
const lines = [
|
|
141
|
+
`**${symbol} DCF Valuation**`,
|
|
142
|
+
``,
|
|
143
|
+
`Current Price: $${quote.price.toFixed(2)}`,
|
|
144
|
+
`Intrinsic Value: $${result.intrinsicValue.toFixed(2)}`,
|
|
145
|
+
`Margin of Safety: ${(marginOfSafety * 100).toFixed(1)}%`,
|
|
146
|
+
`Upside/Downside: ${upside >= 0 ? "+" : ""}${(upside * 100).toFixed(1)}%`,
|
|
147
|
+
``,
|
|
148
|
+
`**Assumptions**`,
|
|
149
|
+
`Free Cash Flow: $${(latestFCF / 1e9).toFixed(2)}B`,
|
|
150
|
+
`Growth Rate: ${(growthRate * 100).toFixed(1)}%`,
|
|
151
|
+
`Discount Rate (WACC): ${(discountRate * 100).toFixed(1)}%`,
|
|
152
|
+
`Terminal Growth: ${(terminalGrowth * 100).toFixed(1)}%`,
|
|
153
|
+
`Projection: ${years} years`,
|
|
154
|
+
``,
|
|
155
|
+
`**Projected Cash Flows**`,
|
|
156
|
+
...result.projectedCashFlows.map((cf) => ` Year ${cf.year}: FCF $${(cf.fcf / 1e9).toFixed(2)}B → PV $${(cf.presentValue / 1e9).toFixed(2)}B`),
|
|
157
|
+
` Terminal Value: $${(result.terminalValue / 1e9).toFixed(2)}B`,
|
|
158
|
+
` Enterprise Value: $${(result.enterpriseValue / 1e9).toFixed(2)}B`,
|
|
159
|
+
``,
|
|
160
|
+
`**Sensitivity Table** (Intrinsic Value at different Growth/Discount rates)`,
|
|
161
|
+
...formatSensitivityTable(result.sensitivityTable),
|
|
162
|
+
];
|
|
163
|
+
return {
|
|
164
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
165
|
+
details: { ...result, currentPrice: quote.price, marginOfSafety, upside },
|
|
166
|
+
};
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
function formatSensitivityTable(table) {
|
|
170
|
+
if (table.length === 0)
|
|
171
|
+
return [" (insufficient data for sensitivity table)"];
|
|
172
|
+
const discountRates = [...new Set(table.map((e) => e.discountRate))].sort((a, b) => a - b);
|
|
173
|
+
const growthRates = [...new Set(table.map((e) => e.growthRate))].sort((a, b) => a - b);
|
|
174
|
+
const header = ` ${"Growth↓/WACC→".padEnd(14)} ${discountRates.map((d) => `${(d * 100).toFixed(0)}%`.padStart(8)).join("")}`;
|
|
175
|
+
const rows = growthRates.map((g) => {
|
|
176
|
+
const cells = discountRates.map((d) => {
|
|
177
|
+
const entry = table.find((e) => e.growthRate === g && e.discountRate === d);
|
|
178
|
+
return entry ? `$${entry.intrinsicValue.toFixed(0)}`.padStart(8) : "N/A".padStart(8);
|
|
179
|
+
});
|
|
180
|
+
return ` ${`${(g * 100).toFixed(0)}%`.padEnd(14)} ${cells.join("")}`;
|
|
181
|
+
});
|
|
182
|
+
return [header, ...rows];
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=dcf.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dcf.js","sourceRoot":"","sources":["../../../src/tools/fundamentals/dcf.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import type { EarningsData } from "../../types/fundamentals.js";
|
|
3
|
+
declare const params: import("@sinclair/typebox").TObject<{
|
|
4
|
+
symbol: import("@sinclair/typebox").TString;
|
|
5
|
+
}>;
|
|
6
|
+
export declare const earningsTool: AgentTool<typeof params, EarningsData>;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { getEarnings } from "../../providers/alpha-vantage.js";
|
|
3
|
+
import { getConfig } from "../../config.js";
|
|
4
|
+
const params = Type.Object({
|
|
5
|
+
symbol: Type.String({ description: "Stock ticker symbol (e.g. AAPL, MSFT)" }),
|
|
6
|
+
});
|
|
7
|
+
export const earningsTool = {
|
|
8
|
+
name: "get_earnings",
|
|
9
|
+
label: "Earnings History",
|
|
10
|
+
description: "Get quarterly earnings: reported EPS, estimated EPS, and surprise percentage for the last 8 quarters. Requires ALPHA_VANTAGE_API_KEY.",
|
|
11
|
+
parameters: params,
|
|
12
|
+
async execute(toolCallId, args) {
|
|
13
|
+
const apiKey = getConfig().alphaVantageApiKey;
|
|
14
|
+
if (!apiKey) {
|
|
15
|
+
throw new Error("Alpha Vantage API key not configured. Set ALPHA_VANTAGE_API_KEY or add ~/.opencandle/config.json.");
|
|
16
|
+
}
|
|
17
|
+
const earnings = await getEarnings(args.symbol.toUpperCase(), apiKey);
|
|
18
|
+
if (earnings.quarterly.length === 0) {
|
|
19
|
+
return {
|
|
20
|
+
content: [{ type: "text", text: `No earnings data found for ${args.symbol}` }],
|
|
21
|
+
details: earnings,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const header = `${args.symbol.toUpperCase()} — Quarterly Earnings (last ${earnings.quarterly.length} quarters)`;
|
|
25
|
+
const rows = earnings.quarterly.map((q) => {
|
|
26
|
+
const sign = q.surprisePercent >= 0 ? "+" : "";
|
|
27
|
+
return `${q.date} | Reported: $${q.reportedEPS.toFixed(2)} | Est: $${q.estimatedEPS.toFixed(2)} | Surprise: ${sign}${q.surprisePercent.toFixed(1)}%`;
|
|
28
|
+
});
|
|
29
|
+
const text = [header, ...rows].join("\n");
|
|
30
|
+
return { content: [{ type: "text", text }], details: earnings };
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=earnings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"earnings.js","sourceRoot":"","sources":["../../../src/tools/fundamentals/earnings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACzB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,uCAAuC,EAAE,CAAC;CAC9E,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAA2C;IAClE,IAAI,EAAE,cAAc;IACpB,KAAK,EAAE,kBAAkB;IACzB,WAAW,EACT,uIAAuI;IACzI,UAAU,EAAE,MAAM;IAClB,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI;QAC5B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC,kBAAkB,CAAC;QAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,mGAAmG,CAAC,CAAC;QACvH,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;QACtE,IAAI,QAAQ,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpC,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,8BAA8B,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC9E,OAAO,EAAE,QAAQ;aAClB,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,+BAA+B,QAAQ,CAAC,SAAS,CAAC,MAAM,YAAY,CAAC;QAChH,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACxC,MAAM,IAAI,GAAG,CAAC,CAAC,eAAe,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/C,OAAO,GAAG,CAAC,CAAC,IAAI,iBAAiB,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,IAAI,GAAG,CAAC,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;QACvJ,CAAC,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAClE,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import type { FinancialStatement } from "../../types/fundamentals.js";
|
|
3
|
+
declare const params: import("@sinclair/typebox").TObject<{
|
|
4
|
+
symbol: import("@sinclair/typebox").TString;
|
|
5
|
+
}>;
|
|
6
|
+
export declare const financialsTool: AgentTool<typeof params, FinancialStatement[]>;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { getFinancials } from "../../providers/alpha-vantage.js";
|
|
3
|
+
import { getConfig } from "../../config.js";
|
|
4
|
+
const params = Type.Object({
|
|
5
|
+
symbol: Type.String({ description: "Stock ticker symbol (e.g. AAPL, MSFT)" }),
|
|
6
|
+
});
|
|
7
|
+
export const financialsTool = {
|
|
8
|
+
name: "get_financials",
|
|
9
|
+
label: "Financial Statements",
|
|
10
|
+
description: "Get annual income statement data: revenue, gross profit, operating income, net income, and EPS. Requires ALPHA_VANTAGE_API_KEY.",
|
|
11
|
+
parameters: params,
|
|
12
|
+
async execute(toolCallId, args) {
|
|
13
|
+
const apiKey = getConfig().alphaVantageApiKey;
|
|
14
|
+
if (!apiKey) {
|
|
15
|
+
throw new Error("Alpha Vantage API key not configured. Set ALPHA_VANTAGE_API_KEY or add ~/.opencandle/config.json.");
|
|
16
|
+
}
|
|
17
|
+
const statements = await getFinancials(args.symbol.toUpperCase(), apiKey);
|
|
18
|
+
if (statements.length === 0) {
|
|
19
|
+
return {
|
|
20
|
+
content: [{ type: "text", text: `No financial data found for ${args.symbol}` }],
|
|
21
|
+
details: [],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
const header = `${args.symbol.toUpperCase()} — Annual Income Statement (${statements.length} years)`;
|
|
25
|
+
const rows = statements.map((s) => `${s.fiscalDate} | Rev: $${fmt(s.revenue)} | GP: $${fmt(s.grossProfit)} | OpInc: $${fmt(s.operatingIncome)} | Net: $${fmt(s.netIncome)}`);
|
|
26
|
+
const text = [header, ...rows].join("\n");
|
|
27
|
+
return { content: [{ type: "text", text }], details: statements };
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
function fmt(n) {
|
|
31
|
+
if (n >= 1e9)
|
|
32
|
+
return `${(n / 1e9).toFixed(2)}B`;
|
|
33
|
+
if (n >= 1e6)
|
|
34
|
+
return `${(n / 1e6).toFixed(2)}M`;
|
|
35
|
+
return n.toLocaleString();
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=financials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"financials.js","sourceRoot":"","sources":["../../../src/tools/fundamentals/financials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACzB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,uCAAuC,EAAE,CAAC;CAC9E,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAmD;IAC5E,IAAI,EAAE,gBAAgB;IACtB,KAAK,EAAE,sBAAsB;IAC7B,WAAW,EACT,iIAAiI;IACnI,UAAU,EAAE,MAAM;IAClB,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI;QAC5B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC,kBAAkB,CAAC;QAC9C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,mGAAmG,CAAC,CAAC;QACvH,CAAC;QAED,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;QAC1E,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,+BAA+B,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC/E,OAAO,EAAE,EAAE;aACZ,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,+BAA+B,UAAU,CAAC,MAAM,SAAS,CAAC;QACrG,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAChC,GAAG,CAAC,CAAC,UAAU,YAAY,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CACzI,CAAC;QAEF,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1C,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;IACpE,CAAC;CACF,CAAC;AAEF,SAAS,GAAG,CAAC,CAAS;IACpB,IAAI,CAAC,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAChD,IAAI,CAAC,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAChD,OAAO,CAAC,CAAC,cAAc,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
declare const params: import("@sinclair/typebox").TObject<{
|
|
3
|
+
symbol: import("@sinclair/typebox").TString;
|
|
4
|
+
form_types: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TArray<import("@sinclair/typebox").TString>>;
|
|
5
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const secFilingsTool: AgentTool<typeof params>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { searchFilings } from "../../providers/sec-edgar.js";
|
|
3
|
+
const params = Type.Object({
|
|
4
|
+
symbol: Type.String({ description: "Stock ticker symbol (e.g. AAPL, MSFT, TSLA)" }),
|
|
5
|
+
form_types: Type.Optional(Type.Array(Type.String(), {
|
|
6
|
+
description: "Filing types to search: 10-K (annual), 10-Q (quarterly), 8-K (material events). Default: all three.",
|
|
7
|
+
})),
|
|
8
|
+
limit: Type.Optional(Type.Number({ description: "Maximum number of filings to return (default: 10)" })),
|
|
9
|
+
});
|
|
10
|
+
export const secFilingsTool = {
|
|
11
|
+
name: "get_sec_filings",
|
|
12
|
+
label: "SEC Filings",
|
|
13
|
+
description: "Search SEC EDGAR for company filings (10-K annual reports, 10-Q quarterly reports, 8-K material events). Returns filing dates, types, and direct links to the documents. Free API, no key required.",
|
|
14
|
+
parameters: params,
|
|
15
|
+
async execute(toolCallId, args) {
|
|
16
|
+
const symbol = args.symbol.toUpperCase();
|
|
17
|
+
const formTypes = args.form_types ?? ["10-K", "10-Q", "8-K"];
|
|
18
|
+
const limit = args.limit ?? 10;
|
|
19
|
+
const filings = await searchFilings(symbol, formTypes, limit);
|
|
20
|
+
if (filings.length === 0) {
|
|
21
|
+
return {
|
|
22
|
+
content: [{ type: "text", text: `No SEC filings found for ${symbol}. Verify the ticker is a US-listed company.` }],
|
|
23
|
+
details: null,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
const lines = [
|
|
27
|
+
`**${symbol} SEC Filings** (${filings.length} found)`,
|
|
28
|
+
``,
|
|
29
|
+
...filings.map((f) => ` ${f.formType.padEnd(6)} | Filed: ${f.filedDate} | Period: ${f.periodOfReport || "N/A"} | ${f.entityName}`),
|
|
30
|
+
``,
|
|
31
|
+
`Links:`,
|
|
32
|
+
...filings.map((f) => ` ${f.formType} (${f.filedDate}): ${f.url}`),
|
|
33
|
+
];
|
|
34
|
+
return {
|
|
35
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
36
|
+
details: { symbol, filings },
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=sec-filings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sec-filings.js","sourceRoot":"","sources":["../../../src/tools/fundamentals/sec-filings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACzB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,6CAA6C,EAAE,CAAC;IACnF,UAAU,EAAE,IAAI,CAAC,QAAQ,CACvB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE;QACxB,WAAW,EAAE,qGAAqG;KACnH,CAAC,CACH;IACD,KAAK,EAAE,IAAI,CAAC,QAAQ,CAClB,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,mDAAmD,EAAE,CAAC,CAClF;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAA6B;IACtD,IAAI,EAAE,iBAAiB;IACvB,KAAK,EAAE,aAAa;IACpB,WAAW,EACT,qMAAqM;IACvM,UAAU,EAAE,MAAM;IAClB,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI;QAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAE/B,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAE9D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,4BAA4B,MAAM,6CAA6C,EAAE,CAAC;gBAClH,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG;YACZ,KAAK,MAAM,mBAAmB,OAAO,CAAC,MAAM,SAAS;YACrD,EAAE;YACF,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACnB,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,SAAS,cAAc,CAAC,CAAC,cAAc,IAAI,KAAK,MAAM,CAAC,CAAC,UAAU,EAAE,CAC7G;YACD,EAAE;YACF,QAAQ;YACR,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,QAAQ,KAAK,CAAC,CAAC,SAAS,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;SACpE,CAAC;QAEF,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE;SAC7B,CAAC;IACJ,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { stockQuoteTool } from "./market/stock-quote.js";
|
|
2
|
+
import { stockHistoryTool } from "./market/stock-history.js";
|
|
3
|
+
import { cryptoPriceTool } from "./market/crypto-price.js";
|
|
4
|
+
import { cryptoHistoryTool } from "./market/crypto-history.js";
|
|
5
|
+
import { searchTickerTool } from "./market/search-ticker.js";
|
|
6
|
+
import { companyOverviewTool } from "./fundamentals/company-overview.js";
|
|
7
|
+
import { financialsTool } from "./fundamentals/financials.js";
|
|
8
|
+
import { earningsTool } from "./fundamentals/earnings.js";
|
|
9
|
+
import { fredDataTool } from "./macro/fred-data.js";
|
|
10
|
+
import { fearGreedTool } from "./macro/fear-greed.js";
|
|
11
|
+
import { redditSentimentTool } from "./sentiment/reddit-sentiment.js";
|
|
12
|
+
import { newsSentimentTool } from "./sentiment/news-sentiment.js";
|
|
13
|
+
import { technicalIndicatorsTool } from "./technical/indicators.js";
|
|
14
|
+
import { portfolioTrackerTool } from "./portfolio/tracker.js";
|
|
15
|
+
import { riskAnalysisTool } from "./portfolio/risk-analysis.js";
|
|
16
|
+
import { watchlistTool } from "./portfolio/watchlist.js";
|
|
17
|
+
import { correlationTool } from "./portfolio/correlation.js";
|
|
18
|
+
import { optionChainTool } from "./options/option-chain.js";
|
|
19
|
+
import { dcfTool } from "./fundamentals/dcf.js";
|
|
20
|
+
import { compsTool } from "./fundamentals/comps.js";
|
|
21
|
+
import { secFilingsTool } from "./fundamentals/sec-filings.js";
|
|
22
|
+
import { backtestTool } from "./technical/backtest.js";
|
|
23
|
+
import { predictionsTool } from "./portfolio/predictions.js";
|
|
24
|
+
export function getAllTools() {
|
|
25
|
+
return [
|
|
26
|
+
searchTickerTool,
|
|
27
|
+
stockQuoteTool,
|
|
28
|
+
stockHistoryTool,
|
|
29
|
+
cryptoPriceTool,
|
|
30
|
+
cryptoHistoryTool,
|
|
31
|
+
companyOverviewTool,
|
|
32
|
+
financialsTool,
|
|
33
|
+
earningsTool,
|
|
34
|
+
dcfTool,
|
|
35
|
+
compsTool,
|
|
36
|
+
secFilingsTool,
|
|
37
|
+
fredDataTool,
|
|
38
|
+
fearGreedTool,
|
|
39
|
+
redditSentimentTool,
|
|
40
|
+
newsSentimentTool,
|
|
41
|
+
technicalIndicatorsTool,
|
|
42
|
+
backtestTool,
|
|
43
|
+
portfolioTrackerTool,
|
|
44
|
+
riskAnalysisTool,
|
|
45
|
+
watchlistTool,
|
|
46
|
+
correlationTool,
|
|
47
|
+
predictionsTool,
|
|
48
|
+
optionChainTool,
|
|
49
|
+
];
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,MAAM,UAAU,WAAW;IACzB,OAAO;QACL,gBAAgB;QAChB,cAAc;QACd,gBAAgB;QAChB,eAAe;QACf,iBAAiB;QACjB,mBAAmB;QACnB,cAAc;QACd,YAAY;QACZ,OAAO;QACP,SAAS;QACT,cAAc;QACd,YAAY;QACZ,aAAa;QACb,mBAAmB;QACnB,iBAAiB;QACjB,uBAAuB;QACvB,YAAY;QACZ,oBAAoB;QACpB,gBAAgB;QAChB,aAAa;QACb,eAAe;QACf,eAAe;QACf,eAAe;KAChB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import type { FearGreedData } from "../../types/sentiment.js";
|
|
3
|
+
declare const params: import("@sinclair/typebox").TObject<{}>;
|
|
4
|
+
export declare const fearGreedTool: AgentTool<typeof params, FearGreedData>;
|
|
5
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { getFearGreedIndex } from "../../providers/fear-greed.js";
|
|
3
|
+
const params = Type.Object({});
|
|
4
|
+
export const fearGreedTool = {
|
|
5
|
+
name: "get_fear_greed",
|
|
6
|
+
label: "Fear & Greed Index",
|
|
7
|
+
description: "Get the Crypto Fear & Greed Index (alternative.me) — a sentiment indicator from 0 (Extreme Fear) to 100 (Extreme Greed). Includes current value and previous close.",
|
|
8
|
+
parameters: params,
|
|
9
|
+
async execute(toolCallId, _args) {
|
|
10
|
+
const fg = await getFearGreedIndex();
|
|
11
|
+
const gauge = buildGauge(fg.value);
|
|
12
|
+
const text = [
|
|
13
|
+
`**Fear & Greed Index: ${fg.value} — ${fg.label}**`,
|
|
14
|
+
gauge,
|
|
15
|
+
`Previous Close: ${fg.previousClose}${fg.weekAgo != null ? ` | Week Ago: ${fg.weekAgo}` : ""}${fg.monthAgo != null ? ` | Month Ago: ${fg.monthAgo}` : ""}`,
|
|
16
|
+
].join("\n");
|
|
17
|
+
return { content: [{ type: "text", text }], details: fg };
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
function buildGauge(value) {
|
|
21
|
+
const width = 20;
|
|
22
|
+
const pos = Math.round((value / 100) * width);
|
|
23
|
+
const bar = "█".repeat(pos) + "░".repeat(width - pos);
|
|
24
|
+
return `[${bar}] ${value}/100`;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=fear-greed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fear-greed.js","sourceRoot":"","sources":["../../../src/tools/macro/fear-greed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAGlE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAE/B,MAAM,CAAC,MAAM,aAAa,GAA4C;IACpE,IAAI,EAAE,gBAAgB;IACtB,KAAK,EAAE,oBAAoB;IAC3B,WAAW,EACT,qKAAqK;IACvK,UAAU,EAAE,MAAM;IAClB,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK;QAC7B,MAAM,EAAE,GAAG,MAAM,iBAAiB,EAAE,CAAC;QAErC,MAAM,KAAK,GAAG,UAAU,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG;YACX,yBAAyB,EAAE,CAAC,KAAK,MAAM,EAAE,CAAC,KAAK,IAAI;YACnD,KAAK;YACL,mBAAmB,EAAE,CAAC,aAAa,GAAG,EAAE,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;SAC3J,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IAC5D,CAAC;CACF,CAAC;AAEF,SAAS,UAAU,CAAC,KAAa;IAC/B,MAAM,KAAK,GAAG,EAAE,CAAC;IACjB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC;IACtD,OAAO,IAAI,GAAG,KAAK,KAAK,MAAM,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import type { FredSeries } from "../../types/macro.js";
|
|
3
|
+
declare const params: import("@sinclair/typebox").TObject<{
|
|
4
|
+
series_id: import("@sinclair/typebox").TString;
|
|
5
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const fredDataTool: AgentTool<typeof params, FredSeries>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { getSeries } from "../../providers/fred.js";
|
|
3
|
+
import { getConfig } from "../../config.js";
|
|
4
|
+
import { FRED_SERIES } from "../../types/macro.js";
|
|
5
|
+
const params = Type.Object({
|
|
6
|
+
series_id: Type.String({
|
|
7
|
+
description: `FRED series ID. Common ones: ${Object.entries(FRED_SERIES).map(([k, v]) => `${v} (${k})`).join(", ")}`,
|
|
8
|
+
}),
|
|
9
|
+
limit: Type.Optional(Type.Number({ description: "Number of observations to return. Default: 30" })),
|
|
10
|
+
});
|
|
11
|
+
export const fredDataTool = {
|
|
12
|
+
name: "get_economic_data",
|
|
13
|
+
label: "FRED Economic Data",
|
|
14
|
+
description: "Get economic data from FRED (Federal Reserve Economic Data): interest rates, CPI, GDP, unemployment, yield curve, and more. Requires FRED_API_KEY.",
|
|
15
|
+
parameters: params,
|
|
16
|
+
async execute(toolCallId, args) {
|
|
17
|
+
const apiKey = getConfig().fredApiKey;
|
|
18
|
+
if (!apiKey) {
|
|
19
|
+
throw new Error("FRED API key not configured. Set FRED_API_KEY or add ~/.opencandle/config.json. Get a free key at https://fred.stlouisfed.org/docs/api/api_key.html");
|
|
20
|
+
}
|
|
21
|
+
const limit = args.limit ?? 30;
|
|
22
|
+
const series = await getSeries(args.series_id.toUpperCase(), apiKey, limit);
|
|
23
|
+
const latest = series.observations[series.observations.length - 1];
|
|
24
|
+
const header = `**${series.title}** (${series.id})`;
|
|
25
|
+
const meta = `Units: ${series.units} | Frequency: ${series.frequency} | Last updated: ${series.lastUpdated}`;
|
|
26
|
+
const current = latest ? `Latest: ${latest.value} (${latest.date})` : "No data";
|
|
27
|
+
// Show last 10 observations
|
|
28
|
+
const recent = series.observations.slice(-10);
|
|
29
|
+
const table = recent.map((o) => `${o.date}: ${o.value}`).join("\n");
|
|
30
|
+
const text = [header, meta, current, "", "Recent observations:", table].join("\n");
|
|
31
|
+
return { content: [{ type: "text", text }], details: series };
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=fred-data.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fred-data.js","sourceRoot":"","sources":["../../../src/tools/macro/fred-data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGnD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACzB,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC;QACrB,WAAW,EAAE,gCAAgC,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;KACrH,CAAC;IACF,KAAK,EAAE,IAAI,CAAC,QAAQ,CAClB,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,+CAA+C,EAAE,CAAC,CAC9E;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,YAAY,GAAyC;IAChE,IAAI,EAAE,mBAAmB;IACzB,KAAK,EAAE,oBAAoB;IAC3B,WAAW,EACT,oJAAoJ;IACtJ,UAAU,EAAE,MAAM;IAClB,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI;QAC5B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC,UAAU,CAAC;QACtC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,qJAAqJ,CAAC,CAAC;QACzK,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QAE5E,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACnE,MAAM,MAAM,GAAG,KAAK,MAAM,CAAC,KAAK,OAAO,MAAM,CAAC,EAAE,GAAG,CAAC;QACpD,MAAM,IAAI,GAAG,UAAU,MAAM,CAAC,KAAK,iBAAiB,MAAM,CAAC,SAAS,oBAAoB,MAAM,CAAC,WAAW,EAAE,CAAC;QAC7G,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC;QAEhF,4BAA4B;QAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEpE,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,sBAAsB,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnF,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAChE,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import type { OHLCV } from "../../types/market.js";
|
|
3
|
+
declare const params: import("@sinclair/typebox").TObject<{
|
|
4
|
+
id: import("@sinclair/typebox").TString;
|
|
5
|
+
days: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
6
|
+
}>;
|
|
7
|
+
export declare const cryptoHistoryTool: AgentTool<typeof params, OHLCV[]>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { getCryptoHistory } from "../../providers/coingecko.js";
|
|
3
|
+
const params = Type.Object({
|
|
4
|
+
id: Type.String({
|
|
5
|
+
description: "CoinGecko coin ID (e.g. bitcoin, ethereum, solana)",
|
|
6
|
+
}),
|
|
7
|
+
days: Type.Optional(Type.Number({
|
|
8
|
+
description: "Number of days of history: 1, 7, 14, 30, 90, 180, 365, max. Default: 180",
|
|
9
|
+
})),
|
|
10
|
+
});
|
|
11
|
+
export const cryptoHistoryTool = {
|
|
12
|
+
name: "get_crypto_history",
|
|
13
|
+
label: "Crypto History",
|
|
14
|
+
description: "Get historical OHLC data for a cryptocurrency",
|
|
15
|
+
parameters: params,
|
|
16
|
+
async execute(toolCallId, args) {
|
|
17
|
+
const id = args.id.toLowerCase();
|
|
18
|
+
const days = args.days ?? 180;
|
|
19
|
+
const bars = await getCryptoHistory(id, days);
|
|
20
|
+
const summary = [
|
|
21
|
+
`${id} — ${bars.length} bars (${days} days)`,
|
|
22
|
+
`Period: ${bars[0]?.date} to ${bars[bars.length - 1]?.date}`,
|
|
23
|
+
];
|
|
24
|
+
const recent = bars.slice(-10);
|
|
25
|
+
const table = recent
|
|
26
|
+
.map((b) => `${b.date} | O:${b.open.toFixed(2)} H:${b.high.toFixed(2)} L:${b.low.toFixed(2)} C:${b.close.toFixed(2)}`)
|
|
27
|
+
.join("\n");
|
|
28
|
+
const text = [...summary, "", "Recent bars:", table].join("\n");
|
|
29
|
+
return { content: [{ type: "text", text }], details: bars };
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=crypto-history.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto-history.js","sourceRoot":"","sources":["../../../src/tools/market/crypto-history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGhE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACzB,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC;QACd,WAAW,EAAE,oDAAoD;KAClE,CAAC;IACF,IAAI,EAAE,IAAI,CAAC,QAAQ,CACjB,IAAI,CAAC,MAAM,CAAC;QACV,WAAW,EAAE,0EAA0E;KACxF,CAAC,CACH;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAsC;IAClE,IAAI,EAAE,oBAAoB;IAC1B,KAAK,EAAE,gBAAgB;IACvB,WAAW,EAAE,+CAA+C;IAC5D,UAAU,EAAE,MAAM;IAClB,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI;QAC5B,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;QAE9C,MAAM,OAAO,GAAG;YACd,GAAG,EAAE,MAAM,IAAI,CAAC,MAAM,UAAU,IAAI,QAAQ;YAC5C,WAAW,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE;SAC7D,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC/B,MAAM,KAAK,GAAG,MAAM;aACjB,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,GAAG,CAAC,CAAC,IAAI,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAC5G;aACA,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,MAAM,IAAI,GAAG,CAAC,GAAG,OAAO,EAAE,EAAE,EAAE,cAAc,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAC9D,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import type { CryptoPrice } from "../../types/market.js";
|
|
3
|
+
declare const params: import("@sinclair/typebox").TObject<{
|
|
4
|
+
id: import("@sinclair/typebox").TString;
|
|
5
|
+
}>;
|
|
6
|
+
export declare const cryptoPriceTool: AgentTool<typeof params, CryptoPrice>;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
import { getCryptoPrice } from "../../providers/coingecko.js";
|
|
3
|
+
const params = Type.Object({
|
|
4
|
+
id: Type.String({
|
|
5
|
+
description: "CoinGecko coin ID (e.g. bitcoin, ethereum, solana, dogecoin). Use lowercase.",
|
|
6
|
+
}),
|
|
7
|
+
});
|
|
8
|
+
export const cryptoPriceTool = {
|
|
9
|
+
name: "get_crypto_price",
|
|
10
|
+
label: "Crypto Price",
|
|
11
|
+
description: "Get current crypto price, 24h change, market cap, volume, ATH, and supply data",
|
|
12
|
+
parameters: params,
|
|
13
|
+
async execute(toolCallId, args) {
|
|
14
|
+
const crypto = await getCryptoPrice(args.id.toLowerCase());
|
|
15
|
+
const sign = crypto.changePercent24h >= 0 ? "+" : "";
|
|
16
|
+
const text = [
|
|
17
|
+
`${crypto.name} (${crypto.symbol.toUpperCase()}): $${formatPrice(crypto.price)} (${sign}${crypto.changePercent24h.toFixed(2)}%)`,
|
|
18
|
+
`24h High: $${formatPrice(crypto.high24h)} | 24h Low: $${formatPrice(crypto.low24h)}`,
|
|
19
|
+
`Market Cap: $${formatLargeNumber(crypto.marketCap)} | 24h Volume: $${formatLargeNumber(crypto.volume24h)}`,
|
|
20
|
+
`ATH: $${formatPrice(crypto.ath)} (${crypto.athDate.split("T")[0]})`,
|
|
21
|
+
`Circulating: ${formatLargeNumber(crypto.circulatingSupply)} ${crypto.symbol.toUpperCase()}`,
|
|
22
|
+
].join("\n");
|
|
23
|
+
return { content: [{ type: "text", text }], details: crypto };
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
function formatPrice(n) {
|
|
27
|
+
if (n >= 1)
|
|
28
|
+
return n.toFixed(2);
|
|
29
|
+
if (n >= 0.01)
|
|
30
|
+
return n.toFixed(4);
|
|
31
|
+
return n.toFixed(8);
|
|
32
|
+
}
|
|
33
|
+
function formatLargeNumber(n) {
|
|
34
|
+
if (n >= 1e12)
|
|
35
|
+
return `${(n / 1e12).toFixed(2)}T`;
|
|
36
|
+
if (n >= 1e9)
|
|
37
|
+
return `${(n / 1e9).toFixed(2)}B`;
|
|
38
|
+
if (n >= 1e6)
|
|
39
|
+
return `${(n / 1e6).toFixed(2)}M`;
|
|
40
|
+
return n.toLocaleString();
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=crypto-price.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crypto-price.js","sourceRoot":"","sources":["../../../src/tools/market/crypto-price.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAG9D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACzB,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC;QACd,WAAW,EACT,8EAA8E;KACjF,CAAC;CACH,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAA0C;IACpE,IAAI,EAAE,kBAAkB;IACxB,KAAK,EAAE,cAAc;IACrB,WAAW,EACT,gFAAgF;IAClF,UAAU,EAAE,MAAM;IAClB,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI;QAC5B,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;QAC3D,MAAM,IAAI,GAAG,MAAM,CAAC,gBAAgB,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,GAAG;YACX,GAAG,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,GAAG,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI;YAChI,cAAc,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,gBAAgB,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;YACrF,gBAAgB,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,mBAAmB,iBAAiB,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;YAC3G,SAAS,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG;YACpE,gBAAgB,iBAAiB,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,EAAE;SAC7F,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAChE,CAAC;CACF,CAAC;AAEF,SAAS,WAAW,CAAC,CAAS;IAC5B,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAChC,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACnC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACtB,CAAC;AAED,SAAS,iBAAiB,CAAC,CAAS;IAClC,IAAI,CAAC,IAAI,IAAI;QAAE,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAClD,IAAI,CAAC,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAChD,IAAI,CAAC,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;IAChD,OAAO,CAAC,CAAC,cAAc,EAAE,CAAC;AAC5B,CAAC"}
|