@@ -131,6 +131,31 @@ def _localize_notification_text(text: str, *, translator) -> str:
131131 return localized
132132
133133
134+ def _render_notification_context_text (
135+ notification_context : Mapping [str , object ] | None ,
136+ * ,
137+ translator ,
138+ fallback : str = "" ,
139+ ) -> str :
140+ if not isinstance (notification_context , Mapping ):
141+ return fallback
142+ key = str (notification_context .get ("code" ) or "" ).strip ()
143+ if not key :
144+ return fallback
145+ params = dict (notification_context .get ("params" ) or {})
146+ rendered = translator (key , ** params )
147+ return fallback if rendered == key else str (rendered )
148+
149+
150+ def _translate_snapshot_guard_decision (decision : object , * , translator ) -> str :
151+ value = str (decision or "" ).strip ()
152+ if not value :
153+ return ""
154+ key = f"snapshot_guard_decision_{ value } "
155+ translated = translator (key )
156+ return value if translated == key else str (translated )
157+
158+
134159def _split_detail_segment (text : str ) -> list [str ]:
135160 value = str (text or "" ).strip ()
136161 if not value :
@@ -585,13 +610,37 @@ def run_strategy_core(
585610 decision = signal_metadata .get ("snapshot_guard_decision" )
586611 no_op_reason = signal_metadata .get ("no_op_reason" )
587612 fail_reason = signal_metadata .get ("fail_reason" )
588- no_op_text = config .translator ("no_trades" )
589- if decision :
590- no_op_text = f"{ no_op_text } | { _localize_notification_text (f'decision={ decision } ' , translator = config .translator )} "
591- if no_op_reason :
592- no_op_text = f"{ no_op_text } | { _localize_notification_text (f'reason={ no_op_reason } ' , translator = config .translator )} "
593- if fail_reason :
594- no_op_text = f"{ no_op_text } | { _localize_notification_text (f'fail_reason={ fail_reason } ' , translator = config .translator )} "
613+ notification_context = signal_metadata .get ("notification_context" )
614+ status_context = (
615+ notification_context .get ("status" )
616+ if isinstance (notification_context , Mapping )
617+ else None
618+ )
619+ rendered_status = _render_notification_context_text (
620+ status_context ,
621+ translator = config .translator ,
622+ fallback = "" ,
623+ )
624+ no_op_segments = [config .translator ("no_trades" )]
625+ if rendered_status :
626+ no_op_segments .append (rendered_status )
627+ else :
628+ if decision :
629+ no_op_segments .append (
630+ config .translator (
631+ "snapshot_decision_detail" ,
632+ value = _translate_snapshot_guard_decision (decision , translator = config .translator ),
633+ )
634+ )
635+ if no_op_reason :
636+ no_op_segments .append (
637+ _localize_notification_text (f"reason={ no_op_reason } " , translator = config .translator )
638+ )
639+ if fail_reason :
640+ no_op_segments .append (
641+ _localize_notification_text (f"fail_reason={ fail_reason } " , translator = config .translator )
642+ )
643+ no_op_text = " | " .join (segment for segment in no_op_segments if str (segment ).strip ())
595644 no_op_text = "\n " .join (_split_labeled_text (no_op_text ))
596645 record = build_reconciliation_record (
597646 strategy_profile = signal_metadata .get ("strategy_profile" ),
0 commit comments