@ebowwa/quant-rust 0.1.0 → 0.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/dist/index.js CHANGED
@@ -126,6 +126,14 @@ var symbols = {
126
126
  returns: FFIType.cstring,
127
127
  args: [FFIType.f64, FFIType.f64]
128
128
  },
129
+ quant_kelly_criterion_batch: {
130
+ returns: FFIType.cstring,
131
+ args: [FFIType.ptr, FFIType.ptr, FFIType.usize, FFIType.f64]
132
+ },
133
+ quant_detect_arbitrage_batch: {
134
+ returns: FFIType.cstring,
135
+ args: [FFIType.ptr, FFIType.ptr, FFIType.usize]
136
+ },
129
137
  quant_convert_odds: {
130
138
  returns: FFIType.cstring,
131
139
  args: [FFIType.f64, FFIType.i32]
@@ -231,12 +239,30 @@ function kellyCriterion(yourProbability, marketPrice, bankroll) {
231
239
  return parseJsonResponse(response);
232
240
  }
233
241
  var kelly_criterion = kellyCriterion;
242
+ function kellyCriterionBatch(bets, bankroll) {
243
+ if (bets.length === 0)
244
+ return [];
245
+ const probs = new Float64Array(bets.map((b) => b.prob));
246
+ const prices = new Float64Array(bets.map((b) => b.price));
247
+ const response = lib.symbols.quant_kelly_criterion_batch(ptr(probs), ptr(prices), bets.length, bankroll);
248
+ return parseJsonResponse(response);
249
+ }
250
+ var kelly_criterion_batch = kellyCriterionBatch;
234
251
  function detectArbitrage(yesPrice, noPrice) {
235
252
  const response = lib.symbols.quant_detect_arbitrage(yesPrice, noPrice);
236
253
  const result = parseJsonResponse(response);
237
254
  return { ...result, profit: result.profit_per_share };
238
255
  }
239
256
  var detect_arbitrage = detectArbitrage;
257
+ function detectArbitrageBatch(pairs) {
258
+ if (pairs.length === 0)
259
+ return [];
260
+ const yesPrices = new Float64Array(pairs.map((p) => p.yesPrice));
261
+ const noPrices = new Float64Array(pairs.map((p) => p.noPrice));
262
+ const response = lib.symbols.quant_detect_arbitrage_batch(ptr(yesPrices), ptr(noPrices), pairs.length);
263
+ return parseJsonResponse(response);
264
+ }
265
+ var detect_arbitrage_batch = detectArbitrageBatch;
240
266
  function convertOdds(value, fromType, toType) {
241
267
  const typeMap = {
242
268
  probability: 0,
@@ -500,8 +526,12 @@ var src_default = {
500
526
  lmsrCalculate,
501
527
  kellyCriterion,
502
528
  kelly_criterion,
529
+ kellyCriterionBatch,
530
+ kelly_criterion_batch,
503
531
  detectArbitrage,
504
532
  detect_arbitrage,
533
+ detectArbitrageBatch,
534
+ detect_arbitrage_batch,
505
535
  convertOdds,
506
536
  convert_odds,
507
537
  mean,
@@ -539,12 +569,16 @@ export {
539
569
  lmsrPrice,
540
570
  lmsrCost,
541
571
  lmsrCalculate,
572
+ kelly_criterion_batch,
542
573
  kelly_criterion,
574
+ kellyCriterionBatch,
543
575
  kellyCriterion,
544
576
  getVersion,
545
577
  getLibraryPath,
546
578
  ema,
579
+ detect_arbitrage_batch,
547
580
  detect_arbitrage,
581
+ detectArbitrageBatch,
548
582
  detectArbitrage,
549
583
  src_default as default,
550
584
  createOHLCV,
@@ -124,6 +124,32 @@ export declare function lmsrCalculate(yesShares: number, noShares: number, liqui
124
124
  */
125
125
  export declare function kellyCriterion(yourProbability: number, marketPrice: number, bankroll: number): KellyResult;
126
126
  export declare const kelly_criterion: typeof kellyCriterion;
127
+ /**
128
+ * Calculate Kelly criterion for multiple bets at once (batch operation)
129
+ *
130
+ * This is significantly more efficient than calling kellyCriterion multiple times
131
+ * because it only crosses the FFI boundary once, eliminating FFI call overhead.
132
+ *
133
+ * @param bets - Array of betting opportunities with prob and price
134
+ * @param bankroll - Total bankroll in currency units (shared across all bets)
135
+ * @returns Array of Kelly criterion results for each bet
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * const bets = [
140
+ * { prob: 0.6, price: 0.5 },
141
+ * { prob: 0.55, price: 0.45 },
142
+ * { prob: 0.7, price: 0.6 },
143
+ * ];
144
+ * const results = kellyCriterionBatch(bets, 1000);
145
+ * // results[0].full_bet_size, results[1].half_bet_size, etc.
146
+ * ```
147
+ */
148
+ export declare function kellyCriterionBatch(bets: Array<{
149
+ prob: number;
150
+ price: number;
151
+ }>, bankroll: number): KellyResult[];
152
+ export declare const kelly_criterion_batch: typeof kellyCriterionBatch;
127
153
  /**
128
154
  * Detect arbitrage opportunities in prediction markets
129
155
  *
@@ -137,6 +163,33 @@ export declare function detectArbitrage(yesPrice: number, noPrice: number): Arbi
137
163
  profit: number;
138
164
  };
139
165
  export declare const detect_arbitrage: typeof detectArbitrage;
166
+ /**
167
+ * Detect arbitrage opportunities for multiple price pairs at once (batch operation)
168
+ *
169
+ * This is significantly more efficient than calling detectArbitrage multiple times
170
+ * because it only crosses the FFI boundary once, eliminating FFI call overhead.
171
+ *
172
+ * @param pairs - Array of YES/NO price pairs to check for arbitrage
173
+ * @returns Array of arbitrage results with profit field for each pair
174
+ *
175
+ * @example
176
+ * ```typescript
177
+ * const pairs = [
178
+ * { yesPrice: 0.45, noPrice: 0.45 }, // 10% arb opportunity
179
+ * { yesPrice: 0.50, noPrice: 0.50 }, // no arb
180
+ * { yesPrice: 0.40, noPrice: 0.40 }, // 20% arb opportunity
181
+ * ];
182
+ * const results = detectArbitrageBatch(pairs);
183
+ * // results[0].profit = 0.10, results[1].profit = 0, results[2].profit = 0.20
184
+ * ```
185
+ */
186
+ export declare function detectArbitrageBatch(pairs: Array<{
187
+ yesPrice: number;
188
+ noPrice: number;
189
+ }>): Array<ArbitrageResult & {
190
+ profit: number;
191
+ }>;
192
+ export declare const detect_arbitrage_batch: typeof detectArbitrageBatch;
140
193
  /** Odds input type */
141
194
  export type OddsType = "probability" | "decimal" | "american";
142
195
  /**
@@ -294,8 +347,12 @@ declare const _default: {
294
347
  lmsrCalculate: typeof lmsrCalculate;
295
348
  kellyCriterion: typeof kellyCriterion;
296
349
  kelly_criterion: typeof kellyCriterion;
350
+ kellyCriterionBatch: typeof kellyCriterionBatch;
351
+ kelly_criterion_batch: typeof kellyCriterionBatch;
297
352
  detectArbitrage: typeof detectArbitrage;
298
353
  detect_arbitrage: typeof detectArbitrage;
354
+ detectArbitrageBatch: typeof detectArbitrageBatch;
355
+ detect_arbitrage_batch: typeof detectArbitrageBatch;
299
356
  convertOdds: typeof convertOdds;
300
357
  convert_odds: typeof convertOdds;
301
358
  mean: typeof mean;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ebowwa/quant-rust",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "High-performance quantitative finance library with Rust FFI bindings for Bun",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/src/ffi.rs CHANGED
@@ -301,6 +301,71 @@ pub extern "C" fn quant_kelly_criterion(
301
301
  // Arbitrage Detection
302
302
  // ============================================================================
303
303
 
304
+ /// Detect arbitrage opportunities for multiple price pairs at once (batch operation)
305
+ /// This is much more efficient than calling quant_detect_arbitrage multiple times
306
+ /// because it only crosses the FFI boundary once.
307
+ ///
308
+ /// # Arguments
309
+ /// * `yes_prices` - Pointer to array of YES prices
310
+ /// * `no_prices` - Pointer to array of NO prices
311
+ /// * `count` - Number of pairs (length of both arrays)
312
+ ///
313
+ /// # Returns
314
+ /// JSON array of arbitrage results with profit field
315
+ #[no_mangle]
316
+ pub extern "C" fn quant_detect_arbitrage_batch(
317
+ yes_prices: *const f64,
318
+ no_prices: *const f64,
319
+ count: usize,
320
+ ) -> *mut c_char {
321
+ if yes_prices.is_null() || no_prices.is_null() || count == 0 {
322
+ set_last_error("Null pointer or zero count provided");
323
+ return ptr::null_mut();
324
+ }
325
+
326
+ let yes_slice = unsafe { std::slice::from_raw_parts(yes_prices, count) };
327
+ let no_slice = unsafe { std::slice::from_raw_parts(no_prices, count) };
328
+
329
+ let mut results = Vec::with_capacity(count);
330
+
331
+ for i in 0..count {
332
+ let yes_price = yes_slice[i];
333
+ let no_price = no_slice[i];
334
+
335
+ // Validate inputs
336
+ if yes_price < 0.0 || yes_price > 1.0 || no_price < 0.0 || no_price > 1.0 {
337
+ results.push(serde_json::json!({
338
+ "error": format!("Prices at index {} must be between 0 and 1", i),
339
+ "index": i,
340
+ "has_arbitrage": false,
341
+ "yes_price": yes_price,
342
+ "no_price": no_price,
343
+ "total_price": yes_price + no_price,
344
+ "profit_per_share": 0.0,
345
+ "profit_bps": 0.0,
346
+ "profit": 0.0
347
+ }));
348
+ continue;
349
+ }
350
+
351
+ let total = yes_price + no_price;
352
+ let has_arb = total < 1.0;
353
+ let profit_per_share = if has_arb { 1.0 - total } else { 0.0 };
354
+
355
+ results.push(serde_json::json!({
356
+ "has_arbitrage": has_arb,
357
+ "yes_price": yes_price,
358
+ "no_price": no_price,
359
+ "total_price": total,
360
+ "profit_per_share": profit_per_share,
361
+ "profit_bps": profit_per_share * 10000.0,
362
+ "profit": profit_per_share
363
+ }));
364
+ }
365
+
366
+ return_json_value(serde_json::json!(results))
367
+ }
368
+
304
369
  /// Detect arbitrage opportunity (if yes_price + no_price < 1)
305
370
  #[no_mangle]
306
371
  pub extern "C" fn quant_detect_arbitrage(yes_price: f64, no_price: f64) -> *mut c_char {
@@ -326,6 +391,92 @@ pub extern "C" fn quant_detect_arbitrage(yes_price: f64, no_price: f64) -> *mut
326
391
  }
327
392
  }
328
393
 
394
+ // ============================================================================
395
+ // Batch Functions (reduce FFI overhead)
396
+ // ============================================================================
397
+
398
+ /// Calculate Kelly criterion for multiple bets at once (batch operation)
399
+ /// This is much more efficient than calling quant_kelly_criterion multiple times
400
+ /// because it only crosses the FFI boundary once.
401
+ ///
402
+ /// # Arguments
403
+ /// * `probs` - Pointer to array of your probabilities
404
+ /// * `prices` - Pointer to array of market prices
405
+ /// * `count` - Number of bets (length of both arrays)
406
+ /// * `bankroll` - Total bankroll (shared across all bets)
407
+ ///
408
+ /// # Returns
409
+ /// JSON array of KellyResult objects
410
+ #[inline(never)]
411
+ #[no_mangle]
412
+ pub extern "C" fn quant_kelly_criterion_batch(
413
+ probs: *const f64,
414
+ prices: *const f64,
415
+ count: usize,
416
+ bankroll: f64,
417
+ ) -> *mut c_char {
418
+ if probs.is_null() || prices.is_null() || count == 0 {
419
+ set_last_error("Null pointer or zero count provided");
420
+ return ptr::null_mut();
421
+ }
422
+
423
+ let probs_slice = unsafe { std::slice::from_raw_parts(probs, count) };
424
+ let prices_slice = unsafe { std::slice::from_raw_parts(prices, count) };
425
+
426
+ let mut results = Vec::with_capacity(count);
427
+
428
+ for i in 0..count {
429
+ let your_probability = probs_slice[i];
430
+ let market_price = prices_slice[i];
431
+
432
+ // Validate inputs
433
+ if your_probability <= 0.0 || your_probability >= 1.0 {
434
+ results.push(serde_json::json!({
435
+ "error": format!("Probability at index {} must be between 0 and 1", i),
436
+ "index": i
437
+ }));
438
+ continue;
439
+ }
440
+ if market_price <= 0.0 || market_price >= 1.0 {
441
+ results.push(serde_json::json!({
442
+ "error": format!("Market price at index {} must be between 0 and 1", i),
443
+ "index": i
444
+ }));
445
+ continue;
446
+ }
447
+ if bankroll <= 0.0 {
448
+ results.push(serde_json::json!({
449
+ "error": "Bankroll must be positive",
450
+ "index": i
451
+ }));
452
+ continue;
453
+ }
454
+
455
+ let edge = your_probability - market_price;
456
+ let odds = (1.0 - market_price) / market_price;
457
+
458
+ // Kelly fraction: (bp - q) / b where b = odds, p = your_prob, q = 1 - your_prob
459
+ let kelly = (odds * your_probability - (1.0 - your_probability)) / odds;
460
+ let kelly = kelly.max(0.0); // Never bet negative
461
+
462
+ let half_kelly = kelly / 2.0;
463
+ let quarter_kelly = kelly / 4.0;
464
+
465
+ results.push(serde_json::json!(KellyResult {
466
+ kelly_fraction: kelly,
467
+ half_kelly,
468
+ quarter_kelly,
469
+ full_bet_size: kelly * bankroll,
470
+ half_bet_size: half_kelly * bankroll,
471
+ quarter_bet_size: quarter_kelly * bankroll,
472
+ edge,
473
+ odds,
474
+ }));
475
+ }
476
+
477
+ return_json_value(serde_json::json!(results))
478
+ }
479
+
329
480
  // ============================================================================
330
481
  // Odds Conversion
331
482
  // ============================================================================
package/src/index.ts CHANGED
@@ -139,6 +139,18 @@ const symbols = {
139
139
  args: [FFIType.f64, FFIType.f64],
140
140
  },
141
141
 
142
+ // Batch Kelly Criterion
143
+ quant_kelly_criterion_batch: {
144
+ returns: FFIType.cstring,
145
+ args: [FFIType.ptr, FFIType.ptr, FFIType.usize, FFIType.f64],
146
+ },
147
+
148
+ // Batch Arbitrage Detection
149
+ quant_detect_arbitrage_batch: {
150
+ returns: FFIType.cstring,
151
+ args: [FFIType.ptr, FFIType.ptr, FFIType.usize],
152
+ },
153
+
142
154
  // Odds Conversion
143
155
  quant_convert_odds: {
144
156
  returns: FFIType.cstring,
@@ -482,6 +494,49 @@ export function kellyCriterion(
482
494
  // Alias matching @ebowwa/quant API
483
495
  export const kelly_criterion = kellyCriterion;
484
496
 
497
+ /**
498
+ * Calculate Kelly criterion for multiple bets at once (batch operation)
499
+ *
500
+ * This is significantly more efficient than calling kellyCriterion multiple times
501
+ * because it only crosses the FFI boundary once, eliminating FFI call overhead.
502
+ *
503
+ * @param bets - Array of betting opportunities with prob and price
504
+ * @param bankroll - Total bankroll in currency units (shared across all bets)
505
+ * @returns Array of Kelly criterion results for each bet
506
+ *
507
+ * @example
508
+ * ```typescript
509
+ * const bets = [
510
+ * { prob: 0.6, price: 0.5 },
511
+ * { prob: 0.55, price: 0.45 },
512
+ * { prob: 0.7, price: 0.6 },
513
+ * ];
514
+ * const results = kellyCriterionBatch(bets, 1000);
515
+ * // results[0].full_bet_size, results[1].half_bet_size, etc.
516
+ * ```
517
+ */
518
+ export function kellyCriterionBatch(
519
+ bets: Array<{ prob: number; price: number }>,
520
+ bankroll: number
521
+ ): KellyResult[] {
522
+ if (bets.length === 0) return [];
523
+
524
+ const probs = new Float64Array(bets.map(b => b.prob));
525
+ const prices = new Float64Array(bets.map(b => b.price));
526
+
527
+ const response = lib.symbols.quant_kelly_criterion_batch(
528
+ ptr(probs),
529
+ ptr(prices),
530
+ bets.length,
531
+ bankroll
532
+ ) as string;
533
+
534
+ return parseJsonResponse<KellyResult[]>(response);
535
+ }
536
+
537
+ // Alias matching @ebowwa/quant API
538
+ export const kelly_criterion_batch = kellyCriterionBatch;
539
+
485
540
  // ============================================================================
486
541
  // Arbitrage Detection Functions
487
542
  // ============================================================================
@@ -505,6 +560,46 @@ export function detectArbitrage(yesPrice: number, noPrice: number): ArbitrageRes
505
560
  // Alias matching @ebowwa/quant API
506
561
  export const detect_arbitrage = detectArbitrage;
507
562
 
563
+ /**
564
+ * Detect arbitrage opportunities for multiple price pairs at once (batch operation)
565
+ *
566
+ * This is significantly more efficient than calling detectArbitrage multiple times
567
+ * because it only crosses the FFI boundary once, eliminating FFI call overhead.
568
+ *
569
+ * @param pairs - Array of YES/NO price pairs to check for arbitrage
570
+ * @returns Array of arbitrage results with profit field for each pair
571
+ *
572
+ * @example
573
+ * ```typescript
574
+ * const pairs = [
575
+ * { yesPrice: 0.45, noPrice: 0.45 }, // 10% arb opportunity
576
+ * { yesPrice: 0.50, noPrice: 0.50 }, // no arb
577
+ * { yesPrice: 0.40, noPrice: 0.40 }, // 20% arb opportunity
578
+ * ];
579
+ * const results = detectArbitrageBatch(pairs);
580
+ * // results[0].profit = 0.10, results[1].profit = 0, results[2].profit = 0.20
581
+ * ```
582
+ */
583
+ export function detectArbitrageBatch(
584
+ pairs: Array<{ yesPrice: number; noPrice: number }>
585
+ ): Array<ArbitrageResult & { profit: number }> {
586
+ if (pairs.length === 0) return [];
587
+
588
+ const yesPrices = new Float64Array(pairs.map(p => p.yesPrice));
589
+ const noPrices = new Float64Array(pairs.map(p => p.noPrice));
590
+
591
+ const response = lib.symbols.quant_detect_arbitrage_batch(
592
+ ptr(yesPrices),
593
+ ptr(noPrices),
594
+ pairs.length
595
+ ) as string;
596
+
597
+ return parseJsonResponse<Array<ArbitrageResult & { profit: number }>>(response);
598
+ }
599
+
600
+ // Alias matching @ebowwa/quant API
601
+ export const detect_arbitrage_batch = detectArbitrageBatch;
602
+
508
603
  // ============================================================================
509
604
  // Odds Conversion Functions
510
605
  // ============================================================================
@@ -1035,10 +1130,14 @@ export default {
1035
1130
  // Kelly
1036
1131
  kellyCriterion,
1037
1132
  kelly_criterion,
1133
+ kellyCriterionBatch,
1134
+ kelly_criterion_batch,
1038
1135
 
1039
1136
  // Arbitrage
1040
1137
  detectArbitrage,
1041
1138
  detect_arbitrage,
1139
+ detectArbitrageBatch,
1140
+ detect_arbitrage_batch,
1042
1141
 
1043
1142
  // Odds
1044
1143
  convertOdds,
package/native/README.md DELETED
@@ -1,62 +0,0 @@
1
- # Native Binaries
2
-
3
- This directory contains prebuilt native binaries for the `@ebowwa/quant-rust` package.
4
-
5
- ## Directory Structure
6
-
7
- ```
8
- native/
9
- ├── darwin-x64/ # macOS (Intel)
10
- │ └── libquant_rust.dylib
11
- ├── darwin-arm64/ # macOS (Apple Silicon)
12
- │ └── libquant_rust.dylib
13
- ├── linux-x64/ # Linux (x86_64)
14
- │ └── libquant_rust.so
15
- └── win32-x64/ # Windows (x86_64)
16
- └── quant_rust.dll
17
- ```
18
-
19
- ## Building from Source
20
-
21
- If a prebuilt binary is not available for your platform, you can build from source:
22
-
23
- ```bash
24
- # Navigate to the package directory
25
- cd node_modules/@ebowwa/quant-rust
26
-
27
- # Build with Cargo
28
- cargo build --release
29
- ```
30
-
31
- The compiled library will be placed in `target/release/`.
32
-
33
- ## Supported Platforms
34
-
35
- | Platform | Architecture | Binary Name |
36
- |----------|--------------|-------------|
37
- | macOS | x64 (Intel) | libquant_rust.dylib |
38
- | macOS | arm64 (Apple Silicon) | libquant_rust.dylib |
39
- | Linux | x64 | libquant_rust.so |
40
- | Windows | x64 | quant_rust.dll |
41
-
42
- ## Adding Prebuilt Binaries
43
-
44
- To add prebuilt binaries for distribution:
45
-
46
- 1. Build the library on the target platform:
47
- ```bash
48
- cargo build --release
49
- ```
50
-
51
- 2. Copy the binary to the appropriate directory:
52
- ```bash
53
- cp target/release/libquant_rust.dylib native/darwin-arm64/
54
- ```
55
-
56
- 3. The postinstall script will automatically detect and use the correct binary.
57
-
58
- ## Binary Requirements
59
-
60
- - Rust 1.70 or later
61
- - Target platform toolchain
62
- - For cross-compilation, see the Rust cross-compilation documentation