From 8d9664cf939bbde6ae5d561e490327b5479080af Mon Sep 17 00:00:00 2001 From: Juliette James Date: Wed, 12 Jun 2024 21:38:02 +0100 Subject: [PATCH] Qs649 update backtest target allocations (#397) * Changed datetime to date in get_target_allocations method * Updated pypi package to qstrader 0.2.8 --- CHANGELOG.md | 5 +++ pyproject.toml | 2 +- qstrader/trading/backtest.py | 2 +- .../integration/trading/test_backtest_e2e.py | 37 ++++++++++++++++++- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5e602d..5471687 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 0.2.8 + +* Updates BacktestTradingSession.get_target_allocations() to use burn_in_dt.date() instead of burn_in_dt Timestamp. Previous method compared a Timestamp to a datetime.date. +* Adds an integration test to check that target allocations match the expected output, including a date index. + # 0.2.7 * Updates the execution handler to update final orders ensuring an execution order is created in the event of a single submission without a further rebalance. diff --git a/pyproject.toml b/pyproject.toml index 0ea19ef..d06027e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "qstrader" -version = "0.2.7" +version = "0.2.8" dependencies = [ "click>=8.1", "matplotlib>=3.8", diff --git a/qstrader/trading/backtest.py b/qstrader/trading/backtest.py index fb6f62f..98d4c09 100644 --- a/qstrader/trading/backtest.py +++ b/qstrader/trading/backtest.py @@ -362,7 +362,7 @@ def get_target_allocations(self): alloc_df.index = alloc_df.index.date alloc_df = alloc_df.reindex(index=equity_curve.index, method='ffill') if self.burn_in_dt is not None: - alloc_df = alloc_df[self.burn_in_dt:] + alloc_df = alloc_df[self.burn_in_dt.date():] return alloc_df def run(self, results=False): diff --git a/tests/integration/trading/test_backtest_e2e.py b/tests/integration/trading/test_backtest_e2e.py index d30507f..0d46aa5 100644 --- a/tests/integration/trading/test_backtest_e2e.py +++ b/tests/integration/trading/test_backtest_e2e.py @@ -159,4 +159,39 @@ def test_backtest_buy_and_hold(etf_filepath, capsys): expected_execution_text = "(2015-11-09 14:30:00+00:00) - executed order:" captured = capsys.readouterr() - assert expected_execution_text in captured.out + assert expected_execution_text in captured.out + + +def test_backtest_target_allocations(etf_filepath,): + """ + """ + settings.print_events=True + os.environ['QSTRADER_CSV_DATA_DIR'] = etf_filepath + + assets = ['EQ:ABC', 'EQ:DEF'] + universe = StaticUniverse(assets) + signal_weights = {'EQ:ABC': 0.6, 'EQ:DEF': 0.4} + alpha_model = FixedSignalsAlphaModel(signal_weights) + + start_dt = pd.Timestamp('2019-01-01 00:00:00', tz=pytz.UTC) + end_dt = pd.Timestamp('2019-01-31 23:59:00', tz=pytz.UTC) + burn_in_dt = pd.Timestamp('2019-01-07 14:30:00', tz=pytz.UTC) + + backtest = BacktestTradingSession( + start_dt, + end_dt, + universe, + alpha_model, + portfolio_id='000001', + rebalance='weekly', + rebalance_weekday='WED', + long_only=True, + cash_buffer_percentage=0.05, + burn_in_dt = burn_in_dt + ) + backtest.run(results=False) + + target_allocations = backtest.get_target_allocations() + expected_ta = pd.DataFrame(data={'EQ:ABC': 0.6, 'EQ:DEF': 0.4}, index=pd.date_range("20190125", periods=5, freq='B')) + actual_ta = target_allocations.tail() + assert expected_ta.equals(actual_ta)