From daa2b6aa78a5a6b61212b9e8c98a345883da229d Mon Sep 17 00:00:00 2001 From: Brett Elliot Date: Tue, 4 Mar 2025 20:29:07 -0500 Subject: [PATCH] added analyze_backtest which can be turned off. --- lumibot/example_strategies/classic_60_40.py | 7 +----- lumibot/example_strategies/crypto_50_50.py | 6 +---- lumibot/strategies/_strategy.py | 8 ++++++ lumibot/strategies/strategy.py | 5 +++- lumibot/tools/save_data.py | 27 ++++++++++----------- tests/test_alpaca_backtesting.py | 26 ++++++++++---------- 6 files changed, 40 insertions(+), 39 deletions(-) diff --git a/lumibot/example_strategies/classic_60_40.py b/lumibot/example_strategies/classic_60_40.py index 30074697..fbfc1464 100644 --- a/lumibot/example_strategies/classic_60_40.py +++ b/lumibot/example_strategies/classic_60_40.py @@ -32,13 +32,8 @@ datasource_class=AlpacaBacktesting, backtesting_start= datetime(2023, 1, 2), backtesting_end=datetime(2025, 1, 1), - benchmark_asset=None, + analyze_backtest=False, parameters=parameters, - show_plot=False, - show_tearsheet=False, - save_tearsheet=False, - show_indicators=False, - save_logfile=False, show_progress_bar=True, # AlpacaBacktesting kwargs diff --git a/lumibot/example_strategies/crypto_50_50.py b/lumibot/example_strategies/crypto_50_50.py index b6dd1aee..41b422de 100644 --- a/lumibot/example_strategies/crypto_50_50.py +++ b/lumibot/example_strategies/crypto_50_50.py @@ -46,11 +46,7 @@ backtesting_start=datetime(2025, 1, 1), backtesting_end=datetime(2025, 2, 1), parameters=parameters, - show_plot=False, - show_tearsheet=False, - save_tearsheet=False, - show_indicators=False, - save_logfile=False, + analyze_backtest=False, show_progress_bar=True, # AlpacaBacktesting kwargs diff --git a/lumibot/strategies/_strategy.py b/lumibot/strategies/_strategy.py index 03aea2e0..c9563cb0 100644 --- a/lumibot/strategies/_strategy.py +++ b/lumibot/strategies/_strategy.py @@ -132,6 +132,7 @@ def __init__( stats_file=None, risk_free_rate=None, benchmark_asset: str | Asset | None = "SPY", + analyze_backtest: bool = True, backtesting_start=None, backtesting_end=None, quote_asset=Asset(symbol="USD", asset_type="forex"), @@ -179,6 +180,8 @@ def __init__( benchmark_asset : Asset or str or None The asset to use as the benchmark for the strategy. Defaults to "SPY". Strings are converted to Asset objects with an asset_type="stock". None, means don't benchmark the strategy. + analyze_backtest: bool + Run the backtest_analysis function at the end. backtesting_start : datetime.datetime The date and time to start backtesting from. Required for backtesting. backtesting_end : datetime.datetime @@ -332,6 +335,7 @@ def __init__( self.is_backtesting = self.broker.IS_BACKTESTING_BROKER self._benchmark_asset = benchmark_asset + self._analyze_backtest = analyze_backtest # Get the backtesting start and end dates from the broker data source if we are backtesting if self.is_backtesting: @@ -956,6 +960,7 @@ def run_backtest( name = None, budget = None, benchmark_asset: str | Asset | None="SPY", + analyze_backtest: bool = True, plot_file_html = None, trades_file = None, settings_file = None, @@ -1017,6 +1022,8 @@ def run_backtest( benchmark_asset : str or Asset or None The benchmark asset to use for the backtest to compare to. If it is a string then it will be converted to a stock Asset object. If it is None, no benchmarking will occur. + analyze_backtest: bool = True + Run the backtest_analysis method on the strategy. plot_file_html : str The file to write the plot html to. trades_file : str @@ -1104,6 +1111,7 @@ def run_backtest( name = self.__name__ self._name = name + self._analyze_backtest = analyze_backtest # If backtesting_start is None, then check the BACKTESTING_START environment variable if backtesting_start is None and BACKTESTING_START is not None: diff --git a/lumibot/strategies/strategy.py b/lumibot/strategies/strategy.py index 76769636..e6562aef 100644 --- a/lumibot/strategies/strategy.py +++ b/lumibot/strategies/strategy.py @@ -2905,6 +2905,9 @@ def write_backtest_settings(self, settings_file: str): >>> self.write_backtest_settings("backtest_settings.json") """ + if not self._analyze_backtest: + return + datasource = self.broker.data_source auto_adjust = datasource.auto_adjust if hasattr(datasource, "auto_adjust") else False settings = { @@ -2920,7 +2923,7 @@ def write_backtest_settings(self, settings_file: str): "quote_asset": self.quote_asset, "benchmark_asset": self._benchmark_asset, "starting_positions": self.starting_positions, - "parameters": self.parameters, + "parameters": {k: v for k, v in self.parameters.items() if k != 'pandas_data'} } os.makedirs(os.path.dirname(settings_file), exist_ok=True) with open(settings_file, "w") as outfile: diff --git a/lumibot/tools/save_data.py b/lumibot/tools/save_data.py index e00666e8..b34f8d57 100644 --- a/lumibot/tools/save_data.py +++ b/lumibot/tools/save_data.py @@ -1,6 +1,6 @@ import logging -import os -import sys +from datetime import datetime +from zoneinfo import ZoneInfo from lumibot.credentials import ALPACA_TEST_CONFIG from lumibot.backtesting import AlpacaBacktesting @@ -10,22 +10,21 @@ if __name__ == "__main__": - tickers = [ - "BTC/USD", - "AMZN" - ] - start_date = "2021-01-01" - end_date = "2021-01-10" - # timestep = 'day' - timestep = 'hour' - # timestep = 'minute' + datetime_start = datetime(2025, 1, 13) + datetime_end = datetime(2025, 1, 18) + timestep = 'day' + tzinfo = ZoneInfo("America/New_York") + tickers = "TSLA" refresh_cache = False + warm_up_trading_days = 0 data_source = AlpacaBacktesting( + datetime_start=datetime_start, + datetime_end=datetime_end, + config=ALPACA_TEST_CONFIG, tickers=tickers, - start_date=start_date, - end_date=end_date, timestep=timestep, - config=ALPACA_TEST_CONFIG, refresh_cache=refresh_cache, + tzinfo=tzinfo, + warm_up_trading_days=warm_up_trading_days ) diff --git a/tests/test_alpaca_backtesting.py b/tests/test_alpaca_backtesting.py index a8b5c13f..044d04eb 100644 --- a/tests/test_alpaca_backtesting.py +++ b/tests/test_alpaca_backtesting.py @@ -34,7 +34,7 @@ def test_single_stock_day_bars_america_new_york(self): datasource_class=AlpacaBacktesting, backtesting_start=backtesting_start, backtesting_end=backtesting_end, - benchmark_asset=None, + analyze_backtest=False, parameters={ "asset": Asset('AMZN', asset_type='stock'), "sleeptime": "1D", @@ -117,7 +117,7 @@ def test_get_historical_prices_single_stock_day_bars_america_new_york(self): datasource_class=AlpacaBacktesting, backtesting_start=backtesting_start, backtesting_end=backtesting_end, - benchmark_asset=None, + analyze_backtest=False, parameters={ "asset": Asset('AMZN', asset_type='stock'), "sleeptime": "1D", @@ -183,7 +183,7 @@ def test_single_stock_minute_bars_america_new_york_regular_hours(self): backtesting_start=backtesting_start, backtesting_end=backtesting_end, minutes_before_closing=0, - benchmark_asset=None, + analyze_backtest=False, parameters={ "asset": Asset('AMZN', asset_type='stock'), "sleeptime": "1M", @@ -264,7 +264,7 @@ def test_single_stock_minute_bars_america_new_york_extended_hours(self): backtesting_start=backtesting_start, backtesting_end=backtesting_end, minutes_before_closing=0, - benchmark_asset=None, + analyze_backtest=False, parameters={ "asset": Asset('AMZN', asset_type='stock'), "sleeptime": "1M", @@ -344,7 +344,7 @@ def test_single_stock_30_minute_bars_america_new_york_regular_hours(self): backtesting_start=backtesting_start, backtesting_end=backtesting_end, minutes_before_closing=0, - benchmark_asset=None, + analyze_backtest=False, parameters={ "asset": Asset('AMZN', asset_type='stock'), "sleeptime": "30M", @@ -428,7 +428,7 @@ def test_single_stock_minute_bars_america_new_york_with_60m_sleeptime(self): backtesting_start=backtesting_start, backtesting_end=backtesting_end, minutes_before_closing=0, - benchmark_asset=None, + analyze_backtest=False, parameters={ "asset": Asset('AMZN', asset_type='stock'), "sleeptime": "60M", @@ -505,7 +505,7 @@ def test_single_stock_hour_bars_america_new_york(self): backtesting_start=backtesting_start, backtesting_end=backtesting_end, minutes_before_closing=0, - benchmark_asset=None, + analyze_backtest=False, parameters={ "asset": Asset('AMZN', asset_type='stock'), "sleeptime": "60M", @@ -590,7 +590,7 @@ def test_get_historical_prices_single_stock_hour_bars_america_new_york(self): datasource_class=AlpacaBacktesting, backtesting_start=backtesting_start, backtesting_end=backtesting_end, - benchmark_asset=None, + analyze_backtest=False, parameters={ "asset": Asset('AMZN', asset_type='stock'), "sleeptime": "1D", @@ -666,7 +666,7 @@ def test_single_crypto_day_bars_america_chicago(self): backtesting_start=backtesting_start, backtesting_end=backtesting_end, minutes_before_closing=0, - benchmark_asset=None, + analyze_backtest=False, parameters={ "asset": Asset('BTC', asset_type='crypto'), "sleeptime": "1D", @@ -749,7 +749,7 @@ def test_single_crypto_minute_bars_america_chicago(self): backtesting_start=backtesting_start, backtesting_end=backtesting_end, minutes_before_closing=0, - benchmark_asset=None, + analyze_backtest=False, parameters={ "asset": Asset('BTC', asset_type='crypto'), "sleeptime": "1M", @@ -831,7 +831,7 @@ def test_single_crypto_hour_bars_utc(self): backtesting_start=backtesting_start, backtesting_end=backtesting_end, minutes_before_closing=0, - benchmark_asset=None, + analyze_backtest=False, parameters={ "asset": Asset('BTC', asset_type='crypto'), "sleeptime": "60M", @@ -915,7 +915,7 @@ def test_single_crypto_hour_bars_america_chicago(self): backtesting_start=backtesting_start, backtesting_end=backtesting_end, minutes_before_closing=0, - benchmark_asset=None, + analyze_backtest=False, parameters={ "asset": Asset('BTC', asset_type='crypto'), "sleeptime": "60M", @@ -998,7 +998,7 @@ def test_get_historical_prices_single_crypto_hour_bars_america_chicago(self): backtesting_start=backtesting_start, backtesting_end=backtesting_end, minutes_before_closing=0, - benchmark_asset=None, + analyze_backtest=False, parameters={ "asset": Asset('BTC', asset_type='crypto'), "sleeptime": "60M",