dita_v2: VenueTelemetrySnapshot + Zinc venue plane (4th shm partition) + local Rust target dir

Upstream-canonical commit of the ~366 lines that sat uncommitted in the working
tree (surveyed in DITAV2_SOA_SURVEY_20260702). Venue telemetry published at every
venue boundary (submit/cancel/reconcile) over the zinc venue_region; SOA per
UV DITAv2 adjudication 2026-07-03.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Codex
2026-07-03 00:42:20 +02:00
parent 1db4802ee8
commit 9bef1f6b01
8 changed files with 1091 additions and 8 deletions

View File

@@ -0,0 +1,725 @@
"""VIOLET V4 execution runner.
This is the live-capable VIOLET runner boundary:
NG7 scan -> BLUE-faithful VIOLET decision -> ExecIntent
-> DITAv2 KernelIntent -> DITAv2 BingX VST venue execution
Safety is explicit rather than castrated: the module can submit real orders via
``ExecutionKernel.process_intent_async`` when the operator runs the V4 launcher
with VST keys and arming gates green. Unit tests inject fake kernels and never
touch a venue.
"""
from __future__ import annotations
import argparse
import asyncio
import gc
import json
import logging
import math
import os
import sys
import threading
import time
import uuid
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Callable, Mapping, Optional
from prod.clean_arch.dita_v2.contracts import (
KernelCommandType,
KernelIntent,
KernelOutcome,
TradeSide,
)
from .contracts_v3 import ExecIntent
from .decision_engine import ShadowDecision
from .exec_intent import to_exec_intent
RUNNER_CONTRACT_VERSION = "violet-v4-exec-runner-contracts-20260626"
LOGGER = logging.getLogger("violet.v4_execution_runner")
_ASEX_SRC = Path("/mnt/dolphinng5_predict/ASEx/src")
if _ASEX_SRC.exists() and str(_ASEX_SRC) not in sys.path:
sys.path.insert(0, str(_ASEX_SRC))
try: # pragma: no cover - exercised when ASEx package is installed/available.
from asex.guarded import ASExGuardedState
from asex.worker import ASExWorker
except Exception: # pragma: no cover - fallback is covered by unit tests.
ASExGuardedState = None
ASExWorker = None
def _finite_positive(value: float, name: str) -> float:
out = float(value)
if not math.isfinite(out) or out <= 0.0:
raise ValueError(f"{name} must be finite and > 0")
return out
def _non_empty(value: str, name: str) -> str:
out = str(value or "").strip()
if not out:
raise ValueError(f"{name} must be non-empty")
return out
def _trade_side(side: str) -> TradeSide:
normalized = str(side or "").strip().upper()
if normalized == "LONG":
return TradeSide.LONG
if normalized == "SHORT":
return TradeSide.SHORT
raise ValueError(f"unsupported VIOLET side: {side!r}")
def _action_from_intent(intent: ExecIntent, explicit: Optional[KernelCommandType]) -> KernelCommandType:
if explicit is not None:
return explicit
if intent.reason == "ENTRY":
return KernelCommandType.ENTER
if intent.reason == "EXIT":
return KernelCommandType.EXIT
raise ValueError(f"unsupported VIOLET intent reason: {intent.reason!r}")
def exec_intent_to_kernel_intent(
intent: ExecIntent,
*,
reference_price: float,
trade_id: str,
slot_id: int = 0,
intent_id: Optional[str] = None,
action: Optional[KernelCommandType] = None,
order_type: str = "MARKET",
limit_price: float = 0.0,
metadata: Optional[Mapping[str, Any]] = None,
timestamp: Optional[datetime] = None,
) -> KernelIntent:
"""Convert a VIOLET ``ExecIntent`` into a DITAv2 ``KernelIntent``.
The function is intentionally pure and strict. It does not fetch prices,
allocate state outside the returned object, or contact a venue. Live runner
code must pass a fresh reference price with provenance in ``metadata``.
"""
price = _finite_positive(reference_price, "reference_price")
qty = _finite_positive(float(intent.qty), "intent.qty")
leverage = _finite_positive(float(intent.exchange_leverage), "intent.exchange_leverage")
tid = _non_empty(trade_id, "trade_id")
oid = _non_empty(intent_id or f"violet-v4-{uuid.uuid4().hex}", "intent_id")
order = _non_empty(order_type, "order_type").upper()
if order == "LIMIT":
_finite_positive(limit_price, "limit_price")
elif float(limit_price or 0.0) < 0.0:
raise ValueError("limit_price must be >= 0")
merged_metadata: dict[str, Any] = dict(metadata or {})
merged_metadata.update(
{
"violet_contract_version": RUNNER_CONTRACT_VERSION,
"violet_ts_ns": int(intent.ts_ns),
"violet_maker_policy": intent.maker_policy,
"violet_target_notional": float(intent.target_notional),
"violet_reason": intent.reason,
}
)
return KernelIntent(
timestamp=timestamp or datetime.now(timezone.utc),
intent_id=oid,
trade_id=tid,
slot_id=int(slot_id),
asset=_non_empty(intent.asset, "intent.asset"),
side=_trade_side(intent.side),
action=_action_from_intent(intent, action),
reference_price=price,
target_size=qty,
leverage=leverage,
reason=f"violet_v4:{intent.reason.lower()}",
metadata=merged_metadata,
order_type=order,
limit_price=float(limit_price or 0.0),
)
@dataclass(frozen=True)
class VioletV4RunnerConfig:
"""Operator/runtime knobs for the V4 execution runner."""
session_id: str
capital: float = 69_000.0
slot_id: int = 0
maker_policy: str = "maker_both"
order_type: str = "MARKET"
limit_price: float = 0.0
poll_interval_s: float = 0.25
queue_maxsize: int = 4096
max_submissions: int = 0
max_notional_usdt: float = 0.0
assume_vol_ok: bool = False
require_arming: bool = True
report_dir: str = "/mnt/vp-VIOLET_main/prod/VIOLET_dev/reports"
hz_cluster: str = "dolphin"
hz_host: str = "localhost:5701"
hz_map: str = "DOLPHIN_FEATURES"
hz_key: str = "latest_eigen_scan"
snapshot_symbol: str = "BTCUSDT"
@classmethod
def from_env(cls) -> "VioletV4RunnerConfig":
return cls(
session_id=os.environ.get("DOLPHIN_VIOLET_SESSION_ID", uuid.uuid4().hex),
capital=float(os.environ.get("DOLPHIN_VIOLET_CAPITAL", "69000")),
slot_id=int(os.environ.get("DOLPHIN_VIOLET_SLOT_ID", "0")),
maker_policy=os.environ.get("DOLPHIN_VIOLET_MAKER_POLICY", "maker_both"),
order_type=os.environ.get("DOLPHIN_VIOLET_ORDER_TYPE", "MARKET"),
limit_price=float(os.environ.get("DOLPHIN_VIOLET_LIMIT_PRICE", "0")),
poll_interval_s=float(os.environ.get("DOLPHIN_VIOLET_POLL_INTERVAL_SEC", "0.25")),
queue_maxsize=int(os.environ.get("DOLPHIN_VIOLET_SCAN_QUEUE_MAX", "4096")),
max_submissions=int(os.environ.get("DOLPHIN_VIOLET_MAX_SUBMISSIONS", "0")),
max_notional_usdt=float(os.environ.get("DOLPHIN_VIOLET_MAX_NOTIONAL_USDT", "0")),
assume_vol_ok=str(os.environ.get("DOLPHIN_VIOLET_ASSUME_VOL_OK", "0")).lower()
in {"1", "true", "yes", "on"},
require_arming=str(os.environ.get("DOLPHIN_VIOLET_REQUIRE_ARMING", "1")).lower()
not in {"0", "false", "no", "off"},
report_dir=os.environ.get(
"DOLPHIN_VIOLET_REPORT_DIR",
"/mnt/vp-VIOLET_main/prod/VIOLET_dev/reports",
),
hz_cluster=os.environ.get("HZ_CLUSTER", "dolphin"),
hz_host=os.environ.get("HZ_HOST", "localhost:5701"),
hz_map=os.environ.get("DOLPHIN_VIOLET_SCAN_MAP", "DOLPHIN_FEATURES"),
hz_key=os.environ.get("DOLPHIN_VIOLET_SCAN_KEY", "latest_eigen_scan"),
snapshot_symbol=os.environ.get("DOLPHIN_VIOLET_SNAPSHOT_SYMBOL", "BTCUSDT"),
)
class _LocalGuardedState:
"""Tiny ASEx-compatible fallback for tests or missing ASEx install."""
def __init__(self) -> None:
self._lock = threading.Lock()
self.last_scan_number = -1
self.scans_seen = 0
self.decisions = 0
self.submissions = 0
self.outcomes = 0
self.errors = 0
self.last_trade_id = ""
self.last_intent_id = ""
def mutate(self, mutation: Mapping[str, Any]) -> dict[str, Any]:
with self._lock:
return self._apply(dict(mutation))
def _apply(self, mutation: dict[str, Any]) -> dict[str, Any]:
op = str(mutation.get("op") or "")
if op == "scan":
sn = int(mutation.get("scan_number") or 0)
if sn <= self.last_scan_number:
return {"accepted": False, "reason": "duplicate_scan", "last_scan_number": self.last_scan_number}
self.last_scan_number = sn
self.scans_seen += 1
return {"accepted": True, "last_scan_number": self.last_scan_number}
if op == "decision":
self.decisions += 1
return {"accepted": True, "decisions": self.decisions}
if op == "submission":
self.submissions += 1
self.last_trade_id = str(mutation.get("trade_id") or "")
self.last_intent_id = str(mutation.get("intent_id") or "")
return {"accepted": True, "submissions": self.submissions}
if op == "outcome":
self.outcomes += 1
return {"accepted": True, "outcomes": self.outcomes}
if op == "error":
self.errors += 1
return {"accepted": True, "errors": self.errors}
return {"accepted": False, "reason": f"unknown_op:{op}"}
if ASExGuardedState is not None:
class VioletRunnerGuardedState(ASExGuardedState[dict[str, Any], dict[str, Any]]):
"""ASEx single-writer state for scan/order lifecycle counters."""
def __init__(self) -> None:
super().__init__()
self._state = _LocalGuardedState()
def _validate(self, mutation: dict[str, Any]) -> bool:
return str(mutation.get("op") or "") in {
"scan",
"decision",
"submission",
"outcome",
"error",
}
def _apply(self, mutation: dict[str, Any]) -> dict[str, Any]:
return self._state._apply(dict(mutation))
else:
VioletRunnerGuardedState = _LocalGuardedState # type: ignore[assignment]
class SerialRunnerState:
"""Small wrapper around ASExWorker with a deterministic local fallback."""
def __init__(self) -> None:
self.backend = VioletRunnerGuardedState()
self.worker = ASExWorker(self.backend) if ASExWorker is not None else None
def mutate(self, mutation: Mapping[str, Any], *, timeout: float = 5.0) -> dict[str, Any]:
payload = dict(mutation)
if self.worker is not None:
return self.worker.mutate(payload).result(timeout=timeout)
return self.backend.mutate(payload) # type: ignore[attr-defined]
def close(self) -> None:
if self.worker is not None:
self.worker.close(timeout=2.0)
def _parse_scan_payload(raw: Any) -> dict[str, Any]:
if raw is None:
return {}
if isinstance(raw, str):
data = json.loads(raw)
elif isinstance(raw, Mapping):
data = dict(raw)
else:
return {}
if isinstance(data, dict) and data.get("version") == "NG7":
try:
from prod.clean_arch.adapters.eigen_scan_normalizer import normalize_ng7_scan
data = normalize_ng7_scan(data)
except Exception:
LOGGER.debug("NG7 normalize failed; using raw scan", exc_info=True)
return data if isinstance(data, dict) else {}
def reference_price_from_scan(payload: Mapping[str, Any], asset: str) -> float:
"""Extract the decision asset price from an NG7/universe payload."""
symbol = str(asset or "").upper()
assets = payload.get("assets") or []
prices = payload.get("asset_prices") or []
if isinstance(assets, list) and isinstance(prices, list):
for raw_asset, raw_price in zip(assets, prices):
if str(raw_asset).upper() != symbol:
continue
price = _finite_positive(float(raw_price), "reference_price")
return price
result = payload.get("result") if isinstance(payload, Mapping) else None
if isinstance(result, Mapping):
result_asset = str(result.get("asset") or payload.get("target_asset") or "").upper()
if result_asset == symbol:
return _finite_positive(float(result.get("price") or payload.get("price")), "reference_price")
payload_asset = str(payload.get("asset") or payload.get("target_asset") or "").upper()
if payload_asset == symbol and payload.get("price") is not None:
return _finite_positive(float(payload.get("price")), "reference_price")
raise ValueError(f"scan payload has no fresh price for {symbol}")
def _decision_from_shadow(
shadow: dict[str, Any],
payload: dict[str, Any],
*,
scan_number: int,
now_ns: int,
vel_div: float,
vol_ok: bool,
) -> Optional[ShadowDecision]:
"""Run the existing BLUE-faithful VIOLET shadow path and return the decision."""
from .shadow_live_factors import _ensure_ob_engine
shadow["engine"].observe(payload, scan_number)
live_source = shadow.get("live_source")
if live_source is None:
return None
ob_engine = _ensure_ob_engine(shadow, payload)
live_result = live_source(
shadow["client"],
scan_history=shadow["scan_history"],
selector=shadow["selector"],
ob_engine=ob_engine,
bar_idx=shadow.get("ob_bar_idx", 0),
prior_boost_beta=shadow.get("prior_boost_beta"),
)
shadow["last_live_source"] = live_result
shadow["ob_bar_idx"] = shadow.get("ob_bar_idx", 0) + 1
ab = getattr(live_result, "acb_boost", None)
bb = getattr(live_result, "acb_beta", None)
if ab is not None and bb is not None:
shadow["prior_boost_beta"] = (ab, bb)
decision = shadow["engine"].decide(
now_ns=now_ns,
scan_number=scan_number,
capital=shadow["capital"],
vel_div=vel_div,
vol_ok=vol_ok,
factors=live_result.factors,
)
if decision is None:
return None
journal = shadow.get("journal")
if journal is not None:
journal.journal(decision, mono_ns=now_ns)
return decision
class HazelcastNG7ScanSource:
"""Event-listener first, polling fallback source for NG7 scans."""
def __init__(self, config: VioletV4RunnerConfig) -> None:
self.config = config
self.client = None
self.map = None
self.blocking_map = None
self.queue: asyncio.Queue[dict[str, Any]] = asyncio.Queue(maxsize=config.queue_maxsize)
self._loop: Optional[asyncio.AbstractEventLoop] = None
self._last_polled_scan = -1
async def connect(self) -> None:
import hazelcast
self._loop = asyncio.get_running_loop()
self.client = hazelcast.HazelcastClient(
cluster_name=self.config.hz_cluster,
cluster_members=[self.config.hz_host],
)
self.map = self.client.get_map(self.config.hz_map)
self.blocking_map = self.map.blocking()
def on_entry(event: Any) -> None:
try:
payload = _parse_scan_payload(getattr(event, "value", None))
if not payload:
return
loop = self._loop
if loop is None:
return
loop.call_soon_threadsafe(self._offer_payload, payload)
except Exception:
LOGGER.debug("scan listener callback failed", exc_info=True)
self.map.add_entry_listener(
include_value=True,
key=self.config.hz_key,
updated_func=on_entry,
added_func=on_entry,
)
def _offer_payload(self, payload: dict[str, Any]) -> None:
try:
self.queue.put_nowait(payload)
except asyncio.QueueFull:
try:
self.queue.get_nowait()
except asyncio.QueueEmpty:
pass
self.queue.put_nowait(payload)
async def next_payload(self) -> dict[str, Any]:
try:
return await asyncio.wait_for(self.queue.get(), timeout=self.config.poll_interval_s)
except asyncio.TimeoutError:
raw = self.blocking_map.get(self.config.hz_key)
payload = _parse_scan_payload(raw)
sn = int(payload.get("scan_number") or 0)
if sn <= self._last_polled_scan:
return {}
self._last_polled_scan = sn
return payload
async def close(self) -> None:
if self.client is not None:
self.client.shutdown()
class VioletV4ExecutionRunner:
"""Live-capable runner: decision path to actual DITAv2 execution."""
def __init__(
self,
*,
bundle: Any,
shadow: dict[str, Any],
config: VioletV4RunnerConfig,
state: Optional[SerialRunnerState] = None,
decision_step: Optional[
Callable[[dict[str, Any], dict[str, Any], int, int, float, bool], Optional[ShadowDecision]]
] = None,
) -> None:
self.bundle = bundle
self.shadow = shadow
self.config = config
self.state = state or SerialRunnerState()
self.decision_step = decision_step or (
lambda sh, payload, sn, now_ns, vd, vol_ok: _decision_from_shadow(
sh,
payload,
scan_number=sn,
now_ns=now_ns,
vel_div=vd,
vol_ok=vol_ok,
)
)
self._closed = False
async def connect(self) -> None:
connect = getattr(self.bundle.venue, "connect", None)
if connect is not None:
result = connect()
if asyncio.iscoroutine(result):
await result
def close(self) -> None:
if self._closed:
return
self._closed = True
try:
close = getattr(self.bundle, "close", None)
if close is not None:
close()
finally:
self.state.close()
def _capital(self) -> float:
try:
cap = float(self.bundle.kernel.account.snapshot.capital)
if math.isfinite(cap) and cap > 0.0:
return cap
except Exception:
pass
return float(self.config.capital)
def _maybe_cap_exec_intent(self, intent: ExecIntent, reference_price: float) -> ExecIntent:
cap = float(self.config.max_notional_usdt or 0.0)
if cap <= 0.0 or float(intent.target_notional) <= cap:
return intent
return ExecIntent(
asset=intent.asset,
side=intent.side,
qty=cap / reference_price,
exchange_leverage=intent.exchange_leverage,
maker_policy=intent.maker_policy,
target_notional=cap,
ts_ns=intent.ts_ns,
reason=intent.reason,
)
async def process_scan_payload(self, raw_payload: Any) -> Optional[KernelOutcome]:
payload = _parse_scan_payload(raw_payload)
if not payload:
return None
scan_number = int(payload.get("scan_number") or 0)
if scan_number <= 0:
return None
scan_state = self.state.mutate({"op": "scan", "scan_number": scan_number})
if not scan_state.get("accepted"):
return None
vel_div = float(payload.get("vel_div") or 0.0)
if not math.isfinite(vel_div):
vel_div = 0.0
vol_ok = bool(payload.get("vol_ok", True))
if self.config.assume_vol_ok:
vol_ok = True
now_ns = int(time.monotonic_ns())
decision = self.decision_step(self.shadow, payload, scan_number, now_ns, vel_div, vol_ok)
if decision is None:
return None
self.state.mutate({"op": "decision", "scan_number": scan_number, "asset": decision.asset})
reference_price = reference_price_from_scan(payload, decision.asset)
exec_intent = to_exec_intent(
decision,
capital=self._capital(),
reference_price=reference_price,
maker_policy=self.config.maker_policy,
)
exec_intent = self._maybe_cap_exec_intent(exec_intent, reference_price)
trade_id = f"VIOLET-{self.config.session_id[:8]}-{scan_number}"
intent_id = f"violet-v4-{self.config.session_id[:8]}-{scan_number}"
kernel_intent = exec_intent_to_kernel_intent(
exec_intent,
reference_price=reference_price,
trade_id=trade_id,
slot_id=self.config.slot_id,
intent_id=intent_id,
order_type=self.config.order_type,
limit_price=self.config.limit_price,
metadata={
"violet_session_id": self.config.session_id,
"scan_number": scan_number,
"price_source": "ng7_scan",
"raw_notional_before_runner_cap": float(decision.target_exposure),
},
)
submission = self.state.mutate(
{"op": "submission", "scan_number": scan_number, "trade_id": trade_id, "intent_id": intent_id}
)
if self.config.max_submissions and int(submission.get("submissions") or 0) > self.config.max_submissions:
LOGGER.critical("max submissions reached; refusing scan=%s trade_id=%s", scan_number, trade_id)
return None
LOGGER.warning(
"VIOLET V4 LIVE SUBMIT scan=%s asset=%s side=%s qty=%.8f lev=%.2f ref=%.8f trade=%s",
scan_number,
kernel_intent.asset,
kernel_intent.side.value,
kernel_intent.target_size,
kernel_intent.leverage,
kernel_intent.reference_price,
trade_id,
)
try:
outcome = await self.bundle.kernel.process_intent_async(kernel_intent)
self.state.mutate(
{
"op": "outcome",
"scan_number": scan_number,
"trade_id": trade_id,
"accepted": bool(getattr(outcome, "accepted", False)),
"diagnostic": str(getattr(getattr(outcome, "diagnostic_code", ""), "value", "")),
}
)
return outcome
except Exception as exc:
self.state.mutate({"op": "error", "scan_number": scan_number, "error": str(exc)})
raise
def _apply_runtime_optimizations() -> None:
if gc.isenabled():
gc.disable()
def _build_shadow(config: VioletV4RunnerConfig) -> dict[str, Any]:
from prod.ch_writer import ch_put_violet
from .decision_engine import VioletDecisionEngine
from .shadow_journal import VioletDecisionJournal
from .shadow_live_factors import build_shadow_live_source
thr = float(os.environ.get("DOLPHIN_VIOLET_ENTRY_VEL_DIV_THRESHOLD", "-0.02"))
return {
"engine": VioletDecisionEngine(entry_vel_div_threshold=thr),
"journal": VioletDecisionJournal(sink=ch_put_violet, session_id=config.session_id),
"capital": float(config.capital),
**build_shadow_live_source(),
}
def _build_real_bundle(config: VioletV4RunnerConfig) -> Any:
from prod.clean_arch.dita_v2.launcher import build_launcher_bundle
from prod.launch_dolphin_violet import (
DDL_APPLY_CMD,
_apply_violet_env,
_preflight_clickhouse,
_violet_table_present,
build_bingx_exec_client_config,
)
from .v4_arming import assess_v4_arming, write_v4_arming_report
_apply_violet_env()
missing = _preflight_clickhouse()
if missing:
raise RuntimeError(f"dolphin_violet tables missing: {missing}; run {DDL_APPLY_CMD}")
if not _violet_table_present("violet_decisions"):
raise RuntimeError(f"dolphin_violet table missing: violet_decisions; run {DDL_APPLY_CMD}")
report = assess_v4_arming(report_dir=config.report_dir, launcher_mode="execution")
write_v4_arming_report(report, report_dir=config.report_dir)
if config.require_arming and not report.can_arm:
raise RuntimeError(f"VIOLET V4 arming refused: {report.reasons}")
return build_launcher_bundle(
venue_mode="BINGX",
max_slots=1,
prefix="violet",
bingx_config=build_bingx_exec_client_config(),
)
async def run_live(
config: Optional[VioletV4RunnerConfig] = None,
*,
stop_after_first_submission: bool = False,
) -> None:
"""Run the actual VIOLET V4 BingX VST execution loop."""
cfg = config or VioletV4RunnerConfig.from_env()
_apply_runtime_optimizations()
bundle = _build_real_bundle(cfg)
shadow = _build_shadow(cfg)
source = HazelcastNG7ScanSource(cfg)
runner = VioletV4ExecutionRunner(bundle=bundle, shadow=shadow, config=cfg)
await runner.connect()
await source.connect()
LOGGER.critical(
"VIOLET V4 EXECUTION RUNNER ARMED: session=%s venue=BINGX_VST hz=%s[%s]",
cfg.session_id,
cfg.hz_map,
cfg.hz_key,
)
try:
while True:
payload = await source.next_payload()
if payload:
outcome = await runner.process_scan_payload(payload)
if stop_after_first_submission and outcome is not None:
return
await asyncio.sleep(0)
finally:
await source.close()
runner.close()
def main(argv: Optional[list[str]] = None) -> int:
parser = argparse.ArgumentParser(description="VIOLET V4 live BingX VST execution runner")
parser.add_argument("--once", action="store_true", help="process one queued/polled scan then exit")
args = parser.parse_args(argv)
config = VioletV4RunnerConfig.from_env()
if args.once:
config = dataclass_replace(config, max_submissions=1)
asyncio.run(run_live(config, stop_after_first_submission=args.once))
return 0
def dataclass_replace(config: VioletV4RunnerConfig, **updates: Any) -> VioletV4RunnerConfig:
data = config.__dict__.copy()
data.update(updates)
return VioletV4RunnerConfig(**data)
__all__ = [
"HazelcastNG7ScanSource",
"RUNNER_CONTRACT_VERSION",
"SerialRunnerState",
"VioletV4ExecutionRunner",
"VioletV4RunnerConfig",
"exec_intent_to_kernel_intent",
"main",
"reference_price_from_scan",
"run_live",
]
if __name__ == "__main__":
raise SystemExit(main())