@@ -33,6 +33,37 @@ def _now_iso() -> str:
3333 return datetime .now (timezone .utc ).isoformat ()
3434
3535
36+ def resolve_lifecycle_stream_id (
37+ explicit_stream_id : str = "" ,
38+ * ,
39+ execution_result : Mapping [str , Any ] | None = None ,
40+ ) -> str :
41+ """Return a stable, account-safe telemetry stream identity.
42+
43+ Cloud Run supplies ``K_SERVICE`` per deployed service, which keeps the
44+ same strategy on different broker accounts from being combined into a
45+ synthetic equity curve. ``LIFECYCLE_STREAM_ID`` is available for
46+ non-Cloud-Run runtimes that need a stable explicit identity.
47+ """
48+ import os
49+
50+ for candidate in (
51+ explicit_stream_id ,
52+ os .environ .get ("LIFECYCLE_STREAM_ID" ),
53+ os .environ .get ("K_SERVICE" ),
54+ ):
55+ value = str (candidate or "" ).strip ()
56+ if value :
57+ return value
58+
59+ payload = execution_result if isinstance (execution_result , Mapping ) else {}
60+ platform = str (payload .get ("platform" ) or "" ).strip ()
61+ account_scope = str (payload .get ("account_scope" ) or payload .get ("service_name" ) or "" ).strip ()
62+ if platform and account_scope :
63+ return f"{ platform } :{ account_scope } "
64+ return platform
65+
66+
3667def _is_valid_series (series : object , * , min_observations : int = 10 ) -> bool :
3768 if not isinstance (series , pd .Series ):
3869 return False
@@ -51,6 +82,7 @@ def run_monitor(
5182 collector : ReturnCollector | None = None ,
5283 strategy_benchmarks : Mapping [str , str ] | None = None ,
5384 require_explicit_benchmark : bool = False ,
85+ live_stream_id : str | None = None ,
5486) -> list [StrategyPerformanceSnapshot ]:
5587 """Run the performance monitor for the given domain.
5688
@@ -67,6 +99,9 @@ def run_monitor(
6799 require_explicit_benchmark: Refuse to monitor profiles without a binding
68100 or without the declared benchmark return series. This is the
69101 promotion-grade setting for leveraged strategies.
102+ live_stream_id: Optional stable telemetry stream identity. When live
103+ account data is used, this prevents independent broker accounts
104+ from being merged into one return series.
70105
71106 Returns:
72107 List of StrategyPerformanceSnapshot objects generated.
@@ -75,7 +110,10 @@ def run_monitor(
75110 collector = collector or ReturnCollector ()
76111
77112 # 1. Collect returns
78- all_returns = collector .collect (domain )
113+ if isinstance (collector , ReturnCollector ):
114+ all_returns = collector .collect (domain , live_stream_id = live_stream_id )
115+ else :
116+ all_returns = collector .collect (domain )
79117 if not all_returns :
80118 if fail_on_empty :
81119 raise RuntimeError (
@@ -118,7 +156,7 @@ def run_monitor(
118156 snapshot = StrategyPerformanceSnapshot (
119157 strategy_profile = profile ,
120158 domain = domain ,
121- platform = "" ,
159+ platform = str ( live_stream_id or "" ). strip () ,
122160 as_of = date .today (),
123161 benchmark_symbol = benchmark_symbol ,
124162 computed_at = _now_iso (),
@@ -234,6 +272,7 @@ def record(
234272 execution_result : Mapping [str , Any ] | None = None ,
235273 * ,
236274 domain : str = "" ,
275+ stream_id : str = "" ,
237276 ) -> dict [str , Any ]:
238277 profile = str (profile_id or "" ).strip ()
239278 if not profile :
@@ -246,8 +285,21 @@ def record(
246285 "decision" : _serialize_decision (decision ),
247286 "execution_result" : dict (execution_result or {}),
248287 }
249- self ._store .save_live_run_record (profile , str (domain or "" ).strip (), payload )
250- return {"ok" : True , "profile" : profile , "domain" : str (domain or "" ).strip ()}
288+ resolved_stream_id = resolve_lifecycle_stream_id (stream_id , execution_result = execution_result )
289+ if resolved_stream_id :
290+ payload ["lifecycle_stream_id" ] = resolved_stream_id
291+ self ._store .save_live_run_record (
292+ profile ,
293+ str (domain or "" ).strip (),
294+ payload ,
295+ stream_id = resolved_stream_id ,
296+ )
297+ return {
298+ "ok" : True ,
299+ "profile" : profile ,
300+ "domain" : str (domain or "" ).strip (),
301+ "stream_id" : resolved_stream_id ,
302+ }
251303
252304 def record_execution (
253305 self ,
@@ -256,6 +308,7 @@ def record_execution(
256308 * ,
257309 domain : str = "" ,
258310 decision : Any | None = None ,
311+ stream_id : str = "" ,
259312 ) -> dict [str , Any ]:
260313 """Persist platform-layer execution telemetry after order routing."""
261314 profile = str (profile_id or "" ).strip ()
@@ -273,8 +326,21 @@ def record_execution(
273326 }
274327 if decision is not None :
275328 payload ["decision" ] = _serialize_decision (decision )
276- self ._store .save_live_run_record (profile , str (domain or "" ).strip (), payload )
277- return {"ok" : True , "profile" : profile , "domain" : str (domain or "" ).strip ()}
329+ resolved_stream_id = resolve_lifecycle_stream_id (stream_id , execution_result = execution_result )
330+ if resolved_stream_id :
331+ payload ["lifecycle_stream_id" ] = resolved_stream_id
332+ self ._store .save_live_run_record (
333+ profile ,
334+ str (domain or "" ).strip (),
335+ payload ,
336+ stream_id = resolved_stream_id ,
337+ )
338+ return {
339+ "ok" : True ,
340+ "profile" : profile ,
341+ "domain" : str (domain or "" ).strip (),
342+ "stream_id" : resolved_stream_id ,
343+ }
278344
279345
280346def infer_strategy_domain (profile_id : str , * , explicit_domain : str = "" ) -> str :
@@ -297,6 +363,7 @@ def try_record_platform_execution(
297363 * ,
298364 domain : str = "" ,
299365 decision : Any | None = None ,
366+ stream_id : str = "" ,
300367) -> None :
301368 """Best-effort execution recorder for platform runtimes; never raises."""
302369 try :
@@ -308,6 +375,7 @@ def try_record_platform_execution(
308375 execution_result ,
309376 domain = infer_strategy_domain (profile_id , explicit_domain = domain ),
310377 decision = decision ,
378+ stream_id = stream_id ,
311379 )
312380 except Exception as exc : # pragma: no cover
313381 logger .warning ("PerformanceMonitor.record_execution failed: %s" , exc )
0 commit comments