@fullstackcraftllc/floe 0.0.1 → 0.0.2

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,202 @@
1
+ "use strict";
2
+ /**
3
+ * OCC (Options Clearing Corporation) symbol utilities
4
+ *
5
+ * OCC symbols follow the format: ROOT + YYMMDD + C/P + STRIKE
6
+ * Example: AAPL230120C00150000 = AAPL $150 Call expiring Jan 20, 2023
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.buildOCCSymbol = buildOCCSymbol;
10
+ exports.parseOCCSymbol = parseOCCSymbol;
11
+ exports.generateStrikesAroundSpot = generateStrikesAroundSpot;
12
+ exports.generateOCCSymbolsForStrikes = generateOCCSymbolsForStrikes;
13
+ exports.generateOCCSymbolsAroundSpot = generateOCCSymbolsAroundSpot;
14
+ /**
15
+ * Builds an OCC-formatted option symbol.
16
+ *
17
+ * @param params - The option parameters
18
+ * @returns OCC-formatted symbol string
19
+ *
20
+ * @remarks
21
+ * OCC format: ROOT(6 chars, left-padded) + YYMMDD + C/P + STRIKE(8 digits, price × 1000)
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const symbol = buildOCCSymbol({
26
+ * symbol: 'AAPL',
27
+ * expiration: new Date('2023-01-20'),
28
+ * optionType: 'call',
29
+ * strike: 150
30
+ * });
31
+ * // Returns: 'AAPL230120C00150000' (compact format, default)
32
+ *
33
+ * // With padded format (standard OCC)
34
+ * const symbol2 = buildOCCSymbol({
35
+ * symbol: 'QQQ',
36
+ * expiration: '2024-03-15',
37
+ * optionType: 'put',
38
+ * strike: 425.50,
39
+ * padded: true
40
+ * });
41
+ * // Returns: 'QQQ 240315P00425500'
42
+ * ```
43
+ */
44
+ function buildOCCSymbol(params) {
45
+ const { symbol, expiration, optionType, strike, padded = false } = params;
46
+ // Format symbol - either padded to 6 chars or compact
47
+ const formattedSymbol = padded
48
+ ? symbol.toUpperCase().padEnd(6, ' ')
49
+ : symbol.toUpperCase();
50
+ // Format expiration date as YYMMDD
51
+ const expirationDate = typeof expiration === 'string' ? new Date(expiration) : expiration;
52
+ const year = expirationDate.getFullYear().toString().slice(-2);
53
+ const month = (expirationDate.getMonth() + 1).toString().padStart(2, '0');
54
+ const day = expirationDate.getDate().toString().padStart(2, '0');
55
+ const dateString = `${year}${month}${day}`;
56
+ // Option type indicator
57
+ const typeIndicator = optionType === 'call' ? 'C' : 'P';
58
+ // Strike price: multiply by 1000, pad to 8 digits
59
+ const strikeInt = Math.round(strike * 1000);
60
+ const strikeString = strikeInt.toString().padStart(8, '0');
61
+ return `${formattedSymbol}${dateString}${typeIndicator}${strikeString}`;
62
+ }
63
+ /**
64
+ * Parses an OCC-formatted option symbol into its components.
65
+ * Supports both compact format (e.g., 'AAPL230120C00150000') and
66
+ * padded format (e.g., 'AAPL 230120C00150000').
67
+ *
68
+ * @param occSymbol - The OCC symbol to parse
69
+ * @returns Parsed symbol components
70
+ * @throws {Error} If the symbol format is invalid
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * // Compact format
75
+ * const parsed = parseOCCSymbol('AAPL230120C00150000');
76
+ * // Returns: { symbol: 'AAPL', expiration: Date, optionType: 'call', strike: 150 }
77
+ *
78
+ * // Padded format (21 chars)
79
+ * const parsed2 = parseOCCSymbol('AAPL 230120C00150000');
80
+ * // Returns: { symbol: 'AAPL', expiration: Date, optionType: 'call', strike: 150 }
81
+ * ```
82
+ */
83
+ function parseOCCSymbol(occSymbol) {
84
+ // Find the option type indicator (C or P) which is always followed by 8 strike digits
85
+ // This works for both compact and padded formats
86
+ const typeMatch = occSymbol.match(/([CP])(\d{8})$/);
87
+ if (!typeMatch) {
88
+ throw new Error(`Invalid OCC symbol format: ${occSymbol}`);
89
+ }
90
+ const typeIndicator = typeMatch[1];
91
+ const strikeString = typeMatch[2];
92
+ // Everything before the type indicator should be: SYMBOL + YYMMDD
93
+ const prefix = occSymbol.slice(0, -9); // Remove C/P + 8 digits
94
+ // Last 6 characters of prefix are the date (YYMMDD)
95
+ if (prefix.length < 6) {
96
+ throw new Error(`Invalid OCC symbol format: ${occSymbol}`);
97
+ }
98
+ const dateString = prefix.slice(-6);
99
+ const symbol = prefix.slice(0, -6).trim();
100
+ if (symbol.length === 0) {
101
+ throw new Error(`Invalid OCC symbol: no ticker found in ${occSymbol}`);
102
+ }
103
+ // Parse date
104
+ const year = 2000 + parseInt(dateString.slice(0, 2), 10);
105
+ const month = parseInt(dateString.slice(2, 4), 10) - 1; // 0-indexed
106
+ const day = parseInt(dateString.slice(4, 6), 10);
107
+ const expiration = new Date(year, month, day);
108
+ // Validate date
109
+ if (isNaN(expiration.getTime())) {
110
+ throw new Error(`Invalid date in OCC symbol: ${dateString}`);
111
+ }
112
+ // Parse option type
113
+ const optionType = typeIndicator === 'C' ? 'call' : 'put';
114
+ // Parse strike (divide by 1000)
115
+ const strike = parseInt(strikeString, 10) / 1000;
116
+ return { symbol, expiration, optionType, strike };
117
+ }
118
+ /**
119
+ * Generates an array of strike prices centered around a spot price.
120
+ *
121
+ * @param params - Strike generation parameters
122
+ * @returns Array of strike prices, sorted ascending
123
+ *
124
+ * @example
125
+ * ```typescript
126
+ * const strikes = generateStrikesAroundSpot({
127
+ * spot: 450.25,
128
+ * strikesAbove: 10,
129
+ * strikesBelow: 10,
130
+ * strikeIncrement: 5
131
+ * });
132
+ * // Returns: [405, 410, 415, 420, 425, 430, 435, 440, 445, 450, 455, 460, 465, 470, 475, 480, 485, 490, 495, 500]
133
+ * ```
134
+ */
135
+ function generateStrikesAroundSpot(params) {
136
+ const { spot, strikesAbove = 10, strikesBelow = 10, strikeIncrement = 1 } = params;
137
+ // Find the nearest strike at or below spot
138
+ const baseStrike = Math.floor(spot / strikeIncrement) * strikeIncrement;
139
+ const strikes = [];
140
+ // Generate strikes below (including base)
141
+ for (let i = strikesBelow; i >= 0; i--) {
142
+ strikes.push(baseStrike - i * strikeIncrement);
143
+ }
144
+ // Generate strikes above
145
+ for (let i = 1; i <= strikesAbove; i++) {
146
+ strikes.push(baseStrike + i * strikeIncrement);
147
+ }
148
+ return strikes;
149
+ }
150
+ /**
151
+ * Generates OCC symbols for calls and puts across multiple strikes.
152
+ *
153
+ * @param symbol - Underlying ticker symbol
154
+ * @param expiration - Option expiration date
155
+ * @param strikes - Array of strike prices
156
+ * @param includeTypes - Which option types to include (default: both)
157
+ * @returns Array of OCC symbol strings
158
+ *
159
+ * @example
160
+ * ```typescript
161
+ * const symbols = generateOCCSymbolsForStrikes(
162
+ * 'QQQ',
163
+ * new Date('2024-01-19'),
164
+ * [495, 500, 505],
165
+ * ['call', 'put']
166
+ * );
167
+ * // Returns 6 symbols: 3 calls + 3 puts
168
+ * ```
169
+ */
170
+ function generateOCCSymbolsForStrikes(symbol, expiration, strikes, includeTypes = ['call', 'put']) {
171
+ const symbols = [];
172
+ for (const strike of strikes) {
173
+ for (const optionType of includeTypes) {
174
+ symbols.push(buildOCCSymbol({ symbol, expiration, optionType, strike }));
175
+ }
176
+ }
177
+ return symbols;
178
+ }
179
+ /**
180
+ * Convenience function to generate OCC symbols around current spot price.
181
+ *
182
+ * @param symbol - Underlying ticker symbol
183
+ * @param expiration - Option expiration date
184
+ * @param spot - Current spot price
185
+ * @param options - Strike generation options
186
+ * @returns Array of OCC symbol strings for calls and puts
187
+ *
188
+ * @example
189
+ * ```typescript
190
+ * // Generate 20 calls + 20 puts around QQQ at $502.50
191
+ * const symbols = generateOCCSymbolsAroundSpot('QQQ', '2024-01-19', 502.50, {
192
+ * strikesAbove: 10,
193
+ * strikesBelow: 10,
194
+ * strikeIncrement: 5
195
+ * });
196
+ * // Returns 42 symbols (21 strikes × 2 types)
197
+ * ```
198
+ */
199
+ function generateOCCSymbolsAroundSpot(symbol, expiration, spot, options) {
200
+ const strikes = generateStrikesAroundSpot({ spot, ...options });
201
+ return generateOCCSymbolsForStrikes(symbol, expiration, strikes);
202
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fullstackcraftllc/floe",
3
- "version": "0.0.1",
4
- "description": "Production-ready options analytics toolkit. Normalize broker data structures and calculate Black-Scholes, Greeks, and GEX with a clean, type-safe API. Built for trading platforms and fintech applications.",
3
+ "version": "0.0.2",
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",
7
7
  "scripts": {
@@ -43,7 +43,7 @@
43
43
  "@types/node": "^20.0.0",
44
44
  "jest": "^29.5.0",
45
45
  "ts-jest": "^29.1.0",
46
- "typescript": "^5.0.0"
46
+ "typescript": "^5.9.3"
47
47
  },
48
48
  "files": [
49
49
  "dist",