+
    +i                        R t ^ RIt^ RIt^ RIt^ RIt^ RIHtHtHtHt ^ RI	H
t
 ^ RIt^ RIt^ RIt]
! ]4      P#                  4       P$                  ^,          t]R,          t]! ]4      ]P,                  9  d"   ]P,                  P/                  ]! ]4      4       ]R,          R,          t]P3                  RRR7       ]P4                  ! ]P6                  R	R
]P8                  ! ]R,          RR7      ]P:                  ! ]P<                  4      .R7       ]P>                  ! R4      t Rt!Rt"Rt#Rt$Rs%Rs&Rt'Rt(^4t)Rt*Rt+Rt,^t-^t.Rt/. R[Ot0^xt1^t2^<t3Rt4RRRRRRRRR RR!RR"RR#R/t5]R,          R$,          R%,          t6]6Pn                  P3                  RRR7       R& t8R' t9R(R/t:]Pv                  ! R)R*4      t<]Pv                  ! R+R,4      t=R- R. lt>R/RR0RR1RR2RR3R/t?R4 R5 lt@R6 R7 ltAR8 tBR9 tC]43R: R; lltDR\R< R= lltER> R? ltFR@ RA ltGRB RC ltHRD RE ltIRF RG ltJRH tKRI RJ ltLRK RL ltMRM RN ltNRO RP ltORQ tPRR tQR]RS ltRR]RT ltSRU tTRV tURW tVRX tWRY tX]YRZ8X  d
   ]X! 4        R# R# )^u&  
live_signal_monitor.py
=======================
Live execution signal monitor for the validated EURUSD macro lead-lag model.

Runs continuously on VPS. Every hour during the London/NY session it:
  1. Updates rate data from FRED and Bundesbank (auto_rates_loader.py)
  2. Pulls latest 1H EURUSD bars from MT5
  3. Rebuilds the lag z-score signal
  4. If signal threshold breached, looks for 15M Fibonacci entry
  5. If entry found and no trade open, places order with TP/stop preset
  6. Monitors open trades for z-score reversal exit

VALIDATED PARAMETERS (DO NOT CHANGE)
--------------------------------------
  Signal threshold : z-score >= 2.75
  Entry            : 0.786 Fibonacci pullback on 15M within 6h
  Take profit      : 0.20%
  Stop loss        : 0.25%
  Z-exit threshold : ±1.5 reversal
  Hold max         : 52 hours
  Session          : 08:00-17:00 EET (hours 7-16)
  Base risk        : 0.75% ($300k notional on $100k)
  Signal scaling   : 1x / 1.5x / 2x by z-score band

Requirements
------------
  pip install MetaTrader5 --break-system-packages
  pip install schedule --break-system-packages

MT5 Setup
---------
  1. Install MT5 on Windows machine or VPS
  2. Enable "Allow Algo Trading" in MT5 settings
  3. Enable "Allow DLL imports" in MT5 Terminal settings
  4. Log in to your broker account in MT5
  5. Set MT5_LOGIN, MT5_PASSWORD, MT5_SERVER in config below

Place this file in:
  C:\Users\paul_\OneDrive\fx_macro_intraday\src\execution\live_signal_monitor.py

Run from project root:
  python src/execution/live_signal_monitor.py

Stop with Ctrl+C
N)datetimetimezonedate	timedeltaPathsrcdatalogsT)parentsexist_okz)%(asctime)s  %(levelname)-8s  %(message)sz%Y-%m-%d %H:%M:%Szlive_monitor.logutf-8encoding)levelformatdatefmthandlerslive_monitoriڐ%zxIaJM$A4t2Vc5szICMarketsSC-DemoEURUSD      @gx&?g{Gzd?gMb`?      ?gQ~?i  position_openFposition_ticketposition_signalentry_price
entry_timeposition_lotlast_zscorelast_signal_timestatezlive_state.jsonc                 B    ^ RI p \        P                  4       pVP                  R4      '       d4   \	        VR,          R4      '       d   VR,          P                  4       VR&   \        P                  4       pVP                  R4      '       d4   \	        VR,          R4      '       d   VR,          P                  4       VR&   W!R&   \        P                  V P                  V^R7      RR7       R#   \         d$   p\        P                  R	T 24        Rp?R# Rp?ii ; i)
zCPersist current STATE and ARMED to disk so it survives VPS reboots.Nr   	isoformat
armed_time_armedindentr   r   zState save failed: )jsonSTATEcopygethasattrr"   ARMED
STATE_FILE
write_textdumps	Exceptionlogwarning)r'   r	   
armed_dataes       VC:\Users\Administrator\OneDrive\fx_macro_intraday\src\execution\live_signal_monitor.py
save_stater6   ~   s    /zz|88L!!gd<.@+&N&N!%l!3!=!=!?D ZZ\
>>,''GJ|4Lk,Z,Z'1,'?'I'I'KJ|$#Xdjjaj87K /)!-../s$   .C0 AC0 AC0 0D;DDc            	        \         P                  4       '       g   R#  ^ RIp ^ RIHp V P	                  \         P                  RR7      4      pVP                  RR4      '       Ed   VP                  RR4      \        R&   VP                  R4      \        R&   VP                  R4      \        R&   VP                  R	4      \        R	&   VP                  R
4      \        R
&   VP                  R4      \        R&   VP                  R4      pV'       d   VP                  ! V4      \        R&   \        P                  R\        R,           R\        R	,           24       \        R\        R,           R\        R	,           R24       M\        P                  R4       VP                  R/ 4      pVP                  RR4      '       EdR   VP                  R4      pV'       Ed6   VP                  ! V4      pVP                  ! 4       V,
          P                  4       R,          pVR8  d   R\        R&   VP                  R4      \        R&   VP                  R4      \        R&   V\        R&   VP                  R4      \        R&   \        R,          ^8X  d   RMRp\        RV,
          ^4      p	\        P                  RV R\        R,          R  R!V	R" R#24       \        R$V R%\        R,          R  R&V	R" R'24       R# \        P                  R(VR" R)24       R# R# R#   \          d$   p
\        P#                  R*T
 24        Rp
?
R# Rp
?
ii ; i)+z
Restore STATE and ARMED from disk on startup.
If a position was open or signal was armed, restores both
so monitoring and entry detection work correctly after restart.
N)r   r   r   r   Fr   r   r   r   r   r   u)   State restored — position open: ticket=z entry=uO   ⚠️ <b>STATE RESTORED AFTER REBOOT</b>
Position was open at restart
Ticket: z
Entry: z
Resuming monitoring...u5   State file found — no open position, starting freshr$   activer#           @T	directiontarget_price
zscore_absLONGSHORTu   Armed state restored —  target=.5fz | .1fzh remaining in windowu4   🎯 <b>SIGNAL RESTORED AFTER REBOOT</b>
Direction: z	
Target: z
Time remaining: zh
Fast polling resuming...z%Armed signal expired during restart (u   h ago) — not restoringzState restore failed: )r-   existsr'   r   loads	read_textr*   r(   fromisoformatr1   infosend_telegramutcnowtotal_secondsr,   roundr0   r2   )r'   r   r	   etr3   armed_time_strr#   hours_sincedir_str	remainingr4   s              r5   
load_staterQ      s    <2%zz*...@A 88OU++'+xx'GE/"'+xx0A'BE#$'+xx0A'BE#$'+xx'>E- '+xx'?E.!'+xx'>E- ,'B&.&<&<R&@l#HH $%678 9#M235 6  !234 5./ 0)* HHLM XXh+
>>(E**'^^L9N~%33NC
'0:=LLNQUU$,0E(O,6NN;,GE+&,6NN>,JE.),6E,',6NN<,HE,'(-k(:a(?fWG %cK&7 ;IHH8	 %n 5c:# )#.CE F "&&-Y /##(#8"= >++4S/ :34 HH  !!,S 11IK L/  +8  2,QC0112s9   AL &B)L B2L L DL 6L M!L??Mr   TELEGRAM_TOKENz.8794831706:AAGzqHNhyvfWL2lG_kCQUupacilRf7GfNSITELEGRAM_CHAT_ID
1031071259c                $    V ^8  d   QhR\         /# )   messagestr)r   s   "r5   __annotate__rZ      s     : :3 :    c                   \         '       d   \        '       g   R#  ^ RIp^ RIp^ RIpVP                  4       pRVn        VP                  Vn        R\          R2pR\         RVP                  P                  V 4       R2pVP                  P                  WEP                  4       RR	7      pVP                  P                  V^
VR
7       R#   \         d$   p\         P#                  RT 24        Rp?R# Rp?ii ; i)z=Send a message to Telegram. Fails silently if not configured.NFzhttps://api.telegram.org/botz/sendMessagezchat_id=z&text=z&parse_mode=HTMLPOST)r	   method)timeoutcontextzTelegram notification failed: )rR   rS   urllib.requesturllib.parsesslcreate_default_contextcheck_hostname	CERT_NONEverify_modeparsequoterequestRequestencodeurlopenr0   r1   r2   )rW   urllibrc   ctxurlr	   reqr4   s   &       r5   rH   rH      s    >!1!1:((*"---n-=\J*+6&,,2D2DW2M1NN^_~~%%cf%MsB< :4QC899:s   B-C C9C44C9r8   r;   r<   r#   r=   c                0    V ^8  d   QhR\         R\         /# )rV   zreturnfloat)r   s   "r5   rZ   rZ      s      e  r[   c                 v    \          F  w  rpYu;8:  d   V8  g   K   Vu #  K  	  \         R,          ^,          # )   )ZSCORE_BANDS)rs   lohimults   &   r5   get_multiplierr~      s5    $<R<K  % Ar[   c                $    V ^8  d   QhR\         /# rV   rt   bool)r   s   "r5   rZ   rZ     s      T r[   c                     ^ RI p V P                  4       '       g)   \        P                  RV P	                  4        24       R# \
        '       df   \        '       dZ   \        '       dN   V P                  \
        \        \        4      '       g)   \        P                  RV P	                  4        24       R# V P                  s
V P                  sV P                  4       pVf   \        P                  R4       R# \        P                  RVP                   RVP                  R R	VP                    24       R
#   \"         d    \        P                  R4        R# i ; i)z;Initialises and logs in to MT5. Returns True if successful.NzMT5 initialize failed: FzMT5 login failed: zCould not retrieve account infozMT5 connected | Account: z | Balance: $,.2fz | Broker: TzWMetaTrader5 package not installed. Run: pip install MetaTrader5 --break-system-packages)MetaTrader5
initializer1   error
last_error	MT5_LOGINMT5_PASSWORD
MT5_SERVERloginTIMEFRAME_H1TIMEFRAME_1HTIMEFRAME_M15TIMEFRAME_15Maccount_inforG   balancecompanyImportError)mt5rG   s     r5   connect_mt5r     s   ! ~~II/0@/ABC9**99YjAA		.s~~/?.@AB(())!<II78,TZZL 9"ll40 1 LL>+ 	,  		 D 	EsA   D7 &D7 D7 D7 D7 ($D7 &D7 5AD7 8=D7 7 EEc                  ~     ^ RI p V P                  4        \        P                  R4       R#   \         d     R# i ; i)    NzMT5 disconnected)r   shutdownr1   rG   r0   )r   s    r5   disconnect_mt5r   $  s2    !#$ s   )- <<c                 :   \         P                  ! 4       p \        R,          V 8X  d   \        P	                  R4       R#  ^ RIHpHp ^ RIpVP                  ! R4      pV'       g   \        P                  R4       R# \        P	                  R	4       V! R
VRRR7       V! RVRRR7       ^ RIHpHpHp V! RVVRR7       V! RVVRR7       V \        R&   \        P	                  R4       R#   \         d$   p\        P                  RT 24        Rp?R# Rp?ii ; i)u|   
Updates US and DE yield data from FRED and Bundesbank.
Only runs once per calendar day — skips if already updated today.
r   u,   Rate data already updated today — skippingT)update_local_csvfetch_fred_seriesNFRED_API_KEYu-   FRED_API_KEY not set — skipping rate updateFz*Updating rate data from FRED/Bundesbank...us2y.csvDGS2us2y)	series_idvalue_col_name	us10y.csvDGS10us10y)fetch_bundesbank_seriesBUNDESBANK_DE2Y_CSVBUNDESBANK_DE10Y_CSVde2y.csvde2y)csv_urlr   	de10y.csvde10yzRate data updated successfullyzRate update failed: )r   todayLAST_RATE_UPDATEr1   rG   ingestion.auto_rates_loaderr   r   osgetenvr2   r   r   r   r0   r   )	r   r   r   r   api_keyr   r   r   r4   s	            r5   update_rate_datar   .  s    
 JJLE5(?@S))N+KKGH=>&76(.	0&77(/	1	
 	
 	%<!4V	M&=!5g	O $) 12 		(,-s%    %C, &C, =A-C, ,D7DDc                R    V ^8  d   QhR\         R\        P                  R,          /# rV   n_barsrt   Nintpd	DataFrame)r   s   "r5   rZ   rZ   X  s#      C bllT.A r[   c                    ^ RI pVP                  \        \        ^ V 4      pVe   \	        V4      ^ 8X  d)   \
        P                  RVP                  4        24       R# \        P                  ! V4      p\        P                  ! VR,          RR7      VR&   VP                  RRRRR	R	R
R
RR/R7      pV. RO,          pVP                  R4      P                  RR7      #   \         d$   p\
        P                  RT 24        Rp?R# Rp?ii ; i)z(Pulls n_bars of 1H EURUSD data from MT5.NzFailed to get 1H bars: timesunitr   openhighlowclosetick_volumevolumecolumnsTdropzget_mt5_bars_1h error: )r   r   r   r   r   r   )r   copy_rates_from_posSYMBOLr   lenr1   r   r   r   r   to_datetimerenamesort_valuesreset_indexr0   r   r   ratesdfr4   s   &    r5   get_mt5_bars_1hr   X  s    !''aH=CJ!OII/0@/ABC\\% 6
=:YY!&w!. :Y ; FG~~j)5545@@ 		+A3/0s   AC A?C D)DDc                R    V ^8  d   QhR\         R\        P                  R,          /# r   r   )r   s   "r5   rZ   rZ   n  s#      S 2<<$+> r[   c           
         ^ RI pVP                  \        \        ^ V 4      pVe   \	        V4      ^ 8X  d)   \
        P                  RVP                  4        24       R# \        P                  ! V4      p\        P                  ! VR,          RR7      VR&   VP                  RRRRR	R	R
R
/R7      pV. RO,          pVP                  R4      P                  RR7      #   \         d$   p\
        P                  RT 24        Rp?R# Rp?ii ; i)z:Pulls recent 15M EURUSD bars from MT5 for entry detection.NzFailed to get 15M bars: r   r   r   r   r   r   r   r   r   Tr   zget_mt5_bars_15m error: )r   r   r   r   r   )r   r   r   r   r   r1   r   r   r   r   r   r   r   r   r0   r   s   &    r5   get_mt5_bars_15mr   n  s    !''q&I=CJ!OII01A0BCD\\% 6
=:YY!&w AY B<=~~j)5545@@ 		,QC01s   AC A=C D
'DD
c                f    V ^8  d   QhR\         P                  R\         P                  R,          /# )rV   	prices_1hrt   N)r   r   )r   s   "r5   rZ   rZ     s+     G G2<< GBLL44G Gr[   c           	     ~  aa   ^ RI Hp ^ RIHp \        R,          R,          R,          oV P                  4       p V R,          P                  P                  4       V R&   V P                  RRR	7      P                  R4R7      P                  R4      P                  RR7      pVR
,          P                  4       VR&   \        P                  ! VR,          4      VR&   V3R lpV! RR4      pV! RR4      pV! RR4      pV! RR4      pVR,          P                  4       p	VR,          P!                  4       p
\        P"                  ! R\        P$                  ! WRR7      /4      o V 3R lpV! VR4      pV! VR4      pV! VR4      pV! VR4      pVP'                  VRR7      P'                  VRR7      P'                  VRR7      pVR,          VR,          ,
          VR&   VR,          VR,          ,
          VR&   VR,          P)                  ^4      VR&   VR,          P)                  ^4      VR&   V. R5O,          P+                  4       pVP'                  VRR R!7      P+                  RR.R"7      p\-        V4      \.        ^,           8  dE   \0        P3                  R#\-        V4       R$\.        ^
,            24       VR,          R6,          VR%&   EM^\-        V4      p\4        P6                  ! V\4        P8                  4      p\4        P6                  ! V\4        P8                  4      p\;        \.        V4       EF  pVP<                  V\.        ,
          V P                  4       pVVR,          P?                  4       ^ 8  VR,          P?                  4       ^ 8  ,          ,          p\-        V4      ^8  d   K~  VPA                  VRR.,          4      p VPC                  VR,          V4      PE                  4       pVPF                  PI                  R\4        P8                  4      VV&   VPF                  PI                  R\4        P8                  4      VV&   EK  	  VVR&&   VVR'&   VR&,          PM                  \N        R(7      PQ                  4       PS                  ^4      PU                  R7R)4      VR*&   VR',          PM                  \N        R(7      PQ                  4       PS                  ^4      PU                  R8R+4      VR,&   VR*,          VR,          ,          VR,,          VR,          ,          ,           VR%&   V. R9O,          P                  4       pV P'                  VRR R!7      p. R:OpVV,          PW                  4       VV&   VR
,          P                  ^4      VR-&   VR%,          VR-,          ,
          VR.&   VR.,          PY                  \Z        \Z        R/7      PQ                  4       pVR.,          PY                  \Z        \Z        R/7      P]                  4       pVR.,          V,
          V,          VR0&   VP+                  R0.R"7      P                  RR7      p\0        P_                  R1\-        V4       R224       V#   \J         d     EKI  i ; i  \J         d8   p\0        Pa                  R3T 24       ^ RI1pTPe                  4         Rp?R# Rp?ii ; i);u  
Rebuilds the lag z-score signal purely from live MT5 1H bars and
the rate CSV files on disk (updated daily by update_rate_data).

Does NOT load any historical price CSVs — uses only the 500 bars
pulled from MT5 (covering ~21 trading days which is enough for the
60-bar z-score window and the 24h return lookback).

Rolling beta is computed inline from the MT5 price data and
the current rate spread files.
Nr   r	   rawr   r   r   F)as_indexr   )r   Tr   eurusd_return_1dc                   < SV ,          pVP                  4       '       g   \        R V 24      h\        P                  ! VR.R7      pVP                   Uu. uF  qDP                  4       NK  	  upVn        \        P                  ! VR,          4      VR&   \        P                  ! W1,          RR7      W1&   VRV.,          P                  4       P                  R4      # u upi )zRate file not found: r   )parse_datescoerce)errors)
rC   FileNotFoundErrorr   read_csvr   lowerr   
to_numericdropnar   )fnamecolpathr   c	RATES_DIRs   &&   r5   	load_rate&compute_live_zscore.<locals>.load_rate  s    u$D;;=='*?v(FGGTx8B-/ZZ8Z'')Z8BJ6
3BvJmmBGH=BGvsm$++-99&AA 9s   Cr   r   r   r   r   r   r   r   D)freqc                    < SP                  4       pV P                  4       pVR ,          P                  R4      VR &   VR ,          P                  R4      VR &   \        P                  ! VP	                  R 4      VP	                  R 4      R RR7      # )r   zdatetime64[us]backward)onr;   )r)   astyper   
merge_asofr   )rate_dfr   leftright
date_ranges   &&  r5   ffill_to_daily+compute_live_zscore.<locals>.ffill_to_daily  s    OO%DLLNE L//0@ADL!&M001ABE&M==!1!1&!9"'"3"3F";%+zC Cr[   )r   	spread_2y
spread_10yspread_2y_change_1dspread_10y_change_1dr   )r   how)subsetz"Insufficient data for beta model: z days, need predicted_return_1dbeta_2y_rawbeta_10y_raw)spang?beta_2yg{Gz?beta_10yeurusd_return_24hlag_gap_24h)min_periodslag_zscore_24hzSignal built from z5 days MT5 data + live rates (no CSV price dependency)zcompute_live_zscore error: )r   last)r   r   r   gQgg{Gz)r   r  r   r   )r  r   r   )3statsmodels.apiapipathlibr   	BASE_PATHr)   dt	normalizegroupbyaggr   r   
pct_changer   r   minmaxr   r   mergediffr   r   BETA_WINDOWr1   r2   npfullnanrangeilocabsadd_constantOLSfitparamsr*   r0   ewmSMOOTH_SPANmeanshiftclipffillrollingZSCORE_WINDOWstdrG   r   	traceback	print_exc)!r   smr   daily_pxr   r   r   r   r   date_mindate_maxr   us2y_dus10y_dde2y_dde10y_dspreadsmodel_dfnb2y_rawb10y_rawisampleXresr   	fill_colslag_meanlag_stdr4   r/  r   r   s!   &                              @@r5   compute_live_zscorerE    s
   {$ &.8	 NN$	%j144>>@	&fu5S(S)[ [d[#	 	 (0'8'C'C'E#$>>(6*:;	B *v.+w/*v.+w/ F#'')F#'')\\62==RU+V"WX
	C !/ 0 / 0,,w6,288F8KQQRY^dQe '76? B ' 0773C C*1+*>*C*CA*F%&*1,*?*D*DQ*G&'QRYY[ >>'f&>AHH&(=> I @ x=;?*KK<S]O<XcdfXfWghi.67L.MPU.UH*+ HA266*G266*H;*!q}Q7<<>(=!>!B!B!Dq!H"()?"@"D"D"F"J!L Mv;#OOF,ACY+Z$[\&&(:!;Q?CCEC"%**..1F"PGAJ"%**..1G"PHQK + (/H]#'/H^$#+M#:#>#>K#>#P#U#U#W#]#]^_#`#e#efkmq#rHY#+N#;#?#?[#?#Q#V#V#X#^#^_`#a#f#fglnr#sHZ #x0E'FF$x0F'GGH *+  M NNRdf 	 __X&f_=Z	9++-9 #%W+"8"8"<"$%:";bAT>U"U=m$,,],V[[]m$,,],VZZ\ "= 1H <GYY/0Y1==4=H%c(m_4ijk	? ! B  		/s34	s>   OY: BY'HY: 'Y72Y: 6Y77Y: :Z<,Z77Z<c                0    V ^8  d   QhR\         R\         /# )rV   r=   rt   ru   )r   s   "r5   rZ   rZ     s     4 45 4U 4r[   c                    ^ RI pVP                  4       pVf   R# VP                  p\        V 4      pV\        ,          V,          p\
        R,          pVP                  \        4      pVf   RpMVP                  ^
,          pWVV,          ,          p	V'       d   VP                  MRp
V'       d   VP                  MRpV'       d   VP                  MRp\        V
\        W4      4      p	\        W,          4      V,          p	\        P!                  RV	R RVR	 R
V RVR 24       V	#   \"         d$   p\        P%                  RT 24        Rp?R# Rp?ii ; i)aP  
Calculates MT5 lot size for the given z-score and account balance.

Formula:
  risk_dollar   = balance * BASE_RISK_PCT * multiplier
  stop_dollars  = lot_size * pip_value_per_lot * stop_pips
  lot_size      = risk_dollar / (stop_pips * pip_value_per_lot)

For EURUSD standard lot:
  pip_value_per_lot = $10 per pip (on $100k notional)
N{Gz?g-C6?g      $@g      Y@zPosition size: .2fz lots | Risk: $z,.0fz | Multiplier: zx | Balance: $r   zcalculate_lot_size error: )r   r   r   r~   BASE_RISK_PCTSTOP_PCTsymbol_infor   trade_tick_value
volume_min
volume_maxvolume_stepr  r  rK   r1   rG   r0   r   )r=   r   accountr   
multiplierrisk_dollar	stop_pipsrL  pip_value_per_lotlot_sizemin_lotmax_lotlot_stepr4   s   &             r5   calculate_lot_sizerZ    sE   (!##%?__#J/
},z9 &	 oof- $ + < <r A.?"?@ /:;))t.9;))u.9;**twG 67,-8?8C. 1&t, -  *| ,%d^- 	.  		.qc23s*   D' BD' 0D' A D' 'E2EEc                b    V ^8  d   QhR\         R\        R\        R\        R\         R,          /# )rV   signalr   rV  r=   rt   Nr   rv   )r   s   "r5   rZ   rZ   G  sE     J JJJ J 	J
 	4ZJr[   c                ^    ^ RI pVP                  \        4      pVf    \        P	                  R\         R24       R# VP
                  '       g;   VP                  \        R4      '       g   \        P	                  R\         24       R# VP                  \        4      pVf   \        P	                  R4       R# V ^8X  dV   VP                  pVP                  p\        V\        V,          ,
          ^4      p	\        V\        V,          ,           ^4      p
MTVP                  pVP                  p\        V\        V,          ,           ^4      p	\        V\        V,          ,
          ^4      p
RVP                  R\        R	VR
VRVRV	RV
R^RRRRVR R2RVP                   RVP"                  /pVP%                  V4      pVf)   \        P	                  RVP'                  4        24       R# VP(                  VP*                  8w  d2   \        P	                  RVP(                   RVP,                   24       R# \        P/                  RV ^8X  d   RMR RVR RVR R V
R R!V	R R"VP0                   24       VP0                  #   \2         d$   p\        P	                  R#T 24        Rp?R# Rp?ii ; i)$zh
Places a market order with TP and stop already set.
Returns the order ticket number or None if failed.
NzSymbol z
 not foundTzFailed to select zFailed to get tick dataactionsymbolr   typepricesltp	deviationmagic4commentzz=rI  z macro signal	type_timetype_fillingzorder_send returned None: zOrder failed: retcode=z
  comment=zORDER PLACED | BUYSELLz  z lots  @rA   z  TP=z  SL=z	  Ticket=zplace_order error: )r   rL  r   r1   r   visiblesymbol_selectsymbol_info_tickORDER_TYPE_BUYaskrK   rK  TP_PCTORDER_TYPE_SELLbidTRADE_ACTION_DEALORDER_TIME_GTCORDER_FILLING_IOC
order_sendr   retcodeTRADE_RETCODE_DONErh  rG   orderr0   )r\  r   rV  r=   r   rL  tick
order_typerb  rc  rd  rj   resultr4   s   &&&&          r5   place_orderr  G  sx   @!oof-IIxz23"""$$VT22		-fX67##F+<II/0Q;++JEux%'77;Buv%'77;B,,JEux%'77;Buv%'77;B c33fhjebbbh:c"2-@c00c33
 (>II23>>3C2DEF>>S333II.v~~.> ?!!' 02 3?#QYEF32S>% 5#heBs8 ,!<<.	* 	+
 || 		's+,sC   :I> I> I> ,I> 
.I> :D,I> (A
I> 4A	I> >J,	J''J,c                <    V ^8  d   QhR\         R\        R\        /# )rV   ticketreasonrt   )r   rY   r   )r   s   "r5   rZ   rZ     s!     2 2# 2s 2t 2r[   c                r    ^ RI pVP                  V R7      pV'       g   \        P                  RV  R24       R# V^ ,          pVP	                  \
        4      pVf   \        P                  R4       R# VP                  ^ 8X  d   VP                  pVP                  pMVP                  pVP                  pRVP                  R	\
        R
VP                  RVRV RVR^RRRRV 2RVP                  RVP                  /pVP!                  V4      p	V	e   V	P"                  VP$                  8w  d/   \        P                  RV	'       d   V	P"                  MR 24       R# VP&                  p
\        P)                  RV  RV RV
R 24       R#   \*         d$   p\        P                  RT 24        Rp?R# Rp?ii ; i)z(Closes an open position at market price.N)r  z	Position u$    not found — may already be closedTzFailed to get tick for closeFr_  r`  r   ra  positionrb  re  rf  rg  rh  zclose: ri  rj  zClose failed: NonezPOSITION CLOSED | Ticket=z
 | Reason=z | P&L=$rI  zclose_position_market error: )r   positions_getr1   r2   ro  r   r   ra  rs  rt  rp  rq  ru  r   rv  rw  rx  ry  rz  profitrG   r0   )r  r  r   r  posr|  
close_typeclose_pricerj   r~  pnlr4   s   &&          r5   close_position_marketr    s   0!$$F$3KK)F8+OPQqk##F+<II4588q=--J((K,,J((K C11FCJJJFKBHgfX.C..C11
 (>V^^s/E/EEIIv~~V&LMNjj,VH 5!((3s)5 	6 		1!56s4   F F 7F 4CF F +F F6F11F6c                $    V ^8  d   QhR\         /# r   r   )r   s   "r5   rZ   rZ     s      t r[   c                      ^ RI p V P                  \        RR7      pVRJ;'       d    \        V4      ^ 8  #   \         d     R# i ; i)z,Checks if our position is still open in MT5.Nrg  )r`  rf  F)r   r  r   r   r0   )r   	positionss     r5   check_position_statusr    sM    !%%V8%D	$;;Y!);; s   %7 7 AAc                      ^ RI p V P                  \        4      pVf   R# VP                  VP                  3#   \
         d     R# i ; i)z&Returns (bid, ask) from MT5 tick data.N)r   ro  r   rt  rq  r0   )r   r|  s     r5   get_live_pricer    sG    !##F+<$((## s   9 9 AAc                <    V ^8  d   QhR\         R\        R\        /# )rV   r;   r<   r=   r]  )r   s   "r5   rZ   rZ     s!       5 e r[   c           	     >   R\         R&   V \         R&   V\         R&   \        P                  ! \        P                  4      \         R&   V\         R&   V ^8X  d   RMRp\
        P                  R	V R
VR RVR R24       \        4        \        RV RVR RVR R24       R# )z
Arms the fast-polling execution engine.
Called when z-score threshold is breached.
Script polls every 5 seconds for the 0.786 level to be touched.
Tr8   r;   r<   r#   r=   r>   r?   zARMED | 
 | Target=rA    | z=.3fz  | Polling every 5s for up to 6hu'   🎯 <b>SIGNAL ARMED</b>
Direction: <b>z</b>
Z-score: z
Fib 0.786 target: z
Watching every 5s for up to 6hN)	r,   r   nowr   utcr1   rG   r6   rH   )r;   r<   r=   	dir_labels   &&& r5   arm_fast_pollingr    s     !E(O%E+(E.$LL6E,&E,#q.gIHHx	{*\#,> ?S!!AC DL" $s# $)#. /)	*r[   c                $    V ^8  d   QhR\         /# )rV   r  rX   )r   s   "r5   rZ   rZ     s       r[   c                    R\         R&   R\         R&   R\         R&   R\         R&   R\         R&   \        P                  RV  24       \        4        R# )	z Disarms the fast-polling engine.Fr8   Nr;   r<   r#   r=   zDISARMED | Reason: )r,   r1   rG   r6   )r  s   &r5   disarm_fast_pollingr    sL    !E(O E+ E. E, E,HH"6(+,Lr[   c                $    V ^8  d   QhR\         /# r   r   )r   s   "r5   rZ   rZ     s     y yt yr[   c                 J   \         R,          '       g   R# \        R,          '       dW   \        4       p V '       gC   \        P	                  R4       R\        R&   R\        R&   R\        R&   R\        R&   R\        R	&   R# \
        P                  ! \        P                  4      pV\         R
,          ,
          P                  4       R,          pVR8  d(   \        P	                  RVR R24       \        R4       R#  \        4       pVf   R# Vw  rE\         R,          p\         R,          p\        \        R4      '       g   ^ \        n        \        ;P                  ^,          un        \        P                  ^,          ^ 8X  dM   \        P	                  RVR RVR RVR RVR;8X  d   RMR RV^8X  d   WW8:  g   VR;8X  d	   WG8  d   RMR 2
4       V^8X  d   WW8*  pTp	MWG8  pTp	V'       g   R# V^<,          p
\        P	                  RV^8X  d   RMR RV	R R VR R!V
R" R#2	4       \        R$V^8X  d   RMR R%V	R R&VR R'V
R" R(2	4       \         R),          p\!        V4      pVR*8  d#   \        P#                  R+4       \        R,4       R# \%        VV	VVR-7      pVe   R.\        R&   V\        R&   V\        R&   V	\        R&   VP'                  RR/7      \        R	&   V\        R0&   \        R14       \)        4        V^8X  d   RMRpV^8X  d   V	^\*        ,           ,          MV	^\*        ,
          ,          pV^8X  d   V	^\,        ,
          ,          MV	^\,        ,           ,          p\        R2V R3V	R R4VR5 R6VR R7VR R8V 24       R.# \        P#                  R94       \        R:4       R# )<u   
Fast execution loop — called every 5 seconds when ARMED.
Checks live bid/ask against the 0.786 target price.
Also checks if an open position has closed (TP/stop hit by MT5).
Returns True if order was placed.
r8   Fr   uE   Position closed by broker (detected in fast poll) — resetting stateNr   r   r   r   r#   r9   r:   zEntry window expired (rB   u   h) — disarmingz	6h expiryr;   r<   _poll_countzFast poll | bid=rA   z ask=r@   z dir=r?   r>   z hit=YESNOzTARGET HIT | z	 | Price=r  z | Elapsed=.0fzm since signalu#   ✅ <b>ENTRY HIT</b>
Direction: <b>z</b>
Price: z
Target was: z
Time since signal: z minutes
Placing order now...r=   rH  u   Lot size too small — skippingzlot size error)r\  r   rV  r=   Ttzinfor   zorder placedu'   📈 <b>ORDER PLACED</b>
Direction: <b>z</b>
Entry: z
Lots: rI  z
TP: z
SL: z	
Ticket: z#Order placement failed in fast pollzorder failedry   )r,   r(   r  r1   rG   r   r  r   r  rJ   r  r  r+   run_fast_pollr  rH   rZ  r   r  replacer6   rr  rK  )
still_openr  elapsed_hourspricesrt  rq  r;   target	entry_hit
exec_priceelapsed_minr=   rV  r  rO   tp_pricesl_prices                    r5   r  r    s    ?? _*,
HH\]',E/"'+E#$'+E#$'+E- '+E,
,,x||
$C 5..==?$FM)-)<<LMNK(
 	 F~HC{#I~&F =-00$%!"  1$)#C9E#c(6#, O#,b=f= >"+Q,3;IrMVYVahlmo 	p
 A~]	
 ]	
  "$KHH}y!|VA B %Zs| <#C(8 9 #,a<W= >S! "cl #)#. /		  |$J#J/H$		34,-	F #'o#) #, #-m#&;;d;#;l#+nN+%qL&g,5qL:qx(j!F(>S.7l:qz*
AhJ@W$I & % &cN #C. !C. !h 	
 		78N+r[   c                $    V ^8  d   QhR\         /# r   r   )r   s   "r5   rZ   rZ     s     < <D <r[   c                     \         P                  ! \        P                  4      p V P                  ^,           ^,          p\
        Tu;8*  ;'       d
    \        8*  # u # )z?Returns True if current time is within London/NY session (EET).)r   r  r   r  hourSESSION_START_EETSESSION_END_EET)now_utchour_eets     r5   in_trading_sessionr    sB    ll8<<(G q B&H;;O;;;;r[   c                    \         P                  ! \        P                  4      p \        P                  RV P                  R4       R24       \        4       '       gi   \        R,          '       d   \        P                  R4       M?\        R,          '       g   \        P                  R4       R# \        P                  R	4       ^ RI
pVP                  4       '       g=   \        P                  R
4       \        4       '       g   \        P                  R4       R# \        R,          '       dU   \        4       pV'       gC   \        P                  R4       R\        R&   R\        R&   R\        R&   R\        R&   R\        R&   \!        4       pVe    \#        V4      \$        \&        ,           8  d   \        P                  R4       R# \)        V4      pVe   VP*                  '       d   \        P                  R4       R# VP,                  RI,          p\/        VR,          4      pV\        R&   \        P                  RVR R\0         R24       \        R,          '       Ed   \        R,          Ee   \        R,          p\        R,          e   V P3                  RR7      \        R,          ,
          P5                  4       R,          pV^48  dF   \        P                  RVR R24       \7        \        R,          R4       R\        R&   R\        R&   R# V^8X  di   V\8        ) 8:  d]   \        P                  R VR R!\8         R"24       \;        R#VR R$24       \7        \        R,          R%4       R\        R&   R\        R&   R# VRI8X  dX   V\8        8  dM   \        P                  R VR R&\8         R'24       \7        \        R,          R%4       R\        R&   R\        R&   R# \        P                  R(\        R,           R)\        R,          R* R+VR R,24       R# \=        V4      \0        8  d}   \        P                  R-\=        V4      R R.\0         R24       \        R,          '       d>   \        R/,          p	V	^8X  d   V\8        ) 8:  g   V	RI8X  d   V\8        8  d   \?        R04       R# V\0        8  d   ^MRIp
V
^8X  d   R1MR2pR3VP@                  9   d   \/        VR3,          4      M"\/        VP,                  RI,          R3,          4      p\/        VP,                  RI,          R4,          4      p\/        VP,                  RI,          R5,          4      p\        P                  R6VP,                  RI,          R7,          R* R8VR* R9VR* R:VR* 24       V
^8X  dA   W,
          pVR;8:  d   \        P                  R<VR* R=24       R# V\B        V,          ,
          pM?W,
          pVR;8:  d   \        P                  R>VR* R=24       R# V\B        V,          ,           p\        R,          '       g5   \        P                  R?V R@VR 24       \E        V
V\=        V4      4       R# \        R/,          V
8w  d@   \        P                  RAV R@VR 24       \?        RB4       \E        V
V\=        V4      4       R# \        RC,          pV\        RC&   \=        V4      \        RD&   \        P                  REV RFVR* RGVR* R@VR RH2	4       R# )JzU
Main function called every hour.
Checks for new signals and manages open positions.
u   ─── Signal check at z%Y-%m-%d %H:%M UTCu
    ───r   u<   Outside trading session — position open, monitoring z-exitr8   u$   Outside trading session — skippingNuD   Outside trading session — but armed, continuing to watch for entryu*   MT5 not connected — attempting reconnectu*   Failed to reconnect MT5 — skipping checkz*Position closed by broker (TP or stop hit)Fr   r   r   r   z+Insufficient 1H bars for signal computationzSignal computation failedr  r   zCurrent z-score: r  u     (threshold ±)r  r9   zHold limit reached (rB   u   h) — closing
time_limitzZ-score reversal detected: z <= -u     (was long) — closing positionu)   ⚠️ <b>Z-EXIT</b>
Z-score reversed to z
Closing LONG positionzscore_reversalz >= +u!    (was short) — closing positionzPosition open | Ticket=z	 | Entry=rA   z | Z-score=u    — holdingzNo signal (|z|=z < r;   zz-score reversed before entryr>   r?   r   r   r   zSignal bar: O=r   z H=z L=z C=g-C6
?z#Pullback range too small for long (u   ) — skippingz$Pullback range too small for short (zSIGNAL DETECTED | r  u(   Signal direction changed — rearming | zdirection changer<   r=   zAlready armed | z | Target updated: u    → z | Fast polling activery   )#r   r  r   r  r1   rG   strftimer  r(   r,   r   r   r2   r   r   r  r   r   r-  r  rE  emptyr   rv   	THRESHOLDr  rJ   r  ZSCORE_EXITrH   r!  r  indexFIBr  )r  r   r  bars_1h	signal_dflatest	current_z
signal_dir
hours_held	armed_dirsignal_directionr  signal_closesignal_high
signal_lowpullback_ranger<   
old_targets                     r5   run_signal_checkr    s   
 ,,x||
$CHH)#,,7K*L)MZXY
 !!HHSTxHH;<HH[\ >>@A}}IIBC _*,
HHAB',E/"'+E#$'+E#$'+E- '+E,
 G#g,)DD		?@ $G,IIOOO		-.^^BFf-./I$E-HH 3 0&Kq* + _%(9":"F,-
 *++T+2|,-.;moEJR/
3/?~NO%e,=&>M+0o&+/'( !O	k\ 9HH29S/{m T7 8 9''0o 6()
 "%(9":<MN',E/"'+E#$B9#;HH29S/{m T8 9 :!%(9":<MN',E/"'+E#$*51B+C*D E.s3 4%c?,8 	9 	 9~	!?3y>#"6c)AFG??k*IQI+$=R[_aRafotf#$CD%2q*a/WI .5-D5)%PWP\P\]_P`ahPiJjLb)&12Kb)%01JHH~gll2.v6s;3{3>O PS!\#$68 9 1%2W$HH:>#:Nn]^#cN&::$3W$HH;N3;O~^_#cN&:: ??%i[i_EF)<YH	{	/	/;I;eIVY?[\./)<YH >*
 ,n #Il#I;.As#5c(: ;_$:< 	=r[   c                T    ^ RI p\        P                  R,          p. pVP                  4       '       d"   VP	                  VP                  RR7      4      pVP                  RV RVRVRVR	\        V^4      R
\        P                  ! 4       P                  4       /4       VP                  VP                  V^R7      RR7       \        P                  R\        V4       R\!        R V 4       4      R 24       R#   \"         d$   p\        P%                  RT 24        Rp?R# Rp?ii ; i)zDAppend closed trade to trade_history.json for dashboard consumption.Ntrade_history.jsonr   r   r  r   r;   rV  net_pnl	closed_atr%   zTrade history saved: z trades, total PnL=$c              3   2   "   T F  qR ,          x  K  	  R# 5ir  N .0ts   & r5   	<genexpr>%save_trade_history.<locals>.<genexpr>;  s     "@AY<<   rI  zTrade history save failed: )r'   r-   parentrC   rD   rE   appendrK   r   r  r"   r.   r/   r1   rG   r   sumr0   r2   )	r  r   r;   rV  r  r'   history_pathtradesr4   s	   &&&&&    r5   save_trade_historyr  )  s   7!((+??  ZZ 6 6 6 HIF6;985!,8<<>335
 	 	

6!
 <wO(V 6""@"@@EG 	H 71!5667s   2C9 CC9 9D'D""D'c                H    ^ RI p^ RIp\        R,          R,          R,          pVP                  P	                  RV4      pVP                  P                  V4      pVP                  P                  V4       VP                  V 4      #   \         d    \        T 4      u # i ; i)uM   Delegate to dashboard_server's get_weekly_outlook — single source of truth.Nr   	executionzdashboard_server.pydashboard_server)importlib.utilsysr  utilspec_from_file_locationmodule_from_specloaderexec_moduleget_weekly_outlookr0   _outlook_fallback)r  	importlib_syssrv_pathspecmods   &     r5   _get_outlook_for_monitorr  C  s    	,*u${25JJ~~556H(S~~..t4$%%i00 , ++,s   BB B! B!c                l   \         P                  ! 4       pV\        VP                  4       R7      ,
          p. ROpRpV\	        V 4      ,
          pV^ 8:  d   ^M%VR8  d   ^MVR8  d   ^MVR8  d   ^M
VR8  d   ^M^p. ROp. ROp. p	\        ^4       EF  p
V\        V
R7      ,           P                  R4      p\         P                  ! VR4      p. pW9   d   VP                  RR	R
RR^K/4       W9   d   VP                  RRR
RR^Z/4       ^VP                  u;8:  d   ^8:  d   M MVP                  RRR
RR^K/4       VP                  4       ^8X  d4   ^VP                  u;8:  d   ^8:  d   M MVP                  RRR
RR^2/4       \        VR RR7      pV'       d   V^ ,          R,          M^ p\        V^d,          ^2,          ^24      pV'       d   \        \        W,           4      ^U4      M^pT	P                  RTRW:,          RVR,          RTRV'       d   V^ ,          R,          MR/4       EK  	  V	# )z2Minimal fallback if dashboard_server import fails.daysr   g      ?      ?r          @%Y-%m-%deventzFOMC Meeting MinutescountryUSscorezECB Rate DecisionEUzCPI (likely this week)zGerman ZEW SentimentDEc                     V R ,          # )r   r  xs   &r5   <lambda>#_outlook_fallback.<locals>.<lambda>h  s    '
r[   T)keyreverser   dayeventsN   Nprob	top_eventNo key events)MonTueWedThuFri)z
2026-02-19z
2026-04-09z
2026-05-21z
2026-06-18z
2026-07-09z
2026-10-08z
2026-11-19z
2026-12-31)	z
2026-01-30z
2026-03-06z
2026-04-17z
2026-05-06z
2026-06-05z
2026-07-16z
2026-09-10z
2026-10-22z
2026-12-03)r   r  r   weekdayr!  r  r  strptimer  r
  sortedr  r   )r  r  mondayr  TdistzpFOMC_MINUTESECB_MEETINGSr~  r>  r   d_objevstopepr  s   &                r5   r  r  Q  s   \\^C9#++-00F,DAYD7Rd3h$s(BdSVhaefiai\]opBILVLF1X)++55jA!!$
3W5KIVZ[bce,f!gW5HSWX_`b,c!deiiW5MiX\]deg,h!i==?A!UYY"2"2JJ 6ygbQRS2DA"%s1vg13s72:r"(+s3rw<$vd5#b'&#sCF7OQ 	R  Mr[   c                 ~    R \        V ^
,          4      ,          R^
\        V ^
,          4      ,
          ,          ,           # )u   █u   ░)rK   ps   &r5   	_prob_barr&  q  s*    uQrT{*5"U1R4[.+AAAr[   c                 *    V ^<8  d   R# V ^#8  d   R# R# )<   u   🟢u   🟡u   ⚪r  r$  s   &r5   _prob_emojir)  r  s    QU6J!R%JUJr[   c                   a V '       g   R # V'       EdY   \        V R R7      p. R!OpV  F  pVR,          VR,          8X  d   VR,          ^8  d   RMR pVR,          '       d'   RP                  R	 VR,          R
,           4       4      MRp\        VR,          4      R,           VR,          ,           R,           \        VR,          4      ,           R,           \	        VR,          4      ,           R,           V,           R,           V,           pVP                  V4       K  	  VRRVR,          ,           R,           \        VR,          4      ,           R,           .,          pRP                  V4      # \        V3R lV  4       R4      p	V	'       g   R # V	R,          '       d(   RP                  R V	R,          R,           4       4      pMRpRV	R,          ,           R,           \        V	R,          4      ,           R,           \        V	R,          4      ,           R,           \	        V	R,          4      ,           R,           V,           R ,           # )" c                     V R ,          # )r  r  r  s   &r5   r  (_build_outlook_section.<locals>.<lambda>x  s    1V9r[   )r  0   ────────────────r   r  u   ⭐r  z, c              3   2   "   T F  qR ,          x  K  	  R# 5i)r  Nr  r  r4   s   & r5   r  )_build_outlook_section.<locals>.<genexpr>|  s     AAwZZr  :NrV   Nr  z <b>r
  z</b>  z%   u	   
    └ u   ⭐ Best day: <b>z</b> at %
c              3   F   <"   T F  qR ,          S8X  g   K  Vx  K  	  R# 5i)r   Nr  )r  d	today_strs   & r5   r  r1    s     @g6i)?11gs   !
!Nc              3   z   "   T F1  pR VR,          ,           R,           VR,          ,           R,           x  K3  	  R# 5i)u       • r  z (r  r  Nr  r0  s   & r5   r  r1    s2     m\lWXMAgJ6=)LsRR\ls   9;r  u!       • No key macro events todayu$   
📅 <b>TODAY'S SIGNAL OUTLOOK — u6   </b>
────────────────
z Signal probability: <b>z%</b>
z
Key events:
u1   
────────────────)r+  u)   📅 <b>WEEK AHEAD — SIGNAL OUTLOOK</b>r.  )r  joinr)  rY   r&  r  next)
outlook	is_mondayr7  bestlinesr6  starr   rowtds
   &&f       r5   _build_outlook_sectionrB  t  s&   yG!45uAfIf5!F)b.5bDEFx[[499A8RAAVeC&	*V3ah>I&	N#%*+-6qy-ABDGHJNO#$&)*C LL  	DF\_cdi_jFjmwFwz}  C  DJ  K  {L  GL  OR  GR  S  	Syy@g@$Gh<<))m\^_g\hik\lmmC8C<r%yH Lq q"V*%&(BCEHF_UW`a 6
#$' "	"%o	o	
r[   c                    \         P                  R4      p \         P                  RR4      p^ pRp ^ RIp\        P                  R,          pVP                  4       '       d?   VP                  VP                  RR7      4      p\        V4      p\        R	 V 4       4      pT e   T R
 MRpT '       d"   \        T 4      \        ,          ^d,          R R2MRpT'       dJ   \         P                  R4      p	\         P                  R4      p
T
^8X  d   RMRpT	'       d
   RT RT	R 2MRpMRpT^ 8  d   RTR 2MR\        T4      R 2p\        P                  ! 4       P                  R4      p\        P                  ! 4       P!                  4       ^ 8H  p \#        \%        T ;'       g    ^ 4      4      p\'        TY4      p\)        RT RT RT RT R T R!\         T 24       R#   \         d     ELLi ; i  \         d    Rp LFi ; i)"z7Sends a daily morning summary to Telegram at 06:05 UTC.r   r   F        Nr  r   r   c              3   2   "   T F  qR ,          x  K  	  R# 5ir  r  r  s   & r5   r  %send_daily_summary.<locals>.<genexpr>  s     ;Fq	llFr  r  u   —r  z% of thresholdr+  r   r   r>   r?   u   🔵 z @ rA   u	   🔵 Openu   ⚪ No positionz+$r   z-$r  uW   📊 <b>DAILY SUMMARY</b>
────────────────
Z-score: <b>z</b>  (z)
Position: z	
Trades: z
  |  PnL: uZ   
System: ✅ Running
────────────────
Threshold needed: ±)r(   r*   r'   r-   r  rC   rD   rE   r   r  r0   r!  r  r   r  r  r  r  rv   rB  rH   )r  pos_opentrade_count	pnl_totalr'   r  r  z_strz_pctentry_px	entry_dirrO   pos_strpnl_strr7  r<  r;  outlook_texts                     r5   send_daily_summaryrQ    s   =)I?E2H KI!((+??  ZZ 6 6 6 HIFf+K;F;;I $-#8	#eEDMIy(,S1@SUEIIm,II/0	'1nF':BeG9C~6#'0A~9T"#RIt?T;UG''
3I&&(A-I/inn10EF-gyL gWUG ,I -z' 3  )k.	
1  *  s/   0G ">G G0 "G0 G-,G-0H ?H c                     \         P                  R<4       \         P                  R4       \         P                  R\         24       \         P                  R\         24       \         P                  R\        R R\
        R 24       \         P                  R\         24       \         P                  R\        R 24       \         P                  R	\         R
\        ^,            R24       \         P                  R<4       \        4       '       g   \         P                  R4       R# \        4        \         P                  R4       \        4        \        4        \        P                   ! 4       P"                  P%                  R4      P'                  \        4       \        P                   ! 4       P(                  P%                  R4      P'                  \        4       \        P                   ! 4       P(                  P%                  R4      P'                  \*        4       \         P                  R4       \         P                  R4       \         P                  R4       \,        P/                  R4      p V e   V R MRp\1        R\         R\         R\        ^,            RV R2	4        \2        P2                  ! 4       p \        P4                  ! 4        \2        P2                  ! 4       V,
          ^<8  d    \7        4        \2        P2                  ! 4       p\,        R,          '       Ed   \9        4       pV'       Eg   \         P                  R4       \,        P/                  R4      p\,        P/                  R 4      ;'       g    ^ p\,        P/                  R!4      ;'       g    ^ p\,        P/                  R"4      ;'       g    ^ pR#p ^ RIp	^ R$IHp
 \<        P@                  ! V
PB                  4      PE                  ^ ^ ^ R%7      \G        R&4      PI                  ^R'7      ,
          pV	PK                  V\<        P@                  ! V
PB                  4      4      pV'       Ed.   ^ RI&pVPN                  ! \Q        V4      V^ ,          PS                  4       PU                  4       R(7      pV'       d/   VVR),          \W        V4      8H  VR*,          ^8H  ,          ,          pMVPN                  ! 4       pVPX                  '       d4   VVR+,          R,8H  VR*,          ^8H  ,          ,          P[                  ^4      pVPX                  '       gL   \]        VP^                  R=,          R-,          4      \]        VP^                  R=,          R.,          4      ,           p\1        R0T R1T^ 8  d   R2MR3 R4TR5 R624       \e        YETYx4       R7\,        R&   R\,        R&   R\,        R!&   R\,        R &   R\,        R8&   \7        4        \f        R9,          '       d$   \i        4        \2        Pj                  ! ^4       EKb  \2        Pj                  ! ^4       EK{    \`         d#   p\         Pc                  R/T 24        Rp?LRp?ii ; i  \l         d    \         P                  R:4        Mi ; i\o        4        \         P                  R;4       R#   \o        4        \         P                  R;4       i ; i)>=zLIVE SIGNAL MONITOR STARTINGzSymbol    : u   Threshold : z-score ±zTP        : z.2%z  |  Stop: u   Z-exit    : ±zRisk      : zSession   : z:00 - z:00 EETuA   Could not connect to MT5 — check credentials and MT5 is runningNz#Running startup rate data update...z:01z06:00z06:05z3Scheduler running. Signal checks every hour at :01.z5Rate data updates: at startup and daily at 06:00 UTC.zPress Ctrl+C to stop.r   r  zcomputing...u?   🟢 <b>LIVE MONITOR STARTED</b>
Symbol: EURUSD
Threshold: z ±z

Session: z:00-z:00 EET
Current z-score: z
Watching for signals...r   u3   Position closed by MT5 (TP or stop) — state resetr   r   r   r   rD  )r   )r  minutesecondr   r  r   position_identryrf  rg  r  swapzP&L lookup failed: u$   🔔 <b>POSITION CLOSED</b>
Ticket: z

Net P&L: +r+  $rI  z
Closed by MT5 (TP or SL hit)Fr   r8   zShutdown requested by userzLive signal monitor stoppedz<============================================================ry   )8r1   rG   r   r  rr  rK  r  rJ  r  r  r   r   rQ   r   r  scheduleeveryr  atdor
  rQ  r(   r*   rH   r   run_pendingr6   r  r   r   r   r  r  r  
__import__r   history_deals_getpandasr   list_asdictkeysr   r  tailrv   r   r0   r2   r  r,   r  sleepKeyboardInterruptr   )	startup_zrJ  last_state_saver  r  rL  rM  rV  r  r   r   from_dtdealsr   r   matchr4   s                    r5   mainrn    s9   HHXHH+,HH|F8$%HH%i[12HH|F3<{8C.ABHH~k]+,HH|M#./0HH|-.f_Q5F4GwOPHHX ==		UV L HH23  NNU#&&'78 NNG$''(89 NNG$''(:;HHBCHHDEHH$% 		-(I"+"7yo^E# %%&d?1+<*= >!7 #"		#S0))+  " yy{_,2"&))+
 _%%24
!zHHRS %		*; <F %		- 8 = =AH %		*; < A AI %		. 9 > >QH "G?15"*,,x||"<"D"D!"1Q #E #8&z2<<!<D#E !$ 5 5#X\\(,,%?!A 5/!#d5k6;Ah6F6F6H6M6M6O"QB  &(*%'%6#f+%E%'[A%5%7)"
 )+${{{(*%'[H%<%'[A%5%7)" #'$q' !& $);;;*/

2x0H*I*/

2v0F*G+H
 "##)( +$*11*C"#=Qwsm L78 'v'/:/4E/*/3E+,/3E+,/3E-(/3E,'L X

1

1/ % ?&9!$=>>?2  /-./ 	./ 	./s~   (A>Y( 'AY(  Y( Y( >Y( D1X8 6AX8 ;AX8 A5Y( <<Y( 8Y%Y Y(  Y%%Y( ( ZZ/ 
ZZ/ /![__main__))r         @r  )rp        @r   )rq  g     X@r  )   )rD  )Z__doc__r   r   loggingr[  r   r   r   r   r  r   r  rb  r   numpyr  __file__resolver   r  SRC_PATHrY   r   r  LOG_DIRmkdirbasicConfigINFOFileHandlerStreamHandlerstdout	getLoggerr1   r   r   r   r   r   r   r  r  
HOLD_HOURSrK  rr  r  r  r  rJ  rz   r  r'  r-  BARS_1Hr(   r-   r  r6   rQ   r   r   rR   rS   rH   r,   r~   r   r   r   r   r   rE  rZ  r  r  r  r  r  r  r  r  r  r  r  r  r&  r)  rB  rQ  rn  __name__r  r[   r5   <module>r     s  -^ 
    8 8  
  N""$,,Q/	x= HHOOCM" f
v
% dT *   \\8 G&887Kcjj)	 ' 	!
 	
   utttttt		 '),==
 
    t  4/$D2N D>  99-1ab99/> :( edddd	D'T #* ,,GV4pJZ2j	2yz<Y=z74,@ B J
B1hF0R zF r[   