@ebowwa/quant-rust 0.1.0 → 0.2.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/dist/index.js +176 -21
- package/dist/src/index.d.ts +121 -6
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/ts-fns.d.ts +115 -0
- package/dist/src/ts-fns.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/ffi.rs +151 -0
- package/src/index.ts +203 -10
- package/src/ts-fns.ts +275 -0
- package/native/README.md +0 -62
- package/native/darwin-arm64/libquant_rust.dylib +0 -0
package/dist/index.js
CHANGED
|
@@ -28,14 +28,6 @@ var CandlePattern;
|
|
|
28
28
|
CandlePattern2["ShootingStar"] = "ShootingStar";
|
|
29
29
|
CandlePattern2["HangingMan"] = "HangingMan";
|
|
30
30
|
})(CandlePattern ||= {});
|
|
31
|
-
function calculateEdge(yourProbability, marketPrice) {
|
|
32
|
-
const edge = yourProbability - marketPrice;
|
|
33
|
-
return {
|
|
34
|
-
edge,
|
|
35
|
-
has_edge: edge > 0,
|
|
36
|
-
edge_percent: edge * 100
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
31
|
function positionSizeFixedFractional(capital, riskPercent, entryPrice, stopLoss) {
|
|
40
32
|
const riskAmount = capital * riskPercent;
|
|
41
33
|
const riskPerShare = Math.abs(entryPrice - stopLoss);
|
|
@@ -49,7 +41,116 @@ function positionSizeFixedFractional(capital, riskPercent, entryPrice, stopLoss)
|
|
|
49
41
|
stop_loss: stopLoss
|
|
50
42
|
};
|
|
51
43
|
}
|
|
52
|
-
|
|
44
|
+
// src/ts-fns.ts
|
|
45
|
+
function kellyCriterion(yourProbability, marketPrice, bankroll) {
|
|
46
|
+
if (yourProbability <= 0 || yourProbability >= 1) {
|
|
47
|
+
throw new Error("Probability must be between 0 and 1 (exclusive)");
|
|
48
|
+
}
|
|
49
|
+
if (marketPrice <= 0 || marketPrice >= 1) {
|
|
50
|
+
throw new Error("Market price must be between 0 and 1 (exclusive)");
|
|
51
|
+
}
|
|
52
|
+
if (bankroll <= 0) {
|
|
53
|
+
throw new Error("Bankroll must be positive");
|
|
54
|
+
}
|
|
55
|
+
const edge = yourProbability - marketPrice;
|
|
56
|
+
const odds = (1 - marketPrice) / marketPrice;
|
|
57
|
+
let kellyFraction = (odds * yourProbability - (1 - yourProbability)) / odds;
|
|
58
|
+
kellyFraction = Math.max(0, kellyFraction);
|
|
59
|
+
const halfKelly = kellyFraction / 2;
|
|
60
|
+
const quarterKelly = kellyFraction / 4;
|
|
61
|
+
return {
|
|
62
|
+
kelly_fraction: kellyFraction,
|
|
63
|
+
half_kelly: halfKelly,
|
|
64
|
+
quarter_kelly: quarterKelly,
|
|
65
|
+
full_bet_size: kellyFraction * bankroll,
|
|
66
|
+
half_bet_size: halfKelly * bankroll,
|
|
67
|
+
quarter_bet_size: quarterKelly * bankroll,
|
|
68
|
+
edge,
|
|
69
|
+
odds
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function fractionalKelly(yourProbability, marketPrice, bankroll, fraction = 0.5) {
|
|
73
|
+
const kelly = kellyCriterion(yourProbability, marketPrice, bankroll);
|
|
74
|
+
return kelly.full_bet_size * fraction;
|
|
75
|
+
}
|
|
76
|
+
function detectArbitrage(yesPrice, noPrice) {
|
|
77
|
+
const totalPrice = yesPrice + noPrice;
|
|
78
|
+
const hasArbitrage = totalPrice < 1;
|
|
79
|
+
const profitPerShare = hasArbitrage ? 1 - totalPrice : 0;
|
|
80
|
+
return {
|
|
81
|
+
has_arbitrage: hasArbitrage,
|
|
82
|
+
yes_price: yesPrice,
|
|
83
|
+
no_price: noPrice,
|
|
84
|
+
total_price: totalPrice,
|
|
85
|
+
profit_per_share: profitPerShare,
|
|
86
|
+
profit_bps: profitPerShare * 1e4,
|
|
87
|
+
profit: profitPerShare
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function findCrossMarketArbitrage(markets) {
|
|
91
|
+
return markets.map((m) => ({
|
|
92
|
+
...detectArbitrage(m.yesPrice, m.noPrice),
|
|
93
|
+
name: m.name
|
|
94
|
+
})).filter((r) => r.has_arbitrage).sort((a, b) => b.profit - a.profit);
|
|
95
|
+
}
|
|
96
|
+
function convertOdds(value, fromType = "probability") {
|
|
97
|
+
let probability;
|
|
98
|
+
switch (fromType) {
|
|
99
|
+
case "probability":
|
|
100
|
+
probability = value;
|
|
101
|
+
break;
|
|
102
|
+
case "decimal":
|
|
103
|
+
probability = 1 / value;
|
|
104
|
+
break;
|
|
105
|
+
case "american":
|
|
106
|
+
probability = value > 0 ? 100 / (value + 100) : -value / (-value + 100);
|
|
107
|
+
break;
|
|
108
|
+
default:
|
|
109
|
+
throw new Error(`Unknown odds type: ${fromType}`);
|
|
110
|
+
}
|
|
111
|
+
const decimalOdds = 1 / probability;
|
|
112
|
+
let americanOdds;
|
|
113
|
+
if (probability >= 0.5) {
|
|
114
|
+
americanOdds = -Math.round(probability / (1 - probability) * 100);
|
|
115
|
+
} else {
|
|
116
|
+
americanOdds = Math.round((1 - probability) / probability * 100);
|
|
117
|
+
}
|
|
118
|
+
return {
|
|
119
|
+
probability,
|
|
120
|
+
decimal_odds: decimalOdds,
|
|
121
|
+
american_odds: americanOdds
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function probToDecimalOdds(prob) {
|
|
125
|
+
return 1 / prob;
|
|
126
|
+
}
|
|
127
|
+
function probToAmericanOdds(prob) {
|
|
128
|
+
if (prob >= 0.5) {
|
|
129
|
+
return -Math.round(prob / (1 - prob) * 100);
|
|
130
|
+
}
|
|
131
|
+
return Math.round((1 - prob) / prob * 100);
|
|
132
|
+
}
|
|
133
|
+
function decimalOddsToProb(odds) {
|
|
134
|
+
return 1 / odds;
|
|
135
|
+
}
|
|
136
|
+
function americanOddsToProb(odds) {
|
|
137
|
+
if (odds > 0) {
|
|
138
|
+
return 100 / (odds + 100);
|
|
139
|
+
}
|
|
140
|
+
return -odds / (-odds + 100);
|
|
141
|
+
}
|
|
142
|
+
function calculateEdge(yourProbability, marketPrice) {
|
|
143
|
+
return yourProbability - marketPrice;
|
|
144
|
+
}
|
|
145
|
+
function expectedValue(yourProbability, winAmount, loseAmount) {
|
|
146
|
+
return yourProbability * winAmount - (1 - yourProbability) * loseAmount;
|
|
147
|
+
}
|
|
148
|
+
function hasPositiveEV(yourProbability, marketPrice) {
|
|
149
|
+
return calculateEdge(yourProbability, marketPrice) > 0;
|
|
150
|
+
}
|
|
151
|
+
function breakEvenProbability(marketPrice) {
|
|
152
|
+
return marketPrice;
|
|
153
|
+
}
|
|
53
154
|
// src/index.ts
|
|
54
155
|
var __dirname2 = dirname(fileURLToPath(import.meta.url));
|
|
55
156
|
function getNativeLibPath() {
|
|
@@ -126,6 +227,14 @@ var symbols = {
|
|
|
126
227
|
returns: FFIType.cstring,
|
|
127
228
|
args: [FFIType.f64, FFIType.f64]
|
|
128
229
|
},
|
|
230
|
+
quant_kelly_criterion_batch: {
|
|
231
|
+
returns: FFIType.cstring,
|
|
232
|
+
args: [FFIType.ptr, FFIType.ptr, FFIType.usize, FFIType.f64]
|
|
233
|
+
},
|
|
234
|
+
quant_detect_arbitrage_batch: {
|
|
235
|
+
returns: FFIType.cstring,
|
|
236
|
+
args: [FFIType.ptr, FFIType.ptr, FFIType.usize]
|
|
237
|
+
},
|
|
129
238
|
quant_convert_odds: {
|
|
130
239
|
returns: FFIType.cstring,
|
|
131
240
|
args: [FFIType.f64, FFIType.i32]
|
|
@@ -226,18 +335,36 @@ function lmsrCalculate(yesShares, noShares, liquidityParam, operation, outcome,
|
|
|
226
335
|
return lmsrCost(yesShares, noShares, liquidityParam, outcome === "yes", sharesToBuy);
|
|
227
336
|
}
|
|
228
337
|
}
|
|
229
|
-
function
|
|
338
|
+
function kellyCriterion2(yourProbability, marketPrice, bankroll) {
|
|
230
339
|
const response = lib.symbols.quant_kelly_criterion(yourProbability, marketPrice, bankroll);
|
|
231
340
|
return parseJsonResponse(response);
|
|
232
341
|
}
|
|
233
|
-
var kelly_criterion =
|
|
234
|
-
function
|
|
342
|
+
var kelly_criterion = kellyCriterion2;
|
|
343
|
+
function kellyCriterionBatch(bets, bankroll) {
|
|
344
|
+
if (bets.length === 0)
|
|
345
|
+
return [];
|
|
346
|
+
const probs = new Float64Array(bets.map((b) => b.prob));
|
|
347
|
+
const prices = new Float64Array(bets.map((b) => b.price));
|
|
348
|
+
const response = lib.symbols.quant_kelly_criterion_batch(ptr(probs), ptr(prices), bets.length, bankroll);
|
|
349
|
+
return parseJsonResponse(response);
|
|
350
|
+
}
|
|
351
|
+
var kelly_criterion_batch = kellyCriterionBatch;
|
|
352
|
+
function detectArbitrage2(yesPrice, noPrice) {
|
|
235
353
|
const response = lib.symbols.quant_detect_arbitrage(yesPrice, noPrice);
|
|
236
354
|
const result = parseJsonResponse(response);
|
|
237
355
|
return { ...result, profit: result.profit_per_share };
|
|
238
356
|
}
|
|
239
|
-
var detect_arbitrage =
|
|
240
|
-
function
|
|
357
|
+
var detect_arbitrage = detectArbitrage2;
|
|
358
|
+
function detectArbitrageBatch(pairs) {
|
|
359
|
+
if (pairs.length === 0)
|
|
360
|
+
return [];
|
|
361
|
+
const yesPrices = new Float64Array(pairs.map((p) => p.yesPrice));
|
|
362
|
+
const noPrices = new Float64Array(pairs.map((p) => p.noPrice));
|
|
363
|
+
const response = lib.symbols.quant_detect_arbitrage_batch(ptr(yesPrices), ptr(noPrices), pairs.length);
|
|
364
|
+
return parseJsonResponse(response);
|
|
365
|
+
}
|
|
366
|
+
var detect_arbitrage_batch = detectArbitrageBatch;
|
|
367
|
+
function convertOdds2(value, fromType, toType) {
|
|
241
368
|
const typeMap = {
|
|
242
369
|
probability: 0,
|
|
243
370
|
decimal: 1,
|
|
@@ -259,7 +386,7 @@ function convertOdds(value, fromType, toType) {
|
|
|
259
386
|
}
|
|
260
387
|
return result;
|
|
261
388
|
}
|
|
262
|
-
var convert_odds =
|
|
389
|
+
var convert_odds = convertOdds2;
|
|
263
390
|
function mean(data) {
|
|
264
391
|
if (data.length === 0)
|
|
265
392
|
return NaN;
|
|
@@ -498,12 +625,24 @@ var src_default = {
|
|
|
498
625
|
lmsrPrice,
|
|
499
626
|
lmsrCost,
|
|
500
627
|
lmsrCalculate,
|
|
501
|
-
kellyCriterion,
|
|
628
|
+
kellyCriterion: kellyCriterion2,
|
|
502
629
|
kelly_criterion,
|
|
503
|
-
|
|
630
|
+
kellyCriterionBatch,
|
|
631
|
+
kelly_criterion_batch,
|
|
632
|
+
kellyCriterionTS: kellyCriterion,
|
|
633
|
+
fractionalKelly,
|
|
634
|
+
calculateEdge,
|
|
635
|
+
expectedValue,
|
|
636
|
+
hasPositiveEV,
|
|
637
|
+
breakEvenProbability,
|
|
638
|
+
detectArbitrage: detectArbitrage2,
|
|
504
639
|
detect_arbitrage,
|
|
505
|
-
|
|
640
|
+
detectArbitrageBatch,
|
|
641
|
+
detect_arbitrage_batch,
|
|
642
|
+
detectArbitrageTS: detectArbitrage,
|
|
643
|
+
convertOdds: convertOdds2,
|
|
506
644
|
convert_odds,
|
|
645
|
+
convertOddsTS: convertOdds,
|
|
507
646
|
mean,
|
|
508
647
|
stdDev,
|
|
509
648
|
std_dev,
|
|
@@ -533,25 +672,39 @@ export {
|
|
|
533
672
|
sma,
|
|
534
673
|
sharpeRatio,
|
|
535
674
|
rsi,
|
|
675
|
+
probToDecimalOdds,
|
|
676
|
+
probToAmericanOdds,
|
|
536
677
|
positionSizeFixedFractional,
|
|
537
678
|
mean,
|
|
538
679
|
macd,
|
|
539
680
|
lmsrPrice,
|
|
540
681
|
lmsrCost,
|
|
541
682
|
lmsrCalculate,
|
|
683
|
+
kelly_criterion_batch,
|
|
542
684
|
kelly_criterion,
|
|
543
|
-
kellyCriterion,
|
|
685
|
+
kellyCriterion as kellyCriterionTS,
|
|
686
|
+
kellyCriterionBatch,
|
|
687
|
+
kellyCriterion2 as kellyCriterion,
|
|
688
|
+
hasPositiveEV,
|
|
544
689
|
getVersion,
|
|
545
690
|
getLibraryPath,
|
|
691
|
+
fractionalKelly,
|
|
692
|
+
findCrossMarketArbitrage,
|
|
693
|
+
expectedValue,
|
|
546
694
|
ema,
|
|
695
|
+
detect_arbitrage_batch,
|
|
547
696
|
detect_arbitrage,
|
|
548
|
-
detectArbitrage,
|
|
697
|
+
detectArbitrage as detectArbitrageTS,
|
|
698
|
+
detectArbitrageBatch,
|
|
699
|
+
detectArbitrage2 as detectArbitrage,
|
|
549
700
|
src_default as default,
|
|
701
|
+
decimalOddsToProb,
|
|
550
702
|
createOHLCV,
|
|
551
703
|
createAMM,
|
|
552
704
|
correlation,
|
|
553
705
|
convert_odds,
|
|
554
|
-
convertOdds,
|
|
706
|
+
convertOdds as convertOddsTS,
|
|
707
|
+
convertOdds2 as convertOdds,
|
|
555
708
|
clearError,
|
|
556
709
|
calculate_var,
|
|
557
710
|
calculate_sortino_ratio,
|
|
@@ -565,12 +718,14 @@ export {
|
|
|
565
718
|
calculateEdge,
|
|
566
719
|
calculateDrawdown,
|
|
567
720
|
calculateBetaAlpha,
|
|
721
|
+
breakEvenProbability,
|
|
568
722
|
amm_price_impact,
|
|
569
723
|
amm_calculate_cost,
|
|
570
724
|
amm_buy_cost,
|
|
571
725
|
ammPriceImpact,
|
|
572
726
|
ammCalculateCostFull,
|
|
573
727
|
ammCalculateCost,
|
|
728
|
+
americanOddsToProb,
|
|
574
729
|
Signal,
|
|
575
730
|
CandlePattern
|
|
576
731
|
};
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,11 +1,48 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* This
|
|
5
|
-
*
|
|
2
|
+
* @ebowwa/quant-rust - High-Performance Quantitative Finance Library
|
|
3
|
+
*
|
|
4
|
+
* This package provides a HYBRID approach:
|
|
5
|
+
* - Rust FFI for array operations (10-20x faster)
|
|
6
|
+
* - TypeScript for scalar operations (20-40x faster due to no FFI overhead)
|
|
7
|
+
*
|
|
8
|
+
* ╔═══════════════════════════════════════════════════════════════════════════╗
|
|
9
|
+
* ║ PERFORMANCE GUIDE ║
|
|
10
|
+
* ├───────────────────────────────────────────────────────────────────────────┤
|
|
11
|
+
* ║ ║
|
|
12
|
+
* ║ ✅ USE RUST FFI (fast) for ARRAY operations: ║
|
|
13
|
+
* ║ • sma(prices, 20) → 10-20x faster on large arrays ║
|
|
14
|
+
* ║ • calculateDrawdown(arr) → 5-10x faster ║
|
|
15
|
+
* ║ • mean(arr), stdDev(arr) → 2-5x faster ║
|
|
16
|
+
* ║ • calculateSharpeRatio(arr)→ 2x faster ║
|
|
17
|
+
* ║ ║
|
|
18
|
+
* ║ ✅ USE TYPESCRIPT (fast) for SCALAR operations: ║
|
|
19
|
+
* ║ • kellyCriterionTS() → 20-40x faster (no FFI overhead) ║
|
|
20
|
+
* ║ • detectArbitrageTS() → 15-40x faster ║
|
|
21
|
+
* ║ • convertOddsTS() → 20-40x faster ║
|
|
22
|
+
* ║ ║
|
|
23
|
+
* ║ ⚠️ WHY IS FFI SLOWER FOR SCALARS? ║
|
|
24
|
+
* ║ FFI overhead ~2500ns per call ║
|
|
25
|
+
* ║ Scalar computation ~5ns ║
|
|
26
|
+
* ║ Overhead/computation ratio: 500:1 ║
|
|
27
|
+
* ║ ║
|
|
28
|
+
* ║ For arrays, O(n) computation amortizes FFI cost. ║
|
|
29
|
+
* ║ For scalars, FFI cost dominates. ║
|
|
30
|
+
* ╚═══════════════════════════════════════════════════════════════════════════╝
|
|
31
|
+
*
|
|
32
|
+
* USAGE:
|
|
33
|
+
* ```typescript
|
|
34
|
+
* // Array operations → Rust FFI
|
|
35
|
+
* import { sma, calculateDrawdown } from '@ebowwa/quant-rust';
|
|
36
|
+
* const ma = sma(prices, 20); // 10x faster
|
|
37
|
+
*
|
|
38
|
+
* // Scalar operations → TypeScript (use TS suffix)
|
|
39
|
+
* import { kellyCriterionTS, detectArbitrageTS } from '@ebowwa/quant-rust';
|
|
40
|
+
* const kelly = kellyCriterionTS(0.6, 0.5, 1000); // 30x faster
|
|
41
|
+
* ```
|
|
6
42
|
*
|
|
7
43
|
* @packageDocumentation
|
|
8
44
|
*/
|
|
45
|
+
import type { OddsType } from "./ts-fns.js";
|
|
9
46
|
import type { OHLCV, AMMState, AMMCostResult, AMMPriceImpactResult, LMSRPriceResult, KellyResult, ArbitrageResult, OddsConversion, VaRResult, DrawdownResult, SharpeResult } from "../types/index.js";
|
|
10
47
|
/**
|
|
11
48
|
* Get the library version
|
|
@@ -124,6 +161,32 @@ export declare function lmsrCalculate(yesShares: number, noShares: number, liqui
|
|
|
124
161
|
*/
|
|
125
162
|
export declare function kellyCriterion(yourProbability: number, marketPrice: number, bankroll: number): KellyResult;
|
|
126
163
|
export declare const kelly_criterion: typeof kellyCriterion;
|
|
164
|
+
/**
|
|
165
|
+
* Calculate Kelly criterion for multiple bets at once (batch operation)
|
|
166
|
+
*
|
|
167
|
+
* This is significantly more efficient than calling kellyCriterion multiple times
|
|
168
|
+
* because it only crosses the FFI boundary once, eliminating FFI call overhead.
|
|
169
|
+
*
|
|
170
|
+
* @param bets - Array of betting opportunities with prob and price
|
|
171
|
+
* @param bankroll - Total bankroll in currency units (shared across all bets)
|
|
172
|
+
* @returns Array of Kelly criterion results for each bet
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* ```typescript
|
|
176
|
+
* const bets = [
|
|
177
|
+
* { prob: 0.6, price: 0.5 },
|
|
178
|
+
* { prob: 0.55, price: 0.45 },
|
|
179
|
+
* { prob: 0.7, price: 0.6 },
|
|
180
|
+
* ];
|
|
181
|
+
* const results = kellyCriterionBatch(bets, 1000);
|
|
182
|
+
* // results[0].full_bet_size, results[1].half_bet_size, etc.
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
export declare function kellyCriterionBatch(bets: Array<{
|
|
186
|
+
prob: number;
|
|
187
|
+
price: number;
|
|
188
|
+
}>, bankroll: number): KellyResult[];
|
|
189
|
+
export declare const kelly_criterion_batch: typeof kellyCriterionBatch;
|
|
127
190
|
/**
|
|
128
191
|
* Detect arbitrage opportunities in prediction markets
|
|
129
192
|
*
|
|
@@ -137,10 +200,36 @@ export declare function detectArbitrage(yesPrice: number, noPrice: number): Arbi
|
|
|
137
200
|
profit: number;
|
|
138
201
|
};
|
|
139
202
|
export declare const detect_arbitrage: typeof detectArbitrage;
|
|
140
|
-
/**
|
|
141
|
-
|
|
203
|
+
/**
|
|
204
|
+
* Detect arbitrage opportunities for multiple price pairs at once (batch operation)
|
|
205
|
+
*
|
|
206
|
+
* This is significantly more efficient than calling detectArbitrage multiple times
|
|
207
|
+
* because it only crosses the FFI boundary once, eliminating FFI call overhead.
|
|
208
|
+
*
|
|
209
|
+
* @param pairs - Array of YES/NO price pairs to check for arbitrage
|
|
210
|
+
* @returns Array of arbitrage results with profit field for each pair
|
|
211
|
+
*
|
|
212
|
+
* @example
|
|
213
|
+
* ```typescript
|
|
214
|
+
* const pairs = [
|
|
215
|
+
* { yesPrice: 0.45, noPrice: 0.45 }, // 10% arb opportunity
|
|
216
|
+
* { yesPrice: 0.50, noPrice: 0.50 }, // no arb
|
|
217
|
+
* { yesPrice: 0.40, noPrice: 0.40 }, // 20% arb opportunity
|
|
218
|
+
* ];
|
|
219
|
+
* const results = detectArbitrageBatch(pairs);
|
|
220
|
+
* // results[0].profit = 0.10, results[1].profit = 0, results[2].profit = 0.20
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
export declare function detectArbitrageBatch(pairs: Array<{
|
|
224
|
+
yesPrice: number;
|
|
225
|
+
noPrice: number;
|
|
226
|
+
}>): Array<ArbitrageResult & {
|
|
227
|
+
profit: number;
|
|
228
|
+
}>;
|
|
229
|
+
export declare const detect_arbitrage_batch: typeof detectArbitrageBatch;
|
|
142
230
|
/**
|
|
143
231
|
* Convert between probability, decimal odds, and American odds
|
|
232
|
+
* @note OddsType is imported from ts-fns.ts (re-exported at end of file)
|
|
144
233
|
*
|
|
145
234
|
* @param value - The value to convert
|
|
146
235
|
* @param fromType - The type of the input value
|
|
@@ -277,6 +366,20 @@ export declare function calculateBetaAlpha(assetReturns: number[], benchmarkRetu
|
|
|
277
366
|
export declare const calculate_sortino_ratio: typeof calculateSortinoRatio;
|
|
278
367
|
export declare const calculate_beta_alpha: typeof calculateBetaAlpha;
|
|
279
368
|
export * from "../types/index.js";
|
|
369
|
+
/**
|
|
370
|
+
* TypeScript implementations for scalar operations.
|
|
371
|
+
*
|
|
372
|
+
* These are 20-40x faster than FFI for simple calculations because:
|
|
373
|
+
* - No FFI boundary crossing (~500ns saved each way)
|
|
374
|
+
* - No type marshalling (~500ns saved)
|
|
375
|
+
* - No JSON serialization (~500ns saved)
|
|
376
|
+
*
|
|
377
|
+
* USE THESE for: kellyCriterion, detectArbitrage, convertOdds
|
|
378
|
+
* USE RUST FFI for: sma, ema, drawdown, sharpe, mean, stdDev
|
|
379
|
+
*/
|
|
380
|
+
export { kellyCriterion as kellyCriterionTS, fractionalKelly, detectArbitrage as detectArbitrageTS, findCrossMarketArbitrage, convertOdds as convertOddsTS, probToDecimalOdds, probToAmericanOdds, decimalOddsToProb, americanOddsToProb, calculateEdge, expectedValue, hasPositiveEV, breakEvenProbability, } from "./ts-fns.js";
|
|
381
|
+
export type { OddsType } from "./ts-fns.js";
|
|
382
|
+
import { kellyCriterion as kellyCriterionTS, detectArbitrage as detectArbitrageTS, convertOdds as convertOddsTS, fractionalKelly, calculateEdge, expectedValue, hasPositiveEV, breakEvenProbability } from "./ts-fns.js";
|
|
280
383
|
declare const _default: {
|
|
281
384
|
getVersion: typeof getVersion;
|
|
282
385
|
clearError: typeof clearError;
|
|
@@ -294,10 +397,22 @@ declare const _default: {
|
|
|
294
397
|
lmsrCalculate: typeof lmsrCalculate;
|
|
295
398
|
kellyCriterion: typeof kellyCriterion;
|
|
296
399
|
kelly_criterion: typeof kellyCriterion;
|
|
400
|
+
kellyCriterionBatch: typeof kellyCriterionBatch;
|
|
401
|
+
kelly_criterion_batch: typeof kellyCriterionBatch;
|
|
402
|
+
kellyCriterionTS: typeof kellyCriterionTS;
|
|
403
|
+
fractionalKelly: typeof fractionalKelly;
|
|
404
|
+
calculateEdge: typeof calculateEdge;
|
|
405
|
+
expectedValue: typeof expectedValue;
|
|
406
|
+
hasPositiveEV: typeof hasPositiveEV;
|
|
407
|
+
breakEvenProbability: typeof breakEvenProbability;
|
|
297
408
|
detectArbitrage: typeof detectArbitrage;
|
|
298
409
|
detect_arbitrage: typeof detectArbitrage;
|
|
410
|
+
detectArbitrageBatch: typeof detectArbitrageBatch;
|
|
411
|
+
detect_arbitrage_batch: typeof detectArbitrageBatch;
|
|
412
|
+
detectArbitrageTS: typeof detectArbitrageTS;
|
|
299
413
|
convertOdds: typeof convertOdds;
|
|
300
414
|
convert_odds: typeof convertOdds;
|
|
415
|
+
convertOddsTS: typeof convertOddsTS;
|
|
301
416
|
mean: typeof mean;
|
|
302
417
|
stdDev: typeof stdDev;
|
|
303
418
|
std_dev: typeof stdDev;
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure TypeScript implementations for scalar operations
|
|
3
|
+
*
|
|
4
|
+
* WHY USE THESE INSTEAD OF RUST FFI?
|
|
5
|
+
*
|
|
6
|
+
* For simple scalar operations (Kelly, Arbitrage, Odds conversion), the FFI
|
|
7
|
+
* crossing overhead dominates the computation time:
|
|
8
|
+
*
|
|
9
|
+
* ┌─────────────────────────────────────────────────────────────┐
|
|
10
|
+
* │ FFI Call Breakdown (per call) │
|
|
11
|
+
* ├─────────────────────────────────────────────────────────────┤
|
|
12
|
+
* │ JS → C type conversion: ~500ns │
|
|
13
|
+
* │ Cross FFI boundary: ~500ns │
|
|
14
|
+
* │ Rust computation: ~5ns ← Rust IS fast! │
|
|
15
|
+
* │ C → JS type conversion: ~500ns │
|
|
16
|
+
* │ JSON parse (result): ~500ns │
|
|
17
|
+
* │ Cross FFI boundary back: ~500ns │
|
|
18
|
+
* │ ───────────────────────────────────── │
|
|
19
|
+
* │ Total FFI overhead: ~2500ns │
|
|
20
|
+
* │ Actual computation: ~5ns │
|
|
21
|
+
* │ Overhead/computation ratio: 500:1 │
|
|
22
|
+
* └─────────────────────────────────────────────────────────────┘
|
|
23
|
+
*
|
|
24
|
+
* For array operations (SMA, Drawdown, etc.), the O(n) computation
|
|
25
|
+
* amortizes the FFI cost, making Rust 10-20x faster.
|
|
26
|
+
*
|
|
27
|
+
* For scalar operations, TypeScript is 20-40x faster because there's
|
|
28
|
+
* no FFI overhead - just pure arithmetic in V8.
|
|
29
|
+
*
|
|
30
|
+
* @module ts-fns
|
|
31
|
+
*/
|
|
32
|
+
import type { KellyResult, ArbitrageResult, OddsConversion } from "../types/index.js";
|
|
33
|
+
/**
|
|
34
|
+
* Calculate optimal bet size using Kelly criterion
|
|
35
|
+
*
|
|
36
|
+
* Kelly formula for prediction markets:
|
|
37
|
+
* b = (1 - marketPrice) / marketPrice (odds received)
|
|
38
|
+
* kelly = (b * yourProb - (1 - yourProb)) / b
|
|
39
|
+
*
|
|
40
|
+
* @param yourProbability - Your estimated probability of winning (0-1)
|
|
41
|
+
* @param marketPrice - Current market price to buy shares (0-1)
|
|
42
|
+
* @param bankroll - Your total bankroll in currency units
|
|
43
|
+
* @returns Kelly calculation results
|
|
44
|
+
*/
|
|
45
|
+
export declare function kellyCriterion(yourProbability: number, marketPrice: number, bankroll: number): KellyResult;
|
|
46
|
+
/**
|
|
47
|
+
* Calculate fractional Kelly (for risk management)
|
|
48
|
+
*/
|
|
49
|
+
export declare function fractionalKelly(yourProbability: number, marketPrice: number, bankroll: number, fraction?: number): number;
|
|
50
|
+
/**
|
|
51
|
+
* Detect arbitrage opportunity in prediction market prices
|
|
52
|
+
*
|
|
53
|
+
* Arbitrage exists when: yesPrice + noPrice < 1
|
|
54
|
+
* Profit = 1 - (yesPrice + noPrice)
|
|
55
|
+
*
|
|
56
|
+
* @param yesPrice - Current YES share price (0-1)
|
|
57
|
+
* @param noPrice - Current NO share price (0-1)
|
|
58
|
+
* @returns Arbitrage analysis with profit calculation
|
|
59
|
+
*/
|
|
60
|
+
export declare function detectArbitrage(yesPrice: number, noPrice: number): ArbitrageResult & {
|
|
61
|
+
profit: number;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Find arbitrage opportunities across multiple markets
|
|
65
|
+
*/
|
|
66
|
+
export declare function findCrossMarketArbitrage(markets: Array<{
|
|
67
|
+
yesPrice: number;
|
|
68
|
+
noPrice: number;
|
|
69
|
+
name?: string;
|
|
70
|
+
}>): Array<ArbitrageResult & {
|
|
71
|
+
profit: number;
|
|
72
|
+
name?: string;
|
|
73
|
+
}>;
|
|
74
|
+
export type OddsType = "probability" | "decimal" | "american";
|
|
75
|
+
/**
|
|
76
|
+
* Convert between probability, decimal odds, and American odds
|
|
77
|
+
*
|
|
78
|
+
* @param value - The value to convert
|
|
79
|
+
* @param fromType - The type of the input value
|
|
80
|
+
* @returns All three formats
|
|
81
|
+
*/
|
|
82
|
+
export declare function convertOdds(value: number, fromType?: OddsType): OddsConversion;
|
|
83
|
+
/**
|
|
84
|
+
* Convert probability to decimal odds
|
|
85
|
+
*/
|
|
86
|
+
export declare function probToDecimalOdds(prob: number): number;
|
|
87
|
+
/**
|
|
88
|
+
* Convert probability to American odds
|
|
89
|
+
*/
|
|
90
|
+
export declare function probToAmericanOdds(prob: number): number;
|
|
91
|
+
/**
|
|
92
|
+
* Convert decimal odds to probability
|
|
93
|
+
*/
|
|
94
|
+
export declare function decimalOddsToProb(odds: number): number;
|
|
95
|
+
/**
|
|
96
|
+
* Convert American odds to probability
|
|
97
|
+
*/
|
|
98
|
+
export declare function americanOddsToProb(odds: number): number;
|
|
99
|
+
/**
|
|
100
|
+
* Calculate your edge in a bet
|
|
101
|
+
*/
|
|
102
|
+
export declare function calculateEdge(yourProbability: number, marketPrice: number): number;
|
|
103
|
+
/**
|
|
104
|
+
* Calculate expected value of a bet
|
|
105
|
+
*/
|
|
106
|
+
export declare function expectedValue(yourProbability: number, winAmount: number, loseAmount: number): number;
|
|
107
|
+
/**
|
|
108
|
+
* Check if a bet has positive expected value
|
|
109
|
+
*/
|
|
110
|
+
export declare function hasPositiveEV(yourProbability: number, marketPrice: number): boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Calculate break-even probability for a given price
|
|
113
|
+
*/
|
|
114
|
+
export declare function breakEvenProbability(marketPrice: number): number;
|
|
115
|
+
//# sourceMappingURL=ts-fns.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ts-fns.d.ts","sourceRoot":"","sources":["../../src/ts-fns.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAMtF;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,WAAW,CAgCb;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,QAAQ,GAAE,MAAY,GACrB,MAAM,CAGR;AAMD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,eAAe,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,CActC;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GACnE,KAAK,CAAC,eAAe,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAQ5D;AAMD,MAAM,MAAM,QAAQ,GAAG,aAAa,GAAG,SAAS,GAAG,UAAU,CAAC;AAE9D;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,MAAM,EACb,QAAQ,GAAE,QAAwB,GACjC,cAAc,CAiChB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKvD;AAMD;;GAEG;AACH,wBAAgB,aAAa,CAC3B,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,GAClB,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM,GAClB,OAAO,CAET;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEhE"}
|