Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 

Repository files navigation

stockprep

Source-agnostic stock data prep utilities. Bring your own data fetcher.

Why?

Stock data comes from many sources (Yahoo Finance, Alpaca, CSVs, etc.), but the prep steps are always the same:

  1. Fetch price data
  2. Handle missing values (forward/backward fill)
  3. Normalize for comparison (start all at 1.0)
  4. Calculate returns

This package decouples the data source from the prep logic. You define how to fetch, it handles the rest.

Usage

from stock_data import StockData

# Define your fetcher - any function that returns a DataFrame
# with DatetimeIndex and symbols as columns
def my_fetcher(symbols, start, end):
    import yfinance as yf
    df = yf.download(symbols, start=start, end=end, progress=False)["Adj Close"]
    return df if len(symbols) > 1 else df.to_frame(symbols[0])

# Use it
data = StockData(my_fetcher)
data.load(["AAPL", "GOOG", "SPY"], "2020-01-01", "2023-12-31")

# Normalized prices (all start at 1.0)
data.normalize()

# Daily returns
data.daily_returns()

# Cumulative returns
data.cumulative_returns()

# Access raw/cleaned data
data.raw      # before cleaning
data.prices   # after ffill/bfill

Fetcher Contract

A fetcher is any callable with this signature:

def fetcher(symbols: list, start: str, end: str) -> pd.DataFrame:
    """
    Returns DataFrame with:
    - DatetimeIndex (dates)
    - Columns = symbol names
    - Values = prices (typically Adj Close)
    """
    pass

Example Fetchers

See fetchers.py for ready-to-use examples:

Fetcher Source Survivorship Bias Free
yfinance_fetcher Yahoo Finance No
csv_fetcher(data_dir) Local CSV files Depends on your data
alpaca_fetcher(api_key, secret) Alpaca Markets No
nasdaqdatalink_fetcher(api_key) Sharadar Yes
tiingo_fetcher(api_key) Tiingo Yes
from fetchers import yfinance_fetcher, csv_fetcher

# Yahoo Finance (quick and free, but has survivorship bias)
data = StockData(yfinance_fetcher)

# Local CSVs
data = StockData(csv_fetcher("./my_data"))

Data Quality Notes

Adjusted Close

All example fetchers use adjusted close prices, which account for stock splits and dividends. This means daily_returns() gives you total return (price + dividends), not just price return. This is what you want for backtesting.

Survivorship Bias

Free data sources (Yahoo Finance, Alpaca) only include stocks that currently exist. If you backtest 2008 using today's stock universe, you'll miss companies that went bankrupt (Lehman Brothers, etc.), making your results look artificially good.

Survivorship bias-free sources:

Source Cost Notes
Sharadar (Nasdaq Data Link) ~$50/mo Includes delisted stocks
Tiingo Free tier Claims delisted coverage
CRSP $$$ Academic gold standard
Polygon.io Paid tiers Has delisted data
from fetchers import nasdaqdatalink_fetcher, tiingo_fetcher

# Sharadar - paid, comprehensive
data = StockData(nasdaqdatalink_fetcher("your_api_key"))

# Tiingo - free tier available
data = StockData(tiingo_fetcher("your_api_key"))

Install

Just copy stock_data.py into your project. That's it.

For fetchers, install what you need:

pip install yfinance           # for yfinance_fetcher
pip install alpaca-py          # for alpaca_fetcher
pip install nasdaq-data-link   # for nasdaqdatalink_fetcher
pip install requests           # for tiingo_fetcher

License

MIT

About

Source-agnostic stock data prep utilities. Bring your own fetcher.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages