"use strict";
/**
 * Options module for retrieving options chain data including calls, puts, and Greeks.
 *
 * This module provides comprehensive options data for stocks, including all available
 * expiration dates, strike prices, implied volatility, open interest, and other
 * essential options trading information.
 *
 * @example Basic Options Chain
 * ```typescript
 * import YahooFinance from "yahoo-finance2";
 * const yahooFinance = new YahooFinance();
 *
 * // Get complete options chain for Apple
 * const optionsData = await yahooFinance.options('AAPL');
 *
 * console.log('Available expirations:', optionsData.expirationDates);
 * console.log('Available strikes:', optionsData.strikes);
 * console.log('Underlying quote:', optionsData.quote.regularMarketPrice);
 *
 * // Access the first expiration's calls and puts
 * const firstExpiration = optionsData.options[0];
 * console.log(`Expiration: ${firstExpiration.expirationDate}`);
 * console.log(`Number of calls: ${firstExpiration.calls.length}`);
 * console.log(`Number of puts: ${firstExpiration.puts.length}`);
 * ```
 *
 * @example Specific Expiration Date
 * ```typescript
 * // Get options for a specific expiration date
 * const specificExpiration = await yahooFinance.options('TSLA', {
 *   date: new Date('2024-03-15')
 * });
 *
 * // Find in-the-money calls
 * const currentPrice = specificExpiration.quote.regularMarketPrice;
 * const itmCalls = specificExpiration.options[0].calls.filter(call =>
 *   call.strike < currentPrice && call.inTheMoney
 * );
 *
 * console.log(`Current stock price: $${currentPrice}`);
 * console.log(`In-the-money calls: ${itmCalls.length}`);
 * ```
 *
 * @example Options Analysis and Screening
 * ```typescript
 * const optionsData = await yahooFinance.options('NVDA');
 * const currentPrice = optionsData.quote.regularMarketPrice;
 *
 * // Analyze all expirations
 * optionsData.options.forEach(expiration => {
 *   console.log(`\nExpiration: ${expiration.expirationDate}`);
 *
 *   // Find at-the-money options
 *   const atmCalls = expiration.calls.filter(call =>
 *     Math.abs(call.strike - currentPrice) < 5
 *   );
 *
 *   const atmPuts = expiration.puts.filter(put =>
 *     Math.abs(put.strike - currentPrice) < 5
 *   );
 *
 *   if (atmCalls.length > 0) {
 *     const atmCall = atmCalls[0];
 *     console.log(`ATM Call: Strike $${atmCall.strike}, IV: ${(atmCall.impliedVolatility * 100).toFixed(2)}%`);
 *   }
 *
 *   if (atmPuts.length > 0) {
 *     const atmPut = atmPuts[0];
 *     console.log(`ATM Put: Strike $${atmPut.strike}, IV: ${(atmPut.impliedVolatility * 100).toFixed(2)}%`);
 *   }
 * });
 * ```
 *
 * @example High Volume and Open Interest Analysis
 * ```typescript
 * const optionsData = await yahooFinance.options('SPY');
 *
 * // Find most active options across all expirations
 * let mostActiveOptions = [];
 *
 * optionsData.options.forEach(expiration => {
 *   const allOptions = [...expiration.calls, ...expiration.puts];
 *   mostActiveOptions.push(...allOptions);
 * });
 *
 * // Sort by volume
 * mostActiveOptions.sort((a, b) => (b.volume || 0) - (a.volume || 0));
 *
 * console.log('Most Active Options:');
 * mostActiveOptions.slice(0, 10).forEach((option, index) => {
 *   const type = option.contractSymbol.includes('C') ? 'CALL' : 'PUT';
 *   console.log(`${index + 1}. ${type} Strike $${option.strike} - Volume: ${option.volume}`);
 * });
 *
 * // Find highest open interest
 * mostActiveOptions.sort((a, b) => (b.openInterest || 0) - (a.openInterest || 0));
 * console.log('\nHighest Open Interest:');
 * mostActiveOptions.slice(0, 5).forEach(option => {
 *   console.log(`Strike $${option.strike} - OI: ${option.openInterest}`);
 * });
 * ```
 *
 * @remarks
 * **Data Refresh**: Options data is updated throughout the trading day.
 * Prices, volumes, and implied volatilities change constantly during market hours.
 *
 * **Expiration Processing**: All expiration dates are provided, but you can
 * filter to specific dates using the `date` parameter.
 *
 * **Mini Options**: Some stocks have mini options (10 shares instead of 100).
 * Check the `hasMiniOptions` flag and individual contract `contractSize`.
 *
 * **Liquidity**: Options with low volume or wide bid-ask spreads may be
 * difficult to trade. Always check volume and open interest.
 *
 * **Greeks**: Basic Greeks like implied volatility are provided. For advanced
 * Greeks (delta, gamma, theta, vega), you may need to calculate them separately.
 *
 * **Currency**: All option prices are in the underlying stock's currency.
 *
 * @see {@link quote} for current stock price and basic data
 *
 * @module options
 */
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = options;
const index_js_1 = require("../lib/validate/index.js");
// @yf-schema: see the docs on how this file is automatically updated.
const options_schema_js_1 = __importDefault(require("./options.schema.js"));
const definitions = (0, index_js_1.getTypedDefinitions)(options_schema_js_1.default);
const queryOptionsDefaults = {
    formatted: false,
    lang: "en-US",
    region: "US",
};
function options(symbol, queryOptionsOverrides, moduleOptions) {
    return this._moduleExec({
        moduleName: "options",
        query: {
            assertSymbol: symbol,
            url: "https://${YF_QUERY_HOST}/v7/finance/options/" + symbol,
            needsCrumb: true,
            definitions,
            schemaKey: "#/definitions/OptionsOptions",
            defaults: queryOptionsDefaults,
            overrides: queryOptionsOverrides,
            transformWith(queryOptions) {
                const date = queryOptions.date;
                if (date) {
                    // yfDate will convert valid number/string to Date.
                    if (date instanceof Date) {
                        // now we convert back to unix epoch in seconds for query
                        queryOptions.date = Math.floor(date.getTime() / 1000);
                    }
                    else {
                        // yfDate didn't recognize it as a date.
                        throw new Error("Unsupported date type: " + date);
                    }
                }
                return queryOptions;
            },
        },
        result: {
            definitions,
            schemaKey: "#/definitions/OptionsResult",
            // deno-lint-ignore no-explicit-any
            transformWith(result) {
                if (!result.optionChain) {
                    throw new Error("Unexpected result: " + JSON.stringify(result));
                }
                return result.optionChain.result[0];
            },
        },
        moduleOptions,
    });
}
