Skip to main content

Comprehensive financial Exploratory Data Analysis for price series and tickers

Project description

fin-eda

Comprehensive financial Exploratory Data Analysis for any stock ticker or price series. Produces a numerical tearsheet (eda) and a visual tearsheet (eda_plot) covering returns, risk, drawdowns, benchmark comparison, volatility, liquidity, and more — all in one call.

Installation

# Numerical tearsheet only
pip install fin-eda

# Numerical + visual tearsheet
pip install fin-eda[plot]

Quick Start — Numerical (eda)

from fin_eda import eda

# Fetch data automatically via yfinance
eda("AAPL")

# Custom date range
eda("MSFT", start="2020-01-01", end="2024-01-01")

# Custom period
eda("TSLA", period="5y")

# Different benchmark
eda("QQQ", benchmark_ticker="SPY")

# Include a risk-free rate
eda("AAPL", risk_free_rate=0.05)

# Pass your own price series
import pandas as pd
prices = pd.Series(...)
eda(prices, benchmark_ticker="SPY")

# Return results as a dict (no print)
results = eda("AAPL", return_results=True, quiet=True)

Quick Start — Visual (eda_plot)

Requires pip install fin-eda[plot].

from fin_eda import eda_plot

# Full 13-panel tearsheet
eda_plot("AAPL")

# Select specific panels
eda_plot("AAPL", panels=["price", "drawdown", "distribution", "heatmap"])

# Save to file (PNG, PDF, SVG — format inferred from extension)
eda_plot("MSFT", save_path="msft_tearsheet.png")

# Return the Figure for notebook embedding or further customisation
fig = eda_plot("TSLA", period="5y", return_fig=True)

# Custom benchmark and risk-free rate
eda_plot("QQQ", benchmark_ticker="^GSPC", risk_free_rate=0.05)

Available panels

Name Description
price Price history with 50D/200D moving averages and volume
cumulative Cumulative return vs benchmark (log scale, shaded gap)
drawdown Underwater drawdown chart with top-3 trough annotations
heatmap Monthly returns heatmap (year × month grid)
distribution Daily return histogram with normal overlay and VaR lines
qq Q-Q plot vs normal distribution (tail points highlighted)
beta_scatter Return scatter vs benchmark with OLS regression line
rolling_sharpe Rolling 63D and 252D annualized Sharpe ratio
rolling_vol Rolling 21D vs 252D volatility regime
capture Up/down capture ratio bar chart by period
autocorr Return autocorrelation at lags 1–21D with confidence bands
parkinson Parkinson (H-L) vs close-to-close volatility comparison
volume Daily volume (last 90 days) with 30D/90D averages and Amihud ratio

Benchmark-dependent panels (cumulative, beta_scatter, capture) are automatically skipped if no benchmark data is available. OHLCV-dependent panels (parkinson, volume) are automatically skipped when a raw price Series is passed instead of a ticker.

Output

eda() renders in the terminal using Rich with colour-coded values (green = positive/good, yellow = neutral, red = negative/risk). A header panel shows the current trend snapshot, followed by one table per section.

eda_plot() produces a single dark-themed matplotlib figure with up to 13 panels. Use save_path to export, or return_fig=True to get the Figure object.

Metrics Covered

Section Key Metrics
Core Return & Risk Cumulative return, arithmetic & geometric mean, median, std dev, annualized volatility & variance — across 1M, 3M, 6M, 1Y, 3Y, 5Y, 10Y, YTD
Risk-Adjusted Performance Sharpe ratio, Sortino ratio, downside deviation, semi-variance, profit factor — from 6M+
Drawdown & Capital Destruction Max drawdown, average drawdown, time to recovery, max consecutive loss days — from 3M+
Trend Structure & Price Health 50/100/200D moving averages, price vs 200D MA, golden/death cross spread, trend persistence, 52W high distance
Relative Performance vs Benchmark Excess return, information ratio — from 6M+
Beta, Correlation & Market Dependence Beta, correlation vs benchmark — from 3M+
Capture Ratios Up-market and down-market capture (annualized) — from 6M+
Return Distribution & Non-Normality Skewness, kurtosis, Jarque-Bera statistic — from 3M+
Tail Risk & Stress Historical VaR (95% & 99%), Expected Shortfall/CVaR, worst daily/weekly/monthly return, extreme loss frequency
Regime & Time-Series Behavior Return autocorrelation at 1D, 5D, 21D lags
Volatility Metrics Parkinson volatility (21D/63D/126D), rolling vol percentile, volatility of volatility, current vs 1Y vol ratio
Liquidity Metrics Average daily volume (30D/90D), volume trend, Amihud illiquidity ratio (30D/90D/full)

Parameters

eda() — shared with eda_plot()

Parameter Type Default Description
ticker_or_prices str or pd.Series Yahoo Finance ticker or a Series of close prices
benchmark_ticker str or None 'SPY' Benchmark symbol. Pass None to skip
risk_free_rate float 0.0 Annual risk-free rate (e.g. 0.05 for 5%)
period str or None '10y' yfinance history period (ignored if start/end provided)
start str or None None Start date YYYY-MM-DD
end str or None None End date YYYY-MM-DD
quiet bool False Suppress benchmark fetch status messages

eda() only

Parameter Type Default Description
return_results bool False Return the metrics dict instead of (or in addition to) printing

eda_plot() only

Parameter Type Default Description
panels list[str] or None None Panels to render. None = all 13. See panel name table above
save_path str or None None Save figure to this path before showing (e.g. 'out.png', 'report.pdf')
return_fig bool False Return the matplotlib.Figure instead of calling plt.show()

Dependencies

Core (installed automatically):

Optional (for eda_plot, installed via pip install fin-eda[plot]):

License

MIT


Changelog

1.1.0

New: eda_plot() — visual tearsheet

  • 13-panel dark-themed matplotlib tearsheet mirroring all eda() inputs.
  • Panels: price history, cumulative return vs benchmark, underwater drawdown, monthly returns heatmap, return distribution, Q-Q plot, beta scatter, rolling Sharpe, rolling volatility regime, up/down capture ratios, autocorrelation, Parkinson volatility, and volume/liquidity.
  • panels=[...] parameter for rendering any subset of panels in one call.
  • save_path parameter to export to PNG, PDF, SVG, or any matplotlib-supported format.
  • return_fig=True for notebook embedding or programmatic figure composition.
  • Benchmark-dependent and OHLCV-dependent panels degrade gracefully when data is unavailable.
  • Style applied via mpl.rc_context — does not pollute the caller's global matplotlib state.
  • Added as an optional dependency: pip install fin-eda[plot].

1.0.1

Bug fixes

  • YTD period — corrected to use the current calendar year at runtime rather than the last year present in the data, which produced wrong results when analyzing historical series ending before the current year.
  • Average drawdown — now returns (no data) when a period has no negative drawdown observations, instead of incorrectly showing 0.0.
  • Time to recovery — now returns when a period has no drawdown to recover from, instead of showing 0 (which implied an instantaneous recovery had occurred).
  • Volatility of volatility key name — internal key mismatch between the success and failure paths caused the metric to appear twice in the output under different names. Now consistently labeled Volatility of volatility (21D rolling, annualized).
  • quiet=True not fully respected — benchmark data-fetch status messages were always printed to stdout regardless of the quiet flag. They now correctly respect quiet=True and route through the Rich console for consistent formatting.
  • Monthly return resampling — added compatibility fallback for pandas < 2.2, where the 'ME' month-end alias was not yet available.

Numerical improvements

  • Cumulative and geometric mean returns — switched from chained .prod() to log-sum form (np.expm1(np.log1p(r).sum())). Mathematically equivalent, but avoids floating-point overflow on very long return histories (20Y+) and resolves a pandas type-stub incompatibility with newer versions.
  • Capture ratios — same log-sum refactor applied to up- and down-market annualization, eliminating potential overflow for assets with extreme up-market streaks.

Code quality

  • period, start, end, and benchmark_ticker parameters now carry correct Optional[str] type annotations (previously typed as str despite accepting None).
  • Period-pattern regex precompiled at module load time instead of on every report render.
  • Removed stale internal comment referencing previously deleted metrics.
  • Docstrings added to all internal helper functions.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fin_eda-1.1.0.tar.gz (34.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fin_eda-1.1.0-py3-none-any.whl (30.6 kB view details)

Uploaded Python 3

File details

Details for the file fin_eda-1.1.0.tar.gz.

File metadata

  • Download URL: fin_eda-1.1.0.tar.gz
  • Upload date:
  • Size: 34.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.10

File hashes

Hashes for fin_eda-1.1.0.tar.gz
Algorithm Hash digest
SHA256 d915c28a89d4f03fed026ebc6a8d3c4128105215bd71462bb1b964128b1a1f06
MD5 a3c7ffff8557c2ba5902ef3b79a147cf
BLAKE2b-256 9f98847190f4472ed897d1ee7bd724432c953cd8c45a73210f5b2f9c441978a7

See more details on using hashes here.

File details

Details for the file fin_eda-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: fin_eda-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 30.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.10

File hashes

Hashes for fin_eda-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 665a25c1bb9a3bb5da090e8314a226df37cbd07b9090392f76b73789abed751b
MD5 b0984342cc03d76703e6f3955e75f448
BLAKE2b-256 f3ddcec836ef857bc4da13517380d6b427a9708565bd224cd772919ef84b8c41

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page