@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 +120 -0
- package/dist/index.cjs +453 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +259 -0
- package/dist/index.d.ts +259 -0
- package/dist/index.js +442 -0
- package/dist/index.js.map +1 -0
- package/package.json +53 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { ActionProvider, CreateAction } from '@coinbase/agentkit';
|
|
3
|
+
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
6
|
+
var PriceOptionSchema = z.object({
|
|
7
|
+
S: z.number().positive().describe("Spot price of the underlying"),
|
|
8
|
+
K: z.number().positive().describe("Strike price"),
|
|
9
|
+
T: z.number().positive().describe("Time to expiry in years (0.083 = 30 days)"),
|
|
10
|
+
r: z.number().describe("Risk-free interest rate as decimal (0.05 = 5%)"),
|
|
11
|
+
sigma: z.number().positive().describe("Annualized volatility as decimal (0.28 = 28%)"),
|
|
12
|
+
option_type: z.enum([
|
|
13
|
+
"call",
|
|
14
|
+
"put"
|
|
15
|
+
]).default("call").describe("Option type \u2014 call or put")
|
|
16
|
+
}).describe("Black-Scholes option pricing with full Greeks. Returns price, breakeven, probability ITM, and all first-order Greeks (delta, gamma, vega, theta, rho).");
|
|
17
|
+
var CalculateKellySchema = z.object({
|
|
18
|
+
win_rate: z.number().min(0.01).max(0.99).describe("Probability of winning (0-1)"),
|
|
19
|
+
avg_win: z.number().positive().describe("Average dollar amount won on winning trades"),
|
|
20
|
+
avg_loss: z.number().positive().describe("Average dollar amount lost on losing trades (positive number)")
|
|
21
|
+
}).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.");
|
|
22
|
+
var SimulatePortfolioSchema = z.object({
|
|
23
|
+
initial_value: z.number().positive().describe("Starting portfolio value"),
|
|
24
|
+
annual_return: z.number().describe("Expected annual return as decimal (0.08 = 8%)"),
|
|
25
|
+
annual_vol: z.number().positive().describe("Annual volatility as decimal (0.18 = 18%)"),
|
|
26
|
+
years: z.number().positive().max(30).describe("Time horizon in years (max 30)"),
|
|
27
|
+
simulations: z.number().int().min(100).max(2500).default(1e3).describe("Number of Monte Carlo paths (100-2500; 1000 default)"),
|
|
28
|
+
contributions: z.number().min(0).default(0).describe("Annual contribution amount (set 0 if none)"),
|
|
29
|
+
withdrawal_rate: z.number().min(0).max(0.5).default(0).describe("Annual withdrawal rate as decimal (0.04 = 4%)")
|
|
30
|
+
}).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.");
|
|
31
|
+
var AssessPortfolioRiskSchema = z.object({
|
|
32
|
+
returns: z.array(z.number()).min(30).max(5e3).describe("Array of historical periodic returns as decimals (0.012 = 1.2%). Daily returns assumed; 30-5000 observations."),
|
|
33
|
+
risk_free_rate: z.number().default(0.04).describe("Annual risk-free rate as decimal (0.04 = 4%)"),
|
|
34
|
+
annualization_factor: z.number().int().default(252).describe("252 for daily returns, 52 for weekly, 12 for monthly")
|
|
35
|
+
}).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.");
|
|
36
|
+
var RecommendHedgeSchema = z.object({
|
|
37
|
+
position_type: z.enum([
|
|
38
|
+
"long_stock",
|
|
39
|
+
"short_stock",
|
|
40
|
+
"long_crypto",
|
|
41
|
+
"long_options"
|
|
42
|
+
]).describe("Type of position to hedge"),
|
|
43
|
+
position_value: z.number().positive().describe("Current dollar value of the position"),
|
|
44
|
+
asset_price: z.number().positive().describe("Current spot price of the underlying"),
|
|
45
|
+
volatility: z.number().positive().describe("Annualized volatility of the underlying as decimal (0.28 = 28%)"),
|
|
46
|
+
time_horizon_days: z.number().int().positive().default(30).describe("Hedge time horizon in days"),
|
|
47
|
+
max_hedge_cost_pct: z.number().min(0).max(0.5).default(0.05).describe("Maximum hedge cost as fraction of position (0.05 = 5%)"),
|
|
48
|
+
r: z.number().default(0.05).describe("Risk-free rate as decimal")
|
|
49
|
+
}).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.");
|
|
50
|
+
|
|
51
|
+
// constants.ts
|
|
52
|
+
var QUANTORACLE_BASE_URL = process.env.QUANTORACLE_API_URL ?? "https://api.quantoracle.dev";
|
|
53
|
+
var FREE_TIER_DAILY_LIMIT = 1e3;
|
|
54
|
+
var USER_AGENT = "QuantOracle-AgentKit/1.0";
|
|
55
|
+
|
|
56
|
+
// quantoracleActionProvider.ts
|
|
57
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
58
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
59
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
60
|
+
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;
|
|
61
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
62
|
+
}
|
|
63
|
+
__name(_ts_decorate, "_ts_decorate");
|
|
64
|
+
function _ts_metadata(k, v) {
|
|
65
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
66
|
+
}
|
|
67
|
+
__name(_ts_metadata, "_ts_metadata");
|
|
68
|
+
var QuantOracleActionProvider = class extends ActionProvider {
|
|
69
|
+
static {
|
|
70
|
+
__name(this, "QuantOracleActionProvider");
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Constructor for QuantOracleActionProvider. No configuration required —
|
|
74
|
+
* the free tier covers the calculator endpoints, and paid composites use
|
|
75
|
+
* AgentKit's wallet to settle x402 payments.
|
|
76
|
+
*/
|
|
77
|
+
constructor() {
|
|
78
|
+
super("quantoracle", []);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* QuantOracle works on any network because the calculations are pure math
|
|
82
|
+
* (no on-chain reads). x402 settlements for paid endpoints work on Base
|
|
83
|
+
* mainnet and Solana mainnet, but the agent doesn't need to be on those
|
|
84
|
+
* networks to call the free-tier calculators.
|
|
85
|
+
*
|
|
86
|
+
* @returns true for any network
|
|
87
|
+
*/
|
|
88
|
+
supportsNetwork = /* @__PURE__ */ __name((_network) => true, "supportsNetwork");
|
|
89
|
+
/**
|
|
90
|
+
* Price a European call or put option using Black-Scholes. Returns the
|
|
91
|
+
* theoretical fair value plus the full Greek profile (delta, gamma, vega,
|
|
92
|
+
* theta, rho). Use this before placing options orders to verify market
|
|
93
|
+
* prices are reasonable, or to compute expected option PnL given a view
|
|
94
|
+
* on the underlying.
|
|
95
|
+
*
|
|
96
|
+
* @param args - Spot price, strike, time to expiry, rate, vol, type
|
|
97
|
+
* @returns Markdown-formatted summary with price, breakeven, and Greeks
|
|
98
|
+
*/
|
|
99
|
+
async priceOption(args) {
|
|
100
|
+
try {
|
|
101
|
+
const data = await this.callApi("/v1/options/price", args);
|
|
102
|
+
const ms = data.ms ?? 0;
|
|
103
|
+
const greeks = data.greeks ?? {};
|
|
104
|
+
return [
|
|
105
|
+
`**${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**`,
|
|
106
|
+
``,
|
|
107
|
+
`- Price: $${data.price.toFixed(4)}`,
|
|
108
|
+
`- Breakeven: $${data.breakeven.toFixed(2)}`,
|
|
109
|
+
`- Probability ITM: ${(data.prob_itm * 100).toFixed(1)}%`,
|
|
110
|
+
`- Delta: ${greeks.delta.toFixed(4)}`,
|
|
111
|
+
`- Gamma: ${greeks.gamma.toFixed(4)}`,
|
|
112
|
+
`- Vega: ${greeks.vega.toFixed(4)}`,
|
|
113
|
+
`- Theta (per day): ${greeks.theta.toFixed(4)}`,
|
|
114
|
+
`- Rho: ${greeks.rho.toFixed(4)}`,
|
|
115
|
+
``,
|
|
116
|
+
`_Computed in ${ms.toFixed(0)}ms via QuantOracle._`
|
|
117
|
+
].join("\n");
|
|
118
|
+
} catch (err) {
|
|
119
|
+
return `Failed to price option: ${err instanceof Error ? err.message : String(err)}`;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Calculate Kelly Criterion optimal bet/position sizing. Returns full-,
|
|
124
|
+
* half-, and quarter-Kelly fractions. Use this to derive a defensible
|
|
125
|
+
* risk-per-trade fraction from your strategy's win rate and average
|
|
126
|
+
* win/loss profile, BEFORE sizing the position.
|
|
127
|
+
*
|
|
128
|
+
* @param args - Win rate, average win, average loss
|
|
129
|
+
* @returns Markdown-formatted summary with Kelly variants and edge analysis
|
|
130
|
+
*/
|
|
131
|
+
async calculateKelly(args) {
|
|
132
|
+
try {
|
|
133
|
+
const data = await this.callApi("/v1/risk/kelly", {
|
|
134
|
+
mode: "discrete",
|
|
135
|
+
...args
|
|
136
|
+
});
|
|
137
|
+
const fullKelly = data.full_kelly * 100;
|
|
138
|
+
const halfKelly = data.half_kelly * 100;
|
|
139
|
+
const quarterKelly = data.quarter_kelly * 100;
|
|
140
|
+
const recommendation = data.recommended.replace(/_/g, " ").toLowerCase();
|
|
141
|
+
return [
|
|
142
|
+
`**Kelly sizing for ${(args.win_rate * 100).toFixed(1)}% win rate, $${args.avg_win} avg win, $${args.avg_loss} avg loss**`,
|
|
143
|
+
``,
|
|
144
|
+
`- Full Kelly: ${fullKelly.toFixed(2)}%`,
|
|
145
|
+
`- Half Kelly: ${halfKelly.toFixed(2)}% _(typical for risk-tolerant)_`,
|
|
146
|
+
`- Quarter Kelly: ${quarterKelly.toFixed(2)}% _(safer; recommended)_`,
|
|
147
|
+
`- Edge: ${data.edge.toFixed(2)}%`,
|
|
148
|
+
`- Payoff ratio: ${data.payoff_ratio.toFixed(2)}\xD7`,
|
|
149
|
+
`- **Recommendation:** ${recommendation}`,
|
|
150
|
+
``,
|
|
151
|
+
fullKelly < 0 ? `_Negative edge \u2014 this strategy has negative expected value. Do not deploy capital._` : `_Computed via QuantOracle._`
|
|
152
|
+
].join("\n");
|
|
153
|
+
} catch (err) {
|
|
154
|
+
return `Failed to calculate Kelly: ${err instanceof Error ? err.message : String(err)}`;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Run a Monte Carlo portfolio simulation to project the distribution of
|
|
159
|
+
* terminal outcomes. Use this to assess sequence-of-returns risk before
|
|
160
|
+
* deploying a strategy or to validate retirement-withdrawal sustainability.
|
|
161
|
+
*
|
|
162
|
+
* @param args - Initial value, return/vol assumptions, time horizon, contributions/withdrawals
|
|
163
|
+
* @returns Markdown-formatted summary with distribution percentiles and probability events
|
|
164
|
+
*/
|
|
165
|
+
async simulatePortfolio(args) {
|
|
166
|
+
try {
|
|
167
|
+
const data = await this.callApi("/v1/simulate/montecarlo", args);
|
|
168
|
+
const t = data.terminal;
|
|
169
|
+
const probLoss = (data.prob_loss * 100).toFixed(1);
|
|
170
|
+
const probRuin = (data.prob_ruin * 100).toFixed(2);
|
|
171
|
+
const cagr = (data.cagr * 100).toFixed(2);
|
|
172
|
+
const fmt = /* @__PURE__ */ __name((v) => `$${v.toLocaleString(void 0, {
|
|
173
|
+
maximumFractionDigits: 0
|
|
174
|
+
})}`, "fmt");
|
|
175
|
+
return [
|
|
176
|
+
`**Monte Carlo: $${args.initial_value.toLocaleString()} over ${args.years} years, ${(args.annual_return * 100).toFixed(1)}% return, ${(args.annual_vol * 100).toFixed(1)}% vol**`,
|
|
177
|
+
``,
|
|
178
|
+
`_Distribution of terminal outcomes (across ${args.simulations.toLocaleString()} simulated paths):_`,
|
|
179
|
+
`- Median: ${fmt(t.median)}`,
|
|
180
|
+
`- 5th percentile (worst 5%): ${fmt(t.p5)}`,
|
|
181
|
+
`- 95th percentile (best 5%): ${fmt(t.p95)}`,
|
|
182
|
+
`- Median CAGR: ${cagr}%`,
|
|
183
|
+
``,
|
|
184
|
+
`**Probability events:**`,
|
|
185
|
+
`- Loss vs starting value: ${probLoss}%`,
|
|
186
|
+
`- Probability of ruin (portfolio depleted): ${probRuin}%`,
|
|
187
|
+
``,
|
|
188
|
+
`_Computed in ${data.ms.toFixed(0)}ms via QuantOracle._`
|
|
189
|
+
].join("\n");
|
|
190
|
+
} catch (err) {
|
|
191
|
+
return `Failed to simulate: ${err instanceof Error ? err.message : String(err)}`;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Compute a full risk-adjusted-return audit: Sharpe, Sortino, Calmar, max
|
|
196
|
+
* drawdown, VaR, CVaR, Kelly. PAID composite endpoint ($0.04 per call,
|
|
197
|
+
* settled in USDC via x402 — AgentKit's wallet handles payment automatically
|
|
198
|
+
* when the free tier is exceeded).
|
|
199
|
+
*
|
|
200
|
+
* @param args - Historical returns array, risk-free rate, annualization factor
|
|
201
|
+
* @returns Markdown-formatted comprehensive risk summary
|
|
202
|
+
*/
|
|
203
|
+
async assessPortfolioRisk(args) {
|
|
204
|
+
try {
|
|
205
|
+
const data = await this.callApi("/v1/risk/full-analysis", args);
|
|
206
|
+
const sharpe = data.sharpe?.sharpe_ratio ?? 0;
|
|
207
|
+
const sortino = data.sortino?.sortino_ratio ?? 0;
|
|
208
|
+
const calmar = data.calmar?.calmar_ratio ?? 0;
|
|
209
|
+
const maxDd = data.drawdown?.max_drawdown ?? 0;
|
|
210
|
+
const varBlock = data.var;
|
|
211
|
+
const var95 = varBlock?.var_results?.["95"]?.var_pct ?? 0;
|
|
212
|
+
const cvar95 = varBlock?.var_results?.["95"]?.cvar_pct ?? 0;
|
|
213
|
+
const kelly = data.kelly?.kelly_fraction ?? 0;
|
|
214
|
+
const hurst = data.hurst?.hurst_exponent ?? 0;
|
|
215
|
+
return [
|
|
216
|
+
`**Risk audit on ${args.returns.length} observations** _(paid via x402, $0.04 USDC)_`,
|
|
217
|
+
``,
|
|
218
|
+
`**Risk-adjusted return:**`,
|
|
219
|
+
`- Sharpe ratio: ${sharpe.toFixed(2)}`,
|
|
220
|
+
`- Sortino ratio: ${sortino.toFixed(2)}`,
|
|
221
|
+
`- Calmar ratio: ${calmar.toFixed(2)}`,
|
|
222
|
+
``,
|
|
223
|
+
`**Tail risk:**`,
|
|
224
|
+
`- Max drawdown: ${(maxDd * 100).toFixed(2)}%`,
|
|
225
|
+
`- VaR (95%): ${var95.toFixed(2)}%`,
|
|
226
|
+
`- CVaR / Expected Shortfall (95%): ${cvar95.toFixed(2)}%`,
|
|
227
|
+
``,
|
|
228
|
+
`**Sizing & regime:**`,
|
|
229
|
+
`- Kelly fraction: ${(kelly * 100).toFixed(2)}%`,
|
|
230
|
+
`- Hurst exponent: ${hurst.toFixed(3)} ${hurst > 0.6 ? "_(trending)_" : hurst < 0.4 ? "_(mean-reverting)_" : "_(random walk)_"}`,
|
|
231
|
+
``,
|
|
232
|
+
`_Composite analysis via QuantOracle. Settled on-chain via x402._`
|
|
233
|
+
].join("\n");
|
|
234
|
+
} catch (err) {
|
|
235
|
+
return `Failed to assess risk: ${err instanceof Error ? err.message : String(err)}`;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* Recommend ranked hedge structures for an existing position. PAID
|
|
240
|
+
* composite endpoint ($0.04 per call, settled in USDC via x402).
|
|
241
|
+
*
|
|
242
|
+
* @param args - Position details and hedge parameters
|
|
243
|
+
* @returns Markdown-formatted ranked list of hedge structures
|
|
244
|
+
*/
|
|
245
|
+
async recommendHedge(args) {
|
|
246
|
+
try {
|
|
247
|
+
const data = await this.callApi("/v1/hedging/recommend", args);
|
|
248
|
+
const structures = data.structures ?? [];
|
|
249
|
+
const lines = [
|
|
250
|
+
`**Hedge recommendations for $${args.position_value.toLocaleString()} ${args.position_type} position over ${args.time_horizon_days} days** _(paid via x402, $0.04 USDC)_`,
|
|
251
|
+
``
|
|
252
|
+
];
|
|
253
|
+
for (let i = 0; i < structures.length; i++) {
|
|
254
|
+
const s = structures[i];
|
|
255
|
+
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"}`);
|
|
256
|
+
if (s.legs) {
|
|
257
|
+
for (const leg of s.legs) {
|
|
258
|
+
lines.push(` - ${leg.action} ${leg.quantity}\xD7 ${leg.type} @ $${leg.strike.toFixed(2)} (premium $${leg.premium.toFixed(2)})`);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
lines.push(``);
|
|
262
|
+
}
|
|
263
|
+
return lines.join("\n");
|
|
264
|
+
} catch (err) {
|
|
265
|
+
return `Failed to recommend hedge: ${err instanceof Error ? err.message : String(err)}`;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Internal helper. Posts JSON to a QuantOracle endpoint and returns the
|
|
270
|
+
* parsed response. Throws on non-2xx responses, including 402 Payment
|
|
271
|
+
* Required when the free tier is exceeded — at which point AgentKit's
|
|
272
|
+
* wallet should auto-retry with x402 payment headers (depending on your
|
|
273
|
+
* walletProvider setup).
|
|
274
|
+
*
|
|
275
|
+
* @param path - Endpoint path beginning with /v1/...
|
|
276
|
+
* @param body - JSON-serializable request body
|
|
277
|
+
* @returns Parsed JSON response
|
|
278
|
+
*/
|
|
279
|
+
async callApi(path, body) {
|
|
280
|
+
const res = await fetch(`${QUANTORACLE_BASE_URL}${path}`, {
|
|
281
|
+
method: "POST",
|
|
282
|
+
headers: {
|
|
283
|
+
"Content-Type": "application/json",
|
|
284
|
+
"User-Agent": USER_AGENT,
|
|
285
|
+
"X-Source": "agentkit"
|
|
286
|
+
},
|
|
287
|
+
body: JSON.stringify(body)
|
|
288
|
+
});
|
|
289
|
+
if (!res.ok) {
|
|
290
|
+
let detail = "";
|
|
291
|
+
try {
|
|
292
|
+
const j = await res.json();
|
|
293
|
+
detail = JSON.stringify(j).slice(0, 200);
|
|
294
|
+
} catch {
|
|
295
|
+
}
|
|
296
|
+
throw new Error(`QuantOracle ${path} returned ${res.status}: ${detail}`);
|
|
297
|
+
}
|
|
298
|
+
return await res.json();
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
_ts_decorate([
|
|
302
|
+
CreateAction({
|
|
303
|
+
name: "price_option",
|
|
304
|
+
description: `
|
|
305
|
+
Price a European call or put option using Black-Scholes with full Greeks.
|
|
306
|
+
Returns the option's theoretical price, breakeven, probability ITM, and
|
|
307
|
+
all first-order Greeks (delta, gamma, vega, theta, rho).
|
|
308
|
+
|
|
309
|
+
Use this when:
|
|
310
|
+
- Verifying that a market option price is reasonable before placing an order
|
|
311
|
+
- Estimating PnL on an existing options position given a view on the underlying
|
|
312
|
+
- Computing position deltas for portfolio hedging decisions
|
|
313
|
+
- Sizing options trades based on Greek exposures
|
|
314
|
+
|
|
315
|
+
Inputs: spot price, strike, time to expiry (in years; 30 days = 0.083),
|
|
316
|
+
risk-free rate, volatility, option type (call or put).
|
|
317
|
+
`,
|
|
318
|
+
schema: PriceOptionSchema
|
|
319
|
+
}),
|
|
320
|
+
_ts_metadata("design:type", Function),
|
|
321
|
+
_ts_metadata("design:paramtypes", [
|
|
322
|
+
typeof z === "undefined" || typeof z.infer === "undefined" ? Object : z.infer
|
|
323
|
+
]),
|
|
324
|
+
_ts_metadata("design:returntype", Promise)
|
|
325
|
+
], QuantOracleActionProvider.prototype, "priceOption", null);
|
|
326
|
+
_ts_decorate([
|
|
327
|
+
CreateAction({
|
|
328
|
+
name: "calculate_kelly",
|
|
329
|
+
description: `
|
|
330
|
+
Calculate Kelly Criterion optimal bet sizing given a strategy's win rate
|
|
331
|
+
and average win/loss amounts. Returns the full-, half-, and quarter-Kelly
|
|
332
|
+
fractions, the edge per dollar risked, and the payoff ratio.
|
|
333
|
+
|
|
334
|
+
Use this when:
|
|
335
|
+
- Deriving the risk-per-trade fraction for a position-sizing system
|
|
336
|
+
- Comparing two strategies head-to-head (higher Kelly = better edge per unit risk)
|
|
337
|
+
- Validating that a strategy is positive-expected-value before deploying capital
|
|
338
|
+
|
|
339
|
+
The formula assumes binary outcomes with fixed amounts (suits options trades,
|
|
340
|
+
event-driven bets, or any discrete win/loss strategy). For continuous-return
|
|
341
|
+
strategies, see the QuantOracle API endpoint /v1/risk/kelly with mode=continuous.
|
|
342
|
+
|
|
343
|
+
Most professionals use half- or quarter-Kelly because edge estimates are noisy
|
|
344
|
+
and overestimating edge causes severe overbetting.
|
|
345
|
+
`,
|
|
346
|
+
schema: CalculateKellySchema
|
|
347
|
+
}),
|
|
348
|
+
_ts_metadata("design:type", Function),
|
|
349
|
+
_ts_metadata("design:paramtypes", [
|
|
350
|
+
typeof z === "undefined" || typeof z.infer === "undefined" ? Object : z.infer
|
|
351
|
+
]),
|
|
352
|
+
_ts_metadata("design:returntype", Promise)
|
|
353
|
+
], QuantOracleActionProvider.prototype, "calculateKelly", null);
|
|
354
|
+
_ts_decorate([
|
|
355
|
+
CreateAction({
|
|
356
|
+
name: "simulate_portfolio",
|
|
357
|
+
description: `
|
|
358
|
+
Run a Monte Carlo simulation projecting the distribution of portfolio
|
|
359
|
+
outcomes over a chosen time horizon. Returns terminal-value percentiles
|
|
360
|
+
(P5/P25/median/P75/P95), probability of loss, probability of doubling,
|
|
361
|
+
and probability of ruin under withdrawals.
|
|
362
|
+
|
|
363
|
+
Use this when:
|
|
364
|
+
- Stress-testing a withdrawal-rate plan (e.g. "is 4% sustainable for 30 years?")
|
|
365
|
+
- Comparing portfolio strategies head-to-head
|
|
366
|
+
- Quantifying sequence-of-returns risk for retirement-style allocations
|
|
367
|
+
- Showing a user the realistic range of outcomes (not just expected return)
|
|
368
|
+
|
|
369
|
+
The simulation uses geometric Brownian motion (log-normal returns) \u2014 a
|
|
370
|
+
standard textbook assumption that is reasonable for diversified portfolios
|
|
371
|
+
but underestimates fat-tail risk for high-vol single-asset strategies.
|
|
372
|
+
`,
|
|
373
|
+
schema: SimulatePortfolioSchema
|
|
374
|
+
}),
|
|
375
|
+
_ts_metadata("design:type", Function),
|
|
376
|
+
_ts_metadata("design:paramtypes", [
|
|
377
|
+
typeof z === "undefined" || typeof z.infer === "undefined" ? Object : z.infer
|
|
378
|
+
]),
|
|
379
|
+
_ts_metadata("design:returntype", Promise)
|
|
380
|
+
], QuantOracleActionProvider.prototype, "simulatePortfolio", null);
|
|
381
|
+
_ts_decorate([
|
|
382
|
+
CreateAction({
|
|
383
|
+
name: "assess_portfolio_risk",
|
|
384
|
+
description: `
|
|
385
|
+
Run a comprehensive risk audit on a return series. Returns Sharpe ratio,
|
|
386
|
+
Sortino ratio, Calmar ratio, max drawdown, VaR (95%/99%), CVaR (Expected
|
|
387
|
+
Shortfall), Kelly fraction, and Hurst exponent (regime indicator).
|
|
388
|
+
|
|
389
|
+
Use this when:
|
|
390
|
+
- Evaluating a backtest before deploying real capital
|
|
391
|
+
- Auditing an existing strategy's risk-adjusted performance
|
|
392
|
+
- Comparing two strategies on multiple risk dimensions in one call
|
|
393
|
+
- Generating a one-page risk summary for a stakeholder
|
|
394
|
+
|
|
395
|
+
PAID composite endpoint: $0.04 per call, settled in USDC via x402 on Base
|
|
396
|
+
or Solana. AgentKit's wallet pays automatically \u2014 no API key, no signup.
|
|
397
|
+
The savings vs running 8 separate calculator calls is meaningful both in
|
|
398
|
+
cost and in latency.
|
|
399
|
+
|
|
400
|
+
Requires at least 30 observations of historical returns; 252+ recommended
|
|
401
|
+
for statistical significance.
|
|
402
|
+
`,
|
|
403
|
+
schema: AssessPortfolioRiskSchema
|
|
404
|
+
}),
|
|
405
|
+
_ts_metadata("design:type", Function),
|
|
406
|
+
_ts_metadata("design:paramtypes", [
|
|
407
|
+
typeof z === "undefined" || typeof z.infer === "undefined" ? Object : z.infer
|
|
408
|
+
]),
|
|
409
|
+
_ts_metadata("design:returntype", Promise)
|
|
410
|
+
], QuantOracleActionProvider.prototype, "assessPortfolioRisk", null);
|
|
411
|
+
_ts_decorate([
|
|
412
|
+
CreateAction({
|
|
413
|
+
name: "recommend_hedge",
|
|
414
|
+
description: `
|
|
415
|
+
Recommend ranked hedge structures (collar, protective put, partial put,
|
|
416
|
+
inverse) for an existing position. Each recommendation includes the cost
|
|
417
|
+
as a percentage of position value, the downside protection floor, and the
|
|
418
|
+
upside cap (if any).
|
|
419
|
+
|
|
420
|
+
Use this when:
|
|
421
|
+
- An agent holding a long position wants to limit downside before an event
|
|
422
|
+
(earnings, FOMC, FDA decision) without selling
|
|
423
|
+
- An agent needs to compare hedge strategies head-to-head by cost vs protection
|
|
424
|
+
- Programmatic risk management of crypto positions ahead of high-vol periods
|
|
425
|
+
|
|
426
|
+
PAID composite endpoint: $0.04 per call, settled in USDC via x402 on Base or
|
|
427
|
+
Solana. AgentKit's wallet pays automatically. The output is a ranked table
|
|
428
|
+
the agent can present to a user or use directly to place hedge orders.
|
|
429
|
+
`,
|
|
430
|
+
schema: RecommendHedgeSchema
|
|
431
|
+
}),
|
|
432
|
+
_ts_metadata("design:type", Function),
|
|
433
|
+
_ts_metadata("design:paramtypes", [
|
|
434
|
+
typeof z === "undefined" || typeof z.infer === "undefined" ? Object : z.infer
|
|
435
|
+
]),
|
|
436
|
+
_ts_metadata("design:returntype", Promise)
|
|
437
|
+
], QuantOracleActionProvider.prototype, "recommendHedge", null);
|
|
438
|
+
var quantoracleActionProvider = /* @__PURE__ */ __name(() => new QuantOracleActionProvider(), "quantoracleActionProvider");
|
|
439
|
+
|
|
440
|
+
export { AssessPortfolioRiskSchema, CalculateKellySchema, FREE_TIER_DAILY_LIMIT, PriceOptionSchema, QUANTORACLE_BASE_URL, QuantOracleActionProvider, RecommendHedgeSchema, SimulatePortfolioSchema, USER_AGENT, quantoracleActionProvider };
|
|
441
|
+
//# sourceMappingURL=index.js.map
|
|
442
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../schemas.ts","../constants.ts","../quantoracleActionProvider.ts"],"names":["PriceOptionSchema","z","object","S","number","positive","describe","K","T","r","sigma","option_type","enum","default","CalculateKellySchema","win_rate","min","max","avg_win","avg_loss","SimulatePortfolioSchema","initial_value","annual_return","annual_vol","years","simulations","int","contributions","withdrawal_rate","AssessPortfolioRiskSchema","returns","array","risk_free_rate","annualization_factor","RecommendHedgeSchema","position_type","position_value","asset_price","volatility","time_horizon_days","max_hedge_cost_pct","QUANTORACLE_BASE_URL","process","env","QUANTORACLE_API_URL","FREE_TIER_DAILY_LIMIT","USER_AGENT","QuantOracleActionProvider","ActionProvider","supportsNetwork","_network","priceOption","args","data","callApi","ms","greeks","toUpperCase","toFixed","price","breakeven","prob_itm","delta","gamma","vega","theta","rho","join","err","Error","message","String","calculateKelly","mode","fullKelly","full_kelly","halfKelly","half_kelly","quarterKelly","quarter_kelly","recommendation","recommended","replace","toLowerCase","edge","payoff_ratio","simulatePortfolio","t","terminal","probLoss","prob_loss","probRuin","prob_ruin","cagr","fmt","v","toLocaleString","undefined","maximumFractionDigits","median","p5","p95","assessPortfolioRisk","sharpe","sharpe_ratio","sortino","sortino_ratio","calmar","calmar_ratio","maxDd","drawdown","max_drawdown","varBlock","var","var95","var_results","var_pct","cvar95","cvar_pct","kelly","kelly_fraction","hurst","hurst_exponent","length","recommendHedge","structures","lines","i","s","push","name","cost_pct","cost_dollars","downside_floor","upside_cap","legs","leg","action","quantity","type","strike","premium","path","body","res","fetch","method","headers","JSON","stringify","ok","detail","j","json","slice","status","description","schema","quantoracleActionProvider"],"mappings":"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","file":"index.js","sourcesContent":["import { z } from \"zod\";\n\n/**\n * Schemas for the five highest-leverage QuantOracle actions an AgentKit\n * agent typically needs. The full QuantOracle API has 73 endpoints; this\n * provider intentionally exposes a curated subset of the actions that\n * solve real agent decisions (size a position, hedge it, simulate it,\n * audit risk, value an option). For the long tail, agents can call the\n * raw API directly via fetch.\n */\n\nexport const PriceOptionSchema = z\n .object({\n S: z.number().positive().describe(\"Spot price of the underlying\"),\n K: z.number().positive().describe(\"Strike price\"),\n T: z.number().positive().describe(\"Time to expiry in years (0.083 = 30 days)\"),\n r: z.number().describe(\"Risk-free interest rate as decimal (0.05 = 5%)\"),\n sigma: z.number().positive().describe(\"Annualized volatility as decimal (0.28 = 28%)\"),\n option_type: z\n .enum([\"call\", \"put\"])\n .default(\"call\")\n .describe(\"Option type — call or put\"),\n })\n .describe(\n \"Black-Scholes option pricing with full Greeks. Returns price, breakeven, probability ITM, and all first-order Greeks (delta, gamma, vega, theta, rho).\",\n );\n\nexport const CalculateKellySchema = z\n .object({\n win_rate: z\n .number()\n .min(0.01)\n .max(0.99)\n .describe(\"Probability of winning (0-1)\"),\n avg_win: z.number().positive().describe(\"Average dollar amount won on winning trades\"),\n avg_loss: z\n .number()\n .positive()\n .describe(\"Average dollar amount lost on losing trades (positive number)\"),\n })\n .describe(\n \"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.\",\n );\n\nexport const SimulatePortfolioSchema = z\n .object({\n initial_value: z.number().positive().describe(\"Starting portfolio value\"),\n annual_return: z.number().describe(\"Expected annual return as decimal (0.08 = 8%)\"),\n annual_vol: z\n .number()\n .positive()\n .describe(\"Annual volatility as decimal (0.18 = 18%)\"),\n years: z\n .number()\n .positive()\n .max(30)\n .describe(\"Time horizon in years (max 30)\"),\n simulations: z\n .number()\n .int()\n .min(100)\n .max(2500)\n .default(1000)\n .describe(\"Number of Monte Carlo paths (100-2500; 1000 default)\"),\n contributions: z\n .number()\n .min(0)\n .default(0)\n .describe(\"Annual contribution amount (set 0 if none)\"),\n withdrawal_rate: z\n .number()\n .min(0)\n .max(0.5)\n .default(0)\n .describe(\"Annual withdrawal rate as decimal (0.04 = 4%)\"),\n })\n .describe(\n \"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.\",\n );\n\nexport const AssessPortfolioRiskSchema = z\n .object({\n returns: z\n .array(z.number())\n .min(30)\n .max(5000)\n .describe(\n \"Array of historical periodic returns as decimals (0.012 = 1.2%). Daily returns assumed; 30-5000 observations.\",\n ),\n risk_free_rate: z\n .number()\n .default(0.04)\n .describe(\"Annual risk-free rate as decimal (0.04 = 4%)\"),\n annualization_factor: z\n .number()\n .int()\n .default(252)\n .describe(\"252 for daily returns, 52 for weekly, 12 for monthly\"),\n })\n .describe(\n \"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.\",\n );\n\nexport const RecommendHedgeSchema = z\n .object({\n position_type: z\n .enum([\"long_stock\", \"short_stock\", \"long_crypto\", \"long_options\"])\n .describe(\"Type of position to hedge\"),\n position_value: z\n .number()\n .positive()\n .describe(\"Current dollar value of the position\"),\n asset_price: z.number().positive().describe(\"Current spot price of the underlying\"),\n volatility: z\n .number()\n .positive()\n .describe(\"Annualized volatility of the underlying as decimal (0.28 = 28%)\"),\n time_horizon_days: z\n .number()\n .int()\n .positive()\n .default(30)\n .describe(\"Hedge time horizon in days\"),\n max_hedge_cost_pct: z\n .number()\n .min(0)\n .max(0.5)\n .default(0.05)\n .describe(\"Maximum hedge cost as fraction of position (0.05 = 5%)\"),\n r: z.number().default(0.05).describe(\"Risk-free rate as decimal\"),\n })\n .describe(\n \"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.\",\n );\n","/**\n * Base URL for the QuantOracle API.\n *\n * Override via the QUANTORACLE_API_URL env var if you're proxying through a\n * private gateway or testing against a staging instance.\n */\nexport const QUANTORACLE_BASE_URL =\n process.env.QUANTORACLE_API_URL ?? \"https://api.quantoracle.dev\";\n\n/**\n * Free tier: 1,000 calls/IP/day, no signup, no API key.\n *\n * Paid composite endpoints (full-analysis, hedging, backtest, rebalance) cost\n * $0.04-$0.10 per call settled in USDC on Base or Solana via the x402\n * protocol. AgentKit's wallet pays automatically — your agent doesn't need\n * to handle billing logic.\n */\nexport const FREE_TIER_DAILY_LIMIT = 1000;\n\n/**\n * Generic User-Agent so the QuantOracle backend can attribute calls and we\n * can show AgentKit usage in our analytics dashboard.\n */\nexport const USER_AGENT = \"QuantOracle-AgentKit/1.0\";\n","import { z } from \"zod\";\nimport { ActionProvider } from \"@coinbase/agentkit\";\nimport { CreateAction } from \"@coinbase/agentkit\";\nimport { Network } from \"@coinbase/agentkit\";\nimport {\n AssessPortfolioRiskSchema,\n CalculateKellySchema,\n PriceOptionSchema,\n RecommendHedgeSchema,\n SimulatePortfolioSchema,\n} from \"./schemas\";\nimport { QUANTORACLE_BASE_URL, USER_AGENT } from \"./constants\";\n\n/**\n * QuantOracleActionProvider — deterministic quant finance math for AgentKit agents.\n *\n * QuantOracle is a free pay-per-call API serving 73 deterministic financial\n * calculators (options pricing, risk metrics, portfolio optimization,\n * Monte Carlo, statistics, crypto/DeFi, FX/macro, TVM). This provider exposes\n * the five highest-leverage actions an autonomous trading or finance agent\n * typically needs.\n *\n * **Why use grounded math over LLM-only computation:**\n * - Same inputs always produce the same outputs (verifiable, cacheable)\n * - Citation-tested against textbook values (Hull, Wilmott, Lopez de Prado)\n * - Sub-70ms response time, no Python deps required\n * - Free tier: 1,000 calls/IP/day with no signup or API key\n * - Paid composites (full-analysis, hedge, backtest) settle in USDC on Base\n * or Solana via x402. AgentKit's wallet pays automatically.\n *\n * @example\n * ```ts\n * import { AgentKit } from \"@coinbase/agentkit\";\n * import { quantoracleActionProvider } from \"@quantoracle/agentkit\";\n *\n * const agent = await AgentKit.from({\n * walletProvider,\n * actionProviders: [quantoracleActionProvider()],\n * });\n *\n * // Agent can now call: price_option, calculate_kelly,\n * // simulate_portfolio, assess_portfolio_risk, recommend_hedge\n * ```\n */\nexport class QuantOracleActionProvider extends ActionProvider {\n /**\n * Constructor for QuantOracleActionProvider. No configuration required —\n * the free tier covers the calculator endpoints, and paid composites use\n * AgentKit's wallet to settle x402 payments.\n */\n constructor() {\n super(\"quantoracle\", []);\n }\n\n /**\n * QuantOracle works on any network because the calculations are pure math\n * (no on-chain reads). x402 settlements for paid endpoints work on Base\n * mainnet and Solana mainnet, but the agent doesn't need to be on those\n * networks to call the free-tier calculators.\n *\n * @returns true for any network\n */\n supportsNetwork = (_network: Network): boolean => true;\n\n /**\n * Price a European call or put option using Black-Scholes. Returns the\n * theoretical fair value plus the full Greek profile (delta, gamma, vega,\n * theta, rho). Use this before placing options orders to verify market\n * prices are reasonable, or to compute expected option PnL given a view\n * on the underlying.\n *\n * @param args - Spot price, strike, time to expiry, rate, vol, type\n * @returns Markdown-formatted summary with price, breakeven, and Greeks\n */\n @CreateAction({\n name: \"price_option\",\n description: `\nPrice a European call or put option using Black-Scholes with full Greeks.\nReturns the option's theoretical price, breakeven, probability ITM, and\nall first-order Greeks (delta, gamma, vega, theta, rho).\n\nUse this when:\n- Verifying that a market option price is reasonable before placing an order\n- Estimating PnL on an existing options position given a view on the underlying\n- Computing position deltas for portfolio hedging decisions\n- Sizing options trades based on Greek exposures\n\nInputs: spot price, strike, time to expiry (in years; 30 days = 0.083),\nrisk-free rate, volatility, option type (call or put).\n`,\n schema: PriceOptionSchema,\n })\n async priceOption(args: z.infer<typeof PriceOptionSchema>): Promise<string> {\n try {\n const data = await this.callApi(\"/v1/options/price\", args);\n const ms = (data.ms as number) ?? 0;\n const greeks = (data.greeks ?? {}) as Record<string, number>;\n return [\n `**${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**`,\n ``,\n `- Price: $${(data.price as number).toFixed(4)}`,\n `- Breakeven: $${(data.breakeven as number).toFixed(2)}`,\n `- Probability ITM: ${((data.prob_itm as number) * 100).toFixed(1)}%`,\n `- Delta: ${(greeks.delta as number).toFixed(4)}`,\n `- Gamma: ${(greeks.gamma as number).toFixed(4)}`,\n `- Vega: ${(greeks.vega as number).toFixed(4)}`,\n `- Theta (per day): ${(greeks.theta as number).toFixed(4)}`,\n `- Rho: ${(greeks.rho as number).toFixed(4)}`,\n ``,\n `_Computed in ${ms.toFixed(0)}ms via QuantOracle._`,\n ].join(\"\\n\");\n } catch (err) {\n return `Failed to price option: ${err instanceof Error ? err.message : String(err)}`;\n }\n }\n\n /**\n * Calculate Kelly Criterion optimal bet/position sizing. Returns full-,\n * half-, and quarter-Kelly fractions. Use this to derive a defensible\n * risk-per-trade fraction from your strategy's win rate and average\n * win/loss profile, BEFORE sizing the position.\n *\n * @param args - Win rate, average win, average loss\n * @returns Markdown-formatted summary with Kelly variants and edge analysis\n */\n @CreateAction({\n name: \"calculate_kelly\",\n description: `\nCalculate Kelly Criterion optimal bet sizing given a strategy's win rate\nand average win/loss amounts. Returns the full-, half-, and quarter-Kelly\nfractions, the edge per dollar risked, and the payoff ratio.\n\nUse this when:\n- Deriving the risk-per-trade fraction for a position-sizing system\n- Comparing two strategies head-to-head (higher Kelly = better edge per unit risk)\n- Validating that a strategy is positive-expected-value before deploying capital\n\nThe formula assumes binary outcomes with fixed amounts (suits options trades,\nevent-driven bets, or any discrete win/loss strategy). For continuous-return\nstrategies, see the QuantOracle API endpoint /v1/risk/kelly with mode=continuous.\n\nMost professionals use half- or quarter-Kelly because edge estimates are noisy\nand overestimating edge causes severe overbetting.\n`,\n schema: CalculateKellySchema,\n })\n async calculateKelly(args: z.infer<typeof CalculateKellySchema>): Promise<string> {\n try {\n const data = await this.callApi(\"/v1/risk/kelly\", { mode: \"discrete\", ...args });\n const fullKelly = (data.full_kelly as number) * 100;\n const halfKelly = (data.half_kelly as number) * 100;\n const quarterKelly = (data.quarter_kelly as number) * 100;\n const recommendation = (data.recommended as string).replace(/_/g, \" \").toLowerCase();\n return [\n `**Kelly sizing for ${(args.win_rate * 100).toFixed(1)}% win rate, $${args.avg_win} avg win, $${args.avg_loss} avg loss**`,\n ``,\n `- Full Kelly: ${fullKelly.toFixed(2)}%`,\n `- Half Kelly: ${halfKelly.toFixed(2)}% _(typical for risk-tolerant)_`,\n `- Quarter Kelly: ${quarterKelly.toFixed(2)}% _(safer; recommended)_`,\n `- Edge: ${(data.edge as number).toFixed(2)}%`,\n `- Payoff ratio: ${(data.payoff_ratio as number).toFixed(2)}×`,\n `- **Recommendation:** ${recommendation}`,\n ``,\n fullKelly < 0\n ? `_Negative edge — this strategy has negative expected value. Do not deploy capital._`\n : `_Computed via QuantOracle._`,\n ].join(\"\\n\");\n } catch (err) {\n return `Failed to calculate Kelly: ${err instanceof Error ? err.message : String(err)}`;\n }\n }\n\n /**\n * Run a Monte Carlo portfolio simulation to project the distribution of\n * terminal outcomes. Use this to assess sequence-of-returns risk before\n * deploying a strategy or to validate retirement-withdrawal sustainability.\n *\n * @param args - Initial value, return/vol assumptions, time horizon, contributions/withdrawals\n * @returns Markdown-formatted summary with distribution percentiles and probability events\n */\n @CreateAction({\n name: \"simulate_portfolio\",\n description: `\nRun a Monte Carlo simulation projecting the distribution of portfolio\noutcomes over a chosen time horizon. Returns terminal-value percentiles\n(P5/P25/median/P75/P95), probability of loss, probability of doubling,\nand probability of ruin under withdrawals.\n\nUse this when:\n- Stress-testing a withdrawal-rate plan (e.g. \"is 4% sustainable for 30 years?\")\n- Comparing portfolio strategies head-to-head\n- Quantifying sequence-of-returns risk for retirement-style allocations\n- Showing a user the realistic range of outcomes (not just expected return)\n\nThe simulation uses geometric Brownian motion (log-normal returns) — a\nstandard textbook assumption that is reasonable for diversified portfolios\nbut underestimates fat-tail risk for high-vol single-asset strategies.\n`,\n schema: SimulatePortfolioSchema,\n })\n async simulatePortfolio(\n args: z.infer<typeof SimulatePortfolioSchema>,\n ): Promise<string> {\n try {\n const data = await this.callApi(\"/v1/simulate/montecarlo\", args);\n const t = data.terminal as Record<string, number>;\n const probLoss = ((data.prob_loss as number) * 100).toFixed(1);\n const probRuin = ((data.prob_ruin as number) * 100).toFixed(2);\n const cagr = ((data.cagr as number) * 100).toFixed(2);\n const fmt = (v: number) => `$${v.toLocaleString(undefined, { maximumFractionDigits: 0 })}`;\n return [\n `**Monte Carlo: $${args.initial_value.toLocaleString()} over ${args.years} years, ${(args.annual_return * 100).toFixed(1)}% return, ${(args.annual_vol * 100).toFixed(1)}% vol**`,\n ``,\n `_Distribution of terminal outcomes (across ${args.simulations.toLocaleString()} simulated paths):_`,\n `- Median: ${fmt(t.median)}`,\n `- 5th percentile (worst 5%): ${fmt(t.p5)}`,\n `- 95th percentile (best 5%): ${fmt(t.p95)}`,\n `- Median CAGR: ${cagr}%`,\n ``,\n `**Probability events:**`,\n `- Loss vs starting value: ${probLoss}%`,\n `- Probability of ruin (portfolio depleted): ${probRuin}%`,\n ``,\n `_Computed in ${(data.ms as number).toFixed(0)}ms via QuantOracle._`,\n ].join(\"\\n\");\n } catch (err) {\n return `Failed to simulate: ${err instanceof Error ? err.message : String(err)}`;\n }\n }\n\n /**\n * Compute a full risk-adjusted-return audit: Sharpe, Sortino, Calmar, max\n * drawdown, VaR, CVaR, Kelly. PAID composite endpoint ($0.04 per call,\n * settled in USDC via x402 — AgentKit's wallet handles payment automatically\n * when the free tier is exceeded).\n *\n * @param args - Historical returns array, risk-free rate, annualization factor\n * @returns Markdown-formatted comprehensive risk summary\n */\n @CreateAction({\n name: \"assess_portfolio_risk\",\n description: `\nRun a comprehensive risk audit on a return series. Returns Sharpe ratio,\nSortino ratio, Calmar ratio, max drawdown, VaR (95%/99%), CVaR (Expected\nShortfall), Kelly fraction, and Hurst exponent (regime indicator).\n\nUse this when:\n- Evaluating a backtest before deploying real capital\n- Auditing an existing strategy's risk-adjusted performance\n- Comparing two strategies on multiple risk dimensions in one call\n- Generating a one-page risk summary for a stakeholder\n\nPAID composite endpoint: $0.04 per call, settled in USDC via x402 on Base\nor Solana. AgentKit's wallet pays automatically — no API key, no signup.\nThe savings vs running 8 separate calculator calls is meaningful both in\ncost and in latency.\n\nRequires at least 30 observations of historical returns; 252+ recommended\nfor statistical significance.\n`,\n schema: AssessPortfolioRiskSchema,\n })\n async assessPortfolioRisk(\n args: z.infer<typeof AssessPortfolioRiskSchema>,\n ): Promise<string> {\n try {\n const data = await this.callApi(\"/v1/risk/full-analysis\", args);\n // The response shape from /v1/risk/full-analysis includes nested objects\n // for sharpe, sortino, drawdown, var, etc. We surface the headline\n // numbers as Markdown.\n // Cast nested response blocks — the API returns Record<string, unknown>\n // and TypeScript needs explicit types to traverse the nested keys.\n const sharpe = ((data.sharpe as Record<string, number>)?.sharpe_ratio as number) ?? 0;\n const sortino = ((data.sortino as Record<string, number>)?.sortino_ratio as number) ?? 0;\n const calmar = ((data.calmar as Record<string, number>)?.calmar_ratio as number) ?? 0;\n const maxDd = ((data.drawdown as Record<string, number>)?.max_drawdown as number) ?? 0;\n const varBlock = data.var as Record<string, Record<string, Record<string, number>>> | undefined;\n const var95 = (varBlock?.var_results?.[\"95\"]?.var_pct as number) ?? 0;\n const cvar95 = (varBlock?.var_results?.[\"95\"]?.cvar_pct as number) ?? 0;\n const kelly = ((data.kelly as Record<string, number>)?.kelly_fraction as number) ?? 0;\n const hurst = ((data.hurst as Record<string, number>)?.hurst_exponent as number) ?? 0;\n return [\n `**Risk audit on ${args.returns.length} observations** _(paid via x402, $0.04 USDC)_`,\n ``,\n `**Risk-adjusted return:**`,\n `- Sharpe ratio: ${sharpe.toFixed(2)}`,\n `- Sortino ratio: ${sortino.toFixed(2)}`,\n `- Calmar ratio: ${calmar.toFixed(2)}`,\n ``,\n `**Tail risk:**`,\n `- Max drawdown: ${(maxDd * 100).toFixed(2)}%`,\n `- VaR (95%): ${var95.toFixed(2)}%`,\n `- CVaR / Expected Shortfall (95%): ${cvar95.toFixed(2)}%`,\n ``,\n `**Sizing & regime:**`,\n `- Kelly fraction: ${(kelly * 100).toFixed(2)}%`,\n `- Hurst exponent: ${hurst.toFixed(3)} ${hurst > 0.6 ? \"_(trending)_\" : hurst < 0.4 ? \"_(mean-reverting)_\" : \"_(random walk)_\"}`,\n ``,\n `_Composite analysis via QuantOracle. Settled on-chain via x402._`,\n ].join(\"\\n\");\n } catch (err) {\n return `Failed to assess risk: ${err instanceof Error ? err.message : String(err)}`;\n }\n }\n\n /**\n * Recommend ranked hedge structures for an existing position. PAID\n * composite endpoint ($0.04 per call, settled in USDC via x402).\n *\n * @param args - Position details and hedge parameters\n * @returns Markdown-formatted ranked list of hedge structures\n */\n @CreateAction({\n name: \"recommend_hedge\",\n description: `\nRecommend ranked hedge structures (collar, protective put, partial put,\ninverse) for an existing position. Each recommendation includes the cost\nas a percentage of position value, the downside protection floor, and the\nupside cap (if any).\n\nUse this when:\n- An agent holding a long position wants to limit downside before an event\n (earnings, FOMC, FDA decision) without selling\n- An agent needs to compare hedge strategies head-to-head by cost vs protection\n- Programmatic risk management of crypto positions ahead of high-vol periods\n\nPAID composite endpoint: $0.04 per call, settled in USDC via x402 on Base or\nSolana. AgentKit's wallet pays automatically. The output is a ranked table\nthe agent can present to a user or use directly to place hedge orders.\n`,\n schema: RecommendHedgeSchema,\n })\n async recommendHedge(args: z.infer<typeof RecommendHedgeSchema>): Promise<string> {\n try {\n // The /v1/hedging/recommend endpoint accepts our schema as-is.\n const data = await this.callApi(\"/v1/hedging/recommend\", args);\n const structures = (data.structures as Array<Record<string, unknown>>) ?? [];\n const lines: string[] = [\n `**Hedge recommendations for $${args.position_value.toLocaleString()} ${args.position_type} position over ${args.time_horizon_days} days** _(paid via x402, $0.04 USDC)_`,\n ``,\n ];\n for (let i = 0; i < structures.length; i++) {\n const s = structures[i];\n lines.push(\n `**${i + 1}. ${s.name as string}** — cost ${((s.cost_pct as number) * 100).toFixed(2)}% ($${(s.cost_dollars as number).toFixed(2)}), floor ${((s.downside_floor as number) * 100).toFixed(1)}%${s.upside_cap ? `, upside cap ${((s.upside_cap as number) * 100).toFixed(1)}%` : \", unlimited upside\"}`,\n );\n if (s.legs) {\n for (const leg of s.legs as Array<Record<string, unknown>>) {\n lines.push(\n ` - ${leg.action as string} ${leg.quantity as number}× ${leg.type as string} @ $${(leg.strike as number).toFixed(2)} (premium $${(leg.premium as number).toFixed(2)})`,\n );\n }\n }\n lines.push(``);\n }\n return lines.join(\"\\n\");\n } catch (err) {\n return `Failed to recommend hedge: ${err instanceof Error ? err.message : String(err)}`;\n }\n }\n\n /**\n * Internal helper. Posts JSON to a QuantOracle endpoint and returns the\n * parsed response. Throws on non-2xx responses, including 402 Payment\n * Required when the free tier is exceeded — at which point AgentKit's\n * wallet should auto-retry with x402 payment headers (depending on your\n * walletProvider setup).\n *\n * @param path - Endpoint path beginning with /v1/...\n * @param body - JSON-serializable request body\n * @returns Parsed JSON response\n */\n private async callApi(\n path: string,\n body: Record<string, unknown>,\n ): Promise<Record<string, unknown>> {\n const res = await fetch(`${QUANTORACLE_BASE_URL}${path}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"User-Agent\": USER_AGENT,\n \"X-Source\": \"agentkit\",\n },\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n let detail = \"\";\n try {\n const j = await res.json();\n detail = JSON.stringify(j).slice(0, 200);\n } catch {\n // ignore\n }\n throw new Error(`QuantOracle ${path} returned ${res.status}: ${detail}`);\n }\n return (await res.json()) as Record<string, unknown>;\n }\n}\n\n/**\n * Factory function — returns a configured QuantOracleActionProvider instance.\n * This is the canonical way to add the provider to AgentKit.\n *\n * @example\n * ```ts\n * import { quantoracleActionProvider } from \"@quantoracle/agentkit\";\n *\n * const agent = await AgentKit.from({\n * walletProvider,\n * actionProviders: [quantoracleActionProvider()],\n * });\n * ```\n *\n * @returns Configured QuantOracleActionProvider\n */\nexport const quantoracleActionProvider = (): QuantOracleActionProvider =>\n new QuantOracleActionProvider();\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@quantoracle/agentkit",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Deterministic quant finance math for Coinbase AgentKit agents — Black-Scholes, Kelly, Monte Carlo, full risk audit, hedge recommendations. Free tier + x402 micropayments for paid composites.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.js",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": ["dist", "README.md"],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsup",
|
|
19
|
+
"prepublishOnly": "npm run build"
|
|
20
|
+
},
|
|
21
|
+
"keywords": [
|
|
22
|
+
"agentkit",
|
|
23
|
+
"coinbase",
|
|
24
|
+
"ai-agent",
|
|
25
|
+
"quant-finance",
|
|
26
|
+
"options-pricing",
|
|
27
|
+
"black-scholes",
|
|
28
|
+
"kelly-criterion",
|
|
29
|
+
"monte-carlo",
|
|
30
|
+
"x402",
|
|
31
|
+
"deterministic"
|
|
32
|
+
],
|
|
33
|
+
"author": "QuantOracle <hello@quantoracle.dev>",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/QuantOracledev/quantoracle.git",
|
|
38
|
+
"directory": "integrations/agentkit"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://quantoracle.dev",
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"@coinbase/agentkit": ">=0.5.0 <1.0.0",
|
|
43
|
+
"zod": ">=3.22.0 <5.0.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@coinbase/agentkit": "^0.5.0",
|
|
47
|
+
"@swc/core": "^1.4.0",
|
|
48
|
+
"@types/node": "^20.0.0",
|
|
49
|
+
"tsup": "^8.0.0",
|
|
50
|
+
"typescript": "^5.0.0",
|
|
51
|
+
"zod": "^3.23.0"
|
|
52
|
+
}
|
|
53
|
+
}
|