Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6,248 changes: 2,770 additions & 3,478 deletions cookbook/2-Mean-Variance-Optimisation.ipynb

Large diffs are not rendered by default.

845 changes: 318 additions & 527 deletions cookbook/3-Advanced-Mean-Variance-Optimisation.ipynb

Large diffs are not rendered by default.

1,166 changes: 605 additions & 561 deletions cookbook/4-Black-Litterman-Allocation.ipynb

Large diffs are not rendered by default.

939 changes: 522 additions & 417 deletions cookbook/5-Hierarchical-Risk-Parity.ipynb

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions pypfopt/data/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .data_loader import load_stockdata, available_tickers, load_marketcaps

__all__ = ["load_stockdata", "available_tickers", "load_marketcaps"]
47 changes: 47 additions & 0 deletions pypfopt/data/data_loader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import pandas as pd
from importlib import resources


def _load_raw_data(filename: str, **read_csv_kwargs):
with resources.files(__package__).joinpath(filename).open("r") as f:
return pd.read_csv(f, **read_csv_kwargs)


def load_stockdata(tickers: list = None, start: str = None, end: str = None):

df = _load_raw_data("stock_prices.csv", parse_dates=["date"])

if start is not None:
df = df[df["date"] >= pd.to_datetime(start)]
if end is not None:
df = df[df["date"] <= pd.to_datetime(end)]

if tickers is not None:
cols = ["date"] + tickers
df = df[cols]

return df.set_index("date")


def load_marketcaps(tickers: list = None):

df = _load_raw_data("market_caps.csv")

if tickers is not None:
available = set(df["ticker"])
invalid = set(tickers) - available
if invalid:
raise ValueError(f"Invalid tickers: {invalid}")

df = df[df["ticker"].isin(tickers)]

return dict(zip(df["ticker"], df["market_cap"]))


def available_tickers():

df = _load_raw_data("stock_prices.csv", parse_dates=["date"])
cols = [c for c in df.columns if c != "date"]
cols.sort()

return cols
34 changes: 34 additions & 0 deletions pypfopt/data/market_caps.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
,ticker,market_cap
0,AAPL,3890834833408
1,ACN,127705194496
2,AMD,323832184832
3,AMZN,2237050126336
4,BAC,363737317376
5,BLK,165749276672
6,COST,445187457024
7,CVS,103888756736
8,DIS,185017466880
9,DPZ,13497629696
10,F,53419077632
11,GILD,186250330112
12,INTU,116666302464
13,JD,38876950528
14,JPM,802528952320
15,KO,345075089408
16,LUV,24963076096
17,MA,464960028672
18,MCD,238929035264
19,MSFT,2962173984768
20,NAT,1262033920
21,NVDA,4435176587264
22,PBI,1733088640
23,PFE,154992394240
24,SBUX,110238670848
25,SPY,629947236352
26,TGT,51424350208
27,TM,317571497984
28,TSLA,1513430843392
29,UL,156296904704
30,UNH,267158962176
31,WMT,1013349351424
32,XOM,642598305792
793 changes: 793 additions & 0 deletions pypfopt/data/stock_prices.csv

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,6 @@ all_extras = [
dev = [
"pytest>=9.0.0",
"pytest-cov>=7.0.0",
"yfinance>=0.2.66",
]

# notebook tests
Expand All @@ -87,6 +86,9 @@ requires = [
[tool.setuptools.packages.find]
exclude = ["example", "example.*", "tests", "tests.*"]

[tool.setuptools.package-data]
pypfopt = ["data/*.csv"]

[tool.ruff]
line-length = 88
# Keep Ruff aligned with project target version
Expand Down