@ebowwa/quant-mcp 1.0.0 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bun.lock CHANGED
@@ -5,7 +5,7 @@
5
5
  "": {
6
6
  "name": "@ebowwa/quant-mcp",
7
7
  "dependencies": {
8
- "@ebowwa/quant": "^0.1.0",
8
+ "@ebowwa/quant-rust": "^0.2.1",
9
9
  "@modelcontextprotocol/sdk": "^1.26.0",
10
10
  "zod": "^4.3.6",
11
11
  },
@@ -17,9 +17,7 @@
17
17
  },
18
18
  },
19
19
  "packages": {
20
- "@ebowwa/codespaces-types": ["@ebowwa/codespaces-types@1.6.1", "", { "dependencies": { "zod": "^3.24.1" } }, "sha512-e3HNbRYwXmh0Rzpy0eB9N92bQEd29F1+ExXIoQPNGH2GN/IU8y40bAWaVkLIWXEv3vTIH02aru686REbVBllSQ=="],
21
-
22
- "@ebowwa/quant": ["@ebowwa/quant@0.1.0", "", { "dependencies": { "@ebowwa/codespaces-types": "^1.4.0" } }, "sha512-edJ10O2gjotsANVyXB6Xwr4wwIHH9QtQ7OAcgp+hAxrivo9+Gaj7Ifu4GoK6lzOYbGLdYOB8TA++aWz7b75GZA=="],
20
+ "@ebowwa/quant-rust": ["@ebowwa/quant-rust@0.2.1", "", {}, "sha512-T6dS7HOp8J3GET7IgJs11YONJEPCMhZO8aeytYEpgK1pna32k/3p+xFNuFjt5q0t74ew5G8394+p25YtLJWRJg=="],
23
21
 
24
22
  "@hono/node-server": ["@hono/node-server@1.19.9", "", { "peerDependencies": { "hono": "^4" } }, "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw=="],
25
23
 
@@ -107,7 +105,7 @@
107
105
 
108
106
  "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
109
107
 
110
- "hono": ["hono@4.12.0", "", {}, "sha512-NekXntS5M94pUfiVZ8oXXK/kkri+5WpX2/Ik+LVsl+uvw+soj4roXIsPqO+XsWrAw20mOzaXOZf3Q7PfB9A/IA=="],
108
+ "hono": ["hono@4.12.1", "", {}, "sha512-hi9afu8g0lfJVLolxElAZGANCTTl6bewIdsRNhaywfP9K8BPf++F2z6OLrYGIinUwpRKzbZHMhPwvc0ZEpAwGw=="],
111
109
 
112
110
  "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="],
113
111
 
@@ -212,7 +210,5 @@
212
210
  "zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
213
211
 
214
212
  "zod-to-json-schema": ["zod-to-json-schema@3.25.1", "", { "peerDependencies": { "zod": "^3.25 || ^4" } }, "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA=="],
215
-
216
- "@ebowwa/codespaces-types/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
217
213
  }
218
214
  }
package/dist/index.d.ts CHANGED
@@ -2,6 +2,10 @@
2
2
  /**
3
3
  * @ebowwa/quant-mcp - Quantitative Trading MCP Server
4
4
  *
5
+ * High-performance MCP server using hybrid TypeScript/Rust approach:
6
+ * - TypeScript for scalar operations (20-40x faster - no FFI overhead)
7
+ * - Rust FFI for array operations (2-13x faster for O(n) calculations)
8
+ *
5
9
  * Multi-market quantitative analysis tools for AI trading:
6
10
  * - Prediction Markets: Kelly criterion, AMM math, LMSR, arbitrage
7
11
  * - Technical Indicators: RSI, MACD, Bollinger, ATR, etc.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG"}
package/dist/index.js CHANGED
@@ -2,6 +2,10 @@
2
2
  /**
3
3
  * @ebowwa/quant-mcp - Quantitative Trading MCP Server
4
4
  *
5
+ * High-performance MCP server using hybrid TypeScript/Rust approach:
6
+ * - TypeScript for scalar operations (20-40x faster - no FFI overhead)
7
+ * - Rust FFI for array operations (2-13x faster for O(n) calculations)
8
+ *
5
9
  * Multi-market quantitative analysis tools for AI trading:
6
10
  * - Prediction Markets: Kelly criterion, AMM math, LMSR, arbitrage
7
11
  * - Technical Indicators: RSI, MACD, Bollinger, ATR, etc.
@@ -11,16 +15,213 @@
11
15
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
12
16
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
13
17
  import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
14
- // Import quant tools
18
+ // Import from quant-rust - HYBRID approach
19
+ // Scalar ops (TS) are 20-40x faster, Array ops (Rust) are 2-13x faster
15
20
  import {
16
- // Prediction markets
17
- kellyCriterion, probToDecimalOdds, probToAmericanOdds, decimalOddsToProb, americanOddsToProb, ammBuyCost, ammSharesReceived, ammPriceImpact, lmsrPrice, lmsrBuyCost, detectArbitrage, brierScore, logLoss, hasPositiveEV, calculateEdge,
18
- // Technical indicators
19
- sma, ema, rsi, macd, stochastic, bollingerBands, atr, pivotPoints, fibonacciRetracement,
20
- // Risk management
21
- fixedFractionalSize, calculateVaR, calculateDrawdown, sharpeRatio, sortinoRatio, beta, alpha,
22
- // Statistics
23
- distributionStats, pearsonCorrelation, linearRegression, autocorrelation, } from "@ebowwa/quant";
21
+ // Scalar operations (TypeScript - FAST for single calls)
22
+ kellyCriterionTS, detectArbitrageTS, convertOddsTS, calculateEdge, hasPositiveEV,
23
+ // Array operations (Rust FFI - FAST for large datasets)
24
+ sma, ema, rsi, macd, mean, stdDev, variance, correlation, calculateDrawdown, calculateSharpeRatio, calculateSortinoRatio, calculateBetaAlpha, calculateVar,
25
+ // AMM/LMSR (Rust FFI)
26
+ ammCalculateCost, ammPriceImpact, lmsrPrice, lmsrCost, } from "@ebowwa/quant-rust";
27
+ // ============================================================================
28
+ // TypeScript Fallbacks for functions not yet in quant-rust
29
+ // ============================================================================
30
+ /**
31
+ * Weighted Moving Average
32
+ */
33
+ function wma(prices, period) {
34
+ if (prices.length < period || period <= 0)
35
+ return [];
36
+ const result = [];
37
+ const weightSum = (period * (period + 1)) / 2;
38
+ for (let i = period - 1; i < prices.length; i++) {
39
+ let sum = 0;
40
+ for (let j = 0; j < period; j++) {
41
+ sum += prices[i - period + 1 + j] * (j + 1);
42
+ }
43
+ result.push(sum / weightSum);
44
+ }
45
+ return result;
46
+ }
47
+ /**
48
+ * Bollinger Bands
49
+ */
50
+ function bollingerBands(prices, period = 20, stdDevMultiplier = 2) {
51
+ const ma = sma(prices, period);
52
+ const upper = [];
53
+ const lower = [];
54
+ for (let i = 0; i < ma.length; i++) {
55
+ const start = i;
56
+ const slice = prices.slice(start, start + period);
57
+ const std = stdDev(slice);
58
+ upper.push(ma[i] + std * stdDevMultiplier);
59
+ lower.push(ma[i] - std * stdDevMultiplier);
60
+ }
61
+ return { middle: ma, upper, lower };
62
+ }
63
+ /**
64
+ * Average True Range
65
+ */
66
+ function atr(high, low, close, period = 14) {
67
+ if (high.length < period + 1)
68
+ return [];
69
+ const trValues = [];
70
+ for (let i = 1; i < high.length; i++) {
71
+ const tr = Math.max(high[i] - low[i], Math.abs(high[i] - close[i - 1]), Math.abs(low[i] - close[i - 1]));
72
+ trValues.push(tr);
73
+ }
74
+ return ema(trValues, period);
75
+ }
76
+ /**
77
+ * Stochastic Oscillator
78
+ */
79
+ function stochastic(high, low, close, kPeriod = 14, dPeriod = 3) {
80
+ const kValues = [];
81
+ for (let i = kPeriod - 1; i < close.length; i++) {
82
+ const highSlice = high.slice(i - kPeriod + 1, i + 1);
83
+ const lowSlice = low.slice(i - kPeriod + 1, i + 1);
84
+ const highestHigh = Math.max(...highSlice);
85
+ const lowestLow = Math.min(...lowSlice);
86
+ const k = ((close[i] - lowestLow) / (highestHigh - lowestLow)) * 100;
87
+ kValues.push(k);
88
+ }
89
+ const dValues = sma(kValues, dPeriod);
90
+ return {
91
+ k: kValues.slice(dPeriod - 1),
92
+ d: dValues
93
+ };
94
+ }
95
+ /**
96
+ * Pivot Points
97
+ */
98
+ function pivotPoints(high, low, close) {
99
+ const pp = (high + low + close) / 3;
100
+ return {
101
+ pivot: pp,
102
+ r1: 2 * pp - low,
103
+ r2: pp + (high - low),
104
+ r3: high + 2 * (pp - low),
105
+ s1: 2 * pp - high,
106
+ s2: pp - (high - low),
107
+ s3: low - 2 * (high - pp),
108
+ };
109
+ }
110
+ /**
111
+ * Fibonacci Retracement
112
+ */
113
+ function fibonacciRetracement(swingHigh, swingLow) {
114
+ const diff = swingHigh - swingLow;
115
+ return {
116
+ level_0: swingHigh,
117
+ level_236: swingHigh - diff * 0.236,
118
+ level_382: swingHigh - diff * 0.382,
119
+ level_500: swingHigh - diff * 0.5,
120
+ level_618: swingHigh - diff * 0.618,
121
+ level_786: swingHigh - diff * 0.786,
122
+ level_1: swingLow,
123
+ };
124
+ }
125
+ /**
126
+ * Fixed Fractional Position Sizing
127
+ */
128
+ function fixedFractionalSize(capital, riskPercent, entryPrice, stopLoss) {
129
+ const riskAmount = capital * riskPercent;
130
+ const priceRisk = Math.abs(entryPrice - stopLoss);
131
+ const shares = priceRisk > 0 ? Math.floor(riskAmount / priceRisk) : 0;
132
+ return {
133
+ shares,
134
+ positionValue: shares * entryPrice,
135
+ riskAmount,
136
+ riskPercent: (riskAmount / capital) * 100,
137
+ };
138
+ }
139
+ /**
140
+ * Brier Score
141
+ */
142
+ function brierScore(predictions) {
143
+ if (predictions.length === 0)
144
+ return 0;
145
+ const sum = predictions.reduce((acc, p) => acc + Math.pow(p.predicted - p.actual, 2), 0);
146
+ return sum / predictions.length;
147
+ }
148
+ /**
149
+ * Log Loss
150
+ */
151
+ function logLoss(predictions) {
152
+ if (predictions.length === 0)
153
+ return 0;
154
+ const epsilon = 1e-15;
155
+ const sum = predictions.reduce((acc, p) => {
156
+ const prob = Math.max(epsilon, Math.min(1 - epsilon, p.predicted));
157
+ const actual = p.actual;
158
+ return acc - (actual * Math.log(prob) + (1 - actual) * Math.log(1 - prob));
159
+ }, 0);
160
+ return sum / predictions.length;
161
+ }
162
+ /**
163
+ * Distribution Statistics
164
+ */
165
+ function distributionStats(data) {
166
+ if (data.length === 0)
167
+ return { mean: 0, median: 0, stdDev: 0, variance: 0, min: 0, max: 0, count: 0 };
168
+ const sorted = [...data].sort((a, b) => a - b);
169
+ const avg = mean(data);
170
+ const std = stdDev(data);
171
+ return {
172
+ mean: avg,
173
+ median: sorted[Math.floor(sorted.length / 2)],
174
+ stdDev: std,
175
+ variance: variance(data),
176
+ min: sorted[0],
177
+ max: sorted[sorted.length - 1],
178
+ count: data.length,
179
+ q1: sorted[Math.floor(sorted.length * 0.25)],
180
+ q3: sorted[Math.floor(sorted.length * 0.75)],
181
+ };
182
+ }
183
+ /**
184
+ * Linear Regression
185
+ */
186
+ function linearRegression(x, y) {
187
+ if (x.length !== y.length || x.length < 2) {
188
+ return { slope: 0, intercept: 0, r2: 0 };
189
+ }
190
+ const n = x.length;
191
+ const sumX = x.reduce((a, b) => a + b, 0);
192
+ const sumY = y.reduce((a, b) => a + b, 0);
193
+ const sumXY = x.reduce((acc, xi, i) => acc + xi * y[i], 0);
194
+ const sumX2 = x.reduce((acc, xi) => acc + xi * xi, 0);
195
+ const slope = (n * sumXY - sumX * sumY) / (n * sumX2 - sumX * sumX);
196
+ const intercept = (sumY - slope * sumX) / n;
197
+ // R-squared
198
+ const yMean = sumY / n;
199
+ const ssTotal = y.reduce((acc, yi) => acc + Math.pow(yi - yMean, 2), 0);
200
+ const ssResidual = y.reduce((acc, yi, i) => {
201
+ const predicted = slope * x[i] + intercept;
202
+ return acc + Math.pow(yi - predicted, 2);
203
+ }, 0);
204
+ const r2 = 1 - ssResidual / ssTotal;
205
+ return { slope, intercept, r2 };
206
+ }
207
+ /**
208
+ * Autocorrelation
209
+ */
210
+ function autocorrelation(data, maxLag = 10) {
211
+ if (data.length < maxLag + 1)
212
+ return [];
213
+ const avg = mean(data);
214
+ const varianceVal = variance(data);
215
+ const acf = [];
216
+ for (let lag = 0; lag <= maxLag; lag++) {
217
+ let sum = 0;
218
+ for (let i = 0; i < data.length - lag; i++) {
219
+ sum += (data[i] - avg) * (data[i + lag] - avg);
220
+ }
221
+ acf.push(sum / (data.length * varianceVal));
222
+ }
223
+ return acf;
224
+ }
24
225
  // ==============
25
226
  // Tool Definitions
26
227
  // ==============
@@ -30,7 +231,7 @@ const tools = [
30
231
  // ===================
31
232
  {
32
233
  name: "kelly_criterion",
33
- description: "Calculate optimal bet size using Kelly criterion for binary prediction markets. Returns Kelly fraction, half-Kelly, quarter-Kelly, and position sizes.",
234
+ description: "Calculate optimal bet size using Kelly criterion for binary prediction markets. Returns Kelly fraction, half-Kelly, quarter-Kelly, and position sizes. Uses TypeScript for 20-40x faster performance.",
34
235
  inputSchema: {
35
236
  type: "object",
36
237
  properties: {
@@ -57,7 +258,7 @@ const tools = [
57
258
  },
58
259
  {
59
260
  name: "convert_odds",
60
- description: "Convert between probability, decimal odds, and American odds formats",
261
+ description: "Convert between probability, decimal odds, and American odds formats. Uses TypeScript for 20-40x faster performance.",
61
262
  inputSchema: {
62
263
  type: "object",
63
264
  properties: {
@@ -73,7 +274,7 @@ const tools = [
73
274
  },
74
275
  {
75
276
  name: "amm_calculate_cost",
76
- description: "Calculate cost to buy shares from a constant-product AMM (like Polymarket). Returns cost in quote currency.",
277
+ description: "Calculate cost to buy shares from a constant-product AMM (like Polymarket). Uses Rust FFI for high performance.",
77
278
  inputSchema: {
78
279
  type: "object",
79
280
  properties: {
@@ -87,7 +288,7 @@ const tools = [
87
288
  },
88
289
  {
89
290
  name: "amm_price_impact",
90
- description: "Calculate price impact and slippage for a trade on a constant-product AMM",
291
+ description: "Calculate price impact and slippage for a trade on a constant-product AMM. Uses Rust FFI for high performance.",
91
292
  inputSchema: {
92
293
  type: "object",
93
294
  properties: {
@@ -101,7 +302,7 @@ const tools = [
101
302
  },
102
303
  {
103
304
  name: "lmsr_calculate",
104
- description: "Calculate price and cost using LMSR (Logarithmic Market Scoring Rule) for prediction markets",
305
+ description: "Calculate price and cost using LMSR (Logarithmic Market Scoring Rule) for prediction markets. Uses Rust FFI for high performance.",
105
306
  inputSchema: {
106
307
  type: "object",
107
308
  properties: {
@@ -121,7 +322,7 @@ const tools = [
121
322
  },
122
323
  {
123
324
  name: "detect_arbitrage",
124
- description: "Detect arbitrage opportunities in prediction markets. Returns profit if YES + NO prices < 1.",
325
+ description: "Detect arbitrage opportunities in prediction markets. Returns profit if YES + NO prices < 1. Uses TypeScript for 15-40x faster performance.",
125
326
  inputSchema: {
126
327
  type: "object",
127
328
  properties: {
@@ -133,7 +334,7 @@ const tools = [
133
334
  },
134
335
  {
135
336
  name: "calculate_edge",
136
- description: "Calculate your edge (advantage) in a prediction market bet",
337
+ description: "Calculate your edge (advantage) in a prediction market bet. Uses TypeScript for fast scalar calculation.",
137
338
  inputSchema: {
138
339
  type: "object",
139
340
  properties: {
@@ -170,7 +371,7 @@ const tools = [
170
371
  // ===================
171
372
  {
172
373
  name: "calculate_sma",
173
- description: "Calculate Simple Moving Average for price data",
374
+ description: "Calculate Simple Moving Average for price data. Uses Rust FFI for 10-20x faster performance on large arrays.",
174
375
  inputSchema: {
175
376
  type: "object",
176
377
  properties: {
@@ -182,7 +383,7 @@ const tools = [
182
383
  },
183
384
  {
184
385
  name: "calculate_ema",
185
- description: "Calculate Exponential Moving Average for price data",
386
+ description: "Calculate Exponential Moving Average for price data. Uses Rust FFI for 10-20x faster performance on large arrays.",
186
387
  inputSchema: {
187
388
  type: "object",
188
389
  properties: {
@@ -194,7 +395,7 @@ const tools = [
194
395
  },
195
396
  {
196
397
  name: "calculate_rsi",
197
- description: "Calculate Relative Strength Index (RSI) momentum indicator (0-100)",
398
+ description: "Calculate Relative Strength Index (RSI) momentum indicator (0-100). Uses Rust FFI for high performance.",
198
399
  inputSchema: {
199
400
  type: "object",
200
401
  properties: {
@@ -206,7 +407,7 @@ const tools = [
206
407
  },
207
408
  {
208
409
  name: "calculate_macd",
209
- description: "Calculate MACD (Moving Average Convergence Divergence) indicator",
410
+ description: "Calculate MACD (Moving Average Convergence Divergence) indicator. Uses Rust FFI for high performance.",
210
411
  inputSchema: {
211
412
  type: "object",
212
413
  properties: {
@@ -304,7 +505,7 @@ const tools = [
304
505
  },
305
506
  {
306
507
  name: "calculate_var",
307
- description: "Calculate Value at Risk (VaR) and Expected Shortfall (CVaR) for a returns series",
508
+ description: "Calculate Value at Risk (VaR) and Expected Shortfall (CVaR) for a returns series. Uses Rust FFI for high performance.",
308
509
  inputSchema: {
309
510
  type: "object",
310
511
  properties: {
@@ -316,7 +517,7 @@ const tools = [
316
517
  },
317
518
  {
318
519
  name: "calculate_drawdown",
319
- description: "Calculate maximum drawdown and drawdown analysis for an equity curve",
520
+ description: "Calculate maximum drawdown and drawdown analysis for an equity curve. Uses Rust FFI for 5-10x faster performance.",
320
521
  inputSchema: {
321
522
  type: "object",
322
523
  properties: {
@@ -327,7 +528,7 @@ const tools = [
327
528
  },
328
529
  {
329
530
  name: "calculate_sharpe_ratio",
330
- description: "Calculate Sharpe ratio for risk-adjusted returns",
531
+ description: "Calculate Sharpe ratio for risk-adjusted returns. Uses Rust FFI for 2x faster performance.",
331
532
  inputSchema: {
332
533
  type: "object",
333
534
  properties: {
@@ -340,7 +541,7 @@ const tools = [
340
541
  },
341
542
  {
342
543
  name: "calculate_sortino_ratio",
343
- description: "Calculate Sortino ratio (only penalizes downside volatility)",
544
+ description: "Calculate Sortino ratio (only penalizes downside volatility). Uses Rust FFI for high performance.",
344
545
  inputSchema: {
345
546
  type: "object",
346
547
  properties: {
@@ -353,7 +554,7 @@ const tools = [
353
554
  },
354
555
  {
355
556
  name: "calculate_beta_alpha",
356
- description: "Calculate beta (market sensitivity) and alpha (excess return) vs benchmark",
557
+ description: "Calculate beta (market sensitivity) and alpha (excess return) vs benchmark. Uses Rust FFI for high performance.",
357
558
  inputSchema: {
358
559
  type: "object",
359
560
  properties: {
@@ -369,7 +570,7 @@ const tools = [
369
570
  // ===================
370
571
  {
371
572
  name: "distribution_statistics",
372
- description: "Calculate comprehensive distribution statistics (mean, median, stdDev, skewness, kurtosis, quartiles)",
573
+ description: "Calculate comprehensive distribution statistics (mean, median, stdDev, skewness, kurtosis, quartiles). Uses Rust FFI for core calculations.",
373
574
  inputSchema: {
374
575
  type: "object",
375
576
  properties: {
@@ -380,7 +581,7 @@ const tools = [
380
581
  },
381
582
  {
382
583
  name: "correlation",
383
- description: "Calculate Pearson correlation coefficient between two series",
584
+ description: "Calculate Pearson correlation coefficient between two series. Uses Rust FFI for 2-3x faster performance.",
384
585
  inputSchema: {
385
586
  type: "object",
386
587
  properties: {
@@ -420,7 +621,7 @@ const tools = [
420
621
  // ==============
421
622
  const server = new Server({
422
623
  name: "@ebowwa/quant-mcp",
423
- version: "1.0.0",
624
+ version: "1.1.1",
424
625
  }, {
425
626
  capabilities: {
426
627
  tools: {},
@@ -439,79 +640,57 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
439
640
  // Prediction Markets
440
641
  case "kelly_criterion": {
441
642
  const { yourProbability, marketPrice, bankroll } = args;
442
- result = kellyCriterion(yourProbability, marketPrice, bankroll);
643
+ // Use TypeScript version (20-40x faster for scalar ops)
644
+ result = kellyCriterionTS(yourProbability, marketPrice, bankroll);
443
645
  break;
444
646
  }
445
647
  case "convert_odds": {
446
648
  const { value, fromFormat } = args;
447
- if (fromFormat === "probability") {
448
- result = {
449
- probability: value,
450
- decimal: probToDecimalOdds(value),
451
- american: probToAmericanOdds(value),
452
- };
453
- }
454
- else if (fromFormat === "decimal") {
455
- result = {
456
- probability: decimalOddsToProb(value),
457
- decimal: value,
458
- american: probToAmericanOdds(decimalOddsToProb(value)),
459
- };
460
- }
461
- else {
462
- const prob = americanOddsToProb(value);
463
- result = {
464
- probability: prob,
465
- decimal: probToDecimalOdds(prob),
466
- american: value,
467
- };
468
- }
649
+ // Use TypeScript version (20-40x faster for scalar ops)
650
+ result = convertOddsTS(value, fromFormat);
469
651
  break;
470
652
  }
471
653
  case "amm_calculate_cost": {
472
654
  const { poolYes, poolNo, outcome, shares } = args;
473
- const state = { poolYes, poolNo, k: poolYes * poolNo, lpTokenSupply: 1000, fee: 0 };
474
- const cost = ammBuyCost(state, outcome, shares);
475
- const sharesOut = ammSharesReceived(state, outcome, cost);
655
+ // Use Rust FFI (fast for AMM math)
656
+ const cost = ammCalculateCost(poolYes, poolNo, outcome, shares);
476
657
  result = {
477
658
  cost,
478
- shares: sharesOut,
479
- avgPrice: cost / sharesOut,
480
- effectivePrice: cost / shares,
659
+ shares,
660
+ avgPrice: cost / shares,
481
661
  };
482
662
  break;
483
663
  }
484
664
  case "amm_price_impact": {
485
665
  const { poolYes, poolNo, outcome, shares } = args;
486
- const state = { poolYes, poolNo, k: poolYes * poolNo, lpTokenSupply: 1000, fee: 0 };
487
- result = ammPriceImpact(state, outcome, shares);
666
+ // Use Rust FFI
667
+ result = ammPriceImpact(poolYes, poolNo, outcome, shares);
488
668
  break;
489
669
  }
490
670
  case "lmsr_calculate": {
491
671
  const { yesShares, noShares, liquidityParam, operation, outcome, sharesToBuy } = args;
492
- const state = { yesShares, noShares, b: liquidityParam };
672
+ // Use Rust FFI
493
673
  if (operation === "price") {
494
- result = {
495
- yesPrice: lmsrPrice(state, "yes"),
496
- noPrice: lmsrPrice(state, "no"),
497
- };
674
+ result = lmsrPrice(yesShares, noShares, liquidityParam);
498
675
  }
499
676
  else {
500
- const cost = sharesToBuy ? lmsrBuyCost(state, outcome, sharesToBuy) : null;
677
+ const cost = sharesToBuy ? lmsrCost(yesShares, noShares, liquidityParam, outcome, sharesToBuy) : null;
501
678
  result = {
502
679
  cost,
503
- price: lmsrPrice(state, outcome),
680
+ price: lmsrPrice(yesShares, noShares, liquidityParam),
504
681
  };
505
682
  }
506
683
  break;
507
684
  }
508
685
  case "detect_arbitrage": {
509
686
  const { yesPrice, noPrice } = args;
510
- result = detectArbitrage(yesPrice, noPrice);
687
+ // Use TypeScript version (15-40x faster for scalar ops)
688
+ result = detectArbitrageTS(yesPrice, noPrice);
511
689
  break;
512
690
  }
513
691
  case "calculate_edge": {
514
692
  const { yourProbability, marketPrice } = args;
693
+ // Use TypeScript (fast scalar)
515
694
  result = {
516
695
  edge: calculateEdge(yourProbability, marketPrice),
517
696
  hasPositiveEV: hasPositiveEV(yourProbability, marketPrice),
@@ -531,21 +710,25 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
531
710
  // Technical Indicators
532
711
  case "calculate_sma": {
533
712
  const { prices, period } = args;
713
+ // Use Rust FFI (10-20x faster for arrays)
534
714
  result = { sma: sma(prices, period) };
535
715
  break;
536
716
  }
537
717
  case "calculate_ema": {
538
718
  const { prices, period } = args;
719
+ // Use Rust FFI (10-20x faster for arrays)
539
720
  result = { ema: ema(prices, period) };
540
721
  break;
541
722
  }
542
723
  case "calculate_rsi": {
543
724
  const { prices, period = 14 } = args;
725
+ // Use Rust FFI
544
726
  result = { rsi: rsi(prices, period) };
545
727
  break;
546
728
  }
547
729
  case "calculate_macd": {
548
730
  const { prices, fastPeriod = 12, slowPeriod = 26, signalPeriod = 9 } = args;
731
+ // Use Rust FFI
549
732
  result = macd(prices, fastPeriod, slowPeriod, signalPeriod);
550
733
  break;
551
734
  }
@@ -556,7 +739,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
556
739
  }
557
740
  case "calculate_atr": {
558
741
  const { high, low, close, period = 14 } = args;
559
- result = atr(high, low, close, period);
742
+ result = { atr: atr(high, low, close, period) };
560
743
  break;
561
744
  }
562
745
  case "calculate_stochastic": {
@@ -582,30 +765,32 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
582
765
  }
583
766
  case "calculate_var": {
584
767
  const { returns, confidenceLevel = 0.95 } = args;
585
- result = calculateVaR(returns, { confidenceLevel });
768
+ // Use Rust FFI
769
+ result = calculateVar(returns, confidenceLevel);
586
770
  break;
587
771
  }
588
772
  case "calculate_drawdown": {
589
773
  const { equityCurve } = args;
774
+ // Use Rust FFI (5-10x faster)
590
775
  result = calculateDrawdown(equityCurve);
591
776
  break;
592
777
  }
593
778
  case "calculate_sharpe_ratio": {
594
779
  const { returns, riskFreeRate = 0.04, periodsPerYear = 252 } = args;
595
- result = { sharpeRatio: sharpeRatio(returns, riskFreeRate, periodsPerYear) };
780
+ // Use Rust FFI (2x faster)
781
+ result = { sharpeRatio: calculateSharpeRatio(returns, riskFreeRate, periodsPerYear) };
596
782
  break;
597
783
  }
598
784
  case "calculate_sortino_ratio": {
599
785
  const { returns, riskFreeRate = 0.04, periodsPerYear = 252 } = args;
600
- result = { sortinoRatio: sortinoRatio(returns, riskFreeRate, periodsPerYear) };
786
+ // Use Rust FFI
787
+ result = { sortinoRatio: calculateSortinoRatio(returns, riskFreeRate, periodsPerYear) };
601
788
  break;
602
789
  }
603
790
  case "calculate_beta_alpha": {
604
- const { assetReturns, marketReturns, riskFreeRate = 0.04 } = args;
605
- result = {
606
- beta: beta(assetReturns, marketReturns),
607
- alpha: alpha(assetReturns, marketReturns, riskFreeRate),
608
- };
791
+ const { assetReturns, marketReturns } = args;
792
+ // Use Rust FFI
793
+ result = calculateBetaAlpha(assetReturns, marketReturns);
609
794
  break;
610
795
  }
611
796
  // Statistics
@@ -616,7 +801,8 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
616
801
  }
617
802
  case "correlation": {
618
803
  const { x, y } = args;
619
- result = { correlation: pearsonCorrelation(x, y) };
804
+ // Use Rust FFI (2-3x faster)
805
+ result = { correlation: correlation(x, y) };
620
806
  break;
621
807
  }
622
808
  case "linear_regression": {
@@ -658,7 +844,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
658
844
  async function main() {
659
845
  const transport = new StdioServerTransport();
660
846
  await server.connect(transport);
661
- console.error("Quant MCP server running on stdio");
847
+ console.error("Quant MCP server running on stdio (powered by Rust FFI + TypeScript hybrid)");
662
848
  }
663
849
  main().catch((error) => {
664
850
  console.error("Fatal error:", error);