"""Starter adapters for MarketCompiler MVP""" from __future__ import annotations from abc import ABC, abstractmethod from typing import Dict, Any from .core import LocalProblem class AbstractAdapter(ABC): @abstractmethod def readState(self) -> Dict[str, Any]: pass @abstractmethod def exposeLocalProblemData(self, lp: LocalProblem) -> Dict[str, Any]: pass @abstractmethod def applyCommand(self, command: Dict[str, Any]) -> Dict[str, Any]: pass class PriceFeedAdapter(AbstractAdapter): """A tiny in-process price feed adapter with mock data.""" def __init__(self): self._state = {"prices": {"AAPL": 150.0, "MSFT": 300.0}} def readState(self) -> Dict[str, Any]: return {"prices": self._state["prices"]} def exposeLocalProblemData(self, lp: LocalProblem) -> Dict[str, Any]: return {"lp_id": lp.id, "assets": lp.assets} def applyCommand(self, command: Dict[str, Any]) -> Dict[str, Any]: # No-op for starter adapter return {"status": "ok", "command": command} class MockBrokerAdapter(AbstractAdapter): """Mock broker to simulate order placement and fills.""" def __init__(self): self._positions: Dict[str, float] = {} self._logs: list = [] def readState(self) -> Dict[str, Any]: return {"positions": self._positions} def exposeLocalProblemData(self, lp: LocalProblem) -> Dict[str, Any]: return {"lp_id": lp.id, "assets": lp.assets, "constraints": lp.constraints} def applyCommand(self, command: Dict[str, Any]) -> Dict[str, Any]: # Very tiny sim: update positions if command contains orders orders = command.get("orders", {}) for asset, qty in orders.items(): self._positions[asset] = self._positions.get(asset, 0.0) + float(qty) self._logs.append((asset, qty)) return {"status": "filled", "positions": self._positions}