← Back to documentation

API Reference

Complete documentation for all floe functions and types.

Pricing Functions

blackScholes

Calculates the theoretical price of a European option using the Black-Scholes-Merton model.

import { blackScholes } from "@fullstackcraftllc/floe";

const price = blackScholes({
  spot: 100,           // Current price of underlying
  strike: 105,         // Option strike price
  timeToExpiry: 0.25,  // Time to expiration in years
  riskFreeRate: 0.05,  // Annual risk-free interest rate
  volatility: 0.20,    // Annualized volatility (as decimal)
  optionType: "call",  // "call" or "put"
  dividendYield: 0.02  // Optional: continuous dividend yield (as decimal)
});

Implied Volatility

calculateImpliedVolatility

Uses the Black-Scholes model with iterative bisection to compute the implied volatility given an option price.

import { calculateImpliedVolatility } from "@fullstackcraftllc/floe";

const iv = calculateImpliedVolatility(
  3.50,      // price: observed option price
  100,       // spot: current underlying price
  105,       // strike: option strike price
  0.05,      // riskFreeRate: annual risk-free rate (as decimal)
  0.02,      // dividendYield: continuous dividend yield (as decimal)
  0.25,      // timeToExpiry: time to expiration in years
  "call"     // optionType: "call" or "put"
);

console.log(`Implied Volatility: ${iv.toFixed(2)}%`);
// Note: Returns IV as a percentage (e.g., 20.0 for 20% volatility)

Greeks

calculateGreeks

Calculate all Greeks up to third order for European call and put options. Returns a complete Greeks object containing the option price and all sensitivity measures.

import { calculateGreeks } from "@fullstackcraftllc/floe";

const greeks = calculateGreeks({
  spot: 100,
  strike: 105,
  timeToExpiry: 0.25,
  riskFreeRate: 0.05,
  volatility: 0.20,
  optionType: "call",      // "call" or "put"
  dividendYield: 0.02      // optional
});

// Access individual Greeks from the returned object:
console.log(`Price: ${greeks.price}`);
console.log(`Delta: ${greeks.delta}`);
console.log(`Gamma: ${greeks.gamma}`);
console.log(`Theta: ${greeks.theta}`);   // per day
console.log(`Vega: ${greeks.vega}`);     // per 1% volatility change
console.log(`Rho: ${greeks.rho}`);       // per 1% rate change

Greeks Interface

The calculateGreeks function returns a Greeks object with all sensitivity measures:

interface Greeks {
  price: number;   // Option theoretical value
  delta: number;   // Rate of change of option price with respect to underlying
  gamma: number;   // Rate of change of delta with respect to underlying
  theta: number;   // Time decay (per day)
  vega: number;    // Sensitivity to volatility (per 1% change)
  rho: number;     // Sensitivity to interest rate (per 1% change)
  vanna: number;   // Sensitivity of delta to volatility
  charm: number;   // Delta decay (per day)
  volga: number;   // Sensitivity of vega to volatility (also known as vomma)
  speed: number;   // Rate of change of gamma
  zomma: number;   // Sensitivity of gamma to volatility
  color: number;   // Gamma decay
  ultima: number;  // Sensitivity of volga to volatility
}

Time Utilities

getTimeToExpirationInYears

Convert an expiration timestamp to time in years:

import { getTimeToExpirationInYears } from "@fullstackcraftllc/floe";

const expirationTimestamp = Date.now() + 30 * 24 * 60 * 60 * 1000; // 30 days from now
const timeToExpiry = getTimeToExpirationInYears(expirationTimestamp);
// Returns: ~0.0822 (30/365)

getMillisecondsToExpiration

Get milliseconds until expiration:

import { getMillisecondsToExpiration } from "@fullstackcraftllc/floe";

const ms = getMillisecondsToExpiration(expirationTimestamp);

Statistical Utilities

cumulativeNormalDistribution

Standard normal cumulative distribution function (CDF):

import { cumulativeNormalDistribution } from "@fullstackcraftllc/floe";

const prob = cumulativeNormalDistribution(1.96);
// Returns: ~0.975 (97.5% probability)

normalPDF

Standard normal probability density function:

import { normalPDF } from "@fullstackcraftllc/floe";

const density = normalPDF(0);
// Returns: ~0.3989 (peak of the normal curve)

IV Surfaces

getIVSurfaces

Generate implied volatility surfaces for all options across all expirations. Used as input for dealer exposure calculations.

import { getIVSurfaces, OptionChain } from "@fullstackcraftllc/floe";

const chain: OptionChain = {
  symbol: 'SPY',
  spot: 450.50,
  riskFreeRate: 0.05,
  dividendYield: 0.02,
  options: normalizedOptions
};

const surfaces = getIVSurfaces('blackscholes', 'totalvariance', chain);
// Returns array of IVSurface objects with rawIVs and smoothedIVs

getIVForStrike

Lookup a specific IV from the surface:

import { getIVForStrike } from "@fullstackcraftllc/floe";

const iv = getIVForStrike(surfaces, expirationTimestamp, 'call', 105);
// Returns smoothed IV as percentage (e.g., 23.0 for 23%)

smoothTotalVarianceSmile

Apply total variance smoothing to a volatility smile:

import { smoothTotalVarianceSmile } from "@fullstackcraftllc/floe";

const smoothedIVs = smoothTotalVarianceSmile(
  [90, 95, 100, 105, 110],  // strikes
  [22, 20, 18, 20, 22],      // raw IVs as percentages
  0.25                        // time to expiry in years
);

Dealer Exposures

calculateGammaVannaCharmExposures

Calculate aggregate dealer exposures across an option chain:

import { 
  calculateGammaVannaCharmExposures, 
  getIVSurfaces 
} from "@fullstackcraftllc/floe";

const ivSurfaces = getIVSurfaces('blackscholes', 'totalvariance', chain);
const exposures = calculateGammaVannaCharmExposures(chain, ivSurfaces);

for (const expiry of exposures) {
  console.log(`Expiration: ${new Date(expiry.expiration).toDateString()}`);
  console.log(`  Total Gamma: ${expiry.totalGammaExposure}`);
  console.log(`  Total Vanna: ${expiry.totalVannaExposure}`);
  console.log(`  Total Charm: ${expiry.totalCharmExposure}`);
}

calculateSharesNeededToCover

Calculate dealer hedging requirements:

import { calculateSharesNeededToCover } from "@fullstackcraftllc/floe";

const coverage = calculateSharesNeededToCover(
  900_000_000,   // shares outstanding
  -5_000_000,    // net exposure
  450.50         // spot price
);

console.log(`Action: ${coverage.actionToCover}`);
console.log(`Shares: ${coverage.sharesToCover}`);
console.log(`Implied Move: ${coverage.impliedMoveToCover}%`);

Implied PDF

estimateImpliedProbabilityDistribution

Estimate implied probability distribution for a single expiration:

import { estimateImpliedProbabilityDistribution } from "@fullstackcraftllc/floe";

const result = estimateImpliedProbabilityDistribution("QQQ", 502.50, callOptions);

if (result.success) {
  const dist = result.distribution;
  console.log(`Mode: ${dist.mostLikelyPrice}`);
  console.log(`Expected Move: ${dist.expectedMove}`);
}

estimateImpliedProbabilityDistributions

Process all expirations at once:

import { estimateImpliedProbabilityDistributions } from "@fullstackcraftllc/floe";

const distributions = estimateImpliedProbabilityDistributions("QQQ", 502.50, options);

getProbabilityInRange

Get probability of finishing in a price range:

import { getProbabilityInRange } from "@fullstackcraftllc/floe";

const prob = getProbabilityInRange(distribution, 495, 510);
// Returns probability (e.g., 0.65 for 65%)

getCumulativeProbability

Get cumulative probability up to a price:

import { getCumulativeProbability } from "@fullstackcraftllc/floe";

const prob = getCumulativeProbability(distribution, 500);

getQuantile

Get strike at a probability quantile:

import { getQuantile } from "@fullstackcraftllc/floe";

const p10 = getQuantile(distribution, 0.10);  // 10th percentile
const p90 = getQuantile(distribution, 0.90);  // 90th percentile

OCC Symbol Utilities

buildOCCSymbol

Build an OCC-formatted option symbol:

import { buildOCCSymbol } from "@fullstackcraftllc/floe";

const symbol = buildOCCSymbol({
  symbol: 'AAPL',
  expiration: '2025-01-17',
  optionType: 'call',
  strike: 150,
  padded: false  // optional, default false
});
// Returns: 'AAPL250117C00150000'

parseOCCSymbol

Parse an OCC symbol into components:

import { parseOCCSymbol } from "@fullstackcraftllc/floe";

const parsed = parseOCCSymbol('AAPL250117C00150000');
// Returns: { symbol: 'AAPL', expiration: Date, optionType: 'call', strike: 150 }

generateStrikesAroundSpot

Generate strike prices around a spot price:

import { generateStrikesAroundSpot } from "@fullstackcraftllc/floe";

const strikes = generateStrikesAroundSpot({
  spot: 450,
  strikesAbove: 10,
  strikesBelow: 10,
  strikeIncrementInDollars: 5
});
// Returns: [400, 405, 410, ..., 495, 500]

generateOCCSymbolsForStrikes

Generate OCC symbols for specific strikes:

import { generateOCCSymbolsForStrikes } from "@fullstackcraftllc/floe";

const symbols = generateOCCSymbolsForStrikes(
  'SPY',
  '2025-12-20',
  [440, 445, 450, 455, 460],
  ['call', 'put']  // optional, default both
);

generateOCCSymbolsAroundSpot

Convenience function combining strike generation and OCC symbol creation:

import { generateOCCSymbolsAroundSpot } from "@fullstackcraftllc/floe";

const symbols = generateOCCSymbolsAroundSpot('SPY', '2025-12-20', 600, {
  strikesAbove: 10,
  strikesBelow: 10,
  strikeIncrementInDollars: 1
});

Broker Adapters

createOptionChain

Create an option chain from raw broker data:

import { createOptionChain } from "@fullstackcraftllc/floe";

const chain = createOptionChain(
  'SPY',           // symbol
  450.50,          // spot
  0.05,            // riskFreeRate
  0.02,            // dividendYield
  rawBrokerData,   // raw options from broker
  'schwab'         // broker name for adapter selection
);

getAdapter

Get a specific broker adapter:

import { getAdapter } from "@fullstackcraftllc/floe";

const adapter = getAdapter('schwab');
const normalizedOption = adapter(rawOptionData);

Available Adapters

import { 
  genericAdapter,
  schwabAdapter,
  ibkrAdapter,
  tdaAdapter,
  brokerAdapters 
} from "@fullstackcraftllc/floe";

// brokerAdapters is a map: { generic, schwab, ibkr, tda }

Real-Time Market Data (FloeClient)

Supported Brokers

Broker Enum Value Authentication
Tradier Broker.TRADIER API Token
TastyTrade Broker.TASTYTRADE Session Token
TradeStation Broker.TRADESTATION OAuth Token
Charles Schwab Broker.SCHWAB OAuth Token

Basic Usage

import { FloeClient, Broker } from "@fullstackcraftllc/floe";

const client = new FloeClient({ verbose: false });
await client.connect(Broker.TRADIER, 'your-api-token');

client.on('optionUpdate', (option) => {
  console.log(`${option.occSymbol}: ${option.bid} / ${option.ask}`);
});

client.on('tickerUpdate', (ticker) => {
  console.log(`${ticker.symbol}: ${ticker.spot}`);
});

client.subscribeToOptions(['SPY251220C00600000']);
client.subscribeToTickers(['SPY']);
await client.fetchOpenInterest();

client.disconnect();

Direct Broker Client Access

import { TradierClient, TastyTradeClient, TradeStationClient } from "@fullstackcraftllc/floe";

// Use broker clients directly for advanced scenarios
const tradier = new TradierClient(token, { verbose: true });

Core Types

OptionType

type OptionType = 'call' | 'put';

BlackScholesParams

interface BlackScholesParams {
  spot: number;
  strike: number;
  timeToExpiry: number;
  volatility: number;
  riskFreeRate: number;
  optionType: OptionType;
  dividendYield?: number;
}

NormalizedOption

interface NormalizedOption {
  occSymbol: string;
  underlying: string;
  strike: number;
  expiration: string;
  expirationTimestamp: number;
  optionType: OptionType;
  bid: number;
  bidSize: number;
  ask: number;
  askSize: number;
  mark: number;
  last: number;
  volume: number;
  openInterest: number;
  liveOpenInterest?: number;
  impliedVolatility: number;
  timestamp: number;
}

NormalizedTicker

interface NormalizedTicker {
  symbol: string;
  spot: number;
  bid: number;
  bidSize: number;
  ask: number;
  askSize: number;
  last: number;
  volume: number;
  timestamp: number;
}

OptionChain

interface OptionChain {
  symbol: string;
  spot: number;
  riskFreeRate: number;
  dividendYield: number;
  options: NormalizedOption[];
}

IVSurface

interface IVSurface {
  expirationDate: number;
  putCall: OptionType;
  strikes: number[];
  rawIVs: number[];
  smoothedIVs: number[];
}

ExposurePerExpiry

interface ExposurePerExpiry {
  spotPrice: number;
  expiration: number;
  totalGammaExposure: number;
  totalVannaExposure: number;
  totalCharmExposure: number;
  totalNetExposure: number;
  strikeOfMaxGamma: number;
  strikeOfMinGamma: number;
  strikeOfMaxVanna: number;
  strikeOfMinVanna: number;
  strikeOfMaxCharm: number;
  strikeOfMinCharm: number;
  strikeOfMaxNet: number;
  strikeOfMinNet: number;
  strikeExposures: StrikeExposure[];
}

ImpliedProbabilityDistribution

interface ImpliedProbabilityDistribution {
  symbol: string;
  expiryDate: number;
  calculationTimestamp: number;
  underlyingPrice: number;
  strikeProbabilities: StrikeProbability[];
  mostLikelyPrice: number;
  medianPrice: number;
  expectedValue: number;
  expectedMove: number;
  tailSkew: number;
  cumulativeProbabilityAboveSpot: number;
  cumulativeProbabilityBelowSpot: number;
}