const Date = @import("date.zig").Date; pub const ContractType = enum { call, put, }; /// A single options contract in a chain. pub const OptionContract = struct { /// Full OCC symbol (e.g., "O:AAPL211022C000150000") contract_symbol: ?[]const u8 = null, contract_type: ContractType, strike: f64, expiration: Date, bid: ?f64 = null, ask: ?f64 = null, last_price: ?f64 = null, volume: ?u64 = null, open_interest: ?u64 = null, implied_volatility: ?f64 = null, // Greeks delta: ?f64 = null, gamma: ?f64 = null, theta: ?f64 = null, vega: ?f64 = null, }; /// Full options chain for an underlying asset at a given expiration. pub const OptionsChain = struct { underlying_symbol: []const u8, underlying_price: ?f64 = null, expiration: Date, calls: []const OptionContract, puts: []const OptionContract, /// Free any owned fields on this chain. Mirrors the pattern in /// `Dividend.deinit` — callers who own a single chain can release /// it directly; callers with a slice use `freeSlice` below. pub fn deinit(self: OptionsChain, allocator: std.mem.Allocator) void { allocator.free(self.underlying_symbol); allocator.free(self.calls); allocator.free(self.puts); } /// Free a slice of chains, calling `deinit` on each element first. pub fn freeSlice(allocator: std.mem.Allocator, chains: []const OptionsChain) void { for (chains) |c| c.deinit(allocator); allocator.free(chains); } }; const std = @import("std");