+
    `jG                     x   R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RI	H	t	H
t
 ^ RIHt ]! ]4      P                  4       P                  ^,          t]R,          R,          t]R,          t]R,          t]R,          t]R	,          R
,          R,          tRtR tR tR tR tR tR t]R8X  d
   ]! 4        R# R# )uJ  
notify_forecast.py — Telegram alert when the daily forecast is built.

Sends the full vol & range block to every dashboard-token holder, each
with their personal link to the forecast page. Sends once per session
(state file: data\logs\forecast_notified.json) — the dashboard server
calls this after every successful build, so retries are no-ops.

Manual use:
    python src\execution\notify_forecast.py                (normal — once per session)
    python src\execution\notify_forecast.py --force        (resend to everyone now)
    python src\execution\notify_forecast.py --to CHAT_ID   (test: that chat only, no state change)

Bot token: uses the TELEGRAM_TOKEN environment variable if set, otherwise
reads the same constant straight out of live_signal_monitor_v3.py — one
source of truth, no credentials duplicated in this file.
N)datetimetimezone)Pathdatalogszforecast_data.jsonzdashboard_tokens.jsonzforecast_notified.jsonsrc	executionzlive_signal_monitor_v3.pyz+https://bennettsdashboard.com/forecast.htmlc                  4   ^ RI p V P                  RR4      P                  4       pV'       d   V#  \        P	                  RRR7      p\
        P                  ! RV4      pV'       d    VP                  ^4      P                  4       #  R#   \         d     R# i ; i)    NTELEGRAM_TOKEN utf-8replace)encodingerrorszDTELEGRAM_TOKEN\s*=\s*os\.getenv\(\s*"TELEGRAM_TOKEN"\s*,\s*"([^"]+)")	osgetenvstripMONITOR_FILE	read_textresearchgroup	Exception)r   tokr   ms       RC:\Users\Administrator\OneDrive\fx_macro_intraday\src\execution\notify_forecast.py	bot_tokenr   &   s    
))$b
)
/
/
1C

$$gi$HIIS 771:##%%    s   5B &B BBc                      \        V R R7      ;_uu_ 4       p\        P                  ! V4      uuRRR4       #   + '       g   i     R# ; i  \         d    Tu # i ; i)r   r   N)openjsonloadr   )pathdefaultfs   && r   	load_jsonr&   7   sC    $))Q99Q< *))) s+   A 8
A A		A 	A AAc           	         V P                  R R4      pRV R2R\        ^^\        V4      ,
          4      ,          ,           .pV P                  R4      '       d   VP                  RV R,           R24       VP                  R	V R
,          R R24       VP                  RV R,          R RV R,          R R24       VP                  RV R,          R RV R,          R R24       RP	                  V4      # )display?u   ────  u   ─event_conditionedu   ⚠️ labelu     day — event-conditioned bandszVolatility (annualized) : ann_volz.2f%zHigh to Low range       : hl_medu   % median · hl_75z% 75th PercentilezOpen to Close move      : oc_medoc_75
)getmaxlenappendjoin)dnameliness   &  r   instrument_blockr<   ?   s    55C DTF!$us1b3t9n/E'EEFEuu !!wqzl*JKL	LL-a	l3-?qAB	LL-ak#->lgJs##46 7	LL-ak#->lgJs##46 799U    c                    R RV P                  RR4       2R.p. pV P                  R. 4       Fh  pVP                  R4      '       d.   VP                  \        V4      4       VP                  R4       KG  VP                  VP                  RR4      4       Kj  	  V'       d6   VP                  RR	P                  V4       R
24       VP                  R4       VP                  R4       RP                  V4      # )u   📊 VOL & RANGE FORECASTzFor session: session_labelr   instrumentsokr(   r)   z(unavailable this session: z, )u/   📈 Chart + levels are live on your dashboard:r3   )r4   r7   r<   r8   )r   partsmissingr9   s   &   r   composerE   L   s    (TXXor:;<bBEGXXmR(55;;LL)!,-LLNN155C01 ) 2499W3E2FaHIR	LLBC99Ur=   c                    R V  R2p\         P                  P                  RVRVRR/4      p\        P                  ! 4       pRVn        \        P                  Vn        \         P                  P                  W4P                  4       RR7      p\         P                  P                  V^VR	7      ;_uu_ 4         R
R
R
4       R#   + '       g   i     R
# ; i)zhttps://api.telegram.org/botz/sendMessagechat_idtextdisable_web_page_previewtrueFPOST)r   method)timeoutcontextNT)urllibparse	urlencodesslcreate_default_contextcheck_hostname	CERT_NONEverify_moderequestRequestencodeurlopen)tokenrG   rH   urlr   ctxreqs   &&&    r   sendr_   ]   s    (|
<C<<!!7"F# D 
$
$
&CCmmCO
..
 
 ;;=
 
HC			R		=	= 
>	=	=	=s   6CC	c                     \         P                  R ,          p RV 9   pRpRV 9   df   V P                  R4      pV^,           \        V 4      8  d(   \	        W^,           ,          4      P                  4       pM\         P                  ! R4       \        \        R4      pV'       d   VP                  R4      '       g   \         P                  ! R4       VP                  RR4      pVf@   V'       g8   \        \        / 4      pVP                  R4      V8X  d   \        R	V R
24       R# \        4       pV'       g   \         P                  ! R4       \        \        / 4      P                  R. 4      pV U	u. uF6  qP                  R4      '       g   K  V	P                  R4      '       g   K4  V	NK8  	  pp	VeU   V U	u. uF&  p	\	        V	P                  R4      4      V8X  g   K$  V	NK(  	  pp	V'       g   \         P                  ! RV R24       V'       g   \        R4       R# \        V4      p
^ p^ pV F{  p	\         RV	R,           2p \!        WyR,          V
R,           V,           4       V^,          p\        RV	P                  RV	R,          4       24       \$        P&                  ! R4       K}  	  \        RV RV RV R24       Vf   V^ 8  d   \        P)                  \        P*                  R,           4      p\-        VRRR 7      ;_uu_ 4       p\.        P0                  ! RVR!VR"\2        P4                  ! \6        P8                  4      P;                  4       /V4       RRR4       ^ RIpVP?                  V\        4       R# R# R# u up	i u up	i   \"         d=   pT^,          p\        RT	P                  RT	R,          4       RT 24        Rp?EL<Rp?ii ; i  + '       g   i     L; i)#:   NNz--forceNz--toz--to needs a CHAT_IDr@   u5   no forecast_data.json — run build_forecast.py firstsession_dater   zalready notified for session u    — nothing to dozMno Telegram bot token found (env TELEGRAM_TOKEN or live_signal_monitor_v3.py)tokensrG   r[   zchat_id z# not found in dashboard_tokens.jsonu3   no dashboard users with tokens yet — nothing sentz?key=r3   z
  sent -> r:   z
  FAIL -> z: g?zdone: z sent, z failed (session rB   z.tmpwr   r   sentat) sysargvindexr6   strr   exitr&   FORECAST_JSONr4   
STATE_FILEprintr   TOKENS_FILErE   FORECAST_PAGE_URLr_   r   timesleep	with_namer:   r    r!   dumpr   nowr   utc	isoformatr   r   )argsforceonly_toir   sdstater[   usersubasere   failedlinketmpr%   r   s                     r   mainr   n   s   88B<DEG~JJvq53t9$1u+&,,.GHH+,]D)Dtxx..HI	."	%Bu*b)99^$*1"5GHIKE . 	/ k2&**8R8EE1y!1QaeeGnQQEE!FEqSy)9%:g%EEFHHxy(KLMCD4=DDF#$E!G*6	C)dTkD&89AIDJquuVQy\:;<= 	

3  
F4&x'8A
>?4!8"":??V#;<#sW--II~r64X\\(,,7AACEFGI . 	


3
# $1 FF   	CaKFJquuVQy\:;2aSABB	C .-sD   1NN'N7!NNANAOO1OOO&	__main__)__doc__r!   r   rR   rg   rq   urllib.parserO   urllib.requestr   r   pathlibr   __file__resolveparents	BASE_PATHLOG_DIRrl   ro   rm   r   rp   r   r&   r<   rE   r_   r   __name__ r=   r   <module>r      s   "  	 
 
    ' N""$,,Q/	
f
v
%00////
5 ;.1LLA "
"":$z zF r=   