JCN Financial Wiki
Complete reference for the JCN Financial Investment Dashboard — architecture, metrics, data, and methodology.
Overview
What is JCN Financial?
JCN Financial is a production-grade investment dashboard that provides real-time portfolio tracking, deep fundamental stock analysis, and institutional-quality data infrastructure. Built for serious investors who need survivorship-bias-free data, point-in-time accuracy, and comprehensive fundamental screening across the top 1,500 US equities by market capitalization.
The platform manages three distinct investment portfolios (Persistent Value, Olivia Growth, Pure Alpha), each with unique strategies, and offers a full Stock Analysis screener with 10 analytical modules covering price performance, per-share data, quality metrics, financial statements, growth rates, valuation, and composite quality scoring.
Technology Stack
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | Next.js 14, React 18, Tailwind CSS | SSR, routing, responsive UI |
| Charts | ECharts 6.0, Recharts | Interactive charts, radar, line graphs |
| UI Kit | Tremor v3, Radix UI | Dashboard components, accessible primitives |
| Backend | FastAPI (Python) | Serverless API on Vercel |
| Database | MotherDuck (DuckDB cloud) | Analytical warehouse — prices, fundamentals, scores |
| Data | EODHD API | EOD prices, fundamentals, bulk downloads |
| Hosting | Vercel Pro | Serverless deploy, 300s function timeout |
| Caching | SWR, localStorage, /tmp | Multi-layer: browser → serverless → DB |
Architecture
The application follows a serverless architecture deployed on Vercel. The Next.js frontend communicates with Python FastAPI serverless functions via /api/* routes. All market data lives in MotherDuck (cloud DuckDB), organized into production tables under thePROD_EODHD database.
Browser (React)
└─ Next.js SSR / Client
└─ /api/* routes (Vercel Serverless)
└─ FastAPI (Python)
├─ Cache: /tmp (Vercel ephemeral)
└─ MotherDuck (DuckDB Cloud)
├─ PROD_EODHD (production)
└─ DEV_EODHD_DATA (staging)Dashboard Pages
Dashboard (Heatmap + Charts)
The main dashboard page features a full-width TradingView stock market heatmap showing real-time sector and stock performance with color-coded daily percentage changes. Above the heatmap, three equally spaced TradingView Advanced Chart widgets display daily candle charts for SPY (S&P 500), QQQ (Nasdaq 100), and ACWI (All Country World Index) — providing instant macro context. Charts use white backgrounds with volume bars hidden for a clean presentation.
Persistent Value Portfolio
A 21-holding portfolio focused on high-quality, durable compounders with strong competitive moats, consistent free cash flow generation, and long-term capital appreciation. Holdings include ASML, COST, AVGO, MA, FICO, SPGI, V, AAPL, NFLX, and others. Uses SPMO as the benchmark ETF.
Features: real-time performance table with YTD/1Y/3Y/5Y returns, market-cap-weighted allocation pie chart, SPY benchmark comparison with alpha calculation, historical price charts, JCN 5-factor score grid, and quality radar charts. All data loads from MotherDuck with 4-layer cache.
Olivia Growth Portfolio
A 20-holding growth-oriented portfolio emphasizing high-momentum technology and infrastructure names. Holdings include GOOG, AMZN, META, NVDA, AMD, CRWD, PLTR, SHOP, and others. Uses QGRW as the benchmark ETF. Identical architecture to Persistent Value.
Pure Alpha Portfolio
A concentrated 10-holding high-conviction portfolio designed for maximum alpha generation. Holdings: GEV, GOOG, NVDA, TSLA, PWR, AXON, LRCX, MELI, MU, NFLX. Benchmarked directly against SPY.
Stock Analysis Screener
Deep single-stock fundamental analysis page with 10 analytical modules. Limited to the top 1,500 US stocks by current market capitalization. Features smart search with autocomplete, recent search history pills (localStorage, max 10), and animated progress bar.
Default symbol: NVDA (loaded automatically). All modules always visible. Data fetched in a single API call and cached 30 minutes in both browser and server.
| # | Module | Description |
|---|---|---|
| 1 | Stock Info Header | Company name, sector, P/E, Forward P/E, Div Yield, Beta, ROE, Analyst Target |
| 2 | Price vs SPY | 5-year chart indexed to 100. Stock (blue) vs SPY (gray) |
| 3 | Per Share Data | 14 metrics over 10+ years: Revenue/Share, EPS, FCF/Share, Book Value, Yields |
| 4 | Quality Metrics | 17 ratios: Margins, Returns, Leverage, Efficiency |
| 5 | Income Statement | Hierarchical P&L with expandable parent-child rows |
| 6 | Balance Sheet | Assets, Liabilities, Equity with 3-level hierarchy |
| 7 | Cash Flows | Operating, Investing, Financing sub-items. Free Cash Flow. |
| 8 | Growth Rates | YoY growth, 12 metrics, heatmap coloring |
| 9 | Valuation Ratios | 9 valuation metrics + analyst consensus bar |
| 10 | JCN Scores | 6-dimension composite scoring (0-100) with radar chart |
Stock Screener
A FinViz-style stock screener that filters the ~3,000 stock investable universe using preset dropdown filters — no manual value input required. Organized into 7 filter tabs: Descriptive (market cap, sector), JCN Scores (5 factor composites + 8 blend composites), Valuation (P/E, PEG, P/B, P/S, EV/EBITDA, dividend yield), Growth (revenue and earnings growth), Profitability (margins, ROE, ROA), Momentum (daily/YTD/YoY changes, beta, and all AF/FIP/System momentum sub-components), and Fundamentals (debt/equity, current ratio, interest coverage).
Results display in a TanStack Table v8 with full sorting on any column, a column picker to show/hide fields, and CSV export. Right-clicking any cell opens a context menu with three options: Analysis (opens the stock in Stock Analysis in a new tab), Add to Watchlist (saves to localStorage), and Grok (placeholder for future AI analysis). Filter and table state are persisted in sessionStorage so navigating away and back preserves the screener exactly as the user left it.
The screener API (POST /api/screener) uses a dynamic SQL query builder with a whitelisted field map to prevent SQL injection. It JOINs across 8 MotherDuck tables using inline subqueries (not CTEs, which fail on MotherDuck). Results are cached in /tmp with a 5-minute TTL. The API is 100% read-only and never writes to any production table.
Watchlist
A personal watchlist page where users can track stocks of interest. Symbols can be added manually via a ticker input field or from the Screener context menu. The watchlist is stored in localStorage (no database writes required) and syncs across components via a custom watchlist-change event.
The watchlist table displays enriched data fetched from the screener API: company name, sector, market cap, price, daily/YTD/YoY percentage changes, and five JCN factor scores (Value, Quality, Growth, Momentum, JCN Full Composite). Users can sort by any column, remove individual symbols, clear all with a confirmation dialog, export to CSV, or open any symbol in Stock Analysis via a new-tab link. An empty state guides new users to add symbols from the input field or the Screener page.
Data Sync Pipeline
A 4-stage automated data pipeline that ingests daily EOD prices from EODHD, validates data quality, promotes to production, and rebuilds composite scores. Each stage is idempotent and safe to re-run. See the Sync Pipeline section for details.
Portfolio Metrics
Performance Table
Each portfolio page displays a performance table showing every holding with current price, daily change, and period returns. Prices come from EODHD real-time API (15-min delayed) or MotherDuck historical data.
| Metric | Formula | Description |
|---|---|---|
| Current Price | EODHD real-time or latest adjusted_close | Most recent price, 15-min delayed max |
| Daily Change % | (close_today - close_yesterday) / close_yesterday * 100 | Percentage move from prior close |
| YTD Return | (price_now - price_jan1) / price_jan1 * 100 | Year-to-date total return |
| 1Y Return | (price_now - price_1yr_ago) / price_1yr_ago * 100 | Trailing 12-month return |
| 3Y Return | (price_now - price_3yr_ago) / price_3yr_ago * 100 | Trailing 3-year cumulative return |
| 5Y Return | (price_now - price_5yr_ago) / price_5yr_ago * 100 | Trailing 5-year cumulative return |
Allocation
Portfolio allocation is displayed as a pie chart, categorized by market cap tier: Mega Cap (above $200B), Large Cap ($10B-$200B), Mid Cap ($2B-$10B), Small Cap (below $2B), and ETF. Allocation weights are equal-weight by default.
Benchmarks and Alpha
Each portfolio is benchmarked against SPY (S&P 500 ETF) and a portfolio-specific ETF. Alpha is calculated as the excess return of the portfolio over SPY for each time period.
Alpha Calculation
Alpha = Portfolio Return - SPY Return
Calculated for YTD, 1Y, 3Y, and 5Y periods. Positive alpha indicates outperformance.
JCN Factor Scores
Each stock in a portfolio receives five composite factor scores (0-100), computed monthly from fundamental data and stored in dedicated score tables in MotherDuck. These scores power the radar charts and fundamentals grid on each portfolio page.
| Score | DB Column | Methodology |
|---|---|---|
| Value Score | value_score_composite | Ranks stocks by valuation attractiveness. Combines P/E, P/B, P/S, EV/EBITDA, and FCF yield relative to sector peers. Lower valuations score higher. |
| Quality Score | quality_score_composite | Measures business quality via gross margin stability, ROE consistency, earnings quality (accruals), and balance sheet strength. |
| Growth Score | growth_score_composite | Evaluates revenue growth, earnings growth, and forward estimates. Combines trailing 3Y CAGR with analyst consensus forward growth. |
| Financial Strength | finstr_score_composite | Assesses balance sheet health: current ratio, debt-to-equity, interest coverage, Altman Z-score components, and cash flow adequacy. |
| Momentum Score | momentum_score_composite | Price momentum signal based on 12-1 month return (skip most recent month). Captures intermediate-term trend persistence. |
Score Normalization
score = round((clamped_value - low) / (high - low) * 100)
Each raw metric is clamped to [low, high] bounds, then linearly scaled to 0-100. A score of 50 indicates median performance.
Stock Analysis Metrics
Every metric displayed in the Stock Analysis screener is computed server-side from PROD_EOD_Fundamentals quarterly data, aggregated into annual figures. P&L and Cash Flow items are summed across quarters; Balance Sheet items use the latest quarter in each calendar year.
Per Share Data (Module 3)
Annual per-share metrics calculated by dividing aggregate financials by shares outstanding. Shares use bs_commonStockSharesOutstanding (quarterly historical), falling back to shares_outstanding (snapshot) if unavailable.
| Metric | Formula | Description |
|---|---|---|
| Revenue/Share | is_totalRevenue / shares | Total annual revenue divided by shares outstanding |
| EPS | is_netIncome / shares | Earnings per share — net income allocated to each share |
| FCF/Share | cf_freeCashFlow / shares | Free cash flow per share — cash available after capex |
| EBITDA/Share | is_ebitda / shares | Earnings before interest, taxes, depreciation, amortization per share |
| Book Value/Share | bs_totalStockholderEquity / shares | Net asset value per share (equity / shares) |
| Operating CF/Share | cf_totalCashFromOperatingActivities / shares | Cash from operations per share |
| Dividend/Share | -cf_dividendsPaid / shares | Annual dividend paid per share (dividends are negative in cash flow) |
| Buyback Yield | -cf_salePurchaseOfStock / market_cap | Share repurchases as a percentage of market cap |
| Dividend Yield | -cf_dividendsPaid / market_cap | Annual dividends as a percentage of market cap |
| Total Return Yield | (-dividends + -buybacks) / market_cap | Combined shareholder yield from dividends and buybacks |
| Shares Outstanding | bs_commonStockSharesOutstanding / 1M | Total shares outstanding in millions |
| Revenue ($M) | is_totalRevenue / 1M | Total annual revenue in millions |
| Net Income ($M) | is_netIncome / 1M | Total annual net income in millions |
| Free Cash Flow ($M) | cf_freeCashFlow / 1M | Annual free cash flow in millions |
Quality Metrics (Module 4)
Annual quality ratios measuring profitability, returns on capital, leverage, and operational efficiency. All computed from aggregated annual data.
| Metric | Formula | Description |
|---|---|---|
| Gross Margin | is_grossProfit / is_totalRevenue | Revenue retained after cost of goods sold. Higher = stronger pricing power. |
| Operating Margin | is_operatingIncome / is_totalRevenue | Profitability from core operations after operating expenses. |
| Net Margin | is_netIncome / is_totalRevenue | Bottom-line profitability after all expenses, interest, and taxes. |
| EBITDA Margin | is_ebitda / is_totalRevenue | Cash earnings margin before non-cash charges and financing. |
| FCF Margin | cf_freeCashFlow / is_totalRevenue | Free cash flow as percentage of revenue. Measures cash conversion. |
| ROIC | is_netIncome / (equity + longTermDebt) | Return on invested capital. Measures efficiency of capital allocation. |
| ROE | is_netIncome / bs_totalStockholderEquity | Return on equity. Profit generated per dollar of shareholder equity. |
| ROA | is_netIncome / bs_totalAssets | Return on assets. Profit generated per dollar of total assets. |
| ROCE | is_operatingIncome / (equity + longTermDebt) | Return on capital employed. Operating profit on invested capital. |
| Debt/Equity | bs_totalLiab / bs_totalStockholderEquity | Total leverage ratio. Higher = more leveraged balance sheet. |
| LT Debt/Equity | bs_longTermDebt / bs_totalStockholderEquity | Long-term debt leverage. Excludes short-term obligations. |
| Current Ratio | bs_totalCurrentAssets / bs_totalCurrentLiabilities | Short-term liquidity. Above 1.0 = can cover near-term obligations. |
| Interest Coverage | is_operatingIncome / is_interestExpense | Ability to service debt. Higher = more comfortable debt burden. |
| Asset Turnover | is_totalRevenue / bs_totalAssets | Revenue generated per dollar of assets. Measures asset efficiency. |
| CapEx/Revenue | abs(cf_capitalExpenditures) / is_totalRevenue | Capital intensity. How much revenue is reinvested in fixed assets. |
| FCF Conversion | cf_freeCashFlow / is_netIncome | How much net income converts to free cash flow. Above 1.0 = high quality. |
| Cash Conversion | cf_operatingCashFlow / is_netIncome | Operating cash flow relative to reported earnings. Earnings quality check. |
Financial Statements (Modules 5-7)
Income Statement, Balance Sheet, and Cash Flows are displayed as hierarchical tables with expandable parent-child rows. All values are shown in millions ($M). Quarterly data is aggregated into annual: P&L and Cash Flow items are summed, Balance Sheet items use the latest quarter.
Revenue
└ Cost of Revenue
Gross Profit
Operating Expenses
├ R&D
├ SG&A
└ D&A
Operating Income
Interest Expense
Income Before Tax
Income Tax
EBITDA
Net IncomeTotal Assets
├ Current Assets
│ ├ Cash & Equivalents
│ ├ Short-Term Investments
│ ├ Net Receivables
│ └ Inventory
└ Non-Current Assets
├ PP&E
├ Goodwill
├ Intangibles
└ Long-Term Investments
Total Liabilities
├ Current Liabilities
│ ├ Accounts Payable
│ └ Short-Term Debt
└ Non-Current Liabilities
└ Long-Term Debt
Stockholder Equity
├ Common Stock
├ Retained Earnings
└ Treasury Stock
Net Debt
Shares OutstandingOperating Cash Flow
├ Net Income
├ D&A
├ Stock-Based Comp
└ Working Capital Changes
Investing Cash Flow
├ Capital Expenditures
└ Investments
Financing Cash Flow
├ Dividends Paid
├ Share Buybacks/Issuance
└ Net Borrowings
Free Cash Flow
Net Change in CashGrowth Rates (Module 8)
Year-over-year growth rates for 12 key financial metrics. Computed as percentage change from the prior year. Displayed with heatmap coloring: deep green for high growth, red for contraction, gray for null.
YoY Growth Rate
growth_pct = (current_year - prior_year) / abs(prior_year) * 100
Null if either year is missing or prior year is zero. Absolute value in denominator handles negative base values.
Tracked metrics: Revenue, Gross Profit, Operating Income, EBITDA, Net Income, EPS, Free Cash Flow, Operating Cash Flow, Total Assets, Stockholder Equity, Long-Term Debt, Dividends Paid.
Valuation Ratios (Module 9)
Current snapshot valuation multiples from EODHD. These are point-in-time values (not historical per quarter) and represent the latest available data for each stock.
| Metric | Formula | Description |
|---|---|---|
| P/E Ratio | price / EPS (trailing) | Price relative to trailing 12-month earnings |
| Forward P/E | price / forward EPS estimate | Price relative to consensus forward earnings estimate |
| PEG Ratio | P/E / earnings growth rate | P/E adjusted for growth. Below 1.0 suggests undervaluation relative to growth. |
| Price/Book | price / book value per share | Market price relative to net asset value. Below 1.0 = trading below book. |
| Price/Sales | market_cap / revenue_ttm | Market cap relative to trailing revenue. Lower = cheaper on revenue basis. |
| EV/EBITDA | enterprise_value / ebitda | Enterprise value per unit of operating cash earnings. Standard M&A metric. |
| EV/Revenue | enterprise_value / revenue_ttm | Enterprise value per unit of revenue. Capital-structure-neutral valuation. |
| Trailing P/E | price / trailing EPS | Price to trailing earnings (may differ from standard P/E by data source). |
| Dividend Yield | annual_dividend / price | Annual dividend as percentage of current share price. |
JCN Factor Scores (Module 10)
Five precomputed composite factor scores fetched from PROD score tables (computed monthly). Each score is 0-100. The JCN Composite is the simple average of all five factor scores. Displayed as score cards and a 5-axis radar chart.
| Score | Source Table | What it Measures |
|---|---|---|
| Value | PROD_OBQ_Value_Scores | Ranks stocks by valuation attractiveness (P/E, P/B, EV/EBITDA, etc.) |
| Quality | PROD_OBQ_Quality_Scores | Business quality via margins, ROE, earnings stability |
| Financial Strength | PROD_OBQ_FinStr_Scores | Balance sheet health, debt coverage, liquidity |
| Growth | PROD_OBQ_Growth_Scores | Revenue growth, earnings growth, forward estimates |
| Momentum | PROD_OBQ_Momentum_Scores | Price momentum signal based on relative strength |
| JCN Composite | Average of all 5 | Overall factor score = (V + Q + FS + G + M) / 5 |
JCN Composite Score
jcn_composite = (value + quality + financial_strength + growth + momentum) / 5
Each factor score is precomputed monthly from fundamental data and stored in PROD score tables (PROD_OBQ_*_Scores). The JCN Composite is the simple average of all five.
JCN Score Methodology
The JCN scoring system evaluates every stock in the investable universe across five fundamental dimensions: Value, Quality, Growth, Financial Strength, and Momentum. Each factor is computed monthly using a proprietary 3-way scoring system that combines cross-sectional, sector-relative, and historical self-relative rankings. The five individual scores are then blended into eight composite presets for different investment strategies.
Investable Universe
Scores are computed only for stocks in the JCN Investable Universe — the top 3,000 US equities by market capitalization, reconstituted annually on the last trading day of May. This mirrors the Russell 3000 reconstitution methodology used by FTSE Russell.
| Parameter | Value |
|---|---|
| Universe Size | Top 3,000 by market cap |
| Rank Day | Last trading day of May each year |
| Effective Period | July 1 through June 30 of the following year |
| DQ Filters | Market cap $10M - $5T, adjusted close $0.01 - $500K |
| Pre-2003 Handling | All available stocks scored (no universe filter) |
| Table | PROD_OBQ_Investable_Universe (67,528 rows, 2003-2025) |
3-Way Scoring System
Each of the five factor scores uses three independent scoring dimensions, combined into a single composite. This multi-lens approach prevents a stock from scoring well simply because its entire sector is cheap or because it happens to be in a historically low-quality industry.
Composite Formula
composite = Universe Score (40%) + Sector Score (40%) + History Score (20%)
All three dimensions use PERCENT_RANK() to produce 0-100 scores. The composite is a weighted average of the three.
| Dimension | Weight | Description |
|---|---|---|
| Universe | 40% | Cross-sectional percentile rank vs. all ~3,000 stocks in the same month. A stock scoring 90 is in the top 10% of the entire investable universe. |
| Sector | 40% | Same percentile rank but within GICS sector peers only (minimum 3 peers). Captures relative standing within an industry — is this tech stock cheap vs. other tech stocks? |
| History | 20% | Percentile rank against the stock's own 8+ quarter history (rolling window). Is this stock cheap relative to its own historical norms? |
Fallback rules: if a sector has fewer than 3 peers, weights shift to Universe 60% + History 40%. If historical data has fewer than 8 quarters, weights shift to Universe 50% + Sector 50%.
Value Score
Measures how attractively priced a stock is relative to its fundamentals. Lower valuation ratios produce higher scores (inverted ranking). The weighting emphasizes cash-flow-based measures over accounting earnings.
| Metric | Weight | Direction | Description |
|---|---|---|---|
| P/FCF (TTM) | 30% | Lower is better | Price to Free Cash Flow. Cash yield to shareholders — hardest metric to manipulate. |
| EV/EBITDA (TTM) | 25% | Lower is better | Enterprise value to operating earnings. Capital-structure-neutral. Standard M&A metric. |
| P/E (TTM) | 20% | Lower is better | Price to trailing earnings. The classic valuation metric, included for universality. |
| P/S (TTM) | 15% | Lower is better | Price to sales. Useful for pre-profit or cyclically depressed companies. |
| P/B (MRQ) | 10% | Lower is better | Price to book value. Asset-based valuation floor, most relevant for financials and industrials. |
P/FCF receives the highest weight because free cash flow is the purest measure of economic value available to shareholders. Unlike earnings, FCF is difficult to inflate through accounting choices. EV/EBITDA is capital-structure-neutral, allowing fair comparison between levered and unlevered firms — the standard metric in M&A valuation. P/E is included for universality but downweighted due to susceptibility to one-time charges and accounting distortions. The value factor draws directly from the HML (High Minus Low) factor identified by Fama & French (1992).
Quality Score
Measures business quality through profitability, capital efficiency, and earnings reliability. Higher values indicate better quality. The weighting emphasizes asset-level profitability measures that academic research has shown to be the most predictive of future returns.
| Metric | Weight | Description |
|---|---|---|
| Gross Profitability (GPA) | 20% | Gross Profit / Total Assets. The Novy-Marx (2013) quality factor — shown to be as powerful as book-to-market in predicting returns. |
| ROIC | 20% | Return on Invested Capital. Net Income / (Equity + Long-Term Debt). Measures how efficiently management allocates capital. |
| ROA | 15% | Return on Assets. Asset-level profitability, independent of capital structure. |
| FCF Margin | 15% | Free Cash Flow / Revenue. How much revenue converts to actual cash available to shareholders. |
| Gross Margin | 10% | Pricing power and cost structure durability. |
| Operating Margin | 10% | Core business profitability after operating expenses. |
| Earnings Quality | 10% | (Operating CF - Net Income) / Total Assets. Detects accrual manipulation — companies where reported earnings exceed actual cash flows score lower. |
The Earnings Quality metric is a Sloan (1996) accruals-based signal: companies where cash flow consistently trails reported earnings tend to have lower future returns, as the accrual component eventually reverses. GPA at 20% weight follows Novy-Marx (2013), who showed gross profitability scaled by assets has strong return-predictive power and is negatively correlated with value — making it an excellent complement in a multi-factor model.
Growth Score
Measures multi-period earnings, revenue, and cash flow growth using blended compound annual growth rates (CAGRs). Equal-weighted across four per-share growth metrics, each blending three lookback periods to balance recent acceleration with durable compounding.
| Metric | Weight | Description |
|---|---|---|
| Revenue/Share Growth | 25% | Top-line growth on a per-share basis. Adjusts for dilution from share issuance. |
| EPS Growth | 25% | Earnings per share growth. Bottom-line compounding. |
| FCF/Share Growth | 25% | Free cash flow per share growth. Cash-based confirmation of earnings growth. |
| Equity/Share Growth | 25% | Book value per share growth. Equity compounding, a proxy for intrinsic value accumulation. |
Period Blending
Blended = 1Y CAGR (40%) + 3Y CAGR (35%) + 5Y CAGR (25%)
Emphasizes recent acceleration while rewarding durable multi-year compounders. Growth rates are winsorized at +/-200% to prevent outliers from distorting rankings.
All growth metrics are computed on a per-share basis to penalize companies that grow revenue by diluting shareholders through stock issuance. The per-share normalization ensures that only genuine organic growth (or efficient capital deployment) is rewarded.
Financial Strength Score
Measures balance sheet health, debt serviceability, and liquidity. Equal-weighted across six metrics covering both stock measures (balance sheet ratios) and flow measures (coverage ratios). Draws from Altman Z-score principles (Altman, 1968) and Piotroski F-score methodology (Piotroski, 2000).
| Metric | Weight | Direction | Description |
|---|---|---|---|
| Interest Coverage | 16.7% | Higher is better | Operating Income / Interest Expense. Can the company comfortably service its debt? |
| FCF / Debt | 16.7% | Higher is better | Free Cash Flow / Total Debt. How quickly could the company repay all debt from cash flow? |
| Net Debt / EBITDA | 16.7% | Lower is better | Net leverage ratio. Years to repay net debt from operating earnings. Below 2x is healthy. |
| Debt / Assets | 16.7% | Lower is better | Total leverage ratio. What fraction of total assets is financed by debt? |
| Cash / Assets | 16.7% | Higher is better | Liquidity buffer as a fraction of total assets. |
| Working Capital / Assets | 16.7% | Higher is better | Short-term financial cushion. Positive working capital = current assets exceed current liabilities. |
Equal weighting ensures no single dimension (leverage, liquidity, or coverage) dominates the score. The mix captures both point-in-time balance sheet health and ongoing cash flow adequacy. Companies with zero debt naturally score high on debt-related metrics but still need strong liquidity and working capital to score well overall.
Momentum Score
Measures price trend strength and persistence from weekly return data. Unlike the other four factor scores which use monthly fundamental data, Momentum is computed weekly from adjusted closing prices.
| Component | Weight | Description |
|---|---|---|
| AF Momentum | ~40% | Average of 3-month, 6-month, and 12-month cumulative returns. Captures intermediate-term trend persistence. Based on the classic Jegadeesh & Titman (1993) momentum factor. |
| FIP Score | ~40% | 180-day directional price strength. Measures sustained trending behavior with less noise than raw returns by filtering short-term reversals. |
| SystemScore | ~20% | 5-year avg annual return multiplied by R-cubed (cube of R-squared to 5-year trend line). Rewards strong AND consistent long-term trends. The R-cubed term aggressively penalizes high-return stocks with erratic paths. |
SystemScore
SystemScore = (5yr_avg_annual_return) * (R_squared ^ 3)
R-squared measures how well the stock's price fits a linear trend. Cubing it means a stock with R²=0.5 retains only 12.5% of its return contribution, while R²=0.9 retains 72.9%. This heavily rewards smooth, consistent uptrends.
Weights are conditional: if a component is unavailable for a stock (e.g., less than 5 years of data for SystemScore), remaining component weights are re-normalized. The momentum score also uses the 3-way scoring system (Universe 40% + Sector 40% + History 20%) for the final composite.
Composite Blends
Eight pre-configured factor blend presets are stored in PROD_JCN_Composite_Scores. Each is a weighted average of the five individual factor composite scores. When a factor is unavailable for a given stock, the remaining factor weights are re-normalized so they still sum to 100%.
Re-normalization
blend_score = SUM(weight_i * factor_i) / SUM(weight_i for non-null factors)
If a stock has 4 of 5 factors, the weights of the available factors are scaled up proportionally.
| Preset | Column | Formula | Use Case |
|---|---|---|---|
| Full OBQ Composite | jcn_full_composite | V:20 + Q:20 + G:20 + M:20 + FS:20 | Balanced all-factor exposure. No single factor dominates. |
| QARP | jcn_qarp | Q:40 + V:40 + M:20 | Quality at Reasonable Price. Buffett-style quality-value investing with trend confirmation. |
| GARP | jcn_garp | G:40 + V:40 + M:20 | Growth at Reasonable Price. Peter Lynch-style growth-value blend. |
| Quality + Momentum | jcn_quality_momentum | Q:50 + M:50 | High-quality businesses in uptrends. Avoids value traps by requiring momentum confirmation. |
| Value + Momentum | jcn_value_momentum | V:50 + M:50 | Deep value with trend confirmation. Avoids catching falling knives. |
| Growth + Quality + Momentum | jcn_growth_quality_momentum | G:34 + Q:33 + M:33 | Growth compounders with quality and momentum filter. Screens for the best growth stories. |
| Fortress | jcn_fortress | Q:40 + FS:40 + V:20 | Defensive. Strong balance sheet + high quality + reasonable price. Best for risk-off periods. |
| Alpha Trifecta | jcn_alpha_trifecta | V:34 + Q:33 + M:33 | The classic academic three-factor alpha blend: value + quality + momentum. |
References
The JCN scoring methodology draws from decades of peer-reviewed financial economics research. Key references:
Value Factor: Fama, E.F. & French, K.R. (1992). "The Cross-Section of Expected Stock Returns." Journal of Finance, 47(2), 427-465.
Quality / Profitability: Novy-Marx, R. (2013). "The Other Side of Value: The Gross Profitability Premium." Journal of Financial Economics, 108(1), 1-28.
Momentum: Jegadeesh, N. & Titman, S. (1993). "Returns to Buying Winners and Selling Losers: Implications for Stock Market Efficiency." Journal of Finance, 48(1), 65-91.
Financial Distress: Altman, E.I. (1968). "Financial Ratios, Discriminant Analysis and the Prediction of Corporate Bankruptcy." Journal of Finance, 23(4), 589-609.
F-Score: Piotroski, J.D. (2000). "Value Investing: The Use of Historical Financial Statement Information to Separate Winners from Losers." Journal of Accounting Research, 38, 1-41.
Accruals Anomaly: Sloan, R.G. (1996). "Do Stock Prices Fully Reflect Information in Accruals and Cash Flows About Future Earnings?" The Accounting Review, 71(3), 289-315.
Five-Factor Model: Fama, E.F. & French, K.R. (2015). "A Five-Factor Asset Pricing Model." Journal of Financial Economics, 116(1), 1-22.
Russell 3000 Methodology: FTSE Russell (2024). "Russell U.S. Equity Indexes: Construction and Methodology." ftserussell.com.
Database & Schema
MotherDuck
MotherDuck is a cloud-hosted DuckDB service that provides the analytical warehouse for all JCN data. Single-writer architecture (concurrent writes fail silently). Connection via MOTHERDUCK_TOKEN environment variable. All symbols stored in TICKER.US format (e.g., AAPL.US).
-- Connection pattern
conn = duckdb.connect(f'md:?motherduck_token={token}')
-- Database layout
PROD_EODHD.main.* -- Production tables (read by dashboard)
DEV_EODHD_DATA.main.* -- Staging tables (written by sync pipeline)PROD_EOD_survivorship
The primary price table. Contains daily OHLC + adjusted_close for all US common stocks and ADRs, including delisted symbols (survivorship-bias free). Over 121 million rows. Zone-map optimized by (date, symbol).
| Column | Type | Description |
|---|---|---|
| symbol | VARCHAR | Ticker in TICKER.US format (e.g., AAPL.US) |
| date | DATE | Trading date |
| open | DOUBLE | Opening price |
| high | DOUBLE | Intraday high |
| low | DOUBLE | Intraday low |
| close | DOUBLE | Raw closing price (NOT used for analysis) |
| adjusted_close | DOUBLE | Split/dividend-adjusted close (PRIMARY price field) |
| isin | VARCHAR | International Securities Identification Number |
| in_sp500 | BOOLEAN | Current S&P 500 membership |
| gics_sector | VARCHAR | GICS sector classification |
| industry | VARCHAR | Industry sub-classification |
| market_cap | DOUBLE | Latest market capitalization in USD |
| listing_date | DATE | IPO / listing date |
| delisting_date | DATE | Delisting date (NULL if still active) |
| is_active | BOOLEAN | TRUE if currently trading |
| instrument_type | VARCHAR | Common Stock, ADR, etc. |
PROD_EOD_ETFs
Daily OHLC + adjusted_close for ETFs. SPY.US is the primary benchmark. Same structure as survivorship but without survivorship metadata columns.
| Column | Type | Description |
|---|---|---|
| symbol | VARCHAR | ETF ticker in TICKER.US format (e.g., SPY.US) |
| date | DATE | Trading date |
| open | DOUBLE | Opening price |
| high | DOUBLE | Intraday high |
| low | DOUBLE | Intraday low |
| close | DOUBLE | Raw closing price |
| adjusted_close | DOUBLE | Adjusted close (PRIMARY) |
| isin | VARCHAR | ISIN identifier |
PROD_EOD_Fundamentals
Quarterly fundamental data for all US stocks. 196 columns covering income statement (is_*), balance sheet (bs_*), cash flow (cf_*), valuation snapshots, analyst estimates, and company metadata. Over 160 quarters of history for major stocks.
| Column Group | Prefix | Aggregation | Key Columns |
|---|---|---|---|
| Identity | symbol, date, filing_date | N/A | symbol (VARCHAR), date (quarter end), filing_date (SEC filing date) |
| Company Info | company_name, sector, industry | Latest | sector, industry, gic_sector, gic_industry, exchange |
| Income Statement | is_* | SUM across quarters | is_totalRevenue, is_grossProfit, is_operatingIncome, is_ebitda, is_netIncome |
| Balance Sheet | bs_* | Latest quarter in year | bs_totalAssets, bs_totalLiab, bs_totalStockholderEquity, bs_cash, bs_longTermDebt |
| Cash Flow | cf_* | SUM across quarters | cf_totalCashFromOperatingActivities, cf_capitalExpenditures, cf_freeCashFlow |
| Valuation (snapshot) | pe_ratio, forward_pe, ... | Latest (overwritten) | market_cap, pe_ratio, forward_pe, peg_ratio, enterprise_value, dividend_yield |
| Analyst | analyst_* | Latest (overwritten) | analyst_target_price, analyst_buy, analyst_hold, analyst_sell, analyst_rating |
| Shares | shares_outstanding, bs_common... | Latest / Historical | shares_outstanding (snapshot), bs_commonStockSharesOutstanding (per quarter) |
Important: Valuation fields (market_cap, pe_ratio, etc.) are SNAPSHOT values — identical across all quarters for a given symbol. They represent the CURRENT latest value, not historical. Only financial statement columns (is_*, bs_*, cf_*) contain true historical quarterly data.
Score Tables
Five separate score tables, each containing monthly composite scores per symbol. Rebuilt during Stage 3 of the sync pipeline. Used by portfolio pages for the JCN 5-factor score grid and radar charts.
| Table | Score Column | Key Columns |
|---|---|---|
| PROD_OBQ_Value_Scores | value_score_composite | symbol, month_date, value_score_composite |
| PROD_OBQ_Quality_Scores | quality_score_composite | symbol, month_date, quality_score_composite |
| PROD_OBQ_Growth_Scores | growth_score_composite | symbol, month_date, growth_score_composite |
| PROD_OBQ_FinStr_Scores | finstr_score_composite | symbol, month_date, finstr_score_composite |
| PROD_OBQ_Momentum_Scores | momentum_score_composite | symbol, month_date, momentum_score_composite |
SYNC_STATE & SYNC_LOG
SYNC_STATE stores the current state of each sync stage (last run timestamp, status, cursor position for resumable operations). SYNC_LOG records every sync run with timing, row counts, and error details. Both tables enable the Prime Directive PD-08 (cursor persistence) and provide audit trail.
EODHD API
API Overview
EODHD (End of Day Historical Data) is the primary external data provider for JCN Financial. It supplies daily end-of-day prices, quarterly fundamentals, and company metadata for all US-listed securities including common stocks, ADRs, and ETFs. Data is point-in-time accurate using SEC filing dates.
Endpoints Used
| Endpoint | Used In | Purpose |
|---|---|---|
| /api/eod-bulk-last-day/US | Stage 1 (Ingest) | Bulk download of latest EOD prices for all US symbols in a single API call |
| /api/real-time/[symbol].US | Live Prices | 15-min delayed real-time quotes for portfolio current prices |
| /api/fundamentals/[symbol].US | Fundamentals Sync | Quarterly financial statements, valuation, analyst data |
Rate Limits
EODHD enforces rate limits of 1,000 API calls per minute and 100,000 calls per day. The sync pipeline uses bulk endpoints to minimize call count. Real-time price fetches for portfolios are throttled to one refresh per 15 minutes (client-side localStorage cache) and only trigger on manual refresh button click or TTL expiry.
Rate Limiter
delay = max(0.06s per call, 60ms between requests)
Enforced via RateLimiter class. API key stored as Vercel environment variable EODHD_API_KEY, never in source code.
Data Sync Pipeline
The sync pipeline is a 4-stage process that maintains the production database. Each stage is independently runnable, idempotent, and designed to operate within Vercel Pro 300-second function timeout (280s budget with 20s safety buffer).
Stage 0: Health Check (diagnostics)
↓
Stage 1: Ingest (EODHD → DEV)
↓
Stage 2: Validate & Promote (DEV → PROD)
↓
Stage 3: Score Rebuild (recompute composites)Stage 0: Health Check
Runs 8 diagnostic checks before any sync operation: (1) MotherDuck connectivity, (2) EODHD API key validation, (3) Required tables existence with estimated row counts, (4) Last sync timestamp from SYNC_STATE, (5) Symbol format consistency (PD-03 — all must be TICKER.US), (6) Fundamentals coverage ratio, (7) Gap analysis (latest date vs today), (8) Duplicate detection in last 7 days. Uses sampled queries and LIMIT 1 patterns for speed. Results cached 5 minutes.
Stage 1: Ingest
Downloads daily EOD prices for all US symbols via EODHD bulk endpoint (/api/eod-bulk-last-day/US). Separates stocks from ETFs based on exchange code. Validates inline (filters out mutual funds, OTC, warrants per PD-06). Writes to DEV_EODHD_DATA staging tables. Idempotent — skips dates already ingested. Tracks cursor in SYNC_STATE for resumability.
Stage 2: Validate & Promote
Four phases: (Phase 1) 6-point data quality audit on DEV — NULL checks on critical columns, duplicate detection, row count validation, date continuity, price reasonableness, symbol format compliance. (Phase 2) DEV to PROD promotion via ANTI JOIN (only new rows inserted, never overwrites). (Phase 3) Incremental Weekly OHLC rebuild. (Phase 3.5) Dashboard snapshot rebuild. (Phase 4) Post-validation + SYNC_LOG entry.
1. NULL check on critical columns (symbol, date, adjusted_close)
2. Duplicate detection (same symbol+date in last 7 days)
3. Row count validation (≥95% of expected rows)
4. Date continuity (no gaps > 3 business days)
5. Price reasonableness (no negative prices, no > 1000% daily moves)
6. Symbol format compliance (all must end in .US)Stage 3: Score Rebuild
Recomputes all 5 JCN composite factor scores (Value, Quality, Growth, Financial Strength, Momentum) for 8 different presets. Reads from PROD tables, applies scoring algorithms, and writes results to the 5 PROD_OBQ_*_Scores tables. Approximately 4.48 million score rows generated.
Prime Directive v1.0
Eight immutable rules governing all data operations in the sync pipeline. These rules cannot be overridden and are enforced at every stage.
| ID | Rule |
|---|---|
| PD-01 | NEVER DELETE HISTORICAL DATA. Append-only. Deactivate via is_active=FALSE. |
| PD-02 | POINT-IN-TIME COMPLIANCE. Use filing_date, not quarter_date, for fundamental joins. |
| PD-03 | SYMBOL FORMAT CANONICAL. All tables use TICKER.US format. |
| PD-04 | NO PARTIAL WRITES TO PROD. All writes to DEV first. Gate: ≥95% rows + zero nulls on critical columns. |
| PD-05 | ADJUSTED_CLOSE ONLY. Raw close never used for analysis. |
| PD-06 | SYMBOL CONTAMINATION ZERO TOLERANCE. Filter mutual funds, OTC, warrants at Stage 1. |
| PD-07 | IDEMPOTENT STAGES. Safe to re-run. UPSERT / ANTI JOIN patterns. |
| PD-08 | CURSOR PERSISTENCE. Long-running stages write progress to SYNC_STATE for resumability. |
Caching Architecture
4-Layer Cache
JCN uses a multi-layer caching strategy to minimize latency and API calls. Each layer has specific TTLs and invalidation rules.
| Layer | Location | Latency | TTL |
|---|---|---|---|
| L3 | Browser localStorage | 0ms | 24hr (perf data), 15min (live prices), 30min (analysis) |
| L2 | Vercel /tmp | 0ms (warm) | Date-based invalidation (new trading day) |
| L1 | PROD_DASHBOARD_SNAPSHOT | ~200ms | Rebuilt during Stage 2 sync |
| L0 | Legacy 5-CTE Query | 2-4s | Always available fallback (no cache) |
| L4 | EODHD Real-Time | ~500ms | 15min client-side throttle, manual refresh only |
TTL Strategy
Cache TTLs are designed around data freshness requirements. Portfolio performance data (24hr TTL) only needs daily refresh since it uses EOD prices. Live prices (15min TTL) balance freshness with API rate limits. Stock analysis data (30min TTL) represents quarterly fundamentals that change infrequently.
// Cache hierarchy — check in order, return first hit:
1. localStorage (instant) → if valid TTL, return
2. /tmp file cache (instant if warm) → if same day, return
3. PROD_DASHBOARD_SNAPSHOT (~200ms) → pre-computed row, return
4. Legacy 5-CTE query (2-4s) → full DB query, return + cache
5. EODHD API (500ms) → live prices only, on manual refresh