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]):
- matplotlib ≥ 3.5
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_pathparameter to export to PNG, PDF, SVG, or any matplotlib-supported format.return_fig=Truefor 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 showing0.0. - Time to recovery — now returns
—when a period has no drawdown to recover from, instead of showing0(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=Truenot fully respected — benchmark data-fetch status messages were always printed to stdout regardless of thequietflag. They now correctly respectquiet=Trueand 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, andbenchmark_tickerparameters now carry correctOptional[str]type annotations (previously typed asstrdespite acceptingNone).- 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d915c28a89d4f03fed026ebc6a8d3c4128105215bd71462bb1b964128b1a1f06
|
|
| MD5 |
a3c7ffff8557c2ba5902ef3b79a147cf
|
|
| BLAKE2b-256 |
9f98847190f4472ed897d1ee7bd724432c953cd8c45a73210f5b2f9c441978a7
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
665a25c1bb9a3bb5da090e8314a226df37cbd07b9090392f76b73789abed751b
|
|
| MD5 |
b0984342cc03d76703e6f3955e75f448
|
|
| BLAKE2b-256 |
f3ddcec836ef857bc4da13517380d6b427a9708565bd224cd772919ef84b8c41
|