@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/src/ts-fns.ts ADDED
@@ -0,0 +1,275 @@
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
+
33
+ import type { KellyResult, ArbitrageResult, OddsConversion } from "../types/index.js";
34
+
35
+ // ============================================================================
36
+ // KELLY CRITERION - TypeScript Implementation (20-40x faster than FFI)
37
+ // ============================================================================
38
+
39
+ /**
40
+ * Calculate optimal bet size using Kelly criterion
41
+ *
42
+ * Kelly formula for prediction markets:
43
+ * b = (1 - marketPrice) / marketPrice (odds received)
44
+ * kelly = (b * yourProb - (1 - yourProb)) / b
45
+ *
46
+ * @param yourProbability - Your estimated probability of winning (0-1)
47
+ * @param marketPrice - Current market price to buy shares (0-1)
48
+ * @param bankroll - Your total bankroll in currency units
49
+ * @returns Kelly calculation results
50
+ */
51
+ export function kellyCriterion(
52
+ yourProbability: number,
53
+ marketPrice: number,
54
+ bankroll: number
55
+ ): KellyResult {
56
+ // Validate inputs
57
+ if (yourProbability <= 0 || yourProbability >= 1) {
58
+ throw new Error("Probability must be between 0 and 1 (exclusive)");
59
+ }
60
+ if (marketPrice <= 0 || marketPrice >= 1) {
61
+ throw new Error("Market price must be between 0 and 1 (exclusive)");
62
+ }
63
+ if (bankroll <= 0) {
64
+ throw new Error("Bankroll must be positive");
65
+ }
66
+
67
+ const edge = yourProbability - marketPrice;
68
+ const odds = (1 - marketPrice) / marketPrice;
69
+
70
+ // Kelly fraction: (bp - q) / b where b = odds, p = yourProb, q = 1 - yourProb
71
+ let kellyFraction = (odds * yourProbability - (1 - yourProbability)) / odds;
72
+ kellyFraction = Math.max(0, kellyFraction); // Never bet negative
73
+
74
+ const halfKelly = kellyFraction / 2;
75
+ const quarterKelly = kellyFraction / 4;
76
+
77
+ return {
78
+ kelly_fraction: kellyFraction,
79
+ half_kelly: halfKelly,
80
+ quarter_kelly: quarterKelly,
81
+ full_bet_size: kellyFraction * bankroll,
82
+ half_bet_size: halfKelly * bankroll,
83
+ quarter_bet_size: quarterKelly * bankroll,
84
+ edge,
85
+ odds,
86
+ };
87
+ }
88
+
89
+ /**
90
+ * Calculate fractional Kelly (for risk management)
91
+ */
92
+ export function fractionalKelly(
93
+ yourProbability: number,
94
+ marketPrice: number,
95
+ bankroll: number,
96
+ fraction: number = 0.5
97
+ ): number {
98
+ const kelly = kellyCriterion(yourProbability, marketPrice, bankroll);
99
+ return kelly.full_bet_size * fraction;
100
+ }
101
+
102
+ // ============================================================================
103
+ // ARBITRAGE DETECTION - TypeScript Implementation (15-40x faster than FFI)
104
+ // ============================================================================
105
+
106
+ /**
107
+ * Detect arbitrage opportunity in prediction market prices
108
+ *
109
+ * Arbitrage exists when: yesPrice + noPrice < 1
110
+ * Profit = 1 - (yesPrice + noPrice)
111
+ *
112
+ * @param yesPrice - Current YES share price (0-1)
113
+ * @param noPrice - Current NO share price (0-1)
114
+ * @returns Arbitrage analysis with profit calculation
115
+ */
116
+ export function detectArbitrage(
117
+ yesPrice: number,
118
+ noPrice: number
119
+ ): ArbitrageResult & { profit: number } {
120
+ const totalPrice = yesPrice + noPrice;
121
+ const hasArbitrage = totalPrice < 1;
122
+ const profitPerShare = hasArbitrage ? 1 - totalPrice : 0;
123
+
124
+ return {
125
+ has_arbitrage: hasArbitrage,
126
+ yes_price: yesPrice,
127
+ no_price: noPrice,
128
+ total_price: totalPrice,
129
+ profit_per_share: profitPerShare,
130
+ profit_bps: profitPerShare * 10000,
131
+ profit: profitPerShare, // Alias for convenience
132
+ };
133
+ }
134
+
135
+ /**
136
+ * Find arbitrage opportunities across multiple markets
137
+ */
138
+ export function findCrossMarketArbitrage(
139
+ markets: Array<{ yesPrice: number; noPrice: number; name?: string }>
140
+ ): Array<ArbitrageResult & { profit: number; name?: string }> {
141
+ return markets
142
+ .map((m) => ({
143
+ ...detectArbitrage(m.yesPrice, m.noPrice),
144
+ name: m.name,
145
+ }))
146
+ .filter((r) => r.has_arbitrage)
147
+ .sort((a, b) => b.profit - a.profit);
148
+ }
149
+
150
+ // ============================================================================
151
+ // ODDS CONVERSION - TypeScript Implementation (20-40x faster than FFI)
152
+ // ============================================================================
153
+
154
+ export type OddsType = "probability" | "decimal" | "american";
155
+
156
+ /**
157
+ * Convert between probability, decimal odds, and American odds
158
+ *
159
+ * @param value - The value to convert
160
+ * @param fromType - The type of the input value
161
+ * @returns All three formats
162
+ */
163
+ export function convertOdds(
164
+ value: number,
165
+ fromType: OddsType = "probability"
166
+ ): OddsConversion {
167
+ let probability: number;
168
+
169
+ switch (fromType) {
170
+ case "probability":
171
+ probability = value;
172
+ break;
173
+ case "decimal":
174
+ probability = 1 / value;
175
+ break;
176
+ case "american":
177
+ probability = value > 0 ? 100 / (value + 100) : -value / (-value + 100);
178
+ break;
179
+ default:
180
+ throw new Error(`Unknown odds type: ${fromType}`);
181
+ }
182
+
183
+ // Calculate decimal odds
184
+ const decimalOdds = 1 / probability;
185
+
186
+ // Calculate American odds
187
+ let americanOdds: number;
188
+ if (probability >= 0.5) {
189
+ americanOdds = -Math.round((probability / (1 - probability)) * 100);
190
+ } else {
191
+ americanOdds = Math.round(((1 - probability) / probability) * 100);
192
+ }
193
+
194
+ return {
195
+ probability,
196
+ decimal_odds: decimalOdds,
197
+ american_odds: americanOdds,
198
+ };
199
+ }
200
+
201
+ /**
202
+ * Convert probability to decimal odds
203
+ */
204
+ export function probToDecimalOdds(prob: number): number {
205
+ return 1 / prob;
206
+ }
207
+
208
+ /**
209
+ * Convert probability to American odds
210
+ */
211
+ export function probToAmericanOdds(prob: number): number {
212
+ if (prob >= 0.5) {
213
+ return -Math.round((prob / (1 - prob)) * 100);
214
+ }
215
+ return Math.round(((1 - prob) / prob) * 100);
216
+ }
217
+
218
+ /**
219
+ * Convert decimal odds to probability
220
+ */
221
+ export function decimalOddsToProb(odds: number): number {
222
+ return 1 / odds;
223
+ }
224
+
225
+ /**
226
+ * Convert American odds to probability
227
+ */
228
+ export function americanOddsToProb(odds: number): number {
229
+ if (odds > 0) {
230
+ return 100 / (odds + 100);
231
+ }
232
+ return -odds / (-odds + 100);
233
+ }
234
+
235
+ // ============================================================================
236
+ // EDGE CALCULATIONS - TypeScript (no FFI overhead)
237
+ // ============================================================================
238
+
239
+ /**
240
+ * Calculate your edge in a bet
241
+ */
242
+ export function calculateEdge(
243
+ yourProbability: number,
244
+ marketPrice: number
245
+ ): number {
246
+ return yourProbability - marketPrice;
247
+ }
248
+
249
+ /**
250
+ * Calculate expected value of a bet
251
+ */
252
+ export function expectedValue(
253
+ yourProbability: number,
254
+ winAmount: number,
255
+ loseAmount: number
256
+ ): number {
257
+ return yourProbability * winAmount - (1 - yourProbability) * loseAmount;
258
+ }
259
+
260
+ /**
261
+ * Check if a bet has positive expected value
262
+ */
263
+ export function hasPositiveEV(
264
+ yourProbability: number,
265
+ marketPrice: number
266
+ ): boolean {
267
+ return calculateEdge(yourProbability, marketPrice) > 0;
268
+ }
269
+
270
+ /**
271
+ * Calculate break-even probability for a given price
272
+ */
273
+ export function breakEvenProbability(marketPrice: number): number {
274
+ return marketPrice;
275
+ }
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