From 73e917836edb35e38f44882711f21a15ac0b440d Mon Sep 17 00:00:00 2001 From: Thomas Schmelzer Date: Sun, 18 Feb 2024 23:33:29 +0400 Subject: [PATCH] shift portfolio in sep module to avoid cyclic dependency (#349) --- cvx/simulator/builder.py | 10 ++++++++++ cvx/simulator/shifter.py | 11 +++++++++++ tests/test_applications/test_shifter.py | 26 +++++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100644 cvx/simulator/shifter.py create mode 100644 tests/test_applications/test_shifter.py diff --git a/cvx/simulator/builder.py b/cvx/simulator/builder.py index 0f14b24f..b8bc037a 100644 --- a/cvx/simulator/builder.py +++ b/cvx/simulator/builder.py @@ -232,3 +232,13 @@ def from_returns(cls, returns): prices = returns2prices(returns) return cls(prices=prices) + + @classmethod + def from_weights(cls, weights, prices, initial_aum=1e6): + """Build Futures Portfolio from weights""" + builder = cls(prices=prices, initial_aum=initial_aum) + for t, state in builder: + builder.weights = weights.loc[t[-1]] + builder.aum = state.aum + + return builder diff --git a/cvx/simulator/shifter.py b/cvx/simulator/shifter.py new file mode 100644 index 00000000..d9ec2c9c --- /dev/null +++ b/cvx/simulator/shifter.py @@ -0,0 +1,11 @@ +from cvx.simulator import Builder, Portfolio + + +def shift(portfolio: Portfolio, periods: int = 0): + """Shift the portfolio by a number of periods""" + # shift the weights + weights = portfolio.weights.shift(periods) + builder = Builder.from_weights( + weights=weights, prices=portfolio.prices, initial_aum=portfolio.aum.iloc[0] + ) + return builder.build() diff --git a/tests/test_applications/test_shifter.py b/tests/test_applications/test_shifter.py new file mode 100644 index 00000000..6c8f6af1 --- /dev/null +++ b/tests/test_applications/test_shifter.py @@ -0,0 +1,26 @@ +# from cvx.simulator import Builder +import pandas as pd + +from cvx.simulator import Builder +from cvx.simulator.shifter import shift + + +def test_portfolio_cumulated(prices): + builder = Builder(prices=prices[["A", "B"]].tail(10), initial_aum=1e6) + + for t, state in builder: + # hold one share in both assets + builder.cashposition = [1e5, 4e5] + + # reduce the available aum by the costs + builder.aum = state.aum # - costs + + portfolio = builder.build() + print(portfolio.weights) + print(portfolio.aum) + + ppp = shift(portfolio=portfolio, periods=2) + print(ppp.weights) + print(ppp.aum) + + pd.testing.assert_frame_equal(portfolio.weights.shift(2), ppp.weights)