UNPKG

@sudowealth/schwab-api

Version:

TypeScript client for Charles Schwab API with OAuth support, market data, trading functionality, and complete type safety

78 lines (77 loc) 4.29 kB
import { z } from 'zod'; import { dateStringSchema } from '../../utils/date-utils'; import { mergeShapes } from '../../utils/schema-utils'; import { InstrumentAssetTypeEnum } from '../shared'; // Enum for the 'markets' query parameter export const MarketHoursMarketQueryEnum = z.enum([ 'equity', 'option', 'bond', 'future', 'forex', ]); // Schema for ISO 8601 datetime string (YYYY-MM-DDTHH:mm:ss±HH:mm) const timeStringSchema = z .string() // Accept ISO 8601 datetime format from the API .regex(/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:Z|[+-]\d{2}:\d{2})$/, 'Time must be in ISO 8601 format'); // Schema for session interval (start and end times) const SessionIntervalSchema = z.object({ start: timeStringSchema.describe('Session start time in ISO 8601 format (YYYY-MM-DDTHH:mm:ss±HH:mm)'), end: timeStringSchema.describe('Session end time in ISO 8601 format (YYYY-MM-DDTHH:mm:ss±HH:mm)'), }); // Schema for sessionHours (e.g., { regularMarket: [{start, end}] }) const MarketSessionHoursSchema = z.record(z.string(), // Session name (e.g., "preMarket", "regularMarket", "postMarket") z.array(SessionIntervalSchema)); // Schema for the data of a single market in the response export const MarketHoursDataSchema = z.object({ date: dateStringSchema .optional() .describe('Date for the market hours (Date object)'), // Optional as per example where it might be part of equity.date marketType: InstrumentAssetTypeEnum.describe('Type of market'), exchange: z.string().optional().describe('Exchange name'), category: z.string().optional().describe('Category of the market'), product: z.string().optional().describe('Product name'), productName: z.string().optional().describe('Display name for the product'), isOpen: z.boolean().describe('Indicates if the market is currently open'), sessionHours: MarketSessionHoursSchema.optional().describe('Market session hours'), }); // --- GET /markets endpoint schemas --- // Path Parameters Schema for GET /markets (no path params) export const GetMarketHoursPathParams = z.object({}); // Query Parameters Schema for GET /markets export const GetMarketHoursQueryParams = z.object({ markets: z .union([MarketHoursMarketQueryEnum, z.array(MarketHoursMarketQueryEnum)]) .transform((val) => (Array.isArray(val) ? val : [val])) .describe(`List of markets. Available values: ${MarketHoursMarketQueryEnum.options.join(', ')}`), date: dateStringSchema .optional() .describe('Date for market hours. Defaults to current day.'), }); // Request Params Schema for GET /markets (merged path + query params) export const GetMarketHoursParams = z.object(mergeShapes(GetMarketHoursQueryParams.shape, GetMarketHoursPathParams.shape)); // Schema for Response Body of GET /markets // The response is a nested structure with market type as the top level key, // then product code as second level, containing the market hours data export const GetMarketHoursResponse = z.record(MarketHoursMarketQueryEnum, // Top level key (e.g., "equity") z.record(z.string(), // Second level key (e.g., "EQ") - product code MarketHoursDataSchema)); // Path Parameters Schema for GET /markets/{market_id} export const GetMarketHoursByMarketIdPathParams = z.object({ market_id: MarketHoursMarketQueryEnum.describe('Market ID (equity, option, etc.)'), }); // Query Parameters Schema for GET /markets/{market_id} export const GetMarketHoursByMarketIdQueryParams = z.object({ date: dateStringSchema .optional() .describe('Date for market hours. Defaults to current day.'), }); // Response Body Schema for GET /markets/{market_id} // This endpoint returns a nested structure with market type as the top level key, // then product code as second level, containing the market hours data export const GetMarketHoursByMarketIdResponse = z.record(MarketHoursMarketQueryEnum, // Top level key (e.g., "equity") z.record(z.string(), // Second level key (e.g., "EQ") - product code MarketHoursDataSchema)); // Request Params Schema for GET /markets/{market_id} (merged path + query params) export const GetMarketHoursByMarketIdParams = z.object(mergeShapes(GetMarketHoursByMarketIdQueryParams.shape, GetMarketHoursByMarketIdPathParams.shape));