Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

before_market_closes not normally called in backtest #573

Open
brettelliot opened this issue Oct 12, 2024 · 2 comments
Open

before_market_closes not normally called in backtest #573

brettelliot opened this issue Oct 12, 2024 · 2 comments

Comments

@brettelliot
Copy link
Collaborator

brettelliot commented Oct 12, 2024

When using lumibot 3.7.8 and python 3.11 before_market_closes is not normally called during a backtest:

Running backtest of MyStrategy
2024-10-12 07:39:18 | __main__ | INFO | Running backtest of MyStrategy
Starting backtest for MyStrategy...
2024-10-12 07:39:18 | backtest_stats | INFO | Starting backtest...
2024-10-12 07:39:18 | root | INFO | Backtesting starting...
2020-01-01 00:00:00-05:00 initialize called
2020-01-02 09:30:00-05:00 on_trading_iteration called
2020-01-03 09:30:00-05:00 on_trading_iteration called
2020-01-06 09:30:00-05:00 on_trading_iteration called
2020-01-07 09:30:00-05:00 on_trading_iteration called
2020-01-08 09:30:00-05:00 on_trading_iteration called
2020-01-09 09:30:00-05:00 on_trading_iteration called
2020-01-10 15:55:00-05:00 before_market_closes called
show_indicators is False, not creating the plot file.

Code:

import logging
from datetime import datetime

from lumibot.backtesting import YahooDataBacktesting
from lumibot.strategies.strategy import Strategy
from lumibot.data_sources import data_source_backtesting

logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
logger.addHandler(logging.StreamHandler())

"""
This shows that the before_market_closes method is not called in the backtest
run using: python -m lumibots.examples.example_backtest_doesnt_call_before_market_closes
"""

# Disable the progress bar
data_source_backtesting.print_progress_bar = lambda *args, **kwargs: None


class MyStrategy(Strategy):

    def initialize(self, symbol=""):
        dt = self.get_datetime()
        logger.info(f"{dt} initialize called")
        self.sleeptime = "1D"
        self.minutes_before_closing = 5

    # def before_market_opens(self):
    #     dt = self.get_datetime()
    #     logger.info(f"{dt} before_market_opens called")

    def before_market_closes(self):
        dt = self.get_datetime()
        logger.info(f"{dt} before_market_closes called")

    # def after_market_closes(self):
    #     dt = self.get_datetime()
    #     logger.info(f"{dt} after_market_closes called")

    def on_trading_iteration(self):
        dt = self.get_datetime()
        logger.info(f"{dt} on_trading_iteration called")


if __name__ == "__main__":
    logger.info("Running backtest of MyStrategy")

    backtesting_start = datetime(2020, 1, 1)
    backtesting_end = datetime(2020, 1, 10)

    result = MyStrategy.backtest(
        YahooDataBacktesting,
        backtesting_start,
        backtesting_end,
        show_plot=False,
        show_tearsheet=False,
        save_tearsheet=False,
        save_logfile=False,
        show_indicators=False,
    )

@brettelliot brettelliot changed the title before_market_closes never called in backtest before_market_closes not normally called in backtest Oct 12, 2024
@brettelliot
Copy link
Collaborator Author

brettelliot commented Oct 14, 2024

I think I found the bug but I don't know how to fix it. In strategy_executor.py, in the backtesting block, we don't call before_market_close or after_market_close.

image

Im not sure if we need to put the calls in this block after on_trading_iteration. There's another option... There is some code in _strategy_sleep that processes expired options. That's another reasonable approach, although its not guranteed to run only for backtesting.

I did try moving the code up, and it kinda worked? Im not sure why but its calling things twice:

2024-10-14 12:02:54,906 | __main__ | INFO | 2023-01-03 09:30:00-05:00 on_trading_iteration called.
2024-10-14 12:02:54,914 | __main__ | INFO | 2023-01-03 15:55:00-05:00 before_market_closes called
2024-10-14 12:02:54,914 | __main__ | INFO | 2023-01-03 16:00:00-05:00 after_market_closes called
2024-10-14 12:02:54,914 | __main__ | INFO | 2023-01-03 15:55:00-05:00 before_market_closes called
2024-10-14 12:02:54,915 | __main__ | INFO | 2023-01-03 16:00:00-05:00 after_market_closes called
2024-10-14 12:02:54,917 | __main__ | INFO | 2023-01-04 09:30:00-05:00 on_trading_iteration called.
2024-10-14 12:02:54,918 | __main__ | INFO | 2023-01-04 15:55:00-05:00 before_market_closes called
2024-10-14 12:02:54,918 | __main__ | INFO | 2023-01-04 16:00:00-05:00 after_market_closes called
2024-10-14 12:02:54,919 | __main__ | INFO | 2023-01-04 15:55:00-05:00 before_market_closes called
2024-10-14 12:02:54,919 | __main__ | INFO | 2023-01-04 16:00:00-05:00 after_market_closes called
2024-10-14 12:02:54,921 | __main__ | INFO | 2023-01-05 09:30:00-05:00 on_trading_iteration called.
2024-10-14 12:02:54,922 | __main__ | INFO | 2023-01-05 15:55:00-05:00 before_market_closes called
2024-10-14 12:02:54,922 | __main__ | INFO | 2023-01-05 16:00:00-05:00 after_market_closes called
2024-10-14 12:02:54,922 | __main__ | INFO | 2023-01-05 15:55:00-05:00 before_market_closes called
2024-10-14 12:02:54,923 | __main__ | INFO | 2023-01-05 16:00:00-05:00 after_market_closes called
2024-10-14 12:02:54,924 | __main__ | INFO | 2023-01-06 09:30:00-05:00 on_trading_iteration called.

@grzesir Do you have any thoughts? I could try it out and let you know how it works.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants
@brettelliot and others