Coverage for src/finbot/market/models.py: 100%

29 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-08-21 17:12 +0000

1import math 

2from dataclasses import dataclass 

3from datetime import datetime 

4 

5 

6@dataclass 

7class Bar: 

8 symbol: str 

9 timestamp: datetime 

10 

11 open: float 

12 high: float 

13 low: float 

14 close: float 

15 volume: float 

16 

17 def __post_init__(self): 

18 if not isinstance(self.symbol, str) or not self.symbol.strip(): 

19 raise ValueError("Symbol must be a non-empty string.") 

20 

21 for name in ("open", "high", "low", "close"): 

22 value = getattr(self, name) 

23 

24 if not math.isfinite(value): 

25 raise ValueError(f"{name.capitalize()} price must be a valid number.") 

26 

27 if value <= 0: 

28 raise ValueError(f"{name.capitalize()} price must be greater than zero.") 

29 

30 if not math.isfinite(self.volume): 

31 raise ValueError("Volume must be a valid number.") 

32 

33 if self.volume < 0: 

34 raise ValueError("Volume cannot be negative.") 

35 

36 if self.high < max(self.open, self.close): 

37 raise ValueError("High price must be >= open and close.") 

38 if self.low > min(self.open, self.close): 

39 raise ValueError("Low price must be <= open and close.")