diff --git a/marimo/demo.html b/marimo/demo.html
new file mode 100644
index 00000000..e1387d53
--- /dev/null
+++ b/marimo/demo.html
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ demo.py
+
+
+
+
+
+ demo
+
+
+
+
+
+
+
+
+
+ import%20marimo%0A%0A__generated_with%20%3D%20%220.9.27%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell%0Adef%20__(__file__)%3A%0A%20%20%20%20from%20pathlib%20import%20Path%0A%0A%20%20%20%20import%20cvxpy%20as%20cp%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20pandas%20as%20pd%0A%0A%20%20%20%20%23import%20marimo%20as%20mo%0A%20%20%20%20from%20cvx.portfolio.min_risk%20import%20minrisk_problem%0A%20%20%20%20from%20cvx.risk.sample%20import%20SampleCovariance%0A%20%20%20%20from%20cvx.simulator%20import%20Builder%0A%0A%20%20%20%20pd.options.plotting.backend%20%3D%20%22plotly%22%0A%0A%20%20%20%20path%20%3D%20Path(__file__).parent%0A%20%20%20%20print(path)%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20Builder%2C%0A%20%20%20%20%20%20%20%20Path%2C%0A%20%20%20%20%20%20%20%20SampleCovariance%2C%0A%20%20%20%20%20%20%20%20cp%2C%0A%20%20%20%20%20%20%20%20minrisk_problem%2C%0A%20%20%20%20%20%20%20%20np%2C%0A%20%20%20%20%20%20%20%20path%2C%0A%20%20%20%20%20%20%20%20pd%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell%0Adef%20__(path%2C%20pd)%3A%0A%20%20%20%20%23%20Load%20some%20historic%20stock%20prices%0A%20%20%20%20prices%20%3D%20pd.read_csv(path%20%2F%20%22data%22%20%2F%20%22stock_prices.csv%22%2C%20index_col%3D0%2C%20parse_dates%3DTrue%2C%20header%3D0%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20Estimate%20a%20series%20of%20historic%20covariance%20matrices%0A%20%20%20%20returns%20%3D%20prices.pct_change().dropna(axis%3D0%2C%20how%3D%22all%22)%0A%20%20%20%20return%20prices%2C%20returns%0A%0A%0A%40app.cell%0Adef%20__(%0A%20%20%20%20Builder%2C%0A%20%20%20%20SampleCovariance%2C%0A%20%20%20%20cp%2C%0A%20%20%20%20minrisk_problem%2C%0A%20%20%20%20np%2C%0A%20%20%20%20prices%2C%0A%20%20%20%20returns%2C%0A)%3A%0A%20%20%20%20cov%20%3D%20returns.ewm(com%3D60%2C%20min_periods%3D100).cov().dropna(axis%3D0%2C%20how%3D%22all%22)%0A%20%20%20%20start%20%3D%20cov.index%5B0%5D%5B0%5D%0A%0A%20%20%20%20%23%20Establish%20a%20risk%20model%0A%20%20%20%20_risk_model%20%3D%20SampleCovariance(num%3D20)%0A%0A%20%20%20%20%23%20Perform%20the%20backtest%0A%20%20%20%20_builder%20%3D%20Builder(prices%3Dprices.truncate(before%3Dstart)%2C%20initial_aum%3D1e6)%0A%0A%20%20%20%20_w%20%3D%20cp.Variable(len(_builder.prices.columns))%0A%20%20%20%20_problem%20%3D%20minrisk_problem(_risk_model%2C%20_w)%0A%0A%20%20%20%20for%20_t%2C%20_state%20in%20_builder%3A%0A%20%20%20%20%20%20%20%20_risk_model.update(%0A%20%20%20%20%20%20%20%20%20%20%20%20cov%3Dcov.loc%5B_t%5B-1%5D%5D.values%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20lower_assets%3Dnp.zeros(20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20upper_assets%3Dnp.ones(20)%2C%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20don't%20reconstruct%20the%20problem%20in%20every%20iteration!%0A%20%20%20%20%20%20%20%20_problem.solve()%0A%0A%20%20%20%20%20%20%20%20_builder.weights%20%3D%20_w.value%0A%20%20%20%20%20%20%20%20_builder.aum%20%3D%20_state.aum%0A%0A%20%20%20%20_portfolio%20%3D%20_builder.build()%0A%0A%20%20%20%20_portfolio.nav.plot()%0A%20%20%20%20return%20cov%2C%20start%0A%0A%0A%40app.cell%0Adef%20__(Builder%2C%20cp%2C%20minrisk_problem%2C%20np%2C%20prices%2C%20returns%2C%20start)%3A%0A%20%20%20%20from%20cvx.risk.cvar%20import%20CVar%0A%0A%20%20%20%20_risk_model%20%3D%20CVar(alpha%3D0.80%2C%20n%3D40%2C%20m%3D20)%0A%0A%20%20%20%20%23%20Perform%20the%20backtest%0A%20%20%20%20_builder%20%3D%20Builder(prices%3Dprices.truncate(before%3Dstart)%2C%20initial_aum%3D1e6)%0A%0A%20%20%20%20_w%20%3D%20cp.Variable(len(_builder.prices.columns))%0A%20%20%20%20_problem%20%3D%20minrisk_problem(_risk_model%2C%20_w)%0A%0A%20%20%20%20for%20_t%2C%20_state%20in%20_builder%3A%0A%20%20%20%20%20%20%20%20_risk_model.update(%0A%20%20%20%20%20%20%20%20%20%20%20%20returns%3Dreturns.truncate(after%3D_t%5B-1%5D).tail(40).values%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20lower_assets%3Dnp.zeros(20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20upper_assets%3Dnp.ones(20)%2C%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20%23%20don't%20reconstruct%20the%20problem%20in%20every%20iteration!%0A%20%20%20%20%20%20%20%20_problem.solve()%0A%0A%20%20%20%20%20%20%20%20_builder.weights%20%3D%20_w.value%0A%20%20%20%20%20%20%20%20_builder.aum%20%3D%20_state.aum%0A%0A%20%20%20%20_portfolio%20%3D%20_builder.build()%0A%20%20%20%20_portfolio.nav.plot()%0A%20%20%20%20return%20(CVar%2C)%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
+
+
+178ccbb25aa7bb720dc7fbc6286bcdb28ea89bb92cfba8871f399d31b9dc78cc
+
+
diff --git a/marimo/demo.py b/marimo/demo.py
index 1050172f..4ed6a603 100644
--- a/marimo/demo.py
+++ b/marimo/demo.py
@@ -5,25 +5,37 @@
@app.cell
-def __():
+def __(__file__):
+ from pathlib import Path
+
import cvxpy as cp
import numpy as np
import pandas as pd
- import marimo as mo
from cvx.portfolio.min_risk import minrisk_problem
from cvx.risk.sample import SampleCovariance
from cvx.simulator import Builder
pd.options.plotting.backend = "plotly"
- return Builder, SampleCovariance, cp, minrisk_problem, mo, np, pd
+
+ path = Path(__file__).parent
+ return (
+ Builder,
+ Path,
+ SampleCovariance,
+ cp,
+ minrisk_problem,
+ np,
+ path,
+ pd,
+ )
@app.cell
-def __(pd):
+def __(path, pd):
# Load some historic stock prices
prices = pd.read_csv(
- "marimo/data/stock_prices.csv", index_col=0, parse_dates=True, header=0
+ path / "data" / "stock_prices.csv", index_col=0, parse_dates=True, header=0
)
# Estimate a series of historic covariance matrices
@@ -99,14 +111,8 @@ def __(Builder, cp, minrisk_problem, np, prices, returns, start):
_portfolio = _builder.build()
_portfolio.nav.plot()
-
return (CVar,)
-@app.cell
-def __():
- return
-
-
if __name__ == "__main__":
app.run()
diff --git a/marimo/factormodel.html b/marimo/factormodel.html
new file mode 100644
index 00000000..af0fbc0a
--- /dev/null
+++ b/marimo/factormodel.html
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ factormodel.py
+
+
+
+
+
+ factormodel
+
+
+
+
+
+
+
+
+
+ import%20marimo%0A%0A__generated_with%20%3D%20%220.9.27%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell%0Adef%20__(__file__)%3A%0A%20%20%20%20from%20pathlib%20import%20Path%0A%0A%20%20%20%20import%20cvxpy%20as%20cvx%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20pandas%20as%20pd%0A%0A%20%20%20%20from%20cvx.portfolio.min_risk%20import%20minrisk_problem%0A%20%20%20%20from%20cvx.risk.factor%20import%20FactorModel%0A%20%20%20%20from%20cvx.risk.linalg%20import%20pca%0A%0A%20%20%20%20path%20%3D%20Path(__file__).parent%0A%20%20%20%20return%20FactorModel%2C%20Path%2C%20cvx%2C%20minrisk_problem%2C%20np%2C%20path%2C%20pca%2C%20pd%0A%0A%0A%40app.cell%0Adef%20__(path%2C%20pd)%3A%0A%20%20%20%20%23%20Load%20some%20historic%20stock%20prices%0A%20%20%20%20prices%20%3D%20pd.read_csv(path%20%2F%20%22data%22%20%2F%20%22stock_prices.csv%22%2C%20index_col%3D0%2C%20parse_dates%3DTrue%2C%20header%3D0%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20Estimate%20a%20series%20of%20historic%20covariance%20matrices%0A%20%20%20%20returns%20%3D%20prices.pct_change().dropna(axis%3D0%2C%20how%3D%22all%22)%0A%20%20%20%20return%20prices%2C%20returns%0A%0A%0A%40app.cell%0Adef%20__(pca%2C%20returns)%3A%0A%20%20%20%20factors%20%3D%20pca(returns%3Dreturns%2C%20n_components%3D10)%0A%20%20%20%20return%20(factors%2C)%0A%0A%0A%40app.cell%0Adef%20__(FactorModel%2C%20factors%2C%20np%2C%20returns)%3A%0A%20%20%20%20model%20%3D%20FactorModel(assets%3Dlen(returns.columns)%2C%20k%3D10)%0A%0A%20%20%20%20%23%20update%20the%20model%20parameters%0A%20%20%20%20model.update(%0A%20%20%20%20%20%20%20%20cov%3Dfactors.cov%2C%0A%20%20%20%20%20%20%20%20exposure%3Dfactors.exposure.values%2C%0A%20%20%20%20%20%20%20%20idiosyncratic_risk%3Dfactors.idiosyncratic.std().values%2C%0A%20%20%20%20%20%20%20%20lower_assets%3Dnp.zeros(20)%2C%0A%20%20%20%20%20%20%20%20upper_assets%3Dnp.ones(20)%2C%0A%20%20%20%20%20%20%20%20lower_factors%3D-0.1%20*%20np.ones(10)%2C%0A%20%20%20%20%20%20%20%20upper_factors%3D0.1%20*%20np.ones(10)%2C%0A%20%20%20%20)%0A%0A%20%20%20%20%23%20test%20the%20risk%20model%20with%20uniform%20weights%0A%20%20%20%20weights%20%3D%200.05%20*%20np.ones(20)%0A%20%20%20%20model.estimate(weights).value%0A%20%20%20%20return%20model%2C%20weights%0A%0A%0A%40app.cell%0Adef%20__(cvx%2C%20minrisk_problem%2C%20model%2C%20np%2C%20pd%2C%20prices)%3A%0A%20%20%20%20w%20%3D%20cvx.Variable(20)%0A%20%20%20%20y%20%3D%20cvx.Variable(10)%0A%0A%20%20%20%20problem%20%3D%20minrisk_problem(model%2C%20w%2C%20y%3Dy)%0A%20%20%20%20problem.solve()%0A%0A%20%20%20%20print(pd.Series(data%3Dw.value%2C%20index%3Dprices.columns))%0A%20%20%20%20print(model.estimate(w%2C%20y%3Dy).value)%0A%0A%20%20%20%20%23%20check%20the%20solution%0A%20%20%20%20assert%20np.isclose(w.value.sum()%2C%201.0)%0A%20%20%20%20assert%20np.all(w.value%20%3E%20-0.01)%0A%20%20%20%20print(y.value)%0A%20%20%20%20return%20problem%2C%20w%2C%20y%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
+
+
+14d9984800eb0dd419c1abafe006ff6c87355e372ef9409c8206c6bc35ee9f06
+
+
diff --git a/marimo/factormodel.py b/marimo/factormodel.py
index 79e02ee8..791d8e4a 100644
--- a/marimo/factormodel.py
+++ b/marimo/factormodel.py
@@ -6,6 +6,8 @@
@app.cell
def __():
+ from pathlib import Path
+
import cvxpy as cvx
import numpy as np
import pandas as pd
@@ -14,15 +16,19 @@ def __():
from cvx.risk.factor import FactorModel
from cvx.risk.linalg import pca
- return FactorModel, cvx, minrisk_problem, np, pca, pd
+ path = Path(__file__).parent
+ return FactorModel, cvx, minrisk_problem, np, pca, path, pd
@app.cell
-def __(pd):
+def __(path, pd):
+ # Load some historic stock prices
prices = pd.read_csv(
- "marimo/data/stock_prices.csv", index_col=0, header=0, parse_dates=True
+ path / "data" / "stock_prices.csv", index_col=0, parse_dates=True, header=0
)
- returns = prices.pct_change().fillna(0.0)
+
+ # Estimate a series of historic covariance matrices
+ returns = prices.pct_change().dropna(axis=0, how="all")
return prices, returns
@@ -71,10 +77,5 @@ def __(cvx, minrisk_problem, model, np, pd, prices):
return problem, w, y
-@app.cell
-def __():
- return
-
-
if __name__ == "__main__":
app.run()