@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,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deriveRegimeParams = deriveRegimeParams;
4
+ exports.interpolateIVAtStrike = interpolateIVAtStrike;
5
+ /**
6
+ * Derive regime parameters from the IV surface
7
+ */
8
+ function deriveRegimeParams(ivSurface, spot) {
9
+ const { strikes, smoothedIVs } = ivSurface;
10
+ const atmIV = interpolateIVAtStrike(strikes, smoothedIVs, spot) / 100;
11
+ const skew = calculateSkewAtSpot(strikes, smoothedIVs, spot);
12
+ const impliedSpotVolCorr = skewToCorrelation(skew);
13
+ const curvature = calculateCurvatureAtSpot(strikes, smoothedIVs, spot);
14
+ const impliedVolOfVol = curvatureToVolOfVol(curvature, atmIV);
15
+ const regime = ivToRegime(atmIV);
16
+ const expectedDailySpotMove = atmIV / Math.sqrt(252);
17
+ const expectedDailyVolMove = impliedVolOfVol / Math.sqrt(252);
18
+ return {
19
+ atmIV,
20
+ impliedSpotVolCorr,
21
+ impliedVolOfVol,
22
+ regime,
23
+ expectedDailySpotMove,
24
+ expectedDailyVolMove,
25
+ };
26
+ }
27
+ function skewToCorrelation(skew) {
28
+ const SKEW_TO_CORR_SCALE = 0.15;
29
+ return Math.max(-0.95, Math.min(0.5, skew * SKEW_TO_CORR_SCALE));
30
+ }
31
+ function curvatureToVolOfVol(curvature, atmIV) {
32
+ const VOL_OF_VOL_SCALE = 2.0;
33
+ return Math.sqrt(Math.abs(curvature)) * VOL_OF_VOL_SCALE * atmIV;
34
+ }
35
+ function ivToRegime(atmIV) {
36
+ if (atmIV < 0.15)
37
+ return 'calm';
38
+ if (atmIV < 0.20)
39
+ return 'normal';
40
+ if (atmIV < 0.35)
41
+ return 'stressed';
42
+ return 'crisis';
43
+ }
44
+ function interpolateIVAtStrike(strikes, ivs, targetStrike) {
45
+ if (strikes.length === 0 || ivs.length === 0)
46
+ return 20;
47
+ if (strikes.length === 1)
48
+ return ivs[0];
49
+ let lower = 0;
50
+ let upper = strikes.length - 1;
51
+ for (let i = 0; i < strikes.length - 1; i++) {
52
+ if (strikes[i] <= targetStrike && strikes[i + 1] >= targetStrike) {
53
+ lower = i;
54
+ upper = i + 1;
55
+ break;
56
+ }
57
+ }
58
+ if (targetStrike <= strikes[0])
59
+ return ivs[0];
60
+ if (targetStrike >= strikes[strikes.length - 1])
61
+ return ivs[ivs.length - 1];
62
+ const t = (targetStrike - strikes[lower]) / (strikes[upper] - strikes[lower]);
63
+ return ivs[lower] + t * (ivs[upper] - ivs[lower]);
64
+ }
65
+ function calculateSkewAtSpot(strikes, ivs, spot) {
66
+ if (strikes.length < 2)
67
+ return 0;
68
+ let lowerIdx = 0;
69
+ let upperIdx = strikes.length - 1;
70
+ for (let i = 0; i < strikes.length - 1; i++) {
71
+ if (strikes[i] <= spot && strikes[i + 1] >= spot) {
72
+ lowerIdx = i;
73
+ upperIdx = i + 1;
74
+ break;
75
+ }
76
+ }
77
+ const dIV = ivs[upperIdx] - ivs[lowerIdx];
78
+ const dK = strikes[upperIdx] - strikes[lowerIdx];
79
+ return dK > 0 ? (dIV / dK) * spot : 0;
80
+ }
81
+ function calculateCurvatureAtSpot(strikes, ivs, spot) {
82
+ if (strikes.length < 3)
83
+ return 0;
84
+ let centerIdx = 0;
85
+ for (let i = 0; i < strikes.length; i++) {
86
+ if (Math.abs(strikes[i] - spot) < Math.abs(strikes[centerIdx] - spot)) {
87
+ centerIdx = i;
88
+ }
89
+ }
90
+ if (centerIdx === 0 || centerIdx === strikes.length - 1)
91
+ return 0;
92
+ const h = (strikes[centerIdx + 1] - strikes[centerIdx - 1]) / 2;
93
+ if (h <= 0)
94
+ return 0;
95
+ const ivMinus = ivs[centerIdx - 1];
96
+ const iv = ivs[centerIdx];
97
+ const ivPlus = ivs[centerIdx + 1];
98
+ return ((ivPlus - 2 * iv + ivMinus) / (h * h)) * spot * spot;
99
+ }
@@ -0,0 +1,182 @@
1
+ import { IVSurface, ExposurePerExpiry } from '../types';
2
+ /**
3
+ * Regime classification based on IV level and surface characteristics
4
+ */
5
+ export type MarketRegime = 'calm' | 'normal' | 'stressed' | 'crisis';
6
+ /**
7
+ * Parameters derived from the IV surface itself (no external data needed)
8
+ */
9
+ export interface RegimeParams {
10
+ /** ATM implied volatility (as decimal, e.g., 0.18 for 18%) */
11
+ atmIV: number;
12
+ /** Implied spot-vol correlation derived from skew */
13
+ impliedSpotVolCorr: number;
14
+ /** Implied vol-of-vol derived from smile curvature */
15
+ impliedVolOfVol: number;
16
+ /** Regime classification */
17
+ regime: MarketRegime;
18
+ /** Expected daily spot move (as decimal) */
19
+ expectedDailySpotMove: number;
20
+ /** Expected daily vol move (as decimal) */
21
+ expectedDailyVolMove: number;
22
+ }
23
+ /**
24
+ * Normalized exposure at a single strike
25
+ */
26
+ export interface NormalizedExposure {
27
+ strike: number;
28
+ rawGamma: number;
29
+ rawVanna: number;
30
+ rawCharm: number;
31
+ effectiveGamma: number;
32
+ effectiveVanna: number;
33
+ effectiveCharm: number;
34
+ totalEffective: number;
35
+ dominant: 'gamma' | 'vanna' | 'charm';
36
+ }
37
+ /**
38
+ * Aggregate normalized exposure metrics
39
+ */
40
+ export interface NormalizedExposureSummary {
41
+ spot: number;
42
+ expiration: number;
43
+ regimeParams: RegimeParams;
44
+ strikeExposures: NormalizedExposure[];
45
+ totalEffectiveGamma: number;
46
+ totalEffectiveVanna: number;
47
+ totalEffectiveCharm: number;
48
+ totalEffective: number;
49
+ dominantGreek: 'gamma' | 'vanna' | 'charm';
50
+ weights: {
51
+ gamma: number;
52
+ vanna: number;
53
+ charm: number;
54
+ };
55
+ }
56
+ /**
57
+ * Hedging pressure at a (spot, time) coordinate
58
+ */
59
+ export interface HedgingPressure {
60
+ spot: number;
61
+ timeToExpiry: number;
62
+ hoursRemaining: number;
63
+ gammaFlow: number;
64
+ vannaFlow: number;
65
+ charmFlow: number;
66
+ netPressure: number;
67
+ effectivePressure: number;
68
+ direction: 'supportive' | 'resistive' | 'neutral';
69
+ }
70
+ /**
71
+ * Grid cell for pressure visualization
72
+ */
73
+ export interface PressureGridCell {
74
+ spot: number;
75
+ hoursRemaining: number;
76
+ pressure: HedgingPressure;
77
+ spotGradient: number;
78
+ timeGradient: number;
79
+ }
80
+ /**
81
+ * Key levels derived from pressure field
82
+ */
83
+ export interface KeyLevels {
84
+ support: number[];
85
+ resistance: number[];
86
+ pinning: number[];
87
+ gammaFlip: number | null;
88
+ }
89
+ /**
90
+ * Path of least resistance analysis
91
+ */
92
+ export interface PathOfLeastResistance {
93
+ direction: 'up' | 'down' | 'pin';
94
+ targetSpot: number;
95
+ confidence: number;
96
+ rationale: string;
97
+ }
98
+ /**
99
+ * Complete pressure grid
100
+ */
101
+ export interface PressureGrid {
102
+ symbol: string;
103
+ expiration: number;
104
+ currentSpot: number;
105
+ timestamp: number;
106
+ regime: MarketRegime;
107
+ spotRange: {
108
+ min: number;
109
+ max: number;
110
+ step: number;
111
+ };
112
+ timeRange: {
113
+ min: number;
114
+ max: number;
115
+ step: number;
116
+ };
117
+ cells: PressureGridCell[][];
118
+ keyLevels: KeyLevels;
119
+ pathOfLeastResistance: PathOfLeastResistance;
120
+ }
121
+ /**
122
+ * IV pressure at a specific strike
123
+ */
124
+ export interface StrikeIVPressure {
125
+ strike: number;
126
+ currentIV: number;
127
+ vannaIVPressure: number;
128
+ vommaIVPressure: number;
129
+ vetaIVPressure: number;
130
+ netIVPressure: number;
131
+ liquidityScore: number;
132
+ expectedIVMove: number;
133
+ }
134
+ /**
135
+ * IV surface evolution prediction
136
+ */
137
+ export interface IVSurfaceEvolution {
138
+ currentSurface: IVSurface;
139
+ predictedSurface: IVSurface;
140
+ strikePressures: StrikeIVPressure[];
141
+ netSurfacePressure: number;
142
+ atmIVMove: number;
143
+ skewChange: number;
144
+ curvatureChange: number;
145
+ confidence: number;
146
+ }
147
+ /**
148
+ * Cascade simulation step
149
+ */
150
+ export interface CascadeStep {
151
+ step: number;
152
+ spot: number;
153
+ ivSurface: IVSurface;
154
+ exposures: ExposurePerExpiry;
155
+ regime: MarketRegime;
156
+ ivPressure: number;
157
+ spotPressure: number;
158
+ cumulativeIVMove: number;
159
+ cumulativeSpotMove: number;
160
+ }
161
+ /**
162
+ * Full cascade simulation result
163
+ */
164
+ export interface CascadeSimulation {
165
+ initial: CascadeStep;
166
+ steps: CascadeStep[];
167
+ terminal: CascadeStep;
168
+ outcome: 'converged' | 'diverged' | 'oscillating';
169
+ insight: string;
170
+ }
171
+ /**
172
+ * Configuration for IV path prediction
173
+ */
174
+ export interface IVPathConfig {
175
+ spotMoveScenario: number;
176
+ timeStepHours: number;
177
+ cascadeIterations: number;
178
+ cascadeDampening: number;
179
+ ivImpactPerMillion: number;
180
+ ivFloor: number;
181
+ ivCeiling: number;
182
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -9,8 +9,9 @@ exports.getUnderlyingFromOptionRoot = exports.OPTION_ROOT_TO_UNDERLYING = void 0
9
9
  exports.OPTION_ROOT_TO_UNDERLYING = {
10
10
  'SPXW': 'SPX', // SPX Weekly options
11
11
  'SPXPM': 'SPX', // SPX PM-settled options
12
- 'NDXP': 'NDX', // NDX PM-settled options
12
+ 'NDXP': 'NDX', // NDXP is Tradier's NDX options root
13
13
  'RUTW': 'RUT', // RUT Weekly options
14
+ 'DJXW': 'DJX', // DJX Weekly options
14
15
  // Add more as needed
15
16
  };
16
17
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fullstackcraftllc/floe",
3
- "version": "0.0.13",
3
+ "version": "0.0.14",
4
4
  "description": "Production-ready options analytics toolkit. Normalize broker data structures and calculate Black-Scholes, Greeks, and exposures with a clean, type-safe API. Built for trading platforms and fintech applications.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",