build(agent): molt-x#ed374b iteration
This commit is contained in:
parent
dc447d8379
commit
fb110bc28b
|
|
@ -0,0 +1,21 @@
|
||||||
|
node_modules/
|
||||||
|
.npmrc
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
__tests__/
|
||||||
|
coverage/
|
||||||
|
.nyc_output/
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
.cache/
|
||||||
|
*.log
|
||||||
|
.DS_Store
|
||||||
|
tmp/
|
||||||
|
.tmp/
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
*.egg-info/
|
||||||
|
.pytest_cache/
|
||||||
|
READY_TO_PUBLISH
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
# ELAC-Plan Agents
|
||||||
|
|
||||||
|
Architecture overview:
|
||||||
|
- Primitives: LocalProblem, SharedVariables, DualVariables, PlanDelta, Governance/AuditLog
|
||||||
|
- Adapters: NBBOFeedAdapter (data feed), BrokerGatewayAdapter (execution gateway)
|
||||||
|
- Solver: LocalSolver (toy solver to generate PlanDelta from LocalProblem)
|
||||||
|
- API: FastAPI app exposing /problems and /status
|
||||||
|
- Audit: Governance/AuditLog stubs for future crypto-signed logging
|
||||||
|
|
||||||
|
Tech stack:
|
||||||
|
- Python 3.8+
|
||||||
|
- FastAPI + Uvicorn for REST API
|
||||||
|
- Pydantic for data modeling
|
||||||
|
- Lightweight, in-process Fed-Coord topology (ADMM-lite) via PlanDelta and DualVariables placeholders
|
||||||
|
|
||||||
|
Tests & packaging:
|
||||||
|
- Pytest for unit tests
|
||||||
|
- Build via python -m build
|
||||||
|
- Packaging metadata in pyproject.toml with package name edge_latency_aware_cross_venue_execution
|
||||||
|
|
||||||
|
How to contribute:
|
||||||
|
- Implement real adapters, enhance solver, and hook up a real consensus/secure-aggregation layer
|
||||||
|
- Add integration tests for end-to-end edge-to-edge flow
|
||||||
|
|
@ -1,4 +1 @@
|
||||||
# edge-latency-aware-cross-venue-execution
|
# ELAC-Plan (Edge-Latency Aware Cross-Venue Execution Planner)
|
||||||
|
|
||||||
A novel, open-source platform to generate cross-venue execution plans locally near exchanges, reducing latency and data leakage. It defines a canonical primitive set for execution planning:
|
|
||||||
- Objects/LocalProblem: per-asset, per-venue optimization t
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
"""ELAC-Plan Python package core namespace."""
|
||||||
|
|
||||||
|
from .core import LocalProblem, SharedVariables, PlanDelta, DualVariables
|
||||||
|
from .solver import LocalSolver
|
||||||
|
from .adapters import NBBOFeedAdapter, BrokerGatewayAdapter
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"LocalProblem",
|
||||||
|
"SharedVariables",
|
||||||
|
"PlanDelta",
|
||||||
|
"DualVariables",
|
||||||
|
"LocalSolver",
|
||||||
|
"NBBOFeedAdapter",
|
||||||
|
"BrokerGatewayAdapter",
|
||||||
|
]
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
from typing import Dict, Any
|
||||||
|
import json
|
||||||
|
|
||||||
|
from .core import SharedVariables, PlanDelta
|
||||||
|
|
||||||
|
|
||||||
|
class NBBOFeedAdapter:
|
||||||
|
"""Starter data-feed adapter: translates NBBO-like quotes into SharedVariables."""
|
||||||
|
|
||||||
|
def __init__(self, contract_id: str = "default-contract") -> None:
|
||||||
|
self.contract_id = contract_id
|
||||||
|
self.version = 1
|
||||||
|
|
||||||
|
def ingest(self, raw_feed: Dict[str, Any]) -> SharedVariables:
|
||||||
|
# naive translation: pass-through with minimal privacy-bounded masking
|
||||||
|
variables = {
|
||||||
|
"mid_price": raw_feed.get("mid_price"),
|
||||||
|
"depth": raw_feed.get("depth", {}),
|
||||||
|
"liquidity_proxy": raw_feed.get("liquidity_proxy", 0.0),
|
||||||
|
}
|
||||||
|
return SharedVariables(variables=variables, version=self.version, contract_id=self.contract_id)
|
||||||
|
|
||||||
|
|
||||||
|
class BrokerGatewayAdapter:
|
||||||
|
"""Starter broker gateway: accepts PlanDelta and simulates publishing to broker API."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.last_sent = None
|
||||||
|
|
||||||
|
def publish(self, delta: PlanDelta) -> str:
|
||||||
|
payload = {
|
||||||
|
"delta": delta.delta,
|
||||||
|
"timestamp": delta.timestamp,
|
||||||
|
"contract_id": delta.contract_id,
|
||||||
|
}
|
||||||
|
self.last_sent = json.dumps(payload)
|
||||||
|
# In a real system, you'd TLS-send to broker API here
|
||||||
|
return self.last_sent
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
from fastapi import FastAPI
|
||||||
|
from pydantic import BaseModel
|
||||||
|
from typing import Dict, Any, Optional
|
||||||
|
|
||||||
|
from .core import LocalProblem, PlanDelta, SharedVariables, DualVariables
|
||||||
|
from .solver import LocalSolver
|
||||||
|
from .adapters import NBBOFeedAdapter, BrokerGatewayAdapter
|
||||||
|
|
||||||
|
app = FastAPI(title="ELAC-Plan API")
|
||||||
|
|
||||||
|
_solver = LocalSolver()
|
||||||
|
_feed = NBBOFeedAdapter()
|
||||||
|
_broker = BrokerGatewayAdapter()
|
||||||
|
|
||||||
|
|
||||||
|
class LocalProblemInput(BaseModel):
|
||||||
|
id: str
|
||||||
|
asset: str
|
||||||
|
venue: str
|
||||||
|
objective: str
|
||||||
|
constraints: Dict[str, Any]
|
||||||
|
price_target: float
|
||||||
|
tolerance: float
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/problems")
|
||||||
|
def create_problem(p: LocalProblemInput) -> Dict[str, Any]:
|
||||||
|
problem = LocalProblem(
|
||||||
|
id=p.id,
|
||||||
|
asset=p.asset,
|
||||||
|
venue=p.venue,
|
||||||
|
objective=p.objective,
|
||||||
|
constraints=p.constraints,
|
||||||
|
price_target=p.price_target,
|
||||||
|
tolerance=p.tolerance,
|
||||||
|
)
|
||||||
|
delta = _solver.solve(problem)
|
||||||
|
_broker.publish(delta)
|
||||||
|
return {"problem": problem.to_json(), "delta": delta.to_json()}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/status")
|
||||||
|
def status() -> Dict[str, Any]:
|
||||||
|
return {"status": "ELAC-Plan API running"}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
from dataclasses import dataclass, asdict
|
||||||
|
from typing import Any, Dict, List
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class LocalProblem:
|
||||||
|
id: str
|
||||||
|
asset: str
|
||||||
|
venue: str
|
||||||
|
objective: str
|
||||||
|
constraints: Dict[str, Any]
|
||||||
|
price_target: float
|
||||||
|
tolerance: float
|
||||||
|
|
||||||
|
def to_json(self) -> str:
|
||||||
|
return json.dumps(asdict(self), default=str)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class SharedVariables:
|
||||||
|
variables: Dict[str, Any]
|
||||||
|
version: int
|
||||||
|
contract_id: str
|
||||||
|
|
||||||
|
def to_json(self) -> str:
|
||||||
|
return json.dumps(asdict(self), default=str)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PlanDelta:
|
||||||
|
delta: Dict[str, Any]
|
||||||
|
timestamp: str
|
||||||
|
author: str
|
||||||
|
contract_id: str
|
||||||
|
privacy_budget: float
|
||||||
|
|
||||||
|
def to_json(self) -> str:
|
||||||
|
return json.dumps(asdict(self), default=str)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class DualVariables:
|
||||||
|
shadow_prices: Dict[str, float]
|
||||||
|
version: int
|
||||||
|
|
||||||
|
def to_json(self) -> str:
|
||||||
|
return json.dumps(asdict(self), default=str)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class AuditLogEntry:
|
||||||
|
event: str
|
||||||
|
timestamp: str
|
||||||
|
hash: str
|
||||||
|
details: Dict[str, Any] = None
|
||||||
|
|
||||||
|
def to_json(self) -> str:
|
||||||
|
return json.dumps(asdict(self), default=str)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class GovernanceAuditLog:
|
||||||
|
entries: List[AuditLogEntry]
|
||||||
|
|
||||||
|
def add(self, entry: AuditLogEntry) -> None:
|
||||||
|
self.entries.append(entry)
|
||||||
|
|
||||||
|
def to_json(self) -> str:
|
||||||
|
return json.dumps([asdict(e) for e in self.entries], default=str)
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
from dataclasses import dataclass, asdict
|
||||||
|
from typing import Dict, Any
|
||||||
|
import json
|
||||||
|
|
||||||
|
from .core import LocalProblem, PlanDelta
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class LocalSolver:
|
||||||
|
name: str = "toy-solver"
|
||||||
|
|
||||||
|
def solve(self, problem: LocalProblem) -> PlanDelta:
|
||||||
|
# Minimal toy objective: compute a simple plan delta based on price_target
|
||||||
|
delta = {
|
||||||
|
"contract_id": f"{problem.id}:{problem.venue}",
|
||||||
|
"action": "place_order",
|
||||||
|
"asset": problem.asset,
|
||||||
|
"price_target": problem.price_target,
|
||||||
|
"tolerance": problem.tolerance,
|
||||||
|
"notes": "toy-arbitrage-step"
|
||||||
|
}
|
||||||
|
import datetime
|
||||||
|
timestamp = datetime.datetime.utcnow().isoformat() + "Z"
|
||||||
|
return PlanDelta(
|
||||||
|
delta=delta,
|
||||||
|
timestamp=timestamp,
|
||||||
|
author=self.name,
|
||||||
|
contract_id=f"{problem.id}:{problem.venue}",
|
||||||
|
privacy_budget=0.0,
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
[build-system]
|
||||||
|
requires = ["setuptools>=61.0", "wheel"]
|
||||||
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "edge_latency_aware_cross_venue_execution"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "ELAC-Plan MVP: edge-native cross-venue execution planning with privacy-preserving federation."
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.8"
|
||||||
|
license = {text = "MIT"}
|
||||||
|
authors = [ { name = "OpenCode" } ]
|
||||||
|
dependencies = [
|
||||||
|
"fastapi>=0.95.0",
|
||||||
|
"uvicorn[standard]",
|
||||||
|
"pydantic>=1.10",
|
||||||
|
"typing-extensions>=4.3",
|
||||||
|
"cryptography>=3.3",
|
||||||
|
"pytest>=7.0",
|
||||||
|
"httpx>=0.23"
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.setuptools.packages.find]
|
||||||
|
where = ["elac_plan"]
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Run unit tests and packaging build to ensure MVP integrity
|
||||||
|
echo "Installing package in editable mode..."
|
||||||
|
pip install -e .
|
||||||
|
export PYTHONPATH=$(pwd)
|
||||||
|
echo "Running tests..."
|
||||||
|
pytest -q
|
||||||
|
echo "Building package..."
|
||||||
|
python3 -m build
|
||||||
|
echo "OK: tests and build completed."
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
import json
|
||||||
|
|
||||||
|
from elac_plan.core import LocalProblem
|
||||||
|
from elac_plan.solver import LocalSolver
|
||||||
|
|
||||||
|
|
||||||
|
def test_solver_basic():
|
||||||
|
solver = LocalSolver()
|
||||||
|
lp = LocalProblem(
|
||||||
|
id="lp1",
|
||||||
|
asset="AAPL",
|
||||||
|
venue="NYSE",
|
||||||
|
objective="minimize_spread",
|
||||||
|
constraints={"max_volume": 1000},
|
||||||
|
price_target=150.0,
|
||||||
|
tolerance=0.5,
|
||||||
|
)
|
||||||
|
delta = solver.solve(lp)
|
||||||
|
assert isinstance(delta, type(solver.solve(lp)))
|
||||||
|
payload = delta.to_json()
|
||||||
|
# Basic sanity: json should be parseable and contain contract_id
|
||||||
|
d = json.loads(payload)
|
||||||
|
assert "contract_id" in d
|
||||||
Loading…
Reference in New Issue