diff --git a/README.md b/README.md index b4c909c..83f45d5 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,20 @@ This repository provides a compact, production-oriented starting point for an ed - Security: basic governance metadata scaffolding (AuditLog placeholders). - MVP roadmap: end-to-end toy demonstration with 2 venues, 2 central analyzers. +## EnergiBridge Interop (IR) +- This repo now includes a lightweight EnergiBridge-compatible intermediate representation (IR) to map edge primitives to a common cross-venue interface. +- Key primitives: +- LocalMarketContext: per-venue local state snapshot. +- SharedSignalsIR: IR payload carrying core metrics plus optional privacy budgets and version metadata. +- Converter: EdgeSignalProcessor.to_ir(signals, context, privacy_budget, version) converts SharedSignals into SharedSignalsIR. + +Usage sketch: +- Compute signals via EdgeSignalProcessor.extract_signals(feed). +- Optionally attach a LocalMarketContext for venue context. +- Convert to IR via EdgeSignalProcessor.to_ir(signals, context, privacy_budget=0.25, version=1). + +This addition enables pluggable adapters to interoperate with a canonical IR without altering existing consumers of SharedSignals. + This project is designed to be production-friendly, with a real packaging setup, tests, and a clear readme that explains how to extend the system. See pyproject.toml for packaging configuration and the src/edgemarketsignal package for the implementation details. diff --git a/src/edgemarketsignal/__init__.py b/src/edgemarketsignal/__init__.py index e714828..656d528 100644 --- a/src/edgemarketsignal/__init__.py +++ b/src/edgemarketsignal/__init__.py @@ -1,3 +1,15 @@ -from .core import EdgeSignalProcessor, DeltaVectorClock, DeltaSync +from .core import ( + EdgeSignalProcessor, + DeltaVectorClock, + DeltaSync, + LocalMarketContext, + SharedSignalsIR, +) -__all__ = ["EdgeSignalProcessor", "DeltaVectorClock", "DeltaSync"] +__all__ = [ + "EdgeSignalProcessor", + "DeltaVectorClock", + "DeltaSync", + "LocalMarketContext", + "SharedSignalsIR", +] diff --git a/src/edgemarketsignal/core.py b/src/edgemarketsignal/core.py index fefa97c..12f1968 100644 --- a/src/edgemarketsignal/core.py +++ b/src/edgemarketsignal/core.py @@ -10,6 +10,35 @@ class SharedSignals: liquidity: int +@dataclass(frozen=True) +class LocalMarketContext: + """Lightweight per-venue local context for edge processing. + + This represents a small snapshot of the venue state captured at the edge + prior to emitting aggregated signals. It is intended for use by interoperable + bridges (EnergiBridge) to map edge primitives to a common intermediate + representation (IR). + """ + venue: str + timestamp: Optional[float] = None + liquidity: int = 0 + + +@dataclass +class SharedSignalsIR: + """EnergiBridge-inspired intermediate representation for SharedSignals. + + This is a lightweight container that carries edge-derived metrics along with + optional privacy budgeting and versioning metadata for reproducible + cross-venue analysis. + """ + venue: str + mid_price: float + liquidity: int + privacy_budget: Optional[float] = None + version: int = 0 + + class EdgeSignalProcessor: @staticmethod def extract_signals(feed: Dict) -> SharedSignals: @@ -29,6 +58,28 @@ class EdgeSignalProcessor: liquidity = int((bid_size or 0) + (ask_size or 0)) return SharedSignals(venue=venue, mid_price=float(mid_price), liquidity=liquidity) + @staticmethod + def to_ir( + signals: SharedSignals, + context: Optional[LocalMarketContext] = None, + privacy_budget: Optional[float] = None, + version: int = 0, + ) -> SharedSignalsIR: + """Convert edge SharedSignals into an EnergiBridge IR payload. + + This is deliberately lightweight: it preserves core fields and attaches + optional governance metadata. It allows adapters to interoperate via a + stable, vendor-agnostic representation without pulling in heavy payloads. + """ + _ = context # Currently unused, but kept for future extensions + return SharedSignalsIR( + venue=signals.venue, + mid_price=signals.mid_price, + liquidity=signals.liquidity, + privacy_budget=privacy_budget, + version=version, + ) + @dataclass class DeltaVectorClock: