| """ |
| Market State Serializer. |
| |
| Converts order book snapshot + agent-specific state into a compact string |
| that the LLM reads as its "user" message each tick. |
| """ |
|
|
| from engine.order_book import OrderBook |
|
|
|
|
| def market_state_to_string( |
| book: OrderBook, |
| agent_id: str, |
| position: int, |
| cash: float, |
| price_history: list[float], |
| ) -> str: |
| """ |
| Build the ~150-token market state string that agents receive each tick. |
| |
| Includes: best bid, best ask, mid price, last trade price, |
| agent's position, agent's cash, last 10 prices. |
| """ |
| snap = book.snapshot() |
|
|
| bb = f"{snap['best_bid']:.2f}" if snap['best_bid'] is not None else "none" |
| ba = f"{snap['best_ask']:.2f}" if snap['best_ask'] is not None else "none" |
| mid = f"{snap['mid_price']:.2f}" if snap['mid_price'] is not None else "none" |
| spread = f"{snap['spread']:.4f}" if snap['spread'] is not None else "none" |
| last_price = f"{snap['last_trade_price']:.2f}" if snap['last_trade_price'] is not None else "none" |
|
|
| |
| recent = price_history[-10:] if price_history else [] |
| price_str = ", ".join(f"{p:.2f}" for p in recent) if recent else "none" |
|
|
| lines = [ |
| f"Best Bid: {bb} | Best Ask: {ba} | Mid: {mid} | Spread: {spread}", |
| f"Last Trade: {last_price}", |
| f"Recent Prices (last {len(recent)}): [{price_str}]", |
| f"Your Position: {position} units | Your Cash: {cash:.2f}", |
| ] |
| return "\n".join(lines) |
|
|