@tjq/cboe-client
v1.0.0
Published
Typed CBOE delayed quotes API client with Zod validation
Readme
@tjq/cboe-client
Typed CBOE delayed quotes API client with Zod validation. Designed for use in Node 18+, Next.js Server Components, and Edge Runtime.
Installation
npm install @tjq/cboe-client zodZod is a peer dependency — if your project already uses it, you're all set.
Usage
Basic
import { CboeClient } from "@tjq/cboe-client";
const cboe = new CboeClient();
const data = await cboe.options("AAPL");
console.log(data.data.current_price); // 271.94
console.log(data.data.options.length); // 3232Client Options
const cboe = new CboeClient({
timeout: 5_000, // ms (default: 10_000)
retries: 1, // retry count on 5xx/network errors (default: 2)
cache: "force-cache", // passed to fetch() (default: "no-store")
onError: (err) => console.error(err), // optional error hook
});Next.js Server Component
import { CboeClient } from "@tjq/cboe-client";
const cboe = new CboeClient();
export default async function OptionsPage({ params }: { params: { symbol: string } }) {
const data = await cboe.options(params.symbol);
return <pre>{JSON.stringify(data.data.current_price)}</pre>;
}Transform Utilities
import {
parseOptionSymbol,
groupByExpiration,
splitCallsPuts,
buildChain,
filterByExpiration,
nearestStrikes,
} from "@tjq/cboe-client";
const data = await new CboeClient().options("AAPL");
const options = data.data.options;
// Parse OCC symbol
parseOptionSymbol("AAPL260209C00175000");
// => { root: "AAPL", expiration: "2026-02-09", type: "C", strike: 175 }
// Group by expiration date
const byExp = groupByExpiration(options); // Map<string, CboeOption[]>
// Split into calls and puts
const { calls, puts } = splitCallsPuts(options);
// Build a nested chain: expiration -> strike -> { call?, put? }
const chain = buildChain(options);
// Filter to a single expiration
const feb = filterByExpiration(options, "2026-02-14");
// Get 10 nearest strikes to current price
const nearest = nearestStrikes(options, data.data.current_price, 10);Error Handling
import {
CboeClient,
CboeNotFoundError,
CboeValidationError,
CboeNetworkError,
CboeRateLimitError,
} from "@tjq/cboe-client";
const cboe = new CboeClient();
try {
await cboe.options("INVALID");
} catch (err) {
if (err instanceof CboeNotFoundError) {
// 404 — symbol not found
} else if (err instanceof CboeValidationError) {
// API response shape changed — check err.zodIssues
} else if (err instanceof CboeNetworkError) {
// Timeout or connection failure
} else if (err instanceof CboeRateLimitError) {
// 429
}
}Using Schemas Directly
import { OptionSchema, QuoteSchema, CboeOptionsResponseSchema } from "@tjq/cboe-client";
import type { CboeOption, CboeQuote, CboeOptionsResponse } from "@tjq/cboe-client";
// Validate arbitrary data against the schema
const result = OptionSchema.safeParse(unknownData);
if (result.success) {
const option: CboeOption = result.data;
}Development
npm install
npm run build # tsup — outputs CJS + ESM to dist/
npm test # vitest