from dataclasses import asdict, dataclass from enum import Enum from typing import Any class Timeframe(str, Enum): M1 = "1m" M2 = "2m" M5 = "5m" M15 = "15m" M30 = "30m" H1 = "1h" H4 = "4h" D1 = "1d" @property def seconds(self) -> int: seconds = { self.M1: 60, self.M2: 120, self.M5: 300, self.M15: 900, self.M30: 1800, self.H1: 3600, self.H4: 14400, } if self is self.D1: raise ValueError("1d is session-defined, not a fixed number of seconds") return seconds[self] @dataclass(slots=True) class Bar: tf: Timeframe t: int o: float h: float l: float c: float v: int closed: bool symbol: str source: str def to_dict(self) -> dict[str, Any]: value = asdict(self) value["tf"] = self.tf.value return value @classmethod def from_dict(cls, value: dict[str, Any]) -> "Bar": return cls( tf=Timeframe(value["tf"]), t=int(value["t"]), o=float(value["o"]), h=float(value["h"]), l=float(value["l"]), c=float(value["c"]), v=int(value.get("v") or 0), closed=bool(value["closed"]), symbol=str(value["symbol"]), source=str(value["source"]), )