import type { Signal, AssetType, RateRegime } from '../types'; export const SIGNAL = { STRONG_BUY: '✅ Strong Buy' as Signal, MOMENTUM: '⚡ Momentum' as Signal, SPECULATION: '⚠️ Speculation' as Signal, NEUTRAL: '🔄 Neutral' as Signal, AVOID: '❌ Avoid' as Signal, }; export const ASSET_TYPE = { STOCK: 'STOCK' as AssetType, ETF: 'ETF' as AssetType, BOND: 'BOND' as AssetType, CRYPTO: 'crypto', }; // ── Why some constants use `as const` and others don't ──────────────────── // // SIGNAL / ASSET_TYPE / REGIME — each member is individually cast to its // named type (e.g. `'✅ Strong Buy' as Signal`). TypeScript already knows // the exact literal type of each value, so `as const` on the object would // be redundant. // // SECTOR / SCORE_MODE / CAP_CATEGORY / GROWTH_CATEGORY — these use // `as const` because their public type aliases are *derived* from the // object itself via `(typeof X)[keyof typeof X]`. Without `as const`, // TypeScript widens every value to `string`, and the derived union // collapses to `string` instead of `'TECHNOLOGY' | 'REIT' | ...`. // ────────────────────────────────────────────────────────────────────────── export const SECTOR = { TECHNOLOGY: 'TECHNOLOGY', REIT: 'REIT', FINANCIAL: 'FINANCIAL', ENERGY: 'ENERGY', HEALTHCARE: 'HEALTHCARE', COMMUNICATION: 'COMMUNICATION', CONSUMER_STAPLES: 'CONSUMER_STAPLES', CONSUMER_DISCRETIONARY: 'CONSUMER_DISCRETIONARY', GENERAL: 'GENERAL', } as const; export type Sector = (typeof SECTOR)[keyof typeof SECTOR]; export const SCORE_MODE = { FUNDAMENTAL: 'FUNDAMENTAL', INFLATED: 'INFLATED', } as const; export const REGIME = { LOW: 'LOW' as RateRegime, NORMAL: 'NORMAL' as RateRegime, HIGH: 'HIGH' as RateRegime, }; export const YAHOO_MODULES: string[] = [ 'assetProfile', 'financialData', 'defaultKeyStatistics', 'price', 'summaryDetail', 'fundProfile', // categoryName drives ETF vs bond-fund classification in DataMapper ]; export const SIGNAL_ORDER: Record = { [SIGNAL.STRONG_BUY]: 0, [SIGNAL.MOMENTUM]: 1, [SIGNAL.NEUTRAL]: 2, [SIGNAL.SPECULATION]: 3, [SIGNAL.AVOID]: 4, }; // ── Market capitalisation tiers ─────────────────────────────────────────── // Thresholds follow institutional convention (MSCI/Russell definitions). export const CAP_CATEGORY = { MEGA: 'Mega Cap', // > $200B LARGE: 'Large Cap', // $10B – $200B MID: 'Mid Cap', // $2B – $10B SMALL: 'Small Cap', // $300M – $2B MICRO: 'Micro Cap', // < $300M } as const; export type CapCategory = (typeof CAP_CATEGORY)[keyof typeof CAP_CATEGORY]; // ── Growth / style classification ───────────────────────────────────────── // Derived from revenue growth, earnings growth, and dividend yield. // Used for display and to contextualise signals within each cap tier. export const GROWTH_CATEGORY = { HIGH_GROWTH: 'High Growth', // rev >15% or earnings >20% MODERATE_GROWTH: 'Growth', // rev 5–15% STABLE: 'Stable', // low growth, modest or no dividend VALUE: 'Value', // low growth + dividend yield ≥ 3% TURNAROUND: 'Turnaround', // negative earnings, positive revenue DECLINING: 'Declining', // negative revenue growth } as const; export type GrowthCategory = (typeof GROWTH_CATEGORY)[keyof typeof GROWTH_CATEGORY];