VIOLET V3.4b: launcher shadow live-factor wiring
This commit is contained in:
79
prod/clean_arch/violet/shadow_live_factors.py
Normal file
79
prod/clean_arch/violet/shadow_live_factors.py
Normal file
@@ -0,0 +1,79 @@
|
||||
"""VIOLET launcher shadow helpers for live BLUE factor sourcing.
|
||||
|
||||
These helpers stay separate from the launcher module so they can be unit-tested
|
||||
without importing the full launcher import chain.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def build_shadow_live_source(
|
||||
*,
|
||||
client_factory=None,
|
||||
selector_factory=None,
|
||||
source_factory=None,
|
||||
scan_history_factory=None,
|
||||
):
|
||||
"""Create the read-only BLUE live-factor mirror for the shadow path."""
|
||||
if client_factory is None or selector_factory is None or source_factory is None or scan_history_factory is None:
|
||||
import hazelcast
|
||||
|
||||
from .alpha_wrappers import VioletAssetSelector
|
||||
from .live_blue_source import LiveBlueScanHistory, source_live_blue_sizing_factors
|
||||
|
||||
client_factory = client_factory or (lambda: hazelcast.HazelcastClient(
|
||||
cluster_name=os.environ.get("HZ_CLUSTER", "dolphin"),
|
||||
cluster_members=[os.environ.get("HZ_HOST", "localhost:5701")],
|
||||
))
|
||||
selector_factory = selector_factory or VioletAssetSelector
|
||||
source_factory = source_factory or source_live_blue_sizing_factors
|
||||
scan_history_factory = scan_history_factory or LiveBlueScanHistory
|
||||
|
||||
client = client_factory()
|
||||
return {
|
||||
"client": client,
|
||||
"scan_history": scan_history_factory(),
|
||||
"selector": selector_factory(),
|
||||
"live_source": source_factory,
|
||||
}
|
||||
|
||||
|
||||
def shadow_decision_step(
|
||||
shadow: dict,
|
||||
payload: dict,
|
||||
*,
|
||||
scan_number: int,
|
||||
now_ns: int,
|
||||
vel_div: float,
|
||||
vol_ok: bool,
|
||||
) -> bool:
|
||||
"""Run one shadow decision against the live BLUE factor plane."""
|
||||
shadow["engine"].observe(payload, scan_number)
|
||||
live_source = shadow.get("live_source")
|
||||
factors = None
|
||||
if live_source is not None:
|
||||
live_result = live_source(
|
||||
shadow["client"],
|
||||
scan_history=shadow["scan_history"],
|
||||
selector=shadow["selector"],
|
||||
)
|
||||
shadow["last_live_source"] = live_result
|
||||
factors = live_result.factors
|
||||
if factors is None:
|
||||
return False
|
||||
decision = shadow["engine"].decide(
|
||||
now_ns=now_ns,
|
||||
scan_number=scan_number,
|
||||
capital=shadow["capital"],
|
||||
vel_div=vel_div,
|
||||
vol_ok=vol_ok,
|
||||
factors=factors,
|
||||
)
|
||||
if decision is None:
|
||||
return False
|
||||
return shadow["journal"].journal(decision, mono_ns=now_ns)
|
||||
Reference in New Issue
Block a user