@fullstackcraftllc/floe 0.0.13 → 0.0.14

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.
@@ -0,0 +1,500 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getQuantile = exports.getCumulativeProbability = exports.getProbabilityInRange = exports.OPEX_CONFIG = exports.CRISIS_CONFIG = exports.LOW_VOL_CONFIG = exports.DEFAULT_ADJUSTMENT_CONFIG = void 0;
4
+ exports.estimateExposureAdjustedPDF = estimateExposureAdjustedPDF;
5
+ exports.getEdgeAtPrice = getEdgeAtPrice;
6
+ exports.getSignificantAdjustmentLevels = getSignificantAdjustmentLevels;
7
+ const index_1 = require("./index");
8
+ Object.defineProperty(exports, "getProbabilityInRange", { enumerable: true, get: function () { return index_1.getProbabilityInRange; } });
9
+ Object.defineProperty(exports, "getCumulativeProbability", { enumerable: true, get: function () { return index_1.getCumulativeProbability; } });
10
+ Object.defineProperty(exports, "getQuantile", { enumerable: true, get: function () { return index_1.getQuantile; } });
11
+ // ============================================================================
12
+ // Default Configuration
13
+ // ============================================================================
14
+ /**
15
+ * Default configuration tuned for SPX-like indices
16
+ */
17
+ exports.DEFAULT_ADJUSTMENT_CONFIG = {
18
+ gamma: {
19
+ enabled: true,
20
+ attractorStrength: 0.3,
21
+ repellentStrength: 0.3,
22
+ threshold: 1000000, // $1M GEX
23
+ decayRate: 2.0,
24
+ },
25
+ vanna: {
26
+ enabled: true,
27
+ spotVolBeta: -3.0,
28
+ maxTailMultiplier: 2.5,
29
+ feedbackIterations: 3,
30
+ },
31
+ charm: {
32
+ enabled: true,
33
+ timeHorizon: 'daily',
34
+ shiftScale: 1.0,
35
+ },
36
+ };
37
+ /**
38
+ * Configuration for low volatility / grinding markets
39
+ */
40
+ exports.LOW_VOL_CONFIG = {
41
+ gamma: {
42
+ enabled: true,
43
+ attractorStrength: 0.4, // Stronger pinning
44
+ repellentStrength: 0.2,
45
+ threshold: 500000,
46
+ decayRate: 1.5,
47
+ },
48
+ vanna: {
49
+ enabled: true,
50
+ spotVolBeta: -2.0, // Less reactive
51
+ maxTailMultiplier: 1.5,
52
+ feedbackIterations: 2,
53
+ },
54
+ charm: {
55
+ enabled: true,
56
+ timeHorizon: 'daily',
57
+ shiftScale: 1.5, // Charm matters more in calm markets
58
+ },
59
+ };
60
+ /**
61
+ * Configuration for high volatility / crisis markets
62
+ */
63
+ exports.CRISIS_CONFIG = {
64
+ gamma: {
65
+ enabled: true,
66
+ attractorStrength: 0.1, // Pins don't hold
67
+ repellentStrength: 0.5, // -GEX acceleration dominates
68
+ threshold: 2000000,
69
+ decayRate: 3.0,
70
+ },
71
+ vanna: {
72
+ enabled: true,
73
+ spotVolBeta: -5.0, // Highly reactive
74
+ maxTailMultiplier: 3.0,
75
+ feedbackIterations: 5,
76
+ },
77
+ charm: {
78
+ enabled: true,
79
+ timeHorizon: 'intraday',
80
+ shiftScale: 0.5, // Charm less important vs gamma/vanna
81
+ },
82
+ };
83
+ /**
84
+ * Configuration for OPEX week
85
+ */
86
+ exports.OPEX_CONFIG = {
87
+ gamma: {
88
+ enabled: true,
89
+ attractorStrength: 0.5, // Strong pinning into expiry
90
+ repellentStrength: 0.4,
91
+ threshold: 1000000,
92
+ decayRate: 2.5,
93
+ },
94
+ vanna: {
95
+ enabled: true,
96
+ spotVolBeta: -3.0,
97
+ maxTailMultiplier: 2.0,
98
+ feedbackIterations: 3,
99
+ },
100
+ charm: {
101
+ enabled: true,
102
+ timeHorizon: 'intraday', // Charm accelerates into expiry
103
+ shiftScale: 2.0,
104
+ },
105
+ };
106
+ // ============================================================================
107
+ // Core Functions
108
+ // ============================================================================
109
+ /**
110
+ * Estimate an exposure-adjusted implied probability distribution.
111
+ *
112
+ * This function takes the standard market-implied PDF (Breeden-Litzenberger)
113
+ * and adjusts it based on dealer Greek exposures to produce a "mechanically-informed"
114
+ * probability distribution that accounts for:
115
+ *
116
+ * - **Gamma**: Creates "sticky" zones (+GEX) where price pins, and "slippery" zones
117
+ * (-GEX) where price accelerates through
118
+ * - **Vanna**: Fattens tails based on the IV-spot feedback loop (selloffs spike IV,
119
+ * which forces more selling via negative vanna)
120
+ * - **Charm**: Shifts the mean based on predictable delta decay over time
121
+ *
122
+ * @param symbol - Underlying ticker symbol
123
+ * @param underlyingPrice - Current spot price
124
+ * @param callOptions - Call options for a single expiry
125
+ * @param exposures - Exposure metrics from calculateGammaVannaCharmExposures()
126
+ * @param config - Adjustment configuration (uses defaults if not provided)
127
+ * @returns Baseline and adjusted PDFs with comparison metrics
128
+ *
129
+ * @example
130
+ * ```typescript
131
+ * // Get exposures first
132
+ * const allExposures = calculateGammaVannaCharmExposures(chain, ivSurfaces);
133
+ * const expiryExposures = allExposures.find(e => e.expiration === targetExpiry);
134
+ *
135
+ * // Calculate adjusted PDF
136
+ * const result = estimateExposureAdjustedPDF(
137
+ * 'SPX',
138
+ * 4520,
139
+ * callOptionsForExpiry,
140
+ * expiryExposures
141
+ * );
142
+ *
143
+ * // Compare probabilities
144
+ * const target = 4400;
145
+ * const baselineProb = getCumulativeProbability(result.baseline, target);
146
+ * const adjustedProb = getCumulativeProbability(result.adjusted, target);
147
+ * console.log(`Market says ${baselineProb}% chance of ${target}`);
148
+ * console.log(`Flow-adjusted: ${adjustedProb}% chance`);
149
+ * ```
150
+ */
151
+ function estimateExposureAdjustedPDF(symbol, underlyingPrice, callOptions, exposures, config = {}) {
152
+ // Merge config with defaults
153
+ const cfg = mergeConfig(config);
154
+ // Step 1: Get baseline PDF using existing Breeden-Litzenberger implementation
155
+ const baselineResult = (0, index_1.estimateImpliedProbabilityDistribution)(symbol, underlyingPrice, callOptions);
156
+ if (!baselineResult.success) {
157
+ return { success: false, error: baselineResult.error };
158
+ }
159
+ const baseline = baselineResult.distribution;
160
+ // Step 2: Calculate gamma modifiers
161
+ const gammaModifiers = cfg.gamma.enabled
162
+ ? calculateGammaModifiers(baseline.strikeProbabilities, exposures, underlyingPrice, cfg.gamma)
163
+ : baseline.strikeProbabilities.map(() => 1.0);
164
+ // Step 3: Calculate vanna modifiers
165
+ const vannaModifiers = cfg.vanna.enabled
166
+ ? calculateVannaModifiers(baseline.strikeProbabilities, exposures, underlyingPrice, cfg.vanna)
167
+ : baseline.strikeProbabilities.map(() => 1.0);
168
+ // Step 4: Calculate charm-induced mean shift
169
+ const charmShift = cfg.charm.enabled
170
+ ? calculateCharmShift(exposures, underlyingPrice, cfg.charm)
171
+ : 0;
172
+ // Step 5: Apply modifiers to create adjusted probabilities
173
+ const adjustedProbabilities = applyModifiers(baseline.strikeProbabilities, gammaModifiers, vannaModifiers, charmShift);
174
+ // Step 6: Normalize to ensure probabilities sum to 1
175
+ const normalizedProbabilities = normalizeProbabilities(adjustedProbabilities);
176
+ // Step 7: Recalculate distribution statistics
177
+ const adjusted = recalculateDistributionStats(baseline, normalizedProbabilities, underlyingPrice);
178
+ // Step 8: Calculate comparison metrics
179
+ const comparison = calculateComparison(baseline, adjusted, gammaModifiers, vannaModifiers, charmShift);
180
+ return {
181
+ baseline,
182
+ adjusted,
183
+ gammaModifiers,
184
+ vannaModifiers,
185
+ charmShift,
186
+ comparison,
187
+ };
188
+ }
189
+ // ============================================================================
190
+ // Modifier Calculations
191
+ // ============================================================================
192
+ /**
193
+ * Calculate gamma-based probability modifiers.
194
+ *
195
+ * Positive GEX creates "attractors" - price tends to pin at these levels.
196
+ * Negative GEX creates "repellents" - price accelerates through these levels.
197
+ *
198
+ * Uses 1/d² decay similar to the "local hedge pressure field" concept.
199
+ */
200
+ function calculateGammaModifiers(strikeProbabilities, exposures, spot, config) {
201
+ const modifiers = [];
202
+ // Find max absolute GEX for normalization
203
+ const maxGex = Math.max(...exposures.strikeExposures.map(e => Math.abs(e.gammaExposure)), 1 // Prevent division by zero
204
+ );
205
+ for (const prob of strikeProbabilities) {
206
+ let modifier = 1.0;
207
+ for (const exposure of exposures.strikeExposures) {
208
+ // Skip insignificant exposures
209
+ if (Math.abs(exposure.gammaExposure) < config.threshold) {
210
+ continue;
211
+ }
212
+ // Distance normalized by spot price
213
+ const distance = Math.abs(prob.strike - exposure.strikePrice) / spot;
214
+ // Influence decays with distance squared (electrostatic/gravitational)
215
+ const influence = 1 / (1 + config.decayRate * distance * distance);
216
+ // Normalized GEX (-1 to 1)
217
+ const normalizedGex = exposure.gammaExposure / maxGex;
218
+ if (exposure.gammaExposure > 0) {
219
+ // Positive GEX = attractor = increase probability density
220
+ modifier *= 1 + config.attractorStrength * normalizedGex * influence;
221
+ }
222
+ else {
223
+ // Negative GEX = repellent = decrease probability density
224
+ modifier *= 1 - config.repellentStrength * Math.abs(normalizedGex) * influence;
225
+ }
226
+ }
227
+ // Clamp to reasonable bounds
228
+ modifiers.push(Math.max(0.1, Math.min(3.0, modifier)));
229
+ }
230
+ return modifiers;
231
+ }
232
+ /**
233
+ * Calculate vanna-based probability modifiers.
234
+ *
235
+ * Vanna creates feedback loops:
236
+ * - Spot drops → IV spikes → negative vanna forces selling → spot drops more
237
+ *
238
+ * This fattens the left tail beyond what the market-implied PDF shows.
239
+ */
240
+ function calculateVannaModifiers(strikeProbabilities, exposures, spot, config) {
241
+ const modifiers = [];
242
+ // Sum vanna below and above spot
243
+ const vannaBelow = exposures.strikeExposures
244
+ .filter(e => e.strikePrice < spot)
245
+ .reduce((sum, e) => sum + e.vannaExposure, 0);
246
+ const vannaAbove = exposures.strikeExposures
247
+ .filter(e => e.strikePrice > spot)
248
+ .reduce((sum, e) => sum + e.vannaExposure, 0);
249
+ for (const prob of strikeProbabilities) {
250
+ let modifier = 1.0;
251
+ // Percentage move to this strike
252
+ const movePercent = (prob.strike - spot) / spot;
253
+ if (movePercent < 0) {
254
+ // Downside move: estimate IV spike
255
+ const ivSpike = -movePercent * Math.abs(config.spotVolBeta);
256
+ // Vanna flow from IV change
257
+ // Negative vanna * positive IV change = selling pressure
258
+ const vannaFlow = vannaBelow * ivSpike;
259
+ if (vannaFlow < 0) {
260
+ // Selling pressure increases left tail probability
261
+ let cumulativeEffect = 0;
262
+ let currentFlow = Math.abs(vannaFlow);
263
+ // Iterate feedback loop (each iteration dampens ~50%)
264
+ for (let i = 0; i < config.feedbackIterations; i++) {
265
+ cumulativeEffect += currentFlow;
266
+ currentFlow *= 0.5;
267
+ }
268
+ // Scale to modifier (normalize by spot * $1M for comparability)
269
+ const effectScale = cumulativeEffect / (spot * 1000000);
270
+ modifier = 1 + Math.min(config.maxTailMultiplier - 1, effectScale);
271
+ }
272
+ }
273
+ else if (movePercent > 0) {
274
+ // Upside move: IV typically compresses (asymmetrically less than down moves)
275
+ const ivCompress = movePercent * Math.abs(config.spotVolBeta) * 0.5;
276
+ // Positive vanna + IV compression = less buying pressure on upside
277
+ const vannaFlow = vannaAbove * (-ivCompress);
278
+ if (vannaFlow > 0) {
279
+ const effectScale = vannaFlow / (spot * 1000000);
280
+ modifier = Math.max(0.5, 1 - effectScale * 0.5);
281
+ }
282
+ }
283
+ modifiers.push(modifier);
284
+ }
285
+ return modifiers;
286
+ }
287
+ /**
288
+ * Calculate charm-induced mean shift.
289
+ *
290
+ * Net charm represents guaranteed delta decay. Negative net charm means
291
+ * dealers will be net sellers over time (downward pressure).
292
+ */
293
+ function calculateCharmShift(exposures, spot, config) {
294
+ const timeMultiplier = {
295
+ 'intraday': 0.25,
296
+ 'daily': 1.0,
297
+ 'weekly': 5.0,
298
+ }[config.timeHorizon];
299
+ // Estimate price impact of charm flow
300
+ // Heuristic: $1B of flow ≈ 0.1% price impact for large indices
301
+ const flowImpactPerBillion = 0.001 * spot;
302
+ const priceShift = (exposures.totalCharmExposure / 1000000000) * flowImpactPerBillion * timeMultiplier;
303
+ return priceShift * config.shiftScale;
304
+ }
305
+ // ============================================================================
306
+ // PDF Operations
307
+ // ============================================================================
308
+ /**
309
+ * Apply gamma, vanna, and charm modifiers to probability distribution
310
+ */
311
+ function applyModifiers(strikeProbabilities, gammaModifiers, vannaModifiers, charmShift) {
312
+ return strikeProbabilities.map((sp, i) => ({
313
+ strike: sp.strike + charmShift,
314
+ probability: sp.probability * gammaModifiers[i] * vannaModifiers[i],
315
+ }));
316
+ }
317
+ /**
318
+ * Normalize probabilities to sum to 1
319
+ */
320
+ function normalizeProbabilities(strikeProbabilities) {
321
+ const sum = strikeProbabilities.reduce((acc, sp) => acc + sp.probability, 0);
322
+ if (sum < 1e-9) {
323
+ // If all probabilities are essentially zero, return uniform
324
+ const uniform = 1 / strikeProbabilities.length;
325
+ return strikeProbabilities.map(sp => ({ ...sp, probability: uniform }));
326
+ }
327
+ return strikeProbabilities.map(sp => ({
328
+ strike: sp.strike,
329
+ probability: sp.probability / sum,
330
+ }));
331
+ }
332
+ /**
333
+ * Recalculate distribution statistics from adjusted probabilities
334
+ */
335
+ function recalculateDistributionStats(baseline, adjustedProbabilities, underlyingPrice) {
336
+ // Most likely price (mode)
337
+ let mostLikelyPrice = adjustedProbabilities[0].strike;
338
+ let maxProb = 0;
339
+ for (const sp of adjustedProbabilities) {
340
+ if (sp.probability > maxProb) {
341
+ maxProb = sp.probability;
342
+ mostLikelyPrice = sp.strike;
343
+ }
344
+ }
345
+ // Median (50th percentile)
346
+ let cumulative = 0;
347
+ let medianPrice = adjustedProbabilities[Math.floor(adjustedProbabilities.length / 2)].strike;
348
+ for (const sp of adjustedProbabilities) {
349
+ cumulative += sp.probability;
350
+ if (cumulative >= 0.5) {
351
+ medianPrice = sp.strike;
352
+ break;
353
+ }
354
+ }
355
+ // Expected value (mean)
356
+ let mean = 0;
357
+ for (const sp of adjustedProbabilities) {
358
+ mean += sp.strike * sp.probability;
359
+ }
360
+ // Variance and expected move (std dev)
361
+ let variance = 0;
362
+ for (const sp of adjustedProbabilities) {
363
+ const diff = sp.strike - mean;
364
+ variance += diff * diff * sp.probability;
365
+ }
366
+ const expectedMove = Math.sqrt(variance);
367
+ // Tail skew
368
+ let leftTail = 0;
369
+ let rightTail = 0;
370
+ for (const sp of adjustedProbabilities) {
371
+ if (sp.strike < mean) {
372
+ leftTail += sp.probability;
373
+ }
374
+ else {
375
+ rightTail += sp.probability;
376
+ }
377
+ }
378
+ const tailSkew = rightTail / Math.max(leftTail, 1e-9);
379
+ // Cumulative above/below spot
380
+ let cumulativeBelowSpot = 0;
381
+ let cumulativeAboveSpot = 0;
382
+ for (const sp of adjustedProbabilities) {
383
+ if (sp.strike < underlyingPrice) {
384
+ cumulativeBelowSpot += sp.probability;
385
+ }
386
+ else if (sp.strike > underlyingPrice) {
387
+ cumulativeAboveSpot += sp.probability;
388
+ }
389
+ }
390
+ return {
391
+ symbol: baseline.symbol,
392
+ expiryDate: baseline.expiryDate,
393
+ calculationTimestamp: Date.now(),
394
+ underlyingPrice,
395
+ strikeProbabilities: adjustedProbabilities,
396
+ mostLikelyPrice,
397
+ medianPrice,
398
+ expectedValue: mean,
399
+ expectedMove,
400
+ tailSkew,
401
+ cumulativeProbabilityAboveSpot: cumulativeAboveSpot,
402
+ cumulativeProbabilityBelowSpot: cumulativeBelowSpot,
403
+ };
404
+ }
405
+ /**
406
+ * Calculate comparison metrics between baseline and adjusted distributions
407
+ */
408
+ function calculateComparison(baseline, adjusted, gammaModifiers, vannaModifiers, charmShift) {
409
+ // Tail percentiles
410
+ const baseline5 = (0, index_1.getQuantile)(baseline, 0.05);
411
+ const baseline95 = (0, index_1.getQuantile)(baseline, 0.95);
412
+ const adjusted5 = (0, index_1.getQuantile)(adjusted, 0.05);
413
+ const adjusted95 = (0, index_1.getQuantile)(adjusted, 0.95);
414
+ // Determine dominant factor
415
+ const gammaEffect = Math.max(...gammaModifiers) - Math.min(...gammaModifiers);
416
+ const vannaEffect = Math.max(...vannaModifiers) - Math.min(...vannaModifiers);
417
+ const charmEffect = Math.abs(charmShift) / baseline.underlyingPrice;
418
+ let dominantFactor = 'none';
419
+ const maxEffect = Math.max(gammaEffect, vannaEffect, charmEffect);
420
+ if (maxEffect > 0.01) {
421
+ if (gammaEffect === maxEffect)
422
+ dominantFactor = 'gamma';
423
+ else if (vannaEffect === maxEffect)
424
+ dominantFactor = 'vanna';
425
+ else
426
+ dominantFactor = 'charm';
427
+ }
428
+ return {
429
+ meanShift: adjusted.expectedValue - baseline.expectedValue,
430
+ meanShiftPercent: ((adjusted.expectedValue - baseline.expectedValue) / baseline.underlyingPrice) * 100,
431
+ stdDevChange: adjusted.expectedMove - baseline.expectedMove,
432
+ tailSkewChange: adjusted.tailSkew - baseline.tailSkew,
433
+ leftTail: {
434
+ baseline: baseline5,
435
+ adjusted: adjusted5,
436
+ ratio: adjusted5 / baseline5,
437
+ },
438
+ rightTail: {
439
+ baseline: baseline95,
440
+ adjusted: adjusted95,
441
+ ratio: adjusted95 / baseline95,
442
+ },
443
+ dominantFactor,
444
+ };
445
+ }
446
+ // ============================================================================
447
+ // Utility Functions
448
+ // ============================================================================
449
+ /**
450
+ * Merge partial config with defaults
451
+ */
452
+ function mergeConfig(partial) {
453
+ return {
454
+ gamma: { ...exports.DEFAULT_ADJUSTMENT_CONFIG.gamma, ...partial.gamma },
455
+ vanna: { ...exports.DEFAULT_ADJUSTMENT_CONFIG.vanna, ...partial.vanna },
456
+ charm: { ...exports.DEFAULT_ADJUSTMENT_CONFIG.charm, ...partial.charm },
457
+ };
458
+ }
459
+ /**
460
+ * Get the "edge" - the difference between market-implied and flow-adjusted
461
+ * probability of reaching a price level.
462
+ *
463
+ * Positive edge means the market is underpricing the probability of reaching that level.
464
+ * Negative edge means the market is overpricing it.
465
+ *
466
+ * @example
467
+ * ```typescript
468
+ * const result = estimateExposureAdjustedPDF(...);
469
+ * const edge = getEdgeAtPrice(result, 4400);
470
+ * console.log(`Edge at 4400: ${(edge * 100).toFixed(2)}%`);
471
+ * // Output: "Edge at 4400: 2.35%"
472
+ * // Meaning: flow mechanics suggest 2.35% higher probability than market prices
473
+ * ```
474
+ */
475
+ function getEdgeAtPrice(result, price) {
476
+ const baselineProb = (0, index_1.getCumulativeProbability)(result.baseline, price);
477
+ const adjustedProb = (0, index_1.getCumulativeProbability)(result.adjusted, price);
478
+ return adjustedProb - baselineProb;
479
+ }
480
+ /**
481
+ * Get price levels where the adjustment is most significant
482
+ */
483
+ function getSignificantAdjustmentLevels(result, threshold = 0.01) {
484
+ const levels = [];
485
+ for (let i = 0; i < result.baseline.strikeProbabilities.length; i++) {
486
+ const baselineProb = result.baseline.strikeProbabilities[i].probability;
487
+ const adjustedProb = result.adjusted.strikeProbabilities[i]?.probability ?? 0;
488
+ const edge = adjustedProb - baselineProb;
489
+ if (Math.abs(edge) >= threshold) {
490
+ levels.push({
491
+ strike: result.baseline.strikeProbabilities[i].strike,
492
+ baselineProb,
493
+ adjustedProb,
494
+ edge,
495
+ });
496
+ }
497
+ }
498
+ // Sort by absolute edge descending
499
+ return levels.sort((a, b) => Math.abs(b.edge) - Math.abs(a.edge));
500
+ }
@@ -146,3 +146,4 @@ export declare function getCumulativeProbability(distribution: ImpliedProbabilit
146
146
  * ```
147
147
  */
148
148
  export declare function getQuantile(distribution: ImpliedProbabilityDistribution, probability: number): number;
149
+ export { estimateExposureAdjustedPDF, getEdgeAtPrice, getSignificantAdjustmentLevels, DEFAULT_ADJUSTMENT_CONFIG, LOW_VOL_CONFIG, CRISIS_CONFIG, OPEX_CONFIG, type ExposureAdjustmentConfig, type AdjustedPDFResult, type PDFComparison, } from './adjusted';
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OPEX_CONFIG = exports.CRISIS_CONFIG = exports.LOW_VOL_CONFIG = exports.DEFAULT_ADJUSTMENT_CONFIG = exports.getSignificantAdjustmentLevels = exports.getEdgeAtPrice = exports.estimateExposureAdjustedPDF = void 0;
3
4
  exports.estimateImpliedProbabilityDistribution = estimateImpliedProbabilityDistribution;
4
5
  exports.estimateImpliedProbabilityDistributions = estimateImpliedProbabilityDistributions;
5
6
  exports.getProbabilityInRange = getProbabilityInRange;
@@ -276,3 +277,12 @@ function getQuantile(distribution, probability) {
276
277
  }
277
278
  return distribution.strikeProbabilities[distribution.strikeProbabilities.length - 1]?.strike ?? 0;
278
279
  }
280
+ // Re-export exposure-adjusted PDF functionality
281
+ var adjusted_1 = require("./adjusted");
282
+ Object.defineProperty(exports, "estimateExposureAdjustedPDF", { enumerable: true, get: function () { return adjusted_1.estimateExposureAdjustedPDF; } });
283
+ Object.defineProperty(exports, "getEdgeAtPrice", { enumerable: true, get: function () { return adjusted_1.getEdgeAtPrice; } });
284
+ Object.defineProperty(exports, "getSignificantAdjustmentLevels", { enumerable: true, get: function () { return adjusted_1.getSignificantAdjustmentLevels; } });
285
+ Object.defineProperty(exports, "DEFAULT_ADJUSTMENT_CONFIG", { enumerable: true, get: function () { return adjusted_1.DEFAULT_ADJUSTMENT_CONFIG; } });
286
+ Object.defineProperty(exports, "LOW_VOL_CONFIG", { enumerable: true, get: function () { return adjusted_1.LOW_VOL_CONFIG; } });
287
+ Object.defineProperty(exports, "CRISIS_CONFIG", { enumerable: true, get: function () { return adjusted_1.CRISIS_CONFIG; } });
288
+ Object.defineProperty(exports, "OPEX_CONFIG", { enumerable: true, get: function () { return adjusted_1.OPEX_CONFIG; } });
package/dist/index.d.ts CHANGED
@@ -12,8 +12,10 @@ export { calculateGammaVannaCharmExposures, calculateSharesNeededToCover, } from
12
12
  export { cumulativeNormalDistribution, normalPDF, } from './utils/statistics';
13
13
  export { buildOCCSymbol, parseOCCSymbol, generateStrikesAroundSpot, generateOCCSymbolsForStrikes, generateOCCSymbolsAroundSpot, } from './utils/occ';
14
14
  export type { OCCSymbolParams, ParsedOCCSymbol, StrikeGenerationParams, } from './utils/occ';
15
- export { estimateImpliedProbabilityDistribution, estimateImpliedProbabilityDistributions, getProbabilityInRange, getCumulativeProbability, getQuantile, } from './impliedpdf';
16
- export type { StrikeProbability, ImpliedProbabilityDistribution, ImpliedPDFResult, } from './impliedpdf';
15
+ export { estimateImpliedProbabilityDistribution, estimateImpliedProbabilityDistributions, getProbabilityInRange, getCumulativeProbability, getQuantile, estimateExposureAdjustedPDF, getEdgeAtPrice, getSignificantAdjustmentLevels, DEFAULT_ADJUSTMENT_CONFIG, LOW_VOL_CONFIG, CRISIS_CONFIG, OPEX_CONFIG, } from './impliedpdf';
16
+ export type { StrikeProbability, ImpliedProbabilityDistribution, ImpliedPDFResult, ExposureAdjustmentConfig, AdjustedPDFResult, PDFComparison, } from './impliedpdf';
17
+ export { deriveRegimeParams, interpolateIVAtStrike, normalizeExposures, calculatePressureAt, buildPressureGrid, calculateIVPressures, predictIVSurfaceEvolution, runCascadeSimulation, analyzeIVPath, getIVPathOfLeastResistance, DEFAULT_IV_PATH_CONFIG, } from './pressure';
18
+ export type { MarketRegime, RegimeParams, NormalizedExposure, NormalizedExposureSummary, HedgingPressure, PressureGridCell, KeyLevels, PathOfLeastResistance, PressureGrid, StrikeIVPressure, IVSurfaceEvolution, CascadeStep, CascadeSimulation, IVPathConfig, } from './pressure';
17
19
  export { FloeClient, Broker } from './client/FloeClient';
18
20
  export { TradierClient } from './client/brokers/TradierClient';
19
21
  export { TastyTradeClient } from './client/brokers/TastyTradeClient';
package/dist/index.js CHANGED
@@ -20,7 +20,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
20
20
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
21
  };
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.createOptionChain = exports.getAdapter = exports.brokerAdapters = exports.tdaAdapter = exports.ibkrAdapter = exports.schwabAdapter = exports.genericAdapter = exports.TradeStationClient = exports.TastyTradeClient = exports.TradierClient = exports.Broker = exports.FloeClient = exports.getQuantile = exports.getCumulativeProbability = exports.getProbabilityInRange = exports.estimateImpliedProbabilityDistributions = exports.estimateImpliedProbabilityDistribution = exports.generateOCCSymbolsAroundSpot = exports.generateOCCSymbolsForStrikes = exports.generateStrikesAroundSpot = exports.parseOCCSymbol = exports.buildOCCSymbol = exports.normalPDF = exports.cumulativeNormalDistribution = exports.calculateSharesNeededToCover = exports.calculateGammaVannaCharmExposures = exports.smoothTotalVarianceSmile = exports.getIVForStrike = exports.getIVSurfaces = exports.getTimeToExpirationInYears = exports.getMillisecondsToExpiration = exports.calculateImpliedVolatility = exports.calculateGreeks = exports.blackScholes = void 0;
23
+ exports.brokerAdapters = exports.tdaAdapter = exports.ibkrAdapter = exports.schwabAdapter = exports.genericAdapter = exports.TradeStationClient = exports.TastyTradeClient = exports.TradierClient = exports.Broker = exports.FloeClient = exports.DEFAULT_IV_PATH_CONFIG = exports.getIVPathOfLeastResistance = exports.analyzeIVPath = exports.runCascadeSimulation = exports.predictIVSurfaceEvolution = exports.calculateIVPressures = exports.buildPressureGrid = exports.calculatePressureAt = exports.normalizeExposures = exports.interpolateIVAtStrike = exports.deriveRegimeParams = exports.OPEX_CONFIG = exports.CRISIS_CONFIG = exports.LOW_VOL_CONFIG = exports.DEFAULT_ADJUSTMENT_CONFIG = exports.getSignificantAdjustmentLevels = exports.getEdgeAtPrice = exports.estimateExposureAdjustedPDF = exports.getQuantile = exports.getCumulativeProbability = exports.getProbabilityInRange = exports.estimateImpliedProbabilityDistributions = exports.estimateImpliedProbabilityDistribution = exports.generateOCCSymbolsAroundSpot = exports.generateOCCSymbolsForStrikes = exports.generateStrikesAroundSpot = exports.parseOCCSymbol = exports.buildOCCSymbol = exports.normalPDF = exports.cumulativeNormalDistribution = exports.calculateSharesNeededToCover = exports.calculateGammaVannaCharmExposures = exports.smoothTotalVarianceSmile = exports.getIVForStrike = exports.getIVSurfaces = exports.getTimeToExpirationInYears = exports.getMillisecondsToExpiration = exports.calculateImpliedVolatility = exports.calculateGreeks = exports.blackScholes = void 0;
24
+ exports.createOptionChain = exports.getAdapter = void 0;
24
25
  // Core types
25
26
  __exportStar(require("./types"), exports);
26
27
  // Black-Scholes pricing and Greeks
@@ -59,6 +60,31 @@ Object.defineProperty(exports, "estimateImpliedProbabilityDistributions", { enum
59
60
  Object.defineProperty(exports, "getProbabilityInRange", { enumerable: true, get: function () { return impliedpdf_1.getProbabilityInRange; } });
60
61
  Object.defineProperty(exports, "getCumulativeProbability", { enumerable: true, get: function () { return impliedpdf_1.getCumulativeProbability; } });
61
62
  Object.defineProperty(exports, "getQuantile", { enumerable: true, get: function () { return impliedpdf_1.getQuantile; } });
63
+ // Exposure-adjusted PDF
64
+ Object.defineProperty(exports, "estimateExposureAdjustedPDF", { enumerable: true, get: function () { return impliedpdf_1.estimateExposureAdjustedPDF; } });
65
+ Object.defineProperty(exports, "getEdgeAtPrice", { enumerable: true, get: function () { return impliedpdf_1.getEdgeAtPrice; } });
66
+ Object.defineProperty(exports, "getSignificantAdjustmentLevels", { enumerable: true, get: function () { return impliedpdf_1.getSignificantAdjustmentLevels; } });
67
+ Object.defineProperty(exports, "DEFAULT_ADJUSTMENT_CONFIG", { enumerable: true, get: function () { return impliedpdf_1.DEFAULT_ADJUSTMENT_CONFIG; } });
68
+ Object.defineProperty(exports, "LOW_VOL_CONFIG", { enumerable: true, get: function () { return impliedpdf_1.LOW_VOL_CONFIG; } });
69
+ Object.defineProperty(exports, "CRISIS_CONFIG", { enumerable: true, get: function () { return impliedpdf_1.CRISIS_CONFIG; } });
70
+ Object.defineProperty(exports, "OPEX_CONFIG", { enumerable: true, get: function () { return impliedpdf_1.OPEX_CONFIG; } });
71
+ // Pressure field and IV path prediction
72
+ var pressure_1 = require("./pressure");
73
+ // Regime derivation
74
+ Object.defineProperty(exports, "deriveRegimeParams", { enumerable: true, get: function () { return pressure_1.deriveRegimeParams; } });
75
+ Object.defineProperty(exports, "interpolateIVAtStrike", { enumerable: true, get: function () { return pressure_1.interpolateIVAtStrike; } });
76
+ // Exposure normalization
77
+ Object.defineProperty(exports, "normalizeExposures", { enumerable: true, get: function () { return pressure_1.normalizeExposures; } });
78
+ // Pressure field
79
+ Object.defineProperty(exports, "calculatePressureAt", { enumerable: true, get: function () { return pressure_1.calculatePressureAt; } });
80
+ Object.defineProperty(exports, "buildPressureGrid", { enumerable: true, get: function () { return pressure_1.buildPressureGrid; } });
81
+ // IV path prediction
82
+ Object.defineProperty(exports, "calculateIVPressures", { enumerable: true, get: function () { return pressure_1.calculateIVPressures; } });
83
+ Object.defineProperty(exports, "predictIVSurfaceEvolution", { enumerable: true, get: function () { return pressure_1.predictIVSurfaceEvolution; } });
84
+ Object.defineProperty(exports, "runCascadeSimulation", { enumerable: true, get: function () { return pressure_1.runCascadeSimulation; } });
85
+ Object.defineProperty(exports, "analyzeIVPath", { enumerable: true, get: function () { return pressure_1.analyzeIVPath; } });
86
+ Object.defineProperty(exports, "getIVPathOfLeastResistance", { enumerable: true, get: function () { return pressure_1.getIVPathOfLeastResistance; } });
87
+ Object.defineProperty(exports, "DEFAULT_IV_PATH_CONFIG", { enumerable: true, get: function () { return pressure_1.DEFAULT_IV_PATH_CONFIG; } });
62
88
  // Client
63
89
  var FloeClient_1 = require("./client/FloeClient");
64
90
  Object.defineProperty(exports, "FloeClient", { enumerable: true, get: function () { return FloeClient_1.FloeClient; } });
@@ -0,0 +1,14 @@
1
+ import { OptionChain, IVSurface, ExposurePerExpiry } from '../types';
2
+ import { RegimeParams, HedgingPressure, PressureGrid } from './types';
3
+ /**
4
+ * Calculate hedging pressure at a specific (spot, time) point
5
+ */
6
+ export declare function calculatePressureAt(spot: number, timeToExpiry: number, exposures: ExposurePerExpiry, regimeParams: RegimeParams): HedgingPressure;
7
+ /**
8
+ * Build a complete pressure grid for visualization
9
+ */
10
+ export declare function buildPressureGrid(symbol: string, chain: OptionChain, exposures: ExposurePerExpiry, ivSurface: IVSurface, options?: {
11
+ spotRangePercent?: number;
12
+ spotStepPercent?: number;
13
+ timeStepMinutes?: number;
14
+ }): PressureGrid;