UNPKG

@sudowealth/schwab-api

Version:

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

205 lines (204 loc) 8.18 kB
import { z } from 'zod'; import { BaseInstrumentSchema } from '../../schemas/base-instrument.schema.js'; import { mergeShapes } from '../../utils/schema-utils.js'; // Enum for projection parameter export const InstrumentProjectionEnum = z.enum([ 'symbol-search', 'symbol-regex', 'desc-search', 'desc-regex', 'search', 'fundamental', ]); // Enum for AssetType specifically used in market-data/instruments export const InstrumentAssetTypeEnum = z.enum([ 'BOND', 'EQUITY', 'ETF', 'EXTENDED', 'FOREX', 'FUTURE', 'FUTURE_OPTION', 'FUNDAMENTAL', 'INDEX', 'INDICATOR', 'MUTUAL_FUND', 'OPTION', 'UNKNOWN', ]); // Market-data specific InstrumentInfo Schema that extends the base schema const InstrumentInfoSchema = BaseInstrumentSchema.pick({ symbol: true, description: true, cusip: true, exchange: true, }).extend({ assetType: InstrumentAssetTypeEnum, }); // Schema for Fundamental Data const FundamentalDataSchema = z.object({ symbol: z.string(), high52: z.number().optional(), low52: z.number().optional(), dividendAmount: z.number().optional(), dividendYield: z.number().optional(), dividendDate: z.string().optional(), peRatio: z.number().optional(), pegRatio: z.number().optional(), pbRatio: z.number().optional(), pcRatio: z.number().optional(), prRatio: z.number().optional(), marketCap: z.number().optional(), mark: z.number().optional(), netChange: z.number().optional(), volatility: z.number().optional(), beta: z.number().optional(), bidPrice: z.number().optional(), askPrice: z.number().optional(), lastPrice: z.number().optional(), openPrice: z.number().optional(), closePrice: z.number().optional(), netPercentChangeInDouble: z.number().optional(), netChangeInDouble: z.number().optional(), bidSize: z.number().int().optional(), askSize: z.number().int().optional(), highPrice: z.number().optional(), lowPrice: z.number().optional(), lastSize: z.number().int().optional(), quoteTimeInLong: z.number().int().optional(), tradeTimeInLong: z.number().int().optional(), lastTradeTime: z.string().datetime({ offset: true }).optional(), grossMarginTTM: z.number().optional(), grossMarginMRQ: z.number().optional(), netProfitMarginTTM: z.number().optional(), netProfitMarginMRQ: z.number().optional(), operatingMarginTTM: z.number().optional(), operatingMarginMRQ: z.number().optional(), revenuePerShareTTM: z.number().optional(), revenueTTM: z.number().optional(), roa: z.number().optional(), roe: z.number().optional(), roi: z.number().optional(), epsTTM: z.number().optional(), epsChangePercentTTM: z.number().optional(), epsChangeYear: z.number().optional(), epsChangePercentYear: z.number().optional(), revChangeYear: z.number().optional(), revChangeTTM: z.number().optional(), revChangeIn: z.number().optional(), sharesOutstanding: z.number().optional(), marketCapFloat: z.number().optional(), bookValuePerShare: z.number().optional(), shortIntToFloat: z.number().optional(), shortIntDayToCover: z.number().optional(), dividendPayAmount: z.number().optional(), dividendGrowthRate3Year: z.number().optional(), dividendPayDate: z.string().optional(), betaText: z.string().optional(), avg10DaysVolume: z.number().int().optional(), avg1DayVolume: z.number().int().optional(), avg3MonthVolume: z.number().int().optional(), avg1YearVolume: z.number().int().optional(), vol1DayAvg: z.number().int().optional(), vol10DayAvg: z.number().int().optional(), vol3MonthAvg: z.number().int().optional(), week52HighDate: z.string().optional(), week52LowDate: z.string().optional(), divYield: z.number().optional(), divAmount: z.number().optional(), divFreq: z.number().int().optional(), divExDate: z.string().optional(), corpActionDate: z.string().optional(), lastTradingDay: z.string().optional(), nextEarningDate: z.string().optional(), nextDividendPayDate: z.string().optional(), nextDividendDate: z.string().optional(), lastDividendDate: z.string().optional(), fundStrategy: z.string().optional(), fundFamily: z.string().optional(), fundLeverage: z.string().optional(), fundType: z.string().optional(), }); // Specific Instrument Types const FundamentalInstrumentSchema = InstrumentInfoSchema.extend({ assetType: z.literal(InstrumentAssetTypeEnum.Enum.FUNDAMENTAL), fundamental: FundamentalDataSchema, }); const BondInstrumentSchema = InstrumentInfoSchema.extend({ assetType: z.literal(InstrumentAssetTypeEnum.Enum.BOND), bondFactor: z.string().optional(), bondMultiplier: z.string().optional(), bondPrice: z.number().optional(), }); const EquityInstrumentSchema = InstrumentInfoSchema.extend({ assetType: z.literal(InstrumentAssetTypeEnum.Enum.EQUITY), }); const ETFInstrumentSchema = InstrumentInfoSchema.extend({ assetType: z.literal(InstrumentAssetTypeEnum.Enum.ETF), }); const ForexInstrumentSchema = InstrumentInfoSchema.extend({ assetType: z.literal(InstrumentAssetTypeEnum.Enum.FOREX), }); const FutureInstrumentSchema = InstrumentInfoSchema.extend({ assetType: z.literal(InstrumentAssetTypeEnum.Enum.FUTURE), }); const FutureOptionInstrumentSchema = InstrumentInfoSchema.extend({ assetType: z.literal(InstrumentAssetTypeEnum.Enum.FUTURE_OPTION), }); const IndexInstrumentSchema = InstrumentInfoSchema.extend({ assetType: z.literal(InstrumentAssetTypeEnum.Enum.INDEX), }); const IndicatorInstrumentSchema = InstrumentInfoSchema.extend({ assetType: z.literal(InstrumentAssetTypeEnum.Enum.INDICATOR), }); const MutualFundInstrumentSchema = InstrumentInfoSchema.extend({ assetType: z.literal(InstrumentAssetTypeEnum.Enum.MUTUAL_FUND), }); const OptionInstrumentSchema = InstrumentInfoSchema.extend({ assetType: z.literal(InstrumentAssetTypeEnum.Enum.OPTION), }); const UnknownInstrumentSchema = InstrumentInfoSchema.extend({ assetType: z.literal(InstrumentAssetTypeEnum.Enum.UNKNOWN), }); const ExtendedInstrumentSchema = InstrumentInfoSchema.extend({ assetType: z.literal(InstrumentAssetTypeEnum.Enum.EXTENDED), }); // Discriminated Union for any Instrument type const InstrumentSchema = z.discriminatedUnion('assetType', [ FundamentalInstrumentSchema, BondInstrumentSchema, EquityInstrumentSchema, ETFInstrumentSchema, ForexInstrumentSchema, FutureInstrumentSchema, FutureOptionInstrumentSchema, IndexInstrumentSchema, IndicatorInstrumentSchema, MutualFundInstrumentSchema, OptionInstrumentSchema, UnknownInstrumentSchema, ExtendedInstrumentSchema, ]); // Path Parameters Schema for GET /instruments (no path params) export const GetInstrumentsPathParams = z.object({}); // Query Parameters Schema for GET /instruments export const GetInstrumentsQueryParams = z.object({ symbol: z.string().describe('Symbol of a security'), projection: InstrumentProjectionEnum.describe(`Search by: ${InstrumentProjectionEnum.options.join(', ')}`), }); // Request Params Schema for GET /instruments (merged path + query params) export const GetInstrumentsParams = z.object(mergeShapes(GetInstrumentsQueryParams.shape, GetInstrumentsPathParams.shape)); // Response Schema for /instruments export const GetInstrumentsResponse = z.object({ instruments: z.array(InstrumentSchema), }); // Path Parameters Schema for GET /instruments/{cusip_id} export const GetInstrumentByCusipPathParams = z.object({ cusip_id: z.string().describe('CUSIP of a security'), }); // Query Parameters Schema for GET /instruments/{cusip_id} (no query params) export const GetInstrumentByCusipQueryParams = z.object({}); // Request Params Schema for GET /instruments/{cusip_id} (merged path + query params) export const GetInstrumentByCusipParams = z.object(mergeShapes(GetInstrumentByCusipQueryParams.shape, GetInstrumentByCusipPathParams.shape)); // Response Body Schema for /instruments/{cusip_id} export const GetInstrumentByCusipResponse = GetInstrumentsResponse;