61 lines
2.2 KiB
Python
61 lines
2.2 KiB
Python
import hashlib
|
|
import time
|
|
from typing import List
|
|
from dataclasses import dataclass
|
|
|
|
from .primitives import LocalArbProblem, SharedSignals
|
|
|
|
|
|
@dataclass
|
|
class PlanDelta:
|
|
legs: List[dict]
|
|
total_size: float
|
|
delta_id: str
|
|
# Additional provenance fields to support deterministic replay and auditing
|
|
timestamp: float | None = None
|
|
parent_delta_id: str | None = None
|
|
signature: str | None = None
|
|
# Extended provenance fields for stronger auditability and replay
|
|
# Versioning to denote IR schema version for adapters and registries
|
|
version: int = 1
|
|
# Optional per-delta nonce to prevent replay of identical deltas
|
|
nonce: str | None = None
|
|
# Optional signer/identity for provenance
|
|
signer: str | None = None
|
|
|
|
|
|
def _deterministic_id(inputs: List[LocalArbProblem], shared: SharedSignals) -> str:
|
|
# Create a stable representation of inputs for deterministic hashing
|
|
parts = []
|
|
for lp in sorted(inputs, key=lambda x: (x.asset_pair[0], x.asset_pair[1])):
|
|
parts.append(
|
|
f"{lp.asset_pair}:{lp.target_mispricing}:{lp.liquidity_budget}:{lp.latency_budget}"
|
|
)
|
|
s = "|".join(parts) + f"|shared:{shared.cross_venue_corr}:{shared.latency_proxy}"
|
|
return hashlib.sha256(s.encode("utf-8")).hexdigest()
|
|
|
|
|
|
def admm_lite_step(local_problems: List[LocalArbProblem], shared_signals: SharedSignals) -> PlanDelta:
|
|
# Deterministic, simple projection: create one leg per local problem
|
|
legs = []
|
|
# deterministic order by asset_pair
|
|
for lp in sorted(local_problems, key=lambda x: (x.asset_pair[0], x.asset_pair[1])):
|
|
leg_size = max(0.0, float(lp.liquidity_budget) * 0.01)
|
|
legs.append({
|
|
"asset_pair": list(lp.asset_pair),
|
|
"size": leg_size,
|
|
"venue": "default",
|
|
})
|
|
|
|
total_size = float(sum(lp.liquidity_budget for lp in local_problems)) * 0.01 if local_problems else 0.0
|
|
delta_id = _deterministic_id(local_problems, shared_signals)
|
|
# Attach provenance metadata for replay and auditing
|
|
return PlanDelta(
|
|
legs=legs,
|
|
total_size=total_size,
|
|
delta_id=delta_id,
|
|
timestamp=time.time(),
|
|
parent_delta_id=None,
|
|
signature=None,
|
|
)
|