@quantoracle/agentkit 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/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # QuantOracle for Coinbase AgentKit
2
+
3
+ Deterministic quant finance math for autonomous agents built with [Coinbase AgentKit](https://github.com/coinbase/agentkit).
4
+
5
+ > 📖 **Read the full integration comparison:** [AgentKit vs LangChain vs Direct HTTP — picking the right integration for paid agent APIs](https://dev.to/quantoracle/agentkit-vs-langchain-vs-direct-http-picking-the-right-integration-for-paid-agent-apis-2582) (dev.to, May 2026)
6
+
7
+ > **Why this exists:** AI agents trying to compute Black-Scholes prices, Kelly fractions, or Monte Carlo simulations in-context drift. The numbers are wrong, the Greeks are hallucinated, and the agent can't tell. QuantOracle is grounded math: same inputs, same outputs, every time. Free tier covers calculator endpoints; paid composites (full risk audit, hedge recommendations) settle automatically via your AgentKit wallet using x402 micropayments on Base or Solana.
8
+
9
+ ## What this provides
10
+
11
+ 5 high-leverage actions covering the financial decisions an autonomous trading or finance agent typically faces:
12
+
13
+ | Action | What it does | Cost |
14
+ |---|---|---|
15
+ | `price_option` | Black-Scholes pricing with full Greeks (delta, gamma, vega, theta, rho) | Free |
16
+ | `calculate_kelly` | Kelly Criterion optimal sizing (full / half / quarter Kelly) | Free |
17
+ | `simulate_portfolio` | Monte Carlo simulation with contributions, withdrawals, probability of ruin | Free |
18
+ | `assess_portfolio_risk` | Composite audit: Sharpe, Sortino, Calmar, max DD, VaR, CVaR, Kelly, Hurst | $0.04 USDC via x402 |
19
+ | `recommend_hedge` | Ranked hedge structures (collar, protective put, partial put, inverse) for any position | $0.04 USDC via x402 |
20
+
21
+ The full QuantOracle API has 73 endpoints; this provider exposes a curated subset. For the long tail (exotic options, FX models, technical indicators, etc.), agents can call the raw API at `https://api.quantoracle.dev/v1/*` directly.
22
+
23
+ ## Free tier
24
+
25
+ - **1,000 calls per IP per day**, no signup, no API key
26
+ - Covers `price_option`, `calculate_kelly`, `simulate_portfolio` for almost any agent
27
+ - Resets daily at 00:00 UTC
28
+
29
+ ## Paid endpoints (x402)
30
+
31
+ `assess_portfolio_risk` and `recommend_hedge` are composite endpoints that wrap 5-15 calculator calls into a single response. They cost $0.04 USDC each, settled on-chain via the [x402 protocol](https://github.com/coinbase/x402) on Base mainnet or Solana mainnet.
32
+
33
+ **Your AgentKit wallet handles payment automatically.** No API key, no signup, no billing setup. The wallet just needs to hold a small amount of USDC on Base or Solana.
34
+
35
+ ## Installation
36
+
37
+ The action provider files live alongside your AgentKit project:
38
+
39
+ ```bash
40
+ # 1. Create a new AgentKit project (or use an existing one)
41
+ npx create-onchain-agent
42
+
43
+ # 2. Copy the QuantOracle action provider files into your project
44
+ mkdir -p src/quantoracle
45
+ curl -sL https://raw.githubusercontent.com/QuantOracledev/quantoracle/main/integrations/agentkit/quantoracleActionProvider.ts -o src/quantoracle/quantoracleActionProvider.ts
46
+ curl -sL https://raw.githubusercontent.com/QuantOracledev/quantoracle/main/integrations/agentkit/schemas.ts -o src/quantoracle/schemas.ts
47
+ curl -sL https://raw.githubusercontent.com/QuantOracledev/quantoracle/main/integrations/agentkit/constants.ts -o src/quantoracle/constants.ts
48
+ curl -sL https://raw.githubusercontent.com/QuantOracledev/quantoracle/main/integrations/agentkit/index.ts -o src/quantoracle/index.ts
49
+ ```
50
+
51
+ Or clone the QuantOracle repo and copy the directory:
52
+
53
+ ```bash
54
+ git clone https://github.com/QuantOracledev/quantoracle
55
+ cp -r quantoracle/integrations/agentkit ./src/quantoracle
56
+ ```
57
+
58
+ ## Usage
59
+
60
+ ```ts
61
+ import { AgentKit, CdpEvmWalletProvider } from "@coinbase/agentkit";
62
+ import { quantoracleActionProvider } from "./quantoracle";
63
+
64
+ const walletProvider = await CdpEvmWalletProvider.configureWithWallet({
65
+ apiKeyId: process.env.CDP_API_KEY_ID!,
66
+ apiKeySecret: process.env.CDP_API_KEY_SECRET!,
67
+ networkId: "base-mainnet",
68
+ });
69
+
70
+ const agentkit = await AgentKit.from({
71
+ walletProvider,
72
+ actionProviders: [quantoracleActionProvider()],
73
+ });
74
+
75
+ // The agent now has 5 new actions:
76
+ // price_option, calculate_kelly, simulate_portfolio,
77
+ // assess_portfolio_risk, recommend_hedge
78
+ ```
79
+
80
+ A complete runnable example is at [`example-agent.ts`](./example-agent.ts). Additional examples:
81
+
82
+ - [`example-agent-solana.ts`](./example-agent-solana.ts) — Same agent but routes x402 payments through a Solana mainnet wallet (SPL USDC) instead of Base. Useful for agents already operating in the Solana ecosystem.
83
+ - [`example-chained-workflow.ts`](./example-chained-workflow.ts) — Scripted demo showing the natural `assess_portfolio_risk` → `recommend_hedge` chained workflow. Pre-baked prompts walk the agent through risk audit → hedge analysis → final recommendation. Spends ~$0.08 USDC per run on real x402 settlements.
84
+
85
+ For a side-by-side comparison of integration patterns (direct HTTP vs AgentKit vs LangChain Python), see [`COMPARISONS.md`](./COMPARISONS.md).
86
+
87
+ ## Example agent prompts
88
+
89
+ Try these in your AgentKit chat:
90
+
91
+ - _"Price a 30-day NVDA call with strike $185, spot $180, 28% IV"_ → uses `price_option`
92
+ - _"I have 55% win rate, $150 avg win, $100 avg loss — what's my Kelly?"_ → uses `calculate_kelly`
93
+ - _"Simulate $100K over 30 years with 7% return, 16% vol, 4% withdrawal"_ → uses `simulate_portfolio`
94
+ - _"Audit risk on my last 252 daily returns: [...]"_ → uses `assess_portfolio_risk` (paid)
95
+ - _"Recommend hedges for my $100K long NVDA position over 30 days"_ → uses `recommend_hedge` (paid)
96
+
97
+ ## Try without code
98
+
99
+ 15 free interactive calculators backed by the same engine are at **[quantoracle.dev](https://quantoracle.dev)** — useful for verifying outputs before wiring the action provider into your agent.
100
+
101
+ ## Why deterministic finance math matters for agents
102
+
103
+ Three failure modes when LLMs do financial math in-context:
104
+
105
+ 1. **Black-Scholes calculations drift.** GPT-4o's Greeks are wrong by 5-30% depending on moneyness. The agent can't tell.
106
+ 2. **Compound interest computations skip steps.** A 30-year projection at 8% loses meaningful precision over many tokens.
107
+ 3. **Kelly and VaR formulas are mis-applied.** LLMs often confuse arithmetic vs geometric returns or fail to annualize correctly.
108
+
109
+ Grounded tools fix all three: the API is bytes-exact against textbook implementations (Hull, Wilmott, Lopez de Prado), tested across 120 accuracy benchmarks, and returns the same value for the same inputs every time. The agent can cite a specific tool call as the source for any number it presents.
110
+
111
+ ## Repository
112
+
113
+ Source: [github.com/QuantOracledev/quantoracle](https://github.com/QuantOracledev/quantoracle)
114
+ API: [api.quantoracle.dev](https://api.quantoracle.dev)
115
+ Calculators: [quantoracle.dev](https://quantoracle.dev)
116
+ OpenAPI spec: [api.quantoracle.dev/openapi.json](https://api.quantoracle.dev/openapi.json)
117
+
118
+ ## License
119
+
120
+ MIT — same as the rest of QuantOracle.
package/dist/index.cjs ADDED
@@ -0,0 +1,453 @@
1
+ 'use strict';
2
+
3
+ var zod = require('zod');
4
+ var agentkit = require('@coinbase/agentkit');
5
+
6
+ var __defProp = Object.defineProperty;
7
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
+ var PriceOptionSchema = zod.z.object({
9
+ S: zod.z.number().positive().describe("Spot price of the underlying"),
10
+ K: zod.z.number().positive().describe("Strike price"),
11
+ T: zod.z.number().positive().describe("Time to expiry in years (0.083 = 30 days)"),
12
+ r: zod.z.number().describe("Risk-free interest rate as decimal (0.05 = 5%)"),
13
+ sigma: zod.z.number().positive().describe("Annualized volatility as decimal (0.28 = 28%)"),
14
+ option_type: zod.z.enum([
15
+ "call",
16
+ "put"
17
+ ]).default("call").describe("Option type \u2014 call or put")
18
+ }).describe("Black-Scholes option pricing with full Greeks. Returns price, breakeven, probability ITM, and all first-order Greeks (delta, gamma, vega, theta, rho).");
19
+ var CalculateKellySchema = zod.z.object({
20
+ win_rate: zod.z.number().min(0.01).max(0.99).describe("Probability of winning (0-1)"),
21
+ avg_win: zod.z.number().positive().describe("Average dollar amount won on winning trades"),
22
+ avg_loss: zod.z.number().positive().describe("Average dollar amount lost on losing trades (positive number)")
23
+ }).describe("Kelly Criterion optimal bet sizing. Returns full-, half-, and quarter-Kelly fractions plus edge and payoff ratio. Use half- or quarter-Kelly in real trading because edge estimates are noisy.");
24
+ var SimulatePortfolioSchema = zod.z.object({
25
+ initial_value: zod.z.number().positive().describe("Starting portfolio value"),
26
+ annual_return: zod.z.number().describe("Expected annual return as decimal (0.08 = 8%)"),
27
+ annual_vol: zod.z.number().positive().describe("Annual volatility as decimal (0.18 = 18%)"),
28
+ years: zod.z.number().positive().max(30).describe("Time horizon in years (max 30)"),
29
+ simulations: zod.z.number().int().min(100).max(2500).default(1e3).describe("Number of Monte Carlo paths (100-2500; 1000 default)"),
30
+ contributions: zod.z.number().min(0).default(0).describe("Annual contribution amount (set 0 if none)"),
31
+ withdrawal_rate: zod.z.number().min(0).max(0.5).default(0).describe("Annual withdrawal rate as decimal (0.04 = 4%)")
32
+ }).describe("Monte Carlo portfolio simulation. Returns distribution of terminal outcomes (P5/P25/median/P75/P95), probability of loss, probability of doubling, and probability of ruin under withdrawals.");
33
+ var AssessPortfolioRiskSchema = zod.z.object({
34
+ returns: zod.z.array(zod.z.number()).min(30).max(5e3).describe("Array of historical periodic returns as decimals (0.012 = 1.2%). Daily returns assumed; 30-5000 observations."),
35
+ risk_free_rate: zod.z.number().default(0.04).describe("Annual risk-free rate as decimal (0.04 = 4%)"),
36
+ annualization_factor: zod.z.number().int().default(252).describe("252 for daily returns, 52 for weekly, 12 for monthly")
37
+ }).describe("Composite full risk analysis: Sharpe, Sortino, Calmar, max drawdown, VaR, CVaR, Hurst exponent, and Kelly. PAID endpoint ($0.04 per call, settled in USDC). AgentKit's wallet pays automatically.");
38
+ var RecommendHedgeSchema = zod.z.object({
39
+ position_type: zod.z.enum([
40
+ "long_stock",
41
+ "short_stock",
42
+ "long_crypto",
43
+ "long_options"
44
+ ]).describe("Type of position to hedge"),
45
+ position_value: zod.z.number().positive().describe("Current dollar value of the position"),
46
+ asset_price: zod.z.number().positive().describe("Current spot price of the underlying"),
47
+ volatility: zod.z.number().positive().describe("Annualized volatility of the underlying as decimal (0.28 = 28%)"),
48
+ time_horizon_days: zod.z.number().int().positive().default(30).describe("Hedge time horizon in days"),
49
+ max_hedge_cost_pct: zod.z.number().min(0).max(0.5).default(0.05).describe("Maximum hedge cost as fraction of position (0.05 = 5%)"),
50
+ r: zod.z.number().default(0.05).describe("Risk-free rate as decimal")
51
+ }).describe("Recommend ranked hedge structures (collar, protective put, partial put, inverse) for an existing position. Returns each structure's cost, downside protection, and upside cap. PAID endpoint ($0.04 per call, settled in USDC). AgentKit's wallet pays automatically.");
52
+
53
+ // constants.ts
54
+ var QUANTORACLE_BASE_URL = process.env.QUANTORACLE_API_URL ?? "https://api.quantoracle.dev";
55
+ var FREE_TIER_DAILY_LIMIT = 1e3;
56
+ var USER_AGENT = "QuantOracle-AgentKit/1.0";
57
+
58
+ // quantoracleActionProvider.ts
59
+ function _ts_decorate(decorators, target, key, desc) {
60
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
61
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
62
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
63
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
64
+ }
65
+ __name(_ts_decorate, "_ts_decorate");
66
+ function _ts_metadata(k, v) {
67
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
68
+ }
69
+ __name(_ts_metadata, "_ts_metadata");
70
+ var QuantOracleActionProvider = class extends agentkit.ActionProvider {
71
+ static {
72
+ __name(this, "QuantOracleActionProvider");
73
+ }
74
+ /**
75
+ * Constructor for QuantOracleActionProvider. No configuration required —
76
+ * the free tier covers the calculator endpoints, and paid composites use
77
+ * AgentKit's wallet to settle x402 payments.
78
+ */
79
+ constructor() {
80
+ super("quantoracle", []);
81
+ }
82
+ /**
83
+ * QuantOracle works on any network because the calculations are pure math
84
+ * (no on-chain reads). x402 settlements for paid endpoints work on Base
85
+ * mainnet and Solana mainnet, but the agent doesn't need to be on those
86
+ * networks to call the free-tier calculators.
87
+ *
88
+ * @returns true for any network
89
+ */
90
+ supportsNetwork = /* @__PURE__ */ __name((_network) => true, "supportsNetwork");
91
+ /**
92
+ * Price a European call or put option using Black-Scholes. Returns the
93
+ * theoretical fair value plus the full Greek profile (delta, gamma, vega,
94
+ * theta, rho). Use this before placing options orders to verify market
95
+ * prices are reasonable, or to compute expected option PnL given a view
96
+ * on the underlying.
97
+ *
98
+ * @param args - Spot price, strike, time to expiry, rate, vol, type
99
+ * @returns Markdown-formatted summary with price, breakeven, and Greeks
100
+ */
101
+ async priceOption(args) {
102
+ try {
103
+ const data = await this.callApi("/v1/options/price", args);
104
+ const ms = data.ms ?? 0;
105
+ const greeks = data.greeks ?? {};
106
+ return [
107
+ `**${args.option_type.toUpperCase()} on $${args.S} underlying, $${args.K} strike, ${(args.T * 365).toFixed(0)}d to expiry, ${(args.sigma * 100).toFixed(1)}% IV**`,
108
+ ``,
109
+ `- Price: $${data.price.toFixed(4)}`,
110
+ `- Breakeven: $${data.breakeven.toFixed(2)}`,
111
+ `- Probability ITM: ${(data.prob_itm * 100).toFixed(1)}%`,
112
+ `- Delta: ${greeks.delta.toFixed(4)}`,
113
+ `- Gamma: ${greeks.gamma.toFixed(4)}`,
114
+ `- Vega: ${greeks.vega.toFixed(4)}`,
115
+ `- Theta (per day): ${greeks.theta.toFixed(4)}`,
116
+ `- Rho: ${greeks.rho.toFixed(4)}`,
117
+ ``,
118
+ `_Computed in ${ms.toFixed(0)}ms via QuantOracle._`
119
+ ].join("\n");
120
+ } catch (err) {
121
+ return `Failed to price option: ${err instanceof Error ? err.message : String(err)}`;
122
+ }
123
+ }
124
+ /**
125
+ * Calculate Kelly Criterion optimal bet/position sizing. Returns full-,
126
+ * half-, and quarter-Kelly fractions. Use this to derive a defensible
127
+ * risk-per-trade fraction from your strategy's win rate and average
128
+ * win/loss profile, BEFORE sizing the position.
129
+ *
130
+ * @param args - Win rate, average win, average loss
131
+ * @returns Markdown-formatted summary with Kelly variants and edge analysis
132
+ */
133
+ async calculateKelly(args) {
134
+ try {
135
+ const data = await this.callApi("/v1/risk/kelly", {
136
+ mode: "discrete",
137
+ ...args
138
+ });
139
+ const fullKelly = data.full_kelly * 100;
140
+ const halfKelly = data.half_kelly * 100;
141
+ const quarterKelly = data.quarter_kelly * 100;
142
+ const recommendation = data.recommended.replace(/_/g, " ").toLowerCase();
143
+ return [
144
+ `**Kelly sizing for ${(args.win_rate * 100).toFixed(1)}% win rate, $${args.avg_win} avg win, $${args.avg_loss} avg loss**`,
145
+ ``,
146
+ `- Full Kelly: ${fullKelly.toFixed(2)}%`,
147
+ `- Half Kelly: ${halfKelly.toFixed(2)}% _(typical for risk-tolerant)_`,
148
+ `- Quarter Kelly: ${quarterKelly.toFixed(2)}% _(safer; recommended)_`,
149
+ `- Edge: ${data.edge.toFixed(2)}%`,
150
+ `- Payoff ratio: ${data.payoff_ratio.toFixed(2)}\xD7`,
151
+ `- **Recommendation:** ${recommendation}`,
152
+ ``,
153
+ fullKelly < 0 ? `_Negative edge \u2014 this strategy has negative expected value. Do not deploy capital._` : `_Computed via QuantOracle._`
154
+ ].join("\n");
155
+ } catch (err) {
156
+ return `Failed to calculate Kelly: ${err instanceof Error ? err.message : String(err)}`;
157
+ }
158
+ }
159
+ /**
160
+ * Run a Monte Carlo portfolio simulation to project the distribution of
161
+ * terminal outcomes. Use this to assess sequence-of-returns risk before
162
+ * deploying a strategy or to validate retirement-withdrawal sustainability.
163
+ *
164
+ * @param args - Initial value, return/vol assumptions, time horizon, contributions/withdrawals
165
+ * @returns Markdown-formatted summary with distribution percentiles and probability events
166
+ */
167
+ async simulatePortfolio(args) {
168
+ try {
169
+ const data = await this.callApi("/v1/simulate/montecarlo", args);
170
+ const t = data.terminal;
171
+ const probLoss = (data.prob_loss * 100).toFixed(1);
172
+ const probRuin = (data.prob_ruin * 100).toFixed(2);
173
+ const cagr = (data.cagr * 100).toFixed(2);
174
+ const fmt = /* @__PURE__ */ __name((v) => `$${v.toLocaleString(void 0, {
175
+ maximumFractionDigits: 0
176
+ })}`, "fmt");
177
+ return [
178
+ `**Monte Carlo: $${args.initial_value.toLocaleString()} over ${args.years} years, ${(args.annual_return * 100).toFixed(1)}% return, ${(args.annual_vol * 100).toFixed(1)}% vol**`,
179
+ ``,
180
+ `_Distribution of terminal outcomes (across ${args.simulations.toLocaleString()} simulated paths):_`,
181
+ `- Median: ${fmt(t.median)}`,
182
+ `- 5th percentile (worst 5%): ${fmt(t.p5)}`,
183
+ `- 95th percentile (best 5%): ${fmt(t.p95)}`,
184
+ `- Median CAGR: ${cagr}%`,
185
+ ``,
186
+ `**Probability events:**`,
187
+ `- Loss vs starting value: ${probLoss}%`,
188
+ `- Probability of ruin (portfolio depleted): ${probRuin}%`,
189
+ ``,
190
+ `_Computed in ${data.ms.toFixed(0)}ms via QuantOracle._`
191
+ ].join("\n");
192
+ } catch (err) {
193
+ return `Failed to simulate: ${err instanceof Error ? err.message : String(err)}`;
194
+ }
195
+ }
196
+ /**
197
+ * Compute a full risk-adjusted-return audit: Sharpe, Sortino, Calmar, max
198
+ * drawdown, VaR, CVaR, Kelly. PAID composite endpoint ($0.04 per call,
199
+ * settled in USDC via x402 — AgentKit's wallet handles payment automatically
200
+ * when the free tier is exceeded).
201
+ *
202
+ * @param args - Historical returns array, risk-free rate, annualization factor
203
+ * @returns Markdown-formatted comprehensive risk summary
204
+ */
205
+ async assessPortfolioRisk(args) {
206
+ try {
207
+ const data = await this.callApi("/v1/risk/full-analysis", args);
208
+ const sharpe = data.sharpe?.sharpe_ratio ?? 0;
209
+ const sortino = data.sortino?.sortino_ratio ?? 0;
210
+ const calmar = data.calmar?.calmar_ratio ?? 0;
211
+ const maxDd = data.drawdown?.max_drawdown ?? 0;
212
+ const varBlock = data.var;
213
+ const var95 = varBlock?.var_results?.["95"]?.var_pct ?? 0;
214
+ const cvar95 = varBlock?.var_results?.["95"]?.cvar_pct ?? 0;
215
+ const kelly = data.kelly?.kelly_fraction ?? 0;
216
+ const hurst = data.hurst?.hurst_exponent ?? 0;
217
+ return [
218
+ `**Risk audit on ${args.returns.length} observations** _(paid via x402, $0.04 USDC)_`,
219
+ ``,
220
+ `**Risk-adjusted return:**`,
221
+ `- Sharpe ratio: ${sharpe.toFixed(2)}`,
222
+ `- Sortino ratio: ${sortino.toFixed(2)}`,
223
+ `- Calmar ratio: ${calmar.toFixed(2)}`,
224
+ ``,
225
+ `**Tail risk:**`,
226
+ `- Max drawdown: ${(maxDd * 100).toFixed(2)}%`,
227
+ `- VaR (95%): ${var95.toFixed(2)}%`,
228
+ `- CVaR / Expected Shortfall (95%): ${cvar95.toFixed(2)}%`,
229
+ ``,
230
+ `**Sizing & regime:**`,
231
+ `- Kelly fraction: ${(kelly * 100).toFixed(2)}%`,
232
+ `- Hurst exponent: ${hurst.toFixed(3)} ${hurst > 0.6 ? "_(trending)_" : hurst < 0.4 ? "_(mean-reverting)_" : "_(random walk)_"}`,
233
+ ``,
234
+ `_Composite analysis via QuantOracle. Settled on-chain via x402._`
235
+ ].join("\n");
236
+ } catch (err) {
237
+ return `Failed to assess risk: ${err instanceof Error ? err.message : String(err)}`;
238
+ }
239
+ }
240
+ /**
241
+ * Recommend ranked hedge structures for an existing position. PAID
242
+ * composite endpoint ($0.04 per call, settled in USDC via x402).
243
+ *
244
+ * @param args - Position details and hedge parameters
245
+ * @returns Markdown-formatted ranked list of hedge structures
246
+ */
247
+ async recommendHedge(args) {
248
+ try {
249
+ const data = await this.callApi("/v1/hedging/recommend", args);
250
+ const structures = data.structures ?? [];
251
+ const lines = [
252
+ `**Hedge recommendations for $${args.position_value.toLocaleString()} ${args.position_type} position over ${args.time_horizon_days} days** _(paid via x402, $0.04 USDC)_`,
253
+ ``
254
+ ];
255
+ for (let i = 0; i < structures.length; i++) {
256
+ const s = structures[i];
257
+ lines.push(`**${i + 1}. ${s.name}** \u2014 cost ${(s.cost_pct * 100).toFixed(2)}% ($${s.cost_dollars.toFixed(2)}), floor ${(s.downside_floor * 100).toFixed(1)}%${s.upside_cap ? `, upside cap ${(s.upside_cap * 100).toFixed(1)}%` : ", unlimited upside"}`);
258
+ if (s.legs) {
259
+ for (const leg of s.legs) {
260
+ lines.push(` - ${leg.action} ${leg.quantity}\xD7 ${leg.type} @ $${leg.strike.toFixed(2)} (premium $${leg.premium.toFixed(2)})`);
261
+ }
262
+ }
263
+ lines.push(``);
264
+ }
265
+ return lines.join("\n");
266
+ } catch (err) {
267
+ return `Failed to recommend hedge: ${err instanceof Error ? err.message : String(err)}`;
268
+ }
269
+ }
270
+ /**
271
+ * Internal helper. Posts JSON to a QuantOracle endpoint and returns the
272
+ * parsed response. Throws on non-2xx responses, including 402 Payment
273
+ * Required when the free tier is exceeded — at which point AgentKit's
274
+ * wallet should auto-retry with x402 payment headers (depending on your
275
+ * walletProvider setup).
276
+ *
277
+ * @param path - Endpoint path beginning with /v1/...
278
+ * @param body - JSON-serializable request body
279
+ * @returns Parsed JSON response
280
+ */
281
+ async callApi(path, body) {
282
+ const res = await fetch(`${QUANTORACLE_BASE_URL}${path}`, {
283
+ method: "POST",
284
+ headers: {
285
+ "Content-Type": "application/json",
286
+ "User-Agent": USER_AGENT,
287
+ "X-Source": "agentkit"
288
+ },
289
+ body: JSON.stringify(body)
290
+ });
291
+ if (!res.ok) {
292
+ let detail = "";
293
+ try {
294
+ const j = await res.json();
295
+ detail = JSON.stringify(j).slice(0, 200);
296
+ } catch {
297
+ }
298
+ throw new Error(`QuantOracle ${path} returned ${res.status}: ${detail}`);
299
+ }
300
+ return await res.json();
301
+ }
302
+ };
303
+ _ts_decorate([
304
+ agentkit.CreateAction({
305
+ name: "price_option",
306
+ description: `
307
+ Price a European call or put option using Black-Scholes with full Greeks.
308
+ Returns the option's theoretical price, breakeven, probability ITM, and
309
+ all first-order Greeks (delta, gamma, vega, theta, rho).
310
+
311
+ Use this when:
312
+ - Verifying that a market option price is reasonable before placing an order
313
+ - Estimating PnL on an existing options position given a view on the underlying
314
+ - Computing position deltas for portfolio hedging decisions
315
+ - Sizing options trades based on Greek exposures
316
+
317
+ Inputs: spot price, strike, time to expiry (in years; 30 days = 0.083),
318
+ risk-free rate, volatility, option type (call or put).
319
+ `,
320
+ schema: PriceOptionSchema
321
+ }),
322
+ _ts_metadata("design:type", Function),
323
+ _ts_metadata("design:paramtypes", [
324
+ typeof zod.z === "undefined" || typeof zod.z.infer === "undefined" ? Object : zod.z.infer
325
+ ]),
326
+ _ts_metadata("design:returntype", Promise)
327
+ ], QuantOracleActionProvider.prototype, "priceOption", null);
328
+ _ts_decorate([
329
+ agentkit.CreateAction({
330
+ name: "calculate_kelly",
331
+ description: `
332
+ Calculate Kelly Criterion optimal bet sizing given a strategy's win rate
333
+ and average win/loss amounts. Returns the full-, half-, and quarter-Kelly
334
+ fractions, the edge per dollar risked, and the payoff ratio.
335
+
336
+ Use this when:
337
+ - Deriving the risk-per-trade fraction for a position-sizing system
338
+ - Comparing two strategies head-to-head (higher Kelly = better edge per unit risk)
339
+ - Validating that a strategy is positive-expected-value before deploying capital
340
+
341
+ The formula assumes binary outcomes with fixed amounts (suits options trades,
342
+ event-driven bets, or any discrete win/loss strategy). For continuous-return
343
+ strategies, see the QuantOracle API endpoint /v1/risk/kelly with mode=continuous.
344
+
345
+ Most professionals use half- or quarter-Kelly because edge estimates are noisy
346
+ and overestimating edge causes severe overbetting.
347
+ `,
348
+ schema: CalculateKellySchema
349
+ }),
350
+ _ts_metadata("design:type", Function),
351
+ _ts_metadata("design:paramtypes", [
352
+ typeof zod.z === "undefined" || typeof zod.z.infer === "undefined" ? Object : zod.z.infer
353
+ ]),
354
+ _ts_metadata("design:returntype", Promise)
355
+ ], QuantOracleActionProvider.prototype, "calculateKelly", null);
356
+ _ts_decorate([
357
+ agentkit.CreateAction({
358
+ name: "simulate_portfolio",
359
+ description: `
360
+ Run a Monte Carlo simulation projecting the distribution of portfolio
361
+ outcomes over a chosen time horizon. Returns terminal-value percentiles
362
+ (P5/P25/median/P75/P95), probability of loss, probability of doubling,
363
+ and probability of ruin under withdrawals.
364
+
365
+ Use this when:
366
+ - Stress-testing a withdrawal-rate plan (e.g. "is 4% sustainable for 30 years?")
367
+ - Comparing portfolio strategies head-to-head
368
+ - Quantifying sequence-of-returns risk for retirement-style allocations
369
+ - Showing a user the realistic range of outcomes (not just expected return)
370
+
371
+ The simulation uses geometric Brownian motion (log-normal returns) \u2014 a
372
+ standard textbook assumption that is reasonable for diversified portfolios
373
+ but underestimates fat-tail risk for high-vol single-asset strategies.
374
+ `,
375
+ schema: SimulatePortfolioSchema
376
+ }),
377
+ _ts_metadata("design:type", Function),
378
+ _ts_metadata("design:paramtypes", [
379
+ typeof zod.z === "undefined" || typeof zod.z.infer === "undefined" ? Object : zod.z.infer
380
+ ]),
381
+ _ts_metadata("design:returntype", Promise)
382
+ ], QuantOracleActionProvider.prototype, "simulatePortfolio", null);
383
+ _ts_decorate([
384
+ agentkit.CreateAction({
385
+ name: "assess_portfolio_risk",
386
+ description: `
387
+ Run a comprehensive risk audit on a return series. Returns Sharpe ratio,
388
+ Sortino ratio, Calmar ratio, max drawdown, VaR (95%/99%), CVaR (Expected
389
+ Shortfall), Kelly fraction, and Hurst exponent (regime indicator).
390
+
391
+ Use this when:
392
+ - Evaluating a backtest before deploying real capital
393
+ - Auditing an existing strategy's risk-adjusted performance
394
+ - Comparing two strategies on multiple risk dimensions in one call
395
+ - Generating a one-page risk summary for a stakeholder
396
+
397
+ PAID composite endpoint: $0.04 per call, settled in USDC via x402 on Base
398
+ or Solana. AgentKit's wallet pays automatically \u2014 no API key, no signup.
399
+ The savings vs running 8 separate calculator calls is meaningful both in
400
+ cost and in latency.
401
+
402
+ Requires at least 30 observations of historical returns; 252+ recommended
403
+ for statistical significance.
404
+ `,
405
+ schema: AssessPortfolioRiskSchema
406
+ }),
407
+ _ts_metadata("design:type", Function),
408
+ _ts_metadata("design:paramtypes", [
409
+ typeof zod.z === "undefined" || typeof zod.z.infer === "undefined" ? Object : zod.z.infer
410
+ ]),
411
+ _ts_metadata("design:returntype", Promise)
412
+ ], QuantOracleActionProvider.prototype, "assessPortfolioRisk", null);
413
+ _ts_decorate([
414
+ agentkit.CreateAction({
415
+ name: "recommend_hedge",
416
+ description: `
417
+ Recommend ranked hedge structures (collar, protective put, partial put,
418
+ inverse) for an existing position. Each recommendation includes the cost
419
+ as a percentage of position value, the downside protection floor, and the
420
+ upside cap (if any).
421
+
422
+ Use this when:
423
+ - An agent holding a long position wants to limit downside before an event
424
+ (earnings, FOMC, FDA decision) without selling
425
+ - An agent needs to compare hedge strategies head-to-head by cost vs protection
426
+ - Programmatic risk management of crypto positions ahead of high-vol periods
427
+
428
+ PAID composite endpoint: $0.04 per call, settled in USDC via x402 on Base or
429
+ Solana. AgentKit's wallet pays automatically. The output is a ranked table
430
+ the agent can present to a user or use directly to place hedge orders.
431
+ `,
432
+ schema: RecommendHedgeSchema
433
+ }),
434
+ _ts_metadata("design:type", Function),
435
+ _ts_metadata("design:paramtypes", [
436
+ typeof zod.z === "undefined" || typeof zod.z.infer === "undefined" ? Object : zod.z.infer
437
+ ]),
438
+ _ts_metadata("design:returntype", Promise)
439
+ ], QuantOracleActionProvider.prototype, "recommendHedge", null);
440
+ var quantoracleActionProvider = /* @__PURE__ */ __name(() => new QuantOracleActionProvider(), "quantoracleActionProvider");
441
+
442
+ exports.AssessPortfolioRiskSchema = AssessPortfolioRiskSchema;
443
+ exports.CalculateKellySchema = CalculateKellySchema;
444
+ exports.FREE_TIER_DAILY_LIMIT = FREE_TIER_DAILY_LIMIT;
445
+ exports.PriceOptionSchema = PriceOptionSchema;
446
+ exports.QUANTORACLE_BASE_URL = QUANTORACLE_BASE_URL;
447
+ exports.QuantOracleActionProvider = QuantOracleActionProvider;
448
+ exports.RecommendHedgeSchema = RecommendHedgeSchema;
449
+ exports.SimulatePortfolioSchema = SimulatePortfolioSchema;
450
+ exports.USER_AGENT = USER_AGENT;
451
+ exports.quantoracleActionProvider = quantoracleActionProvider;
452
+ //# sourceMappingURL=index.cjs.map
453
+ //# sourceMappingURL=index.cjs.map