Files
All-in-one-Financial-Analysis/atlas-terminal/server/utils/safe_float.py
T
shawnkim1997andClaude Opus 4.6 b2acda81ee feat: add Atlas Terminal — Next.js 14 + FastAPI full-stack migration
Complete migration from Streamlit to Next.js 14 App Router + FastAPI backend.

Frontend (Next.js 14):
- 10 pages: Overview, Research, Valuation, Technical, Markets, Earnings, News, Portfolio, Filings, Settings
- Terminal Noir dark theme with custom Tailwind config
- TradingView Lightweight Charts for candlestick/volume
- Valuation: DCF, Sensitivity Matrix, Monte Carlo, Tornado, Reverse DCF
- Financial Statements table with YoY growth badges and margin rows
- SEC EDGAR inline filing viewer with section tabs
- News split-view with iframe article embedding
- Technical Analysis with RSI, MACD, Bollinger, Fibonacci, Moving Averages
- Earnings beat/miss visualization
- AI Copilot chat panel with Gemini integration

Backend (FastAPI):
- 13 routers: market_data, financials, valuation, technical, earnings, insider, edgar, news, portfolio, analysis, chat, estimates, fx
- Services: DCF engine, Monte Carlo simulation, sensitivity analysis, risk metrics, SEC parser, technical indicators
- yfinance + yahooquery data sources with fallback pattern
- SQLite caching layer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 02:10:10 +00:00

89 lines
2.2 KiB
Python

"""Numeric safety utilities for the ATLAS Terminal backend.
Provides safe type-coercion helpers used across all services to handle
None, NaN, and non-numeric values gracefully without raising exceptions.
"""
from typing import Optional
import pandas as pd
def _safe_float(x: object) -> Optional[float]:
"""Convert *x* to ``float``, returning ``None`` for unconvertible values.
Handles ``None``, ``NaN`` (both Python ``float('nan')`` and pandas
``pd.NA``), and arbitrary objects whose ``float()`` conversion fails.
Parameters
----------
x:
Any value that might be numeric.
Returns
-------
Optional[float]
The float representation, or ``None`` if conversion is impossible.
"""
if x is None or (isinstance(x, float) and (x != x or pd.isna(x))):
return None
try:
return float(x)
except (TypeError, ValueError):
return None
def _na(x: object) -> object:
"""Return the string ``'N/A'`` for ``None``/``NaN``, otherwise *x* unchanged.
Useful when building display-ready dictionaries or DataFrames where
missing numeric values should appear as a human-readable sentinel.
Parameters
----------
x:
Any value.
Returns
-------
object
``'N/A'`` when *x* is ``None`` or ``NaN``; *x* otherwise.
"""
if x is None or (isinstance(x, float) and (pd.isna(x) or x != x)):
return "N/A"
return x
def _format_shares_display(shares: Optional[float]) -> str:
"""Format a share count for human-friendly display.
Examples
--------
>>> _format_shares_display(15_420_000_000)
'15.42B Shares'
>>> _format_shares_display(1_200_000)
'1.20M Shares'
>>> _format_shares_display(None)
'N/A'
Parameters
----------
shares:
Raw share count (absolute number, not in millions/billions).
Returns
-------
str
A concise string such as ``'15.42B Shares'`` or ``'N/A'``.
"""
if shares is None or shares <= 0:
return "N/A"
s = float(shares)
if s >= 1e9:
return f"{s / 1e9:.2f}B Shares"
if s >= 1e6:
return f"{s / 1e6:.2f}M Shares"
if s >= 1e3:
return f"{s / 1e3:.2f}K Shares"
return f"{s:.0f} Shares"