Skip to content

Commit

Permalink
more testing
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Schmelzer committed Dec 3, 2023
1 parent 31fed78 commit a47fc7d
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 28 deletions.
23 changes: 10 additions & 13 deletions cvx/simulator/builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class _State:
"""

prices: pd.Series = None
_position: pd.Series = None
__position: pd.Series = None
cash: float = 1e6
input_data: dict[str, Any] = field(default_factory=dict)
model: TradingCostModel | None = None
Expand Down Expand Up @@ -82,10 +82,7 @@ def weights(self) -> pd.Series:
fraction of the total portfolio value. If the positions are still
missing, then a series of zeroes is returned.
"""
try:
return self.cashposition / self.nav
except TypeError:
return 0 * self.prices
return self.cashposition / self.nav

@property
def leverage(self) -> float:
Expand All @@ -105,17 +102,17 @@ def cashposition(self):

@property
def position(self):
if self._position is None:
if self.__position is None:
return pd.Series(dtype=float)

return self._position
return self.__position

@position.setter
def position(self, position):
def _position(self, position: np.array):
position = pd.Series(index=self.assets, data=position)
trades = self._trade(target_pos=position)

self._position = position
self.__position = position
self.cash -= (trades * self.prices).sum()

if self.model is not None:
Expand All @@ -132,10 +129,10 @@ def _trade(self, target_pos):
"""
Compute the trade vector given a target position
"""
if self._position is None:
return target_pos
# if self._position is None:
# return target_pos

return target_pos.subtract(self._position, fill_value=0.0)
return target_pos.subtract(self.position, fill_value=0.0)


def builder(
Expand Down Expand Up @@ -303,7 +300,7 @@ def position(self, position: pd.Series) -> None:
Returns: pd.Series: a pandas Series object containing the current position of the portfolio.
"""
self.stocks.loc[self._state.time, self._state.assets] = position
self._state.position = position
self._state._position = position

@property
def cashposition(self):
Expand Down
10 changes: 0 additions & 10 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,3 @@ def portfolio(prices):
"""portfolio fixture"""
positions = pd.DataFrame(index=prices.index, columns=prices.columns, data=1.0)
return EquityPortfolio(prices, stocks=positions, initial_cash=1e6)


@pytest.fixture()
def returns(resource_dir):
"""returns fixture"""
return (
pd.read_csv(resource_dir / "ts.csv", index_col=0, header=None, parse_dates=True)
.squeeze()
.pct_change()
)
4 changes: 4 additions & 0 deletions tests/test_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ def test_set_weights(prices):
b = _builder(prices=prices[["B", "C"]].head(5), initial_cash=50000)
for times, state in b:
b.weights = np.array([0.5, 0.5])
assert np.allclose(b.weights, np.array([0.5, 0.5]))
assert np.allclose(state.weights.values, np.array([0.5, 0.5]))

portfolio = b.build()
assert portfolio.nav.values[-1] == pytest.approx(49773.093729)
Expand All @@ -158,6 +160,7 @@ def test_set_cashpositions(prices):
b = _builder(prices=prices[["B", "C"]].head(5), initial_cash=50000)
for times, state in b:
b.cashposition = np.ones(2) * state.nav / 2
assert np.allclose(b.cashposition, np.ones(2) * state.nav / 2)

portfolio = b.build()
assert portfolio.nav.values[-1] == pytest.approx(49773.093729)
Expand All @@ -167,6 +170,7 @@ def test_set_position(prices):
b = _builder(prices=prices[["B", "C"]].head(5), initial_cash=50000)
for times, state in b:
b.position = state.nav / (state.prices * 2)
assert np.allclose(b.position, state.nav / (state.prices * 2))

portfolio = b.build()
assert portfolio.nav.values[-1] == pytest.approx(49773.093729)
Expand Down
2 changes: 1 addition & 1 deletion tests/test_portfolio.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def test_state():
positions = pd.Series(data=[100, 300])
cash = 400
state = _State(cash=cash, prices=prices)
state.position = positions
state._position = positions
# value is the money in stocks
assert state.value == 1100.0
# nav is the value plus the cash
Expand Down
14 changes: 10 additions & 4 deletions tests/test_state.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,33 @@
import numpy as np
import pandas as pd

from cvx.simulator.builder import _State


def test_trade(prices):
s = _State(prices=prices)
s._position = pd.Series({"A": 10, "B": 20, "C": -10})
s = _State(prices=prices[["A", "B", "C"]].iloc[0])
s.time = prices.index[0]
print(s.assets)

s._position = np.array([10, 20, -10])
print(s.position)

x = s._trade(pd.Series({"B": 25, "C": -15, "D": 40}))
pd.testing.assert_series_equal(
x, pd.Series({"A": -10.0, "B": 5.0, "C": -5.0, "D": 40.0})
)


def test_trade_no_init_pos(prices):
s = _State(prices=prices)
s = _State(prices=prices.iloc[0])
x = s._trade(pd.Series({"B": 25.0, "C": -15.0, "D": 40.0}))
pd.testing.assert_series_equal(x, pd.Series({"B": 25.0, "C": -15.0, "D": 40.0}))


def test_update(prices):
s = _State(prices=prices.iloc[0])
assert s.cash == 1e6
s.position = pd.Series({"B": 25.0, "C": -15.0, "D": 40.0})
s._position = pd.Series({"B": 25.0, "C": -15.0, "D": 40.0})
assert s.cash == 1206047.2
assert s.value == -206047.2
assert s.nav == 1e6

0 comments on commit a47fc7d

Please sign in to comment.