+
    j6                       R t ^ RIHt ^ RIt^ RIHtHt ^ RIHt ^ RIt	^ RI
t. R,Ot. R-Ot. R.Ot^^K.t^t^<t. R/Ot. R0OtRtR	RRRRRRRRRRR/tRRRRRRRR/tRRRRRRRRR
RRR/tRRRR RR!RR/tR" tR# tR$ tR% tR& tR' tR( tR) t ]!R*8X  dM   ]! ]"4      PG                  4       PH                  ^,          t%] ! ]%4      t&]'! ]PP                  ! ]&^])R+7      4       R# R# )1u  
regime_live.py
==============
Lightweight regime classification module called by dashboard_server.py
on each refresh cycle.

Provides:
  compute_regimes(trades_eu, trades_uj, base_path) -> dict

Returns a dict suitable for inclusion in dashboard_data.json with
Activity tier (from signal density) and Macro tier (from spread
state) for each pair, plus descriptive context.

This module is read-only — it never writes thresholds. The cutoffs
come from data/research/regime_thresholds.json which is calibrated
by src/research/regime_classifier_v1.py.

If regime_thresholds.json is missing or malformed, compute_regimes()
returns a dict with all tiers set to "Unknown" — the dashboard renders
a placeholder rather than crashing.
)annotationsN)datetime	timedelta)PathQuietLightSteadyActivePeak
CompressedSubduedNormalElevatedHigh Dislocationg      ?zeStrategy firing at top 10% of historical density. Setups occurring multiple times per day on average.zVAbove-average signal density (60-90th percentile of history). Steady stream of setups.zYTypical signal density at historical median (~7 trades / 14d). Standard operating rhythm.zaBelow-average signal density (10-30th percentile). Setups present but less frequent than average.ut   Signal density in bottom 10% of history. Few setups expected — strategy edge unchanged, frequency is the variable.UnknownuA   Cutoffs not yet calibrated — run regime_classifier_v1.py first.zAbove-average signal density (top 25% of history). Common during BoJ policy shifts, JPY intervention windows, or Fed-BoJ divergence stretches.zYTypical signal density at historical median (~5 trades / 60d). Standard operating regime.z}Signal density in bottom 25% of history (<3 trades / 60d). Common when US and JP central banks are in similar policy stances.zUS-DE 2Y spread heavily out of sync. Composite score in top 10% of history. Spreads moving fast and/or sitting at extreme levels.zgAbove-average spread dislocation (60-90th percentile). Either velocity is high, level is wide, or both.zOTypical macro conditions. Spread moving and sitting in normal historical range.zGBelow-average dislocation. Spreads stable, level near central tendency.zNUS-DE 2Y spread tight or rangebound. Composite score in bottom 10% of history.zPUS-JP 2Y spread showing meaningful moves. Composite score in top 25% of history.zHSpread in typical range with normal movement. Standard operating regime.zqSpread compressed or stable. Bottom 25% of history. Common when both central banks are in similar policy stances.c                    V f   R# \        V \        4      '       d   \        P                  ! V 4      '       d   R# \	        V4       F  w  r4W8  g   K  W#,          u # 	  VR,          # )zuGiven a value, list of ascending cutoffs (length N-1), and list of N tier
names (lowest-first), return the tier name.r   )
isinstancefloatnpisnan	enumerate)valuecutoffsnamesics   &&&  NC:\Users\Administrator\OneDrive\fx_macro_intraday\src\execution\regime_live.py_assign_tierr   O   sQ     }%BHHUOO'"98O # 9    c                    \        V 4      R,          R,          R,          pVP                  4       '       g   R#  \        P                  ! VP	                  RR7      4      #   \
         d     R# i ; i)zBLoad regime_thresholds.json if it exists. Returns None on failure.dataresearchzregime_thresholds.jsonNutf-8encoding)r   existsjsonloads	read_text	Exception)	base_pathps   & r   _load_thresholdsr-   \   sZ    Y& :-0HHA88::zz!++w+788 s   %A   A/.A/c                (   \        V 4      R ,          R,          R,          V,          pVP                  4       '       g   R#  \        P                  ! V4      pVP                   Uu. uF  qUP                  4       NK  	  upVn        \        P                  ! VR,          4      VR&   \        P                  ! WB,          RR7      WB&   VRV.,          P                  4       P                  R4      P                  RR7      # u upi   \         d     R# i ; i)	r!   rawratesNdatecoerce)errorsTdrop)r   r&   pdread_csvcolumnslowerto_datetime
to_numericdropnasort_valuesreset_indexr*   )r+   fnamecolr,   dfr   s   &&&   r   
_load_raterB   g   s    Y& 5(72U:A88::[[^)+4Aggi4
^^BvJ/6
--963- '')55f=IItITT 5  s%   $D %C==A?D =D DDc                   \        WV4      p\        WV4      pVe   Vf   R# \        P                  ! R\        P                  ! \	        VR,          P	                  4       VR,          P	                  4       4      \        VR,          P                  4       VR,          P                  4       4      RR7      /4      p\        P                  ! WuRRR7      P                  4       p\        P                  ! WvRRR7      P                  4       p\        P                  ! WVRRR7      P                  4       pW,          W,          ,
          VR&   VRR.,          P                  R	R
7      # )z@Build daily spread = A - B, forward-filled across calendar days.Nr1   D)freqleft)onhowinnerspreadTr4   )
rB   r6   	DataFrame
date_rangeminmaxmergeffillr<   r>   )	r+   a_csva_colb_csvb_colabdrrA   s	   &&&&&    r   _build_spread_seriesrX   u   s   9U+A9U+AyAI	vr}}AfIMMOQvY]]_-AfIMMOQvY]]_-C 9 : 
;B 	6v.446A
6v.446A	!6w	/	6	6	8B9ry(BxLvx !--4-88r   c                   V P                  4       pVR,          VR,          P                  V4      ,
          VR&   V^,           p\        V4      V^,           8  d   R# VR,          P                  VR P	                  4       pVR,          P                  VR P                  4       pVR,          P                  VR P	                  4       pVR,          P                  VR P                  4       pVR,          V,
          V,          VR&   VR,          V,
          V,          VR&   VR,          P                  4       \        VR,          P                  4       ,          ,           VR&   VP                  R.R7      P                  R	,          pRVR,          P                  4       R\        VR,          4      R\        VR,          4      R\        VR,          4      R\        VR,          4      /# )
zBCompute the macro composite score series. Returns latest row dict.rJ   velocityNlevel_z
velocity_z	composite)subsetr1   r   )copyshiftlenilocmeanstdabsLEVEL_WEIGHTr<   	isoformatr   )		spread_dfvelocity_daysrA   warmuplmlsvmvslatests	   &&       r   _compute_composite_scorerp      s   		B\BxL$6$6}$EEBzNRF
2w!	H		67	#	(	(	*B	H		67	#	'	'	)B	J		VW	%	*	*	,B	J		VW	%	)	)	+B8+r1ByM:+r1B|,'++-r)}?P?P?R0RRB{OYY{mY,11"5FfVn..0eF8,-eF9-.eF<01eF;/0 r   c                   \        V 4      R,          R,          RVP                  4        R2,          pVP                  4       '       g   \        P                  ! RR7      #  \
        P                  ! VP                  RR7      4      p\        V\        4      '       g   \        P                  ! RR7      # . pV FC  pR	 F:  pWe9   g   K   \        P                  ! WV,          4      pVP                  V4        KA  	  KE  	  \        P                  ! V4      #   \         d     Kf  i ; i  \         d    \        P                  ! RR7      u # i ; i)
u  Load entry/close timestamps from the live monitor's trade_history_<pair>.json.

The live JSON schema records `closed_at` (trade close time), not entry_time.
For activity counting purposes we use close time as a proxy for entry time
— trades hold 24-52h max so the shift is small relative to the 14d/60d
activity windows.

Returns pandas Series of timestamps, or empty Series on failure.
r!   logstrade_history_z.jsonzdatetime64[ns])dtyper#   r$   )
entry_time	closed_atentry	open_time
close_timetime)r   r9   r&   r6   Seriesr'   r(   r)   r   listr:   appendr*   )r+   pairr,   livetimestradekts   &&      r   _load_live_trade_timesr      s    	Y& 6)nTZZ\N%,PPA88::yy/001zz!++w+78$%%99#344E\:NN584Q ]  yy %   1yy/001s=   !AD' 4D' 	-D6D' D$ D' #D$$D' '"EEc                   \        W4      pVP                  '       d   R# \        P                  P	                  4       pV\        P
                  ! VR7      ,
          p\        W58  W48*  ,          P                  4       4      pV\        V4      3# )u  Count trades in the trailing window_days ending NOW, from live JSON only.

The backtest CSVs are not consulted here — they're historical artifacts
that don't update continuously. For live regime classification we use the
live monitor's trade_history_<pair>.json as the single source of truth.

Returns a tuple (count, total_live_trades):
  count             = trades within window
  total_live_trades = total trades in live history (for "early sample" detection)
)days)    r   )	r   emptyr6   	Timestampnow	Timedeltaintsumra   )r+   r~   window_daysr   r   cutoff	in_windows   &&&    r   _count_trades_in_windowr      sl     #93E{{{
,,


C2<<[11Fen6;;=>Ic%j  r   c                   \        V 4      p R\        P                  ! 4       P                  RR7      RR/ R/ /RR/ R/ /R. /p\	        V 4      pVf   VR,          P                  R
4       ^p^p\        V R\        4      w  rVR	pV'       d    RV9   d   VR,          P                  R4      pV'       d   \        YW;'       g    . RO\        4      MRpRVRVR\        RVR\        P                  VR4      RVRWc8  /VR,          R&   \        V R\        4      w  rR	pV'       d    RV9   d   VR,          P                  R4      pV'       d   \        Y;'       g    ^ ^ .\        4      MRpRVRV	R\        RVR\        P                  VR4      RV
RW8  /VR,          R&   RpR	pV'       d   RV9   dy   VR,          P                  R4      pVR,          P                  R^4      pV'       d@   \        V RRRR4      pVe-   \!        VV4      pV'       d   \        VR,          V\"        4      pRVRVR\$        P                  VR4      /VR,          R&   RpR	pV'       d   RV9   dy   VR,          P                  R4      pVR,          P                  R^<4      pV'       d@   \        V RRRR4      pVe-   \!        VV4      pV'       d   \        VR,          V\&        4      pRVRVR\(        P                  VR4      /VR,          R&   V# )u  Compute Activity + Macro regime tiers for both pairs.

Args:
  base_path: project root Path (where data/ lives)

Returns:
  dict suitable for direct inclusion in dashboard_data.json

Activity counts are sourced from the live monitor's trade history JSON
(data/logs/trade_history_eurusd.json and trade_history_usdjpy.json) only.
Backtest CSVs are not consulted at runtime — those are historical and
do not auto-update. When live history is small (early deployment), an
"early_sample" flag is set so the dashboard can show a caveat.

updated_atseconds)timespeceurusdactivitymacrousdjpyr3   Nu>   regime_thresholds.json missing — run regime_classifier_v1.pyactivity_cutoffsr   tiercountr   r   description 
total_liveearly_sampleri   zus2y.csvus2yzde2y.csvde2yr]   r!   zjp2y.csvjp2y)r   r   r   r   )r   r   r   rg   r-   r}   r   ACTIVITY_WINDOW_EUgetr   ACTIVITY_NAMES_EUACTIVITY_DESCRIPTIONS_EUACTIVITY_WINDOW_UJACTIVITY_NAMES_UJACTIVITY_DESCRIPTIONS_UJrX   rp   MACRO_NAMES_EUMACRO_DESCRIPTIONS_EUMACRO_NAMES_UJMACRO_DESCRIPTIONS_UJ)r+   out
thresholdsEU_MIN_TRADES_FOR_RELIABLEUJ_MIN_TRADES_FOR_RELIABLEeu_counteu_totaleu_act_cutoffseu_act_tieruj_countuj_totaluj_act_cutoffsuj_act_tiereu_macro_tiereu_macro_dataeu_macro_cutoffseu_velocity_daysrJ   uj_macro_tieruj_macro_datauj_macro_cutoffsuj_velocity_dayss   &                     r   compute_regimesr      s<    YI 	hlln..	.B:r7B/:r7B/"	C "),JH]^ "$!" 1HFXYHNh*,#H-112DE x)G)G<IZ[(  	+155k2F>!CM* 1HFXYHNh*,#H-112DE x)A)AAq6CTU(  	+155k2F>!CM* MMh*,'155i@'155orJ))ZU[\F! 8AQ R $0%k24Dn%VM 	-11-DCM' MMh*,'155i@'155orJ))ZU[\F! 8AQ R $0%k24Dn%VM 	-11-DCM' Jr   __main__)indentdefault)r   r   r   r	   r
   )r   r   r	   )
      <   Z   )r   r   r   r   r   )r   r   r	   )*__doc__
__future__r   r'   r   r   pathlibr   numpyr   pandasr6   r   r   ACTIVITY_PCTS_EUACTIVITY_PCTS_UJr   r   r   r   rf   r   r   r   r   r   r-   rB   rX   rp   r   r   r   __name____file__resolveparentsbaseresultprintdumpsstr r   r   <module>r      s  * #  (    C 1 $ H    U0 ufiq  EQ    _i  NQ	    \  Biah[  jb  L[	 
9 01B!*iZ z>!!#++A.DT"F	$**VAs
34 r   