class TestFinalPnl: universe_hand = Universe( pd.DataFrame( {"A0": [3, 1, 4, 1, 5, 9, 2], "A1": [2, 7, 1, 8, 2, 8, 1],}, index=range(7), dtype=float, ) ) @pytest.mark.parametrize("seed", range(10)) def test_random(self, seed): universe = make_randomwalk(n_bars=100, n_assets=10, seed=seed) trade = RandomTrader(n_trades=1, seed=seed).run(universe).trades[0] result = trade.final_pnl(universe) expected = trade.array_pnl(universe)[-1] assert np.allclose(result, expected) @pytest.mark.parametrize("a", [-2.0, -1.0, 0.0, 1.0, 2.0]) @pytest.mark.parametrize("seed", range(1)) def test_linearity_mul(self, a, seed): universe = make_randomwalk(seed=seed) trade0 = RandomTrader(n_trades=1, seed=seed).run(universe).trades[0] tradeA = a * trade0 result0 = trade0.final_pnl(universe) resultA = tradeA.final_pnl(universe) assert np.allclose(a * result0, resultA)
class TestColumn: universe = Universe( pd.DataFrame({f"A{i}": range(10) for i in range(10)}, index=[f"B{i}" for i in range(10)])) trades = [ Trade( asset=["A0", "A1"], lot=[1, 2], open_bar="B0", shut_bar="B8", take=1.0, stop=-1.0, ), Trade( asset=["A2", "A3"], lot=[3, 4], open_bar="B1", shut_bar="B9", take=2.0, stop=-2.0, ), ] def _get_history(self): strategy = DeterminedTrader(trades=self.trades).run(self.universe) return History(strategy) def test_trade_id(self): result = self._get_history().trade_id assert np.array_equal(result, [0, 0, 1, 1]) def test_order_id(self): result = self._get_history().order_id assert np.array_equal(result, [0, 1, 2, 3]) def test_asset(self): result = self._get_history().asset assert np.array_equal(result, ["A0", "A1", "A2", "A3"]) def test_open_bar(self): result = self._get_history().open_bar assert np.array_equal(result, ["B0", "B0", "B1", "B1"]) def test_shut_bar(self): result = self._get_history().shut_bar assert np.array_equal(result, ["B8", "B8", "B9", "B9"]) def test_take(self): result = self._get_history().take assert np.array_equal(result, [1.0, 1.0, 2.0, 2.0]) def test_stop(self): result = self._get_history().stop assert np.array_equal(result, [-1.0, -1.0, -2.0, -2.0]) def test_pnl(self): pass # TODO
class TestSeriesExposure: """ Test `Trade.series_exposure()`. """ universe_hand = Universe( pd.DataFrame( {"A0": [3, 1, 4, 1, 5, 9, 2], "A1": [2, 7, 1, 8, 2, 8, 1],}, index=range(7), dtype=float, ) ) @pytest.mark.parametrize("net", [True, False]) def test_hand(self, net): trade = Trade(asset=["A0", "A1"], lot=[2, -3], open_bar=1, shut_bar=3) result = trade.series_exposure(net=net, universe=self.universe_hand) if net: expected = [0, -19, 5, -22, 0, 0, 0] else: expected = [0, 23, 11, 26, 0, 0, 0] assert np.allclose(result, expected) def test_value_zero(self): trade = Trade(asset=["A0", "A1"], lot=[0, 0], open_bar=1, shut_bar=3) result = trade.series_exposure(self.universe_hand) expected = np.zeros((self.universe_hand.n_bars)) assert np.allclose(result, expected) # Abs exposure doesn't satisfy linearity add @pytest.mark.parametrize("net", [True]) @pytest.mark.parametrize("seed", range(1)) def test_linearity_add(self, net, seed): np.random.seed(seed) lot0, lot1 = np.random.random(2) trade0 = Trade(asset="A0", lot=lot0, open_bar=1, shut_bar=3) trade1 = Trade(asset="A0", lot=lot1, open_bar=1, shut_bar=3) tradeA = Trade(asset="A0", lot=lot0 + lot1, open_bar=1, shut_bar=3) result0 = trade0.series_exposure(self.universe_hand, net=net) result1 = trade1.series_exposure(self.universe_hand, net=net) resultA = tradeA.series_exposure(self.universe_hand, net=net) assert np.allclose(result0 + result1, resultA) @pytest.mark.parametrize("a", [-2.0, -1.0, 0.0, 1.0, 2.0]) @pytest.mark.parametrize("net", [True, False]) @pytest.mark.parametrize("seed", range(1)) def test_linearity_mul(self, a, net, seed): universe = make_randomwalk(seed=seed) trade0 = RandomTrader(n_trades=1, seed=seed).run(universe).trades[0] tradeA = a * trade0 result0 = trade0.series_exposure(universe, net=net) resultA = tradeA.series_exposure(universe, net=net) if net: assert np.allclose(a * result0, resultA) else: assert np.allclose(abs(a) * result0, resultA)
def test_result_zero_1(self, net, n_bars): universe = Universe( pd.DataFrame({ "A0": np.linspace(0.0, 1.0, n_bars), })) strategy = DeterminedTrader([Trade("A0", lot=0.0)]).run(universe) result = self.MetricClass(net=net).result(strategy) expected = np.zeros(n_bars) assert np.allclose(result, expected)
def test_result_zero_0(self, net, n_bars): universe = Universe( pd.DataFrame({ "A0": np.zeros(n_bars, dtype=float), })) strategy = DeterminedTrader([Trade("A0")]).run(universe) result = self.MetricClass(net=net).result(strategy) expected = np.zeros(n_bars) assert np.allclose(result, expected)
class TestNOrders: """ Test `Strategy.n_orders`. """ universe = Universe(pd.DataFrame({f"A{i}": range(10) for i in range(4)})) def test_value(self): strategy = SampleStrategy().run(self.universe) assert strategy.n_orders == 4
def test_result_zero(self, rate, init_wealth, n_bars): universe = Universe( pd.DataFrame({ "A0": np.ones(n_bars, dtype=float), })) strategy = DeterminedTrader([Trade("A0")]).run(universe, budget=init_wealth) result = self.MetricClass(rate=rate).result(strategy) expected = 0 assert np.allclose(result, expected)
class TestIsRun: """ Test `Strategy.is_run`. """ universe = Universe(pd.DataFrame({f"A{i}": range(10) for i in range(4)})) def test_value(self): strategy = SampleStrategy() assert strategy.is_run == False strategy.run(self.universe) assert strategy.is_run == True
class TestArrayExposure: """ Test `Trade.array_exposure()`. """ universe_hand = Universe( pd.DataFrame( {"A0": [3, 1, 4, 1, 5, 9, 2], "A1": [2, 7, 1, 8, 2, 8, 1],}, index=range(7), dtype=float, ) ) trade0 = Trade(asset=["A0", "A1"], lot=[2, -3], open_bar=1, shut_bar=3) trade1 = Trade(asset=["A1", "A0"], lot=[-3, 2], open_bar=1, shut_bar=3) expected0 = [[0, 0], [2, -21], [8, -3], [2, -24], [0, 0], [0, 0], [0, 0]] expected1 = [[0, 0], [-21, 2], [-3, 8], [-24, 2], [0, 0], [0, 0], [0, 0]] @pytest.mark.parametrize( "trade, expected", [(trade0, expected0), (trade1, expected1)], ) def test_hand(self, trade, expected): result = trade.array_exposure(universe=self.universe_hand) assert np.allclose(result, expected) def test_value_zero(self): trade = Trade(asset=["A0", "A1"], lot=[0, 0], open_bar=1, shut_bar=3) result = trade.array_exposure(self.universe_hand) expected = np.zeros((self.universe_hand.n_bars, 2)) assert np.allclose(result, expected) @pytest.mark.parametrize("seed", range(1)) def test_linearity_add(self, seed): np.random.seed(seed) lot0, lot1 = np.random.random(2) trade0 = Trade(asset="A0", lot=lot0, open_bar=1, shut_bar=3) trade1 = Trade(asset="A0", lot=lot1, open_bar=1, shut_bar=3) tradeA = Trade(asset="A0", lot=lot0 + lot1, open_bar=1, shut_bar=3) result0 = trade0.array_exposure(self.universe_hand) result1 = trade1.array_exposure(self.universe_hand) resultA = tradeA.array_exposure(self.universe_hand) assert np.allclose(result0 + result1, resultA) @pytest.mark.parametrize("a", [-2.0, -1.0, 0.0, 1.0, 2.0]) @pytest.mark.parametrize("seed", range(1)) def test_linearity_mul(self, a, seed): universe = make_randomwalk(seed=seed) trade0 = RandomTrader(n_trades=1, seed=seed).run(universe).trades[0] tradeA = a * trade0 result0 = trade0.array_exposure(universe) resultA = tradeA.array_exposure(universe) assert np.allclose(a * result0, resultA)
class TestExposure: """ Test `Exposure`. """ MetricClass = Exposure universe_hand = Universe( pd.DataFrame({ "A0": [3, 1, 4, 1, 5, 9, 2], "A1": [2, 7, 1, 8, 1, 8, 1], })) @pytest.mark.parametrize("net", [True, False]) @pytest.mark.parametrize("n_bars", [100]) def test_result_zero_0(self, net, n_bars): universe = Universe( pd.DataFrame({ "A0": np.zeros(n_bars, dtype=float), })) strategy = DeterminedTrader([Trade("A0")]).run(universe) result = self.MetricClass(net=net).result(strategy) expected = np.zeros(n_bars) assert np.allclose(result, expected) @pytest.mark.parametrize("net", [True, False]) @pytest.mark.parametrize("n_bars", [100]) def test_result_zero_1(self, net, n_bars): universe = Universe( pd.DataFrame({ "A0": np.linspace(0.0, 1.0, n_bars), })) strategy = DeterminedTrader([Trade("A0", lot=0.0)]).run(universe) result = self.MetricClass(net=net).result(strategy) expected = np.zeros(n_bars) assert np.allclose(result, expected) @pytest.mark.parametrize("net", [True, False]) def test_hand(self, net): universe = self.universe_hand trade0 = Trade("A0", lot=2.0, open_bar=1, shut_bar=5) trade1 = Trade("A1", lot=-3.0, open_bar=2, shut_bar=4) strategy = DeterminedTrader([trade0, trade1]).run(universe) result = Exposure(net=net).result(strategy) if net: # 0 2 8 2 10 18 0 # 0 0 -3 -24 -3 0 0 expected = [0, 2, 5, -22, 7, 18, 0] else: expected = [0, 2, 11, 26, 13, 18, 0] assert np.allclose(result, expected)
def test(self): universe = Universe( pd.DataFrame({ "A": [1, 2, 3], "B": [2, 3, 4], "C": [3, 4, 5] })) strategy = BuyAndHold({"A": 0.5, "B": 0.5}).run(universe) assert len(strategy.trades) == 1 assert (strategy.trades[0].asset == ["A", "B"]).all() assert (strategy.trades[0].lot == [0.5 / 1, 0.5 / 2]).all() assert strategy.trades[0].open_bar == 0 assert strategy.trades[0].close_bar == 2
def fetch_usstocks( begin_date="2000-01-01", end_date="2019-12-31", n_assets=10, column="Adj Close", verbose=True, ): """ Return Universe of US stocks. Parameters ---------- - begin_date : str - end_date : str - n_assets : int Returns ------- universe : Universe """ begin_date = pd.Timestamp(begin_date) end_date = pd.Timestamp(end_date) with open(module_path / "usstocks.txt") as f: tickers = [ticker.strip() for ticker in f.readlines()] if n_assets > len(tickers): raise ValueError("n_assets should be <=", len(tickers)) prices = pd.DataFrame({ ticker: fill_and_cut( DataReader( name=ticker, data_source="yahoo", start=begin_date - pd.Timedelta(days=10), end=end_date, )[column], begin_date=begin_date, ) for ticker in tickers[:n_assets] }) return Universe(prices)
def make_randomwalk( n_bars=1000, n_assets=10, volatility=0.01, name="RandomWalk", bars=None, assets=None, seed=None, ): """ Return Universe whose prices are random-walks. Daily returns follow log-normal distribution. Parameters ---------- - n_bars : int, default 1000 - n_assets : int, default 10 - volatility : float, default 0.01 - name : str, default='RandomWalk' - bars - assets - seed : int Returns ------- Universe """ data = np.random.lognormal(sigma=volatility, size=(n_bars, n_assets)).cumprod(axis=0) data /= data[0, :] bars = bars or list(range(n_bars)) assets = assets or [str(i) for i in range(n_assets)] prices = pd.DataFrame(data, index=bars, columns=assets) return Universe(prices, name=name)
import pytest import numpy as np import pandas as pd from epymetheus import Universe universe = Universe(prices=pd.DataFrame( { "Asset0": [0, 1, 2, 3], "Asset1": [0, 1, 2, 3], "Asset2": [0, 1, 2, 3], }, index=["Bar0", "Bar1", "Bar2", "Bar3"], )) params_universe = [universe] # -------------------------------------------------------------------------------- @pytest.mark.parametrize("universe", params_universe) def test_bars(universe): assert np.array_equal(universe.bars, ["Bar0", "Bar1", "Bar2", "Bar3"]) @pytest.mark.parametrize("universe", params_universe) def test_assets(universe): assert np.array_equal(universe.assets, ["Asset0", "Asset1", "Asset2"])