chart/app/runtime.py

38 lines
1.3 KiB
Python

import asyncio
from dataclasses import dataclass, field
from app.bars.models import Bar, Timeframe
from app.bars.store import InMemoryBarStore
from app.config import Settings
from app.market.factory import live_source, seed_source
from app.market.stream import StreamService
@dataclass
class Runtime:
settings: Settings
store: InMemoryBarStore = field(init=False)
stream: StreamService = field(init=False)
subscribers: set[asyncio.Queue[Bar]] = field(default_factory=set)
def __post_init__(self) -> None:
self.store = InMemoryBarStore(self.settings.max_bars_per_tf)
self.stream = StreamService(live_source(self.settings), self.settings.yahoo_symbol)
self.stream.add_handler(self.on_bar)
async def on_bar(self, bar: Bar) -> None:
self.store.put(bar)
for queue in self.subscribers.copy():
if queue.full():
queue.get_nowait()
queue.put_nowait(bar)
async def start(self) -> asyncio.Task:
try:
await self.stream.seed(
seed_source(self.settings), Timeframe.M1, self.settings.seed_1m_range
)
except Exception:
# A transient seed failure must not prevent the live stream or UI starting.
pass
return asyncio.create_task(self.stream.run(), name="market-stream")