diff --git a/core/interfaces/abstract_executor_actor_factory.py b/core/interfaces/abstract_executor_actor_factory.py index 14243813..ea1ecaae 100644 --- a/core/interfaces/abstract_executor_actor_factory.py +++ b/core/interfaces/abstract_executor_actor_factory.py @@ -1,7 +1,7 @@ from abc import ABC, abstractmethod from core.interfaces.abstract_market_repository import AbstractMarketRepository -from core.models.order import OrderType +from core.models.order_type import OrderType from core.models.symbol import Symbol from core.models.timeframe import Timeframe diff --git a/core/models/entity/base.py b/core/models/entity/_base.py similarity index 72% rename from core/models/entity/base.py rename to core/models/entity/_base.py index 1b2f2873..fa7cb6b8 100644 --- a/core/models/entity/base.py +++ b/core/models/entity/_base.py @@ -17,12 +17,10 @@ def to_dict(self) -> Dict[str, Any]: result = {**field_dict, **property_dict} for key, value in result.items(): - if isinstance(value, Enum): - result[key] = str(value) - - elif hasattr(value, "to_dict") and callable(value.to_dict): + if hasattr(value, "to_dict") and callable(value.to_dict): result[key] = value.to_dict() - + elif isinstance(value, Enum): + result[key] = str(value) elif isinstance(value, list): result[key] = [ v.to_dict() if hasattr(v, "to_dict") and callable(v.to_dict) else v @@ -32,7 +30,7 @@ def to_dict(self) -> Dict[str, Any]: return result def to_json(self) -> str: - return json.dumps(self.to_dict()) + return json.dumps(self.to_dict(), default=str) @classmethod def from_dict(cls, data: Dict[str, Any]) -> "Entity": @@ -40,8 +38,7 @@ def from_dict(cls, data: Dict[str, Any]) -> "Entity": @classmethod def from_json(cls, json_str: str) -> "Entity": - data = json.loads(json_str) - return cls.from_dict(data) + return cls.from_dict(json.loads(json_str)) @classmethod def from_list(cls, values: List[Any]) -> "Entity": @@ -55,8 +52,11 @@ def from_list(cls, values: List[Any]) -> "Entity": return cls.from_dict(data) def __str__(self) -> str: - field_dict = self.to_dict() - field_strings = [] + field_dict = { + key: value + for key, value in self.to_dict().items() + if not key.startswith("_") + } def format_value(value): if isinstance(value, dict): @@ -69,23 +69,13 @@ def format_value(value): return f"{value:.8f}" return str(value) - for key, value in field_dict.items(): - if value is not None: - formatted_value = format_value(value) - field_strings.append(f"{key}={formatted_value}") - else: - field_strings.append(f"{key}=NA") - - return ", ".join(field_strings) + return ", ".join( + f"{key}={format_value(value)}" if value is not None else f"{key}=NA" + for key, value in field_dict.items() + ) def __repr__(self) -> str: return f"{self.__class__.__name__}({self.__str__()})" def __format__(self, format_spec: str) -> str: - if format_spec == "": - return self.__str__() - - if format_spec == "json": - return self.to_json() - - return self.__str__() + return self.to_json() if format_spec == "json" else self.__str__() diff --git a/core/models/entity/bar.py b/core/models/entity/bar.py index e0927b55..065440e8 100644 --- a/core/models/entity/bar.py +++ b/core/models/entity/bar.py @@ -1,6 +1,6 @@ from dataclasses import dataclass -from .base import Entity +from ._base import Entity from .ohlcv import OHLCV diff --git a/core/models/entity/ohlcv.py b/core/models/entity/ohlcv.py index 06673076..fcb74696 100644 --- a/core/models/entity/ohlcv.py +++ b/core/models/entity/ohlcv.py @@ -3,7 +3,7 @@ from core.models.candle_type import CandleType -from .base import Entity +from ._base import Entity @dataclass(frozen=True) diff --git a/core/models/order.py b/core/models/entity/order.py similarity index 54% rename from core/models/order.py rename to core/models/entity/order.py index 6de0ef99..9e3a988a 100644 --- a/core/models/order.py +++ b/core/models/entity/order.py @@ -1,23 +1,14 @@ import uuid -from dataclasses import asdict, dataclass, field +from dataclasses import dataclass, field from datetime import datetime -from enum import Enum, auto +from core.models.order_type import OrderStatus, OrderType -class OrderStatus(Enum): - PENDING = "pending" - EXECUTED = "executed" - FAILED = "failed" - CLOSED = "closed" - - -class OrderType(Enum): - MARKET = auto() - PAPER = auto() +from ._base import Entity @dataclass(frozen=True) -class Order: +class Order(Entity): status: OrderStatus price: float size: float @@ -25,6 +16,3 @@ class Order: id: str = field(default_factory=lambda: str(uuid.uuid4())) timestamp: float = field(default_factory=lambda: int(datetime.now().timestamp())) fee: float = field(default_factory=lambda: 0.0) - - def to_dict(self): - return asdict(self) diff --git a/core/models/order_type.py b/core/models/order_type.py new file mode 100644 index 00000000..8caead36 --- /dev/null +++ b/core/models/order_type.py @@ -0,0 +1,13 @@ +from enum import Enum, auto + + +class OrderStatus(Enum): + PENDING = "pending" + EXECUTED = "executed" + FAILED = "failed" + CLOSED = "closed" + + +class OrderType(Enum): + MARKET = auto() + PAPER = auto() diff --git a/core/models/position.py b/core/models/position.py index d31146de..ba8bdeb4 100644 --- a/core/models/position.py +++ b/core/models/position.py @@ -7,7 +7,8 @@ import numpy as np from .entity.ohlcv import OHLCV -from .order import Order, OrderStatus +from .entity.order import Order +from .order_type import OrderStatus from .position_risk import PositionRisk from .profit_target import ProfitTarget from .risk_type import PositionRiskType, SessionRiskType, SignalRiskType diff --git a/core/queries/position.py b/core/queries/position.py index 79836b3a..f807302e 100644 --- a/core/queries/position.py +++ b/core/queries/position.py @@ -1,7 +1,7 @@ from dataclasses import dataclass, field from core.events.base import EventMeta -from core.models.order import Order +from core.models.entity.order import Order from core.models.position import Position from core.queries.base import Query, QueryGroup diff --git a/executor/_factory.py b/executor/_factory.py index d5ebeb96..11c4cc65 100644 --- a/executor/_factory.py +++ b/executor/_factory.py @@ -1,6 +1,6 @@ from core.interfaces.abstract_actor import AbstractActor from core.interfaces.abstract_executor_actor_factory import AbstractExecutorActorFactory -from core.models.order import OrderType +from core.models.order_type import OrderType from core.models.symbol import Symbol from core.models.timeframe import Timeframe diff --git a/executor/_paper_actor.py b/executor/_paper_actor.py index 368427df..8380c57d 100644 --- a/executor/_paper_actor.py +++ b/executor/_paper_actor.py @@ -11,7 +11,8 @@ ) from core.mixins import EventHandlerMixin from core.models.entity.ohlcv import OHLCV -from core.models.order import Order, OrderStatus, OrderType +from core.models.entity.order import Order +from core.models.order_type import OrderStatus, OrderType from core.models.position import Position from core.models.side import PositionSide from core.models.symbol import Symbol diff --git a/feed/_historical.py b/feed/_historical.py index 3941f399..89fb80fc 100644 --- a/feed/_historical.py +++ b/feed/_historical.py @@ -14,7 +14,6 @@ from core.models.timeframe import Timeframe - class AsyncHistoricalData: def __init__( self, diff --git a/sor/_router.py b/sor/_router.py index 57acfa41..897b4e6c 100644 --- a/sor/_router.py +++ b/sor/_router.py @@ -10,8 +10,9 @@ from core.interfaces.abstract_config import AbstractConfig from core.interfaces.abstract_event_manager import AbstractEventManager from core.interfaces.abstract_exhange_factory import AbstractExchangeFactory +from core.models.entity.order import Order from core.models.exchange import ExchangeType -from core.models.order import Order, OrderStatus +from core.models.order_type import OrderStatus from core.models.side import PositionSide from core.queries.account import GetBalance from core.queries.broker import GetSymbol, GetSymbols, HasPosition @@ -65,6 +66,8 @@ def get_close_position(self, query: GetClosePosition): self.config["max_order_slice"], ) + print(trade) + if not trade: return Order(status=OrderStatus.FAILED, price=0, size=0) diff --git a/system/backtest.py b/system/backtest.py index a8f4d8bf..430d9f51 100644 --- a/system/backtest.py +++ b/system/backtest.py @@ -11,7 +11,7 @@ from core.models.feed import FeedType from core.models.lookback import Lookback from core.models.optimizer import Optimizer -from core.models.order import OrderType +from core.models.order_type import OrderType from core.models.strategy import Strategy from core.models.symbol import Symbol from core.models.timeframe import Timeframe diff --git a/system/trading.py b/system/trading.py index abf064ff..353f4b8e 100644 --- a/system/trading.py +++ b/system/trading.py @@ -19,7 +19,7 @@ from core.models.exchange import ExchangeType from core.models.feed import FeedType from core.models.lookback import Lookback -from core.models.order import OrderType +from core.models.order_type import OrderType logger = logging.getLogger(__name__)