def test_run(): class TestStrategy(Strategy): @overrides def run(self, dt: date, prices_df: pd.DataFrame, fees_df: pd.DataFrame) -> List[str]: if dt == date(2001, 1, 1): # 1st BDAY return ["isin1", "isin2"] if dt == date(2001, 1, 4): # 4th BDAY return ["isin1"] if dt == date(2001, 1, 9): # 7th BDAY return [] if dt == date(2001, 1, 10): # 8th BDAY return ["isin2"] raise ValueError() @overrides def on_data_ready(self, data: Simulator.Data) -> None: pass simulator = Simulator(strategy=TestStrategy(), tie_breaker=NoOpTieBreaker(), num_portfolio=2, hold_interval=2 * BDAY, buy_sell_gap=BDAY) [result] = simulator.run(start_date=date(2001, 1, 1), end_date=date(2001, 1, 12)) # Does not factor in platform fees, check_less_precise later expected_account = pd.DataFrame(data=[ [100, [], []], [ 100 * (0.5 * (14 / 12) + 0.5 * (24 / 22)), ["isin1", "isin2"], ["Fund 1", "Fund 2"] ], [ 100 * (0.5 * (14 / 12) + 0.5 * (24 / 22)) * (17 / 15), ["isin1"], ["Fund 1"] ], [100 * (0.5 * (14 / 12) + 0.5 * (24 / 22)) * (17 / 15), [], []], [ 100 * (0.5 * (14 / 12) + 0.5 * (24 / 22)) * (17 / 15) * (30 / 29), ["isin2"], ["Fund 2"] ] ], index=[ date(2001, 1, 1), date(2001, 1, 4), date(2001, 1, 9), date(2001, 1, 11), date(2001, 1, 12) ], columns=["value", "isins", "names"]) assert_frame_equal(result.account, expected_account, rtol=1e-4) assert result.returns == 0.32330550475798586 assert result.annual_returns == 10955.427133719217 assert result.max_drawdown == -1.3864736012392243e-05 assert result.sharpe_ratio == 12.37846848338121 assert result.start_date == date(2001, 1, 1) assert result.end_date == date(2001, 1, 12)
) @overrides def on_data_ready(self, data: Simulator.Data) -> None: for strategy in self.strategies: strategy.on_data_ready(data) if __name__ == "__main__": simulator = Simulator( strategy=AndStrategy( BollingerReturns(), TargetReturns() ), isins=[ "GB00B1XFGM25", "GB00B4TZHH95", "GB00B8JYLC77", # "GB00B39RMM81", "GB00B80QG615", "GB00B99C0657", # "GB00BH57C751", "GB0006061963", # "IE00B4WL8048", "IE00B90P3080", "LU0827884411", ] ) results = simulator.run() Simulator.describe_and_plot(results)
from datetime import date from typing import List import pandas as pd from lib.simulate.simulator import Simulator from lib.simulate.strategy.strategy import SelectAll from lib.simulate.tiebreaker.tie_breaker import TieBreaker class RandomTieBreaker(TieBreaker): def run(self, allowed_isins: List[str], num_portfolio: int, dt: date, prices_df: pd.DataFrame, fees_df: pd.DataFrame) -> List[str]: return prices_df.loc[dt].dropna().sample(num_portfolio).index.tolist() def on_data_ready(self, data: Simulator.Data) -> None: pass if __name__ == "__main__": num_runs = 10 simulator = Simulator(strategy=SelectAll(), tie_breaker=RandomTieBreaker()) results = [res for res in simulator.run() for i in range(num_runs)] Simulator.describe_and_plot(results)
def _build_simulator(cls, params: SimulateRoutes.SimulateParam) -> Simulator: return Simulator( strategy=params.strategy, isins=params.isins, num_portfolio=params.num_portfolio)
import pandas as pd from overrides import overrides from lib.fund.fund_utils import calc_returns from lib.simulate.simulator import Simulator from lib.simulate.strategy.strategy import Strategy from lib.simulate.tiebreaker.no_op_tie_breaker import NoOpTieBreaker class MaxReturns(Strategy): @overrides def run(self, dt: date, prices_df: pd.DataFrame, fees_df: pd.DataFrame) -> List[str]: next_dt = dt + self._hold_interval next_returns = calc_returns(prices_df, next_dt, self._hold_interval, fees_df) isin = next_returns.idxmax() return [isin] @overrides def on_data_ready(self, data: Simulator.Data) -> None: self._hold_interval = data.hold_interval if __name__ == "__main__": simulator = Simulator(strategy=MaxReturns(), tie_breaker=NoOpTieBreaker(), num_portfolio=1) results = simulator.run() Simulator.describe_and_plot(results)
from lib.simulate.simulator import Simulator from lib.simulate.strategy.strategy import SelectAll from lib.simulate.tiebreaker.no_op_tie_breaker import NoOpTieBreaker from lib.util.dates import BDAY if __name__ == "__main__": simulator = Simulator( strategy=SelectAll(), tie_breaker=NoOpTieBreaker(), buy_sell_gap=0 * BDAY, isins=[ "GB00B1XFGM25", "GB00B4TZHH95", "GB00B8JYLC77", "GB00B39RMM81", "GB00B80QG615", "GB00B99C0657", # "GB00BH57C751", "GB0006061963", # "IE00B4WL8048", "IE00B90P3080", "LU0827884411", ]) results = simulator.run() Simulator.describe_and_plot(results)