+
    c@j                        R t ^ RIt^ RIt^ RIHtHt ^ RIHt ]! ]4      P                  t	]P                  P                  ^ ]! ]	4      4       ^ RIHt ^ RIHt ]! 4       '       g   ]P                   ! ^ 4       ]	R,          t]	R,          t]! ]4      ;_uu_ 4       t]P*                  ! ]4      tRRR4       ]R,          t]R	,          t]R
,          t]R,          t]R,          t]P8                  ! 4       P;                  4       t/ t]P?                  4       '       d,   ]! ]4      ;_uu_ 4       t]P*                  ! ]4      tRRR4       ]PA                  R4      ]8w  d	   R]R/ R/ /t]PC                  R/ 4      t"]PC                  R/ 4      t#]PC                  R/ 4      t$. t%] EF  t&]! ]&4      t']''       d   ]'PA                  R4      f   K)  ]'R,          t(]'R,          ]$]&&   ]"PC                  ]&. 4      t)])PU                  ](4       ]+! ])4      ]^,           8  d   ])]^,           ) R ])R&   ]#PA                  ]&4      '       d   K  ](]8  d   K  ]+! ])4      ]8:  d   K  ](])^ ,          ,
          t,],]8  d   K  R]#]&&   ]%PU                  ]&P[                  RR4       R](R R],R R] R]'R,          R R2
4       EK  	  ]P\                  ! 4       P;                  RR7      ]R &   ]! ]R!4      ;_uu_ 4       t]P^                  ! ]]^R"7       RRR4       ]% F  t0]1! ]04       K  	  R#   + '       g   i     ELq; i  + '       g   i     EL; i  + '       g   i     LK; i)#a
  
Cheap intraday mechanical poller for the high-risk options sleeve (added
2026-08-31). No web searches, no Claude invocation, no MCP tools -- just
tmx_quotes.get_quote() against sleeve_watchlist.json's static candidate list,
run every 5 minutes during TSX hours from sleeve_monitor.sh. This mirrors
check_watchlist_triggers.py's role: a cheap mechanical pre-filter that only
escalates to a real (expensive) Claude-modeled check when something actually
looks like it's happening, instead of running the LLM reconfirm on a timer
regardless of whether anything changed.

Flags a ticker when BOTH:
  1. today's tmx_quotes changePct >= thresholds.momentum_threshold_pct
  2. changePct has grown by >= thresholds.acceleration_threshold_pct over the
     last thresholds.acceleration_lookback_polls polls (recorded in
     sleeve_monitor_state.json) -- i.e. genuinely accelerating right now, not
     a stock that gapped up at the open and has been flat since.

This is a PRICE-ONLY proxy for setup_D_momentum's volume-acceleration
criterion -- tmx_quotes.py's quote has no volume field, so this mechanical
layer can't check real volume. sleeve_reconfirm_prompt.md pulls the real
volume/RSI/MACD via Questrade before any alert claims a genuine setup; this
script's job is only to decide when that more expensive check is worth
running.

De-dupes per ticker per calendar day (same pattern as
watchlist_alerts_state.json) -- fires once per ticker per day, not once per
5-min poll for the duration of a single move.

Prints one line per newly-triggered ticker to stdout (ticker + changePct),
consumed by sleeve_monitor.sh the same way check_positions.sh consumes
check_watchlist_triggers.py's stdout.

Run manually: python3 sleeve_monitor.py
Cron: sleeve_monitor.sh, every 5 min during TSX hours -- see crontab.
N)datedatetime)Path)is_trading_day)	get_quotezsleeve_watchlist.jsonzsleeve_monitor_state.jsontickers
thresholdsmomentum_threshold_pctacceleration_lookback_pollsacceleration_threshold_pctr   historyalertedprices	changePctprice:NNNTz.TO z SLEEVE CANDIDATE: z+.2fz
% today, +z.2fz% over last z polls (price $)seconds)timespeclast_updatedw)indent)2__doc__jsonsysr   r   pathlibr   __file__parentBASEpathinsertstrr   
tmx_quotesr   exitwatchlist_file
state_fileopenfloadconfigr   thmomentum_thresholdlookbackaccel_thresholdtoday	isoformatstateexistsget
setdefaultr   r   r   
new_alertstickerquotechghistappendlenaccelreplacenowdumpmsgprint     sleeve_monitor.py<module>rD      s  "F  
 # H~ 3t9  )  HHQK////
	.QYYq\F  
L01 +,12

 
	j		Q		! 

 	99VUIr9b9E


9b
)


9b
)			(B	'
FfEEIIk*2

C7^F6Nfb)DKK
4y8a<A'(Q{{6

4yH$q'MEGFOr233Fs4j Q +\(?5QX>Z]J^^_a b7 < !00)0Dn 	*caIIeQq!  C	#J }  
		\ s$   L)L)$L=L&	)L:	=M	