Files
market_screener/server/domains/shared/config/constants.ts
T
saikiranvella 662a717916 UI enhancemnts
2026-06-09 19:34:31 -04:00

99 lines
3.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<string, number> = {
[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 515%
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];