Skip to content

Commit

Permalink
Fix: backtest is aborted in the middle with half of report (#539)
Browse files Browse the repository at this point in the history
* feat: compare backtest result when run it in cloud

* feat: use delay between is_backtest_done validation

* refactor: more performance in is_backtest_done

* refactor: more readable and reset counter in is_backtest_done

* Update cloud_runner.py

---------

Co-authored-by: Martin-Molinero <[email protected]>
  • Loading branch information
Romazes and Martin-Molinero authored Jan 10, 2025
1 parent 17556ea commit ff59030
Showing 1 changed file with 39 additions and 1 deletion.
40 changes: 39 additions & 1 deletion lean/components/cloud/cloud_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,44 @@ def __init__(self, logger: Logger, api_client: APIClient, task_manager: TaskMana
self._logger = logger
self._api_client = api_client
self._task_manager = task_manager
self._mismatch_counter = 0

def is_backtest_done(self, backtest_data: QCBacktest, delay: float = 10.0):
"""Checks if the backtest is complete.
:param backtest_data: The current state of the backtest.
:param delay: The delay in seconds between consecutive checks. Default is 60 seconds (1 minute).
:return: True if the backtest is complete and the state has changed, False otherwise.
"""
try:
if backtest_data.error or backtest_data.stacktrace:
self._mismatch_counter = 0
return True

is_complete = backtest_data.is_complete()
self._logger.debug(f"[Backtest ID: {backtest_data.backtestId}] Completion status: {is_complete}")

if is_complete:
if backtest_data.totalPerformance:
self._mismatch_counter = 0
return True

if self._mismatch_counter >= 6:
self._logger.error(f"[Backtest ID: {backtest_data.backtestId}] We could not retrieve "
f"the complete backtest results, please try again later.")
self._mismatch_counter = 0
return True

self._mismatch_counter += 1
self._logger.debug(f"[Backtest ID: {backtest_data.backtestId}] Incremented mismatch counter to "
f"{self._mismatch_counter}. Will re-check after {delay} seconds.")
import time
time.sleep(delay)

return False
except Exception as e:
self._logger.error(f"Error checking backtest completion status for ID {backtest_data.backtestId}: {e}")
raise

def run_backtest(self, project: QCProject, name: str) -> QCBacktest:
"""Runs a backtest in the cloud.
Expand All @@ -53,7 +91,7 @@ def run_backtest(self, project: QCProject, name: str) -> QCBacktest:
try:
return self._task_manager.poll(
make_request=lambda: self._api_client.backtests.get(project.projectId, created_backtest.backtestId),
is_done=lambda data: data.is_complete(),
is_done=self.is_backtest_done,
get_progress=lambda data: data.progress
)
except KeyboardInterrupt as e:
Expand Down

0 comments on commit ff59030

Please sign in to comment.