From 17bb6408ea87b570ffe2e731717736ee10bcc68f Mon Sep 17 00:00:00 2001 From: Ali Majdzadeh-Kohbanani Date: Wed, 4 Jun 2025 01:42:37 -0400 Subject: [PATCH 1/2] Disable wait on order processing when backtesting Broker waits when processing orders only if it is not a backtesting broker. Resolves #764 --- lumibot/brokers/broker.py | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/lumibot/brokers/broker.py b/lumibot/brokers/broker.py index 6860ef4e3..8c17eba71 100644 --- a/lumibot/brokers/broker.py +++ b/lumibot/brokers/broker.py @@ -1005,21 +1005,38 @@ def submit_orders(self, orders, **kwargs) -> Union[Order, list[Order]]: def wait_for_order_registration(self, order): """Wait for the order to be registered by the broker""" - order.wait_to_be_registered() + if not self.IS_BACKTESTING_BROKER: + order.wait_to_be_registered() + else: + self.logger.warning(f"Not applicable when backtesting") + return + def wait_for_order_execution(self, order): """Wait for the order to execute/be canceled""" - order.wait_to_be_closed() + if not self.IS_BACKTESTING_BROKER: + order.wait_to_be_closed() + else: + self.logger.warning(f"Not applicable when backtesting") + return def wait_for_orders_registration(self, orders): """Wait for the orders to be registered by the broker""" - for order in orders: - order.wait_to_be_registered() + if not self.IS_BACKTESTING_BROKER: + for order in orders: + order.wait_to_be_registered() + else: + self.logger.warning(f"Not applicable when backtesting") + return def wait_for_orders_execution(self, orders): """Wait for the orders to execute/be canceled""" - for order in orders: - order.wait_to_be_closed() + if not self.IS_BACKTESTING_BROKER: + for order in orders: + order.wait_to_be_closed() + else: + self.logger.warning(f"Not applicable when backtesting") + return def cancel_orders(self, orders): """cancel orders""" From e609fba88b5904281326bafabc7953cb364d8312 Mon Sep 17 00:00:00 2001 From: Ali Majdzadeh-Kohbanani Date: Fri, 6 Jun 2025 01:02:14 -0400 Subject: [PATCH 2/2] Deduplicate StrEnum A single `StrEnum` class is defined and imported by `Order` and `Asset` classes. Resolves #788 --- lumibot/entities/asset.py | 26 +------------------------- lumibot/entities/order.py | 28 +--------------------------- lumibot/tools/types.py | 23 +++++++++++++++++++++++ 3 files changed, 25 insertions(+), 52 deletions(-) diff --git a/lumibot/entities/asset.py b/lumibot/entities/asset.py index 4da0b06f4..79d7d591b 100644 --- a/lumibot/entities/asset.py +++ b/lumibot/entities/asset.py @@ -1,32 +1,8 @@ from collections import UserDict from datetime import date, datetime -from enum import Enum from lumibot.tools import parse_symbol - - -# Custom string enum implementation for Python 3.9 compatibility -class StrEnum(str, Enum): - """ - A string enum implementation that works with Python 3.9+ - - This class extends str and Enum to create string enums that: - 1. Can be used like strings (string methods, comparison) - 2. Are hashable (for use in dictionaries, sets, etc.) - 3. Can be used in string comparisons without explicit conversion - """ - def __str__(self): - return self.value - - def __eq__(self, other): - if isinstance(other, str): - return self.value == other - return super().__eq__(other) - - def __hash__(self): - # Use the hash of the enum member, not the string value - # This ensures proper hashability while maintaining enum identity - return super().__hash__() +from lumibot.tools.types import StrEnum class Asset: diff --git a/lumibot/entities/order.py b/lumibot/entities/order.py index 428a9184c..c724cf458 100644 --- a/lumibot/entities/order.py +++ b/lumibot/entities/order.py @@ -2,38 +2,12 @@ import uuid from collections import namedtuple from decimal import Decimal -from enum import Enum from threading import Event import datetime from typing import Union import lumibot.entities as entities -from lumibot.tools.types import check_positive, check_price - - -# Custom string enum implementation for Python 3.9 compatibility -class StrEnum(str, Enum): - """ - A string enum implementation that works with Python 3.9+ - - This class extends str and Enum to create string enums that: - 1. Can be used like strings (string methods, comparison) - 2. Are hashable (for use in dictionaries, sets, etc.) - 3. Can be used in string comparisons without explicit conversion - """ - def __str__(self): - return self.value - - def __eq__(self, other): - if isinstance(other, str): - return self.value == other - return super().__eq__(other) - - def __hash__(self): - # Use the hash of the enum member, not the string value - # This ensures proper hashability while maintaining enum identity - return super().__hash__() - +from lumibot.tools.types import check_positive, check_price, StrEnum SELL = "sell" BUY = "buy" diff --git a/lumibot/tools/types.py b/lumibot/tools/types.py index f0bf8cc43..114fbb6b1 100644 --- a/lumibot/tools/types.py +++ b/lumibot/tools/types.py @@ -1,6 +1,29 @@ import warnings +from enum import Enum from decimal import Decimal +# Custom string enum implementation for Python 3.9 compatibility +class StrEnum(str, Enum): + """ + A string enum implementation that works with Python 3.9+ + + This class extends str and Enum to create string enums that: + 1. Can be used like strings (string methods, comparison) + 2. Are hashable (for use in dictionaries, sets, etc.) + 3. Can be used in string comparisons without explicit conversion + """ + def __str__(self): + return self.value + + def __eq__(self, other): + if isinstance(other, str): + return self.value == other + return super().__eq__(other) + + def __hash__(self): + # Use the hash of the enum member, not the string value + # This ensures proper hashability while maintaining enum identity + return super().__hash__() def check_numeric( input, type, error_message, positive=True, strict=False, nullable=False, ratio=False, allow_negative=True