UNPKG

@railpath/finance-toolkit

Version:

Production-ready finance library for portfolio construction, risk analytics, quantitative metrics, and ML-based regime detection

80 lines (79 loc) 3.12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.VolatilityOptionsSchema = void 0; const zod_1 = require("zod"); /** * Zod schema for volatility calculation options */ exports.VolatilityOptionsSchema = zod_1.z.object({ method: zod_1.z.enum(['standard', 'exponential', 'parkinson', 'garman-klass']), annualizationFactor: zod_1.z.number().positive().optional(), lambda: zod_1.z.number().min(0).max(1).optional(), highPrices: zod_1.z.array(zod_1.z.number().positive()).optional(), lowPrices: zod_1.z.array(zod_1.z.number().positive()).optional(), openPrices: zod_1.z.array(zod_1.z.number().positive()).optional(), closePrices: zod_1.z.array(zod_1.z.number().positive()).optional(), }).superRefine((data, ctx) => { // EWMA-specific validation if (data.method === 'exponential' && data.lambda === undefined) { ctx.addIssue({ code: zod_1.z.ZodIssueCode.custom, message: 'Lambda is required for exponential method', path: ['lambda'], }); } // Parkinson-specific validation if (data.method === 'parkinson') { if (!data.highPrices) { ctx.addIssue({ code: zod_1.z.ZodIssueCode.custom, message: 'High prices required for Parkinson method', path: ['highPrices'], }); } if (!data.lowPrices) { ctx.addIssue({ code: zod_1.z.ZodIssueCode.custom, message: 'Low prices required for Parkinson method', path: ['lowPrices'], }); } if (data.highPrices && data.lowPrices && data.highPrices.length !== data.lowPrices.length) { ctx.addIssue({ code: zod_1.z.ZodIssueCode.custom, message: 'High and low prices must have equal length', path: ['highPrices'], }); } } // Garman-Klass-specific validation if (data.method === 'garman-klass') { const requiredFields = ['openPrices', 'highPrices', 'lowPrices', 'closePrices']; const missing = requiredFields.filter(field => !data[field]); if (missing.length > 0) { missing.forEach(field => { ctx.addIssue({ code: zod_1.z.ZodIssueCode.custom, message: `${field} required for Garman-Klass method`, path: [field], }); }); } // Length validation if (data.openPrices && data.highPrices && data.lowPrices && data.closePrices) { const lengths = [ data.openPrices.length, data.highPrices.length, data.lowPrices.length, data.closePrices.length, ]; if (new Set(lengths).size > 1) { ctx.addIssue({ code: zod_1.z.ZodIssueCode.custom, message: 'All OHLC arrays must have equal length', path: ['openPrices'], }); } } } });