@fullstackcraftllc/floe 0.0.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 ADDED
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ /**
3
+ * @fullstackcraftllc/floe - Options Analytics Library
4
+ *
5
+ * A comprehensive TypeScript library for options pricing, Greeks calculation,
6
+ * and dealer exposure analysis across multiple brokers.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
20
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.createOptionChain = exports.getAdapter = exports.brokerAdapters = exports.tdaAdapter = exports.ibkrAdapter = exports.schwabAdapter = exports.genericAdapter = 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
+ // Core types
25
+ __exportStar(require("./types"), exports);
26
+ // Black-Scholes pricing and Greeks
27
+ var blackscholes_1 = require("./blackscholes");
28
+ Object.defineProperty(exports, "blackScholes", { enumerable: true, get: function () { return blackscholes_1.blackScholes; } });
29
+ Object.defineProperty(exports, "calculateGreeks", { enumerable: true, get: function () { return blackscholes_1.calculateGreeks; } });
30
+ Object.defineProperty(exports, "calculateImpliedVolatility", { enumerable: true, get: function () { return blackscholes_1.calculateImpliedVolatility; } });
31
+ Object.defineProperty(exports, "getMillisecondsToExpiration", { enumerable: true, get: function () { return blackscholes_1.getMillisecondsToExpiration; } });
32
+ Object.defineProperty(exports, "getTimeToExpirationInYears", { enumerable: true, get: function () { return blackscholes_1.getTimeToExpirationInYears; } });
33
+ // Volatility surface construction
34
+ var volatility_1 = require("./volatility");
35
+ Object.defineProperty(exports, "getIVSurfaces", { enumerable: true, get: function () { return volatility_1.getIVSurfaces; } });
36
+ Object.defineProperty(exports, "getIVForStrike", { enumerable: true, get: function () { return volatility_1.getIVForStrike; } });
37
+ // Smoothing algorithms
38
+ var smoothing_1 = require("./volatility/smoothing");
39
+ Object.defineProperty(exports, "smoothTotalVarianceSmile", { enumerable: true, get: function () { return smoothing_1.smoothTotalVarianceSmile; } });
40
+ // Exposure calculations
41
+ var exposure_1 = require("./exposure");
42
+ Object.defineProperty(exports, "calculateGammaVannaCharmExposures", { enumerable: true, get: function () { return exposure_1.calculateGammaVannaCharmExposures; } });
43
+ Object.defineProperty(exports, "calculateSharesNeededToCover", { enumerable: true, get: function () { return exposure_1.calculateSharesNeededToCover; } });
44
+ // Statistical utilities
45
+ var statistics_1 = require("./utils/statistics");
46
+ Object.defineProperty(exports, "cumulativeNormalDistribution", { enumerable: true, get: function () { return statistics_1.cumulativeNormalDistribution; } });
47
+ Object.defineProperty(exports, "normalPDF", { enumerable: true, get: function () { return statistics_1.normalPDF; } });
48
+ // Broker adapters
49
+ var adapters_1 = require("./adapters");
50
+ Object.defineProperty(exports, "genericAdapter", { enumerable: true, get: function () { return adapters_1.genericAdapter; } });
51
+ Object.defineProperty(exports, "schwabAdapter", { enumerable: true, get: function () { return adapters_1.schwabAdapter; } });
52
+ Object.defineProperty(exports, "ibkrAdapter", { enumerable: true, get: function () { return adapters_1.ibkrAdapter; } });
53
+ Object.defineProperty(exports, "tdaAdapter", { enumerable: true, get: function () { return adapters_1.tdaAdapter; } });
54
+ Object.defineProperty(exports, "brokerAdapters", { enumerable: true, get: function () { return adapters_1.brokerAdapters; } });
55
+ Object.defineProperty(exports, "getAdapter", { enumerable: true, get: function () { return adapters_1.getAdapter; } });
56
+ Object.defineProperty(exports, "createOptionChain", { enumerable: true, get: function () { return adapters_1.createOptionChain; } });
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Core types for options analytics
3
+ */
4
+ /**
5
+ * Option type (call or put)
6
+ */
7
+ export type OptionType = 'call' | 'put';
8
+ /**
9
+ * Volatility calculation method
10
+ */
11
+ export type VolatilityModel = 'blackscholes' | 'svm' | 'garch';
12
+ /**
13
+ * Smoothing method for IV surface
14
+ */
15
+ export type SmoothingModel = 'totalvariance' | 'none';
16
+ /**
17
+ * Parameters for Black-Scholes calculation
18
+ */
19
+ export interface BlackScholesParams {
20
+ /** Current price of the underlying asset */
21
+ spot: number;
22
+ /** Strike price of the option */
23
+ strike: number;
24
+ /** Time to expiration in years */
25
+ timeToExpiry: number;
26
+ /** Implied volatility (annualized, as decimal e.g., 0.20 for 20%) */
27
+ volatility: number;
28
+ /** Risk-free interest rate (annualized, as decimal) */
29
+ riskFreeRate: number;
30
+ /** Option type */
31
+ optionType: OptionType;
32
+ /** Dividend yield (annualized, as decimal) */
33
+ dividendYield?: number;
34
+ }
35
+ /**
36
+ * Complete set of option Greeks and higher-order Greeks
37
+ */
38
+ export interface Greeks {
39
+ /** Price: Option theoretical value */
40
+ price: number;
41
+ /** Delta: Rate of change of option price with respect to underlying price */
42
+ delta: number;
43
+ /** Gamma: Rate of change of delta with respect to underlying price */
44
+ gamma: number;
45
+ /** Theta: Rate of change of option price with respect to time (per day) */
46
+ theta: number;
47
+ /** Vega: Rate of change of option price with respect to volatility (per 1% change) */
48
+ vega: number;
49
+ /** Rho: Rate of change of option price with respect to interest rate (per 1% change) */
50
+ rho: number;
51
+ /** Charm: Rate of change of delta with respect to time (per day) */
52
+ charm: number;
53
+ /** Vanna: Rate of change of delta with respect to volatility */
54
+ vanna: number;
55
+ /** Volga (Vomma): Rate of change of vega with respect to volatility */
56
+ volga: number;
57
+ /** Speed: Rate of change of gamma with respect to underlying price */
58
+ speed: number;
59
+ /** Zomma: Rate of change of gamma with respect to volatility */
60
+ zomma: number;
61
+ /** Color: Rate of change of gamma with respect to time */
62
+ color: number;
63
+ /** Ultima: Rate of change of volga with respect to volatility */
64
+ ultima: number;
65
+ }
66
+ /**
67
+ * Normalized option data structure (broker-agnostic)
68
+ */
69
+ export interface NormalizedOption {
70
+ /** Strike price */
71
+ strike: number;
72
+ /** Expiration date (ISO 8601) */
73
+ expiration: string;
74
+ /** Expiration timestamp in milliseconds */
75
+ expirationTimestamp: number;
76
+ /** Option type */
77
+ optionType: OptionType;
78
+ /** Current bid price */
79
+ bid: number;
80
+ /** Current ask price */
81
+ ask: number;
82
+ /** Mark (mid) price */
83
+ mark: number;
84
+ /** Last traded price */
85
+ last: number;
86
+ /** Trading volume */
87
+ volume: number;
88
+ /** Open interest */
89
+ openInterest: number;
90
+ /** Implied volatility (as decimal) */
91
+ impliedVolatility: number;
92
+ /** Pre-calculated Greeks (optional) */
93
+ greeks?: Greeks;
94
+ }
95
+ /**
96
+ * Complete option chain with market context
97
+ */
98
+ export interface OptionChain {
99
+ /** Underlying symbol */
100
+ symbol: string;
101
+ /** Current spot price of the underlying */
102
+ spot: number;
103
+ /** Risk-free interest rate (as decimal, e.g., 0.05 for 5%) */
104
+ riskFreeRate: number;
105
+ /** Dividend yield (as decimal, e.g., 0.02 for 2%) */
106
+ dividendYield: number;
107
+ /** All options in the chain */
108
+ options: NormalizedOption[];
109
+ }
110
+ /**
111
+ * IV Surface for a single expiration and option type
112
+ */
113
+ export interface IVSurface {
114
+ /** Expiration timestamp in milliseconds */
115
+ expirationDate: number;
116
+ /** Option type (CALL or PUT) */
117
+ putCall: OptionType;
118
+ /** Sorted strike prices */
119
+ strikes: number[];
120
+ /** Raw calculated IVs (as percentages) */
121
+ rawIVs: number[];
122
+ /** Smoothed IVs after applying smoothing algorithm (as percentages) */
123
+ smoothedIVs: number[];
124
+ }
125
+ /**
126
+ * Strike-level exposure metrics
127
+ */
128
+ export interface StrikeExposure {
129
+ /** Strike price */
130
+ strikePrice: number;
131
+ /** Gamma exposure at this strike */
132
+ gammaExposure: number;
133
+ /** Vanna exposure at this strike */
134
+ vannaExposure: number;
135
+ /** Charm exposure at this strike */
136
+ charmExposure: number;
137
+ /** Net exposure (gamma + vanna + charm) */
138
+ netExposure: number;
139
+ }
140
+ /**
141
+ * Exposure metrics per expiration
142
+ */
143
+ export interface ExposurePerExpiry {
144
+ /** Current spot price */
145
+ spotPrice: number;
146
+ /** Expiration timestamp in milliseconds */
147
+ expiration: number;
148
+ /** Total gamma exposure for this expiration */
149
+ totalGammaExposure: number;
150
+ /** Total vanna exposure for this expiration */
151
+ totalVannaExposure: number;
152
+ /** Total charm exposure for this expiration */
153
+ totalCharmExposure: number;
154
+ /** Total net exposure (sum of all three) */
155
+ totalNetExposure: number;
156
+ /** Strike with maximum gamma */
157
+ strikeOfMaxGamma: number;
158
+ /** Strike with minimum gamma */
159
+ strikeOfMinGamma: number;
160
+ /** Strike with maximum vanna */
161
+ strikeOfMaxVanna: number;
162
+ /** Strike with minimum vanna */
163
+ strikeOfMinVanna: number;
164
+ /** Strike with maximum charm */
165
+ strikeOfMaxCharm: number;
166
+ /** Strike with minimum charm */
167
+ strikeOfMinCharm: number;
168
+ /** Strike with maximum net exposure */
169
+ strikeOfMaxNet: number;
170
+ /** Strike with minimum net exposure */
171
+ strikeOfMinNet: number;
172
+ /** Per-strike exposures */
173
+ strikeExposures: StrikeExposure[];
174
+ }
175
+ /**
176
+ * Dealer Gamma Exposure (GEX) metrics
177
+ */
178
+ export interface GEXMetrics {
179
+ /** Total gamma exposure by strike */
180
+ byStrike: Map<number, number>;
181
+ /** Net gamma exposure */
182
+ netGamma: number;
183
+ /** Largest positive gamma strike */
184
+ maxPositiveStrike: number;
185
+ /** Largest negative gamma strike */
186
+ maxNegativeStrike: number;
187
+ /** Zero gamma level (flip point) */
188
+ zeroGammaLevel: number | null;
189
+ }
190
+ /**
191
+ * Dealer Vanna Exposure (VEX) metrics
192
+ */
193
+ export interface VannaMetrics {
194
+ /** Total vanna exposure by strike */
195
+ byStrike: Map<number, number>;
196
+ /** Net vanna exposure */
197
+ netVanna: number;
198
+ }
199
+ /**
200
+ * Dealer Charm Exposure (CEX) metrics
201
+ */
202
+ export interface CharmMetrics {
203
+ /** Total charm exposure by strike */
204
+ byStrike: Map<number, number>;
205
+ /** Net charm exposure */
206
+ netCharm: number;
207
+ }
208
+ /**
209
+ * Broker-specific data types
210
+ */
211
+ /**
212
+ * Raw option data from any broker (to be normalized)
213
+ */
214
+ export interface RawOptionData {
215
+ [key: string]: any;
216
+ }
217
+ /**
218
+ * Adapter function type for normalizing broker data
219
+ */
220
+ export type BrokerAdapter = (data: RawOptionData) => NormalizedOption;
221
+ /**
222
+ * Constants
223
+ */
224
+ export declare const MILLISECONDS_PER_YEAR = 31536000000;
225
+ export declare const MILLISECONDS_PER_DAY = 86400000;
226
+ export declare const MINUTES_PER_YEAR = 525600;
227
+ export declare const MINUTES_PER_DAY = 1440;
228
+ export declare const DAYS_PER_YEAR = 365;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ /**
3
+ * Core types for options analytics
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DAYS_PER_YEAR = exports.MINUTES_PER_DAY = exports.MINUTES_PER_YEAR = exports.MILLISECONDS_PER_DAY = exports.MILLISECONDS_PER_YEAR = void 0;
7
+ /**
8
+ * Constants
9
+ */
10
+ exports.MILLISECONDS_PER_YEAR = 31536000000;
11
+ exports.MILLISECONDS_PER_DAY = 86400000;
12
+ exports.MINUTES_PER_YEAR = 525600;
13
+ exports.MINUTES_PER_DAY = 1440;
14
+ exports.DAYS_PER_YEAR = 365;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Statistical utility functions
3
+ */
4
+ /**
5
+ * Cumulative distribution function for standard normal distribution
6
+ * Using an approximation method (Abramowitz and Stegun)
7
+ *
8
+ * @param x - Input value
9
+ * @returns Cumulative probability
10
+ */
11
+ export declare function cumulativeNormalDistribution(x: number): number;
12
+ /**
13
+ * Probability density function for standard normal distribution
14
+ *
15
+ * @param x - Input value
16
+ * @returns Probability density
17
+ */
18
+ export declare function normalPDF(x: number): number;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /**
3
+ * Statistical utility functions
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.cumulativeNormalDistribution = cumulativeNormalDistribution;
7
+ exports.normalPDF = normalPDF;
8
+ /**
9
+ * Cumulative distribution function for standard normal distribution
10
+ * Using an approximation method (Abramowitz and Stegun)
11
+ *
12
+ * @param x - Input value
13
+ * @returns Cumulative probability
14
+ */
15
+ function cumulativeNormalDistribution(x) {
16
+ const t = 1 / (1 + 0.2316419 * Math.abs(x));
17
+ const d = 0.3989423 * Math.exp((-x * x) / 2);
18
+ const probability = d *
19
+ t *
20
+ (0.3193815 +
21
+ t * (-0.3565638 + t * (1.781478 + t * (-1.821256 + t * 1.330274))));
22
+ return x > 0 ? 1 - probability : probability;
23
+ }
24
+ /**
25
+ * Probability density function for standard normal distribution
26
+ *
27
+ * @param x - Input value
28
+ * @returns Probability density
29
+ */
30
+ function normalPDF(x) {
31
+ return Math.exp((-x * x) / 2) / Math.sqrt(2 * Math.PI);
32
+ }
@@ -0,0 +1,37 @@
1
+ import { OptionChain, IVSurface, VolatilityModel, SmoothingModel } from '../types';
2
+ /**
3
+ * Build IV surfaces for all expirations in an option chain
4
+ *
5
+ * @param volatilityModel - Method to calculate IV
6
+ * - 'blackscholes': Use Black-Scholes IV inversion (implemented) ✅
7
+ * - 'svm': TODO - Support Vector Machine based IV estimation
8
+ * - 'garch': TODO - GARCH model for volatility forecasting
9
+ * @param smoothingModel - Smoothing method to apply
10
+ * - 'totalvariance': Cubic spline + convex hull (implemented) ✅
11
+ * - 'none': No smoothing, use raw IVs ✅
12
+ * - TODO: Future - 'svi', 'ssvi', 'sabr' parametric models
13
+ * @param chain - Option chain with market context (spot, rates, options)
14
+ * @returns Array of IV surfaces (one per expiration per option type)
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const surfaces = getIVSurfaces('blackscholes', 'totalvariance', chain);
19
+ * ```
20
+ */
21
+ export declare function getIVSurfaces(volatilityModel: VolatilityModel, smoothingModel: SmoothingModel, chain: OptionChain): IVSurface[];
22
+ /**
23
+ * Get smoothed IV for a specific expiration, option type, and strike
24
+ *
25
+ * @param ivSurfaces - Array of IV surfaces
26
+ * @param expiration - Expiration timestamp in milliseconds
27
+ * @param optionType - 'call' or 'put'
28
+ * @param strike - Strike price
29
+ * @returns Smoothed IV as a percentage, or 0 if not found
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * const iv = getIVForStrike(surfaces, 1234567890000, 'call', 105);
34
+ * console.log(`IV: ${iv}%`);
35
+ * ```
36
+ */
37
+ export declare function getIVForStrike(ivSurfaces: IVSurface[], expiration: number, optionType: 'call' | 'put', strike: number): number;
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getIVSurfaces = getIVSurfaces;
4
+ exports.getIVForStrike = getIVForStrike;
5
+ const types_1 = require("../types");
6
+ const blackscholes_1 = require("../blackscholes");
7
+ const smoothing_1 = require("./smoothing");
8
+ /**
9
+ * Build IV surfaces for all expirations in an option chain
10
+ *
11
+ * @param volatilityModel - Method to calculate IV
12
+ * - 'blackscholes': Use Black-Scholes IV inversion (implemented) ✅
13
+ * - 'svm': TODO - Support Vector Machine based IV estimation
14
+ * - 'garch': TODO - GARCH model for volatility forecasting
15
+ * @param smoothingModel - Smoothing method to apply
16
+ * - 'totalvariance': Cubic spline + convex hull (implemented) ✅
17
+ * - 'none': No smoothing, use raw IVs ✅
18
+ * - TODO: Future - 'svi', 'ssvi', 'sabr' parametric models
19
+ * @param chain - Option chain with market context (spot, rates, options)
20
+ * @returns Array of IV surfaces (one per expiration per option type)
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const surfaces = getIVSurfaces('blackscholes', 'totalvariance', chain);
25
+ * ```
26
+ */
27
+ function getIVSurfaces(volatilityModel, smoothingModel, chain) {
28
+ const { spot, riskFreeRate, dividendYield, options } = chain;
29
+ const ivSurfaces = [];
30
+ // Get all unique expirations from options
31
+ const expirationsSet = new Set();
32
+ for (const option of options) {
33
+ expirationsSet.add(option.expirationTimestamp);
34
+ }
35
+ const expirations = Array.from(expirationsSet).sort((a, b) => a - b);
36
+ // Loop through all expirations
37
+ for (const expiration of expirations) {
38
+ // Separate CALL and PUT surfaces for this expiration
39
+ const callStrikes = [];
40
+ const callIVs = [];
41
+ const putStrikes = [];
42
+ const putIVs = [];
43
+ // Loop through options to find those that match the expiration
44
+ for (const option of options) {
45
+ if (option.expirationTimestamp !== expiration) {
46
+ continue;
47
+ }
48
+ // Compute IV using selected model
49
+ if (volatilityModel === 'blackscholes') {
50
+ const timeToExpirationInYears = (0, blackscholes_1.getTimeToExpirationInYears)(option.expirationTimestamp);
51
+ const isCall = option.optionType === 'call';
52
+ // Rates are already decimals in OptionChain
53
+ const iv = (0, blackscholes_1.calculateImpliedVolatility)(option.mark, spot, option.strike, riskFreeRate, dividendYield, timeToExpirationInYears, option.optionType);
54
+ if (isCall) {
55
+ callStrikes.push(option.strike);
56
+ callIVs.push(iv);
57
+ }
58
+ else {
59
+ putStrikes.push(option.strike);
60
+ putIVs.push(iv);
61
+ }
62
+ }
63
+ // TODO: Implement 'svm' model
64
+ // else if (volatilityModel === 'svm') {
65
+ // // Support Vector Machine based IV estimation
66
+ // // Could use historical data patterns to predict IV
67
+ // }
68
+ // TODO: Implement 'garch' model
69
+ // else if (volatilityModel === 'garch') {
70
+ // // GARCH model for volatility forecasting
71
+ // // Time series approach for IV prediction
72
+ // }
73
+ }
74
+ // Helper to sort and append surface
75
+ const appendSurface = (strikes, ivs, optionType) => {
76
+ if (strikes.length === 0) {
77
+ return;
78
+ }
79
+ // Sort by strike
80
+ const pairs = strikes.map((strike, i) => ({ strike, iv: ivs[i] }));
81
+ pairs.sort((a, b) => a.strike - b.strike);
82
+ const sortedStrikes = pairs.map((p) => p.strike);
83
+ const rawIVs = pairs.map((p) => p.iv);
84
+ // Default: no smoothing, smoothedIVs = copy of rawIVs
85
+ let smoothedIVs = [...rawIVs];
86
+ // Only smooth if we have enough valid data points (IV > 1.5% floor)
87
+ // Filter out floor values before smoothing to avoid contamination
88
+ if (smoothingModel === 'totalvariance' && expiration > Date.now()) {
89
+ const IV_FLOOR = 1.5; // IVs at or below this are considered unreliable (deep ITM/OTM)
90
+ // Find the range of valid IVs
91
+ const validData = [];
92
+ for (let i = 0; i < rawIVs.length; i++) {
93
+ if (rawIVs[i] > IV_FLOOR) {
94
+ validData.push({
95
+ strike: sortedStrikes[i],
96
+ iv: rawIVs[i],
97
+ index: i,
98
+ });
99
+ }
100
+ }
101
+ // Only smooth if we have at least 5 valid points
102
+ if (validData.length >= 5) {
103
+ const validStrikes = validData.map((d) => d.strike);
104
+ const validIVs = validData.map((d) => d.iv);
105
+ const T = (expiration - Date.now()) / types_1.MILLISECONDS_PER_YEAR;
106
+ const smoothedValidIVs = (0, smoothing_1.smoothTotalVarianceSmile)(validStrikes, validIVs, T);
107
+ // Copy smoothed values back to corresponding indices
108
+ smoothedIVs = [...rawIVs]; // Start with raw IVs
109
+ for (let j = 0; j < validData.length; j++) {
110
+ smoothedIVs[validData[j].index] = smoothedValidIVs[j];
111
+ }
112
+ }
113
+ }
114
+ // TODO: Future smoothing models
115
+ // else if (smoothingModel === 'svi') {
116
+ // // Stochastic Volatility Inspired parametric model
117
+ // }
118
+ // else if (smoothingModel === 'ssvi') {
119
+ // // Surface SVI for multiple expirations
120
+ // }
121
+ const ivSurface = {
122
+ expirationDate: expiration,
123
+ putCall: optionType,
124
+ strikes: sortedStrikes,
125
+ rawIVs,
126
+ smoothedIVs,
127
+ };
128
+ ivSurfaces.push(ivSurface);
129
+ };
130
+ // Append call and put surfaces if present
131
+ appendSurface(callStrikes, callIVs, 'call');
132
+ appendSurface(putStrikes, putIVs, 'put');
133
+ }
134
+ return ivSurfaces;
135
+ }
136
+ /**
137
+ * Get smoothed IV for a specific expiration, option type, and strike
138
+ *
139
+ * @param ivSurfaces - Array of IV surfaces
140
+ * @param expiration - Expiration timestamp in milliseconds
141
+ * @param optionType - 'call' or 'put'
142
+ * @param strike - Strike price
143
+ * @returns Smoothed IV as a percentage, or 0 if not found
144
+ *
145
+ * @example
146
+ * ```typescript
147
+ * const iv = getIVForStrike(surfaces, 1234567890000, 'call', 105);
148
+ * console.log(`IV: ${iv}%`);
149
+ * ```
150
+ */
151
+ function getIVForStrike(ivSurfaces, expiration, optionType, strike) {
152
+ for (const ivSurface of ivSurfaces) {
153
+ if (ivSurface.expirationDate === expiration && ivSurface.putCall === optionType) {
154
+ // Find the strike in the strikes array
155
+ for (let i = 0; i < ivSurface.strikes.length; i++) {
156
+ if (ivSurface.strikes[i] === strike) {
157
+ return ivSurface.smoothedIVs[i];
158
+ }
159
+ }
160
+ }
161
+ }
162
+ return 0.0;
163
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Volatility surface smoothing algorithms
3
+ */
4
+ /**
5
+ * Smooth total variance smile using cubic spline interpolation and convexity enforcement
6
+ *
7
+ * @param strikes - Sorted array of strike prices
8
+ * @param ivs - Array of IVs as percentages (e.g., 20 = 20%)
9
+ * @param T - Time to expiration in years
10
+ * @returns Smoothed IVs as percentages
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const smoothed = smoothTotalVarianceSmile([90, 95, 100, 105, 110], [22, 20, 18, 20, 22], 0.25);
15
+ * ```
16
+ */
17
+ export declare function smoothTotalVarianceSmile(strikes: number[], ivs: number[], T: number): number[];