
    \qj                       U d Z ddlmZ ddlZddlZddlZddlZddlZddlmZ ddl	m
Z
 ddlmZ ddlmZ ddlZddlZ e
e      j)                         j*                  d   Z ee      ej0                  vr"ej0                  j3                  d ee             dd	lmZmZmZmZmZm Z m!Z!m"Z" dd
l#m$Z$m%Z%m&Z&  ed      Z'edz  dz  dz  Z(e(dz  Z)edz  dz  dz  dz  Z*edz  dz  dz  dz  Z+dZ,dddddddddd	Z-de.d<   dddddddddd	Z/de.d<   d>dZ0d?dZ1d@d Z2	 	 	 	 	 	 dAd!Z3d"d#d$	 	 	 	 	 	 	 	 	 dBd%Z4	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dCd&Z5dDd'Z6dEd(Z7d)dd*	 	 	 	 	 	 	 dFd+Z8dGdHd,Z9d-d-d-d.d/d/d/d0d0d0d0d0d0d1Z:de.d2<   dId3Z;dJd4Z<dKd5Z=d)d6	 	 	 	 	 	 	 	 	 dLd7Z>d)d8d9d:	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dMd;Z?dNd<Z@eAd=k(  r e@        yy)Oa=  
Build a **shareable, multi-tenant-ready** snapshot for the Today Trades website (Stage A).

Schema is designed so Stage B can add more ``books[]`` entries without rewriting the UI.

Example::

    cd /Users/robzingale/trading_bot && PYTHONUNBUFFERED=1 .venv/bin/python \
      -m RenTech.monitor.build_today_trades_snapshot \
      --nav 50000 --fund-scale 1.5 \
      --held AMZN,QCOM,AXP,INTC,LRCX,AMAT,MU,AMD,GEV \
      --out RenTech/data/logs/today_trades_snapshot.json

Then serve::

    .venv/bin/python -m RenTech.monitor.serve_today_trades --password 'change-me'
    )annotationsN)datetime)Path)Any)ZoneInfo   )DEFAULT_DIP_MAX_HOLDINGSSTOCK_ONLY_WEIGHTSSTOCK_SLEEVE_LABELSTODAY_TRADES_CORE_SLEEVESdip_per_name_budget_usdsleeve_budget_usdtoday_trades_core_weightstoday_trades_strategy_guide)_dip_actions_scan_cm_dip_signalsbuild_stock_only_signalszAmerica/New_YorkRenTechdatalogsztoday_trades_snapshot.json
live_statezcm_dip_positions.jsonmonitorconfigztoday_trades_history.json   z
2026-07-22
2026-07-23)	AMZNQCOMAXPINTCLRCXAMATMUAMDGEVzdict[str, str]_DEFAULT_SIGNALz
2026-07-24z
2026-07-27_DEFAULT_ENTRYc                     t         j                  j                  t              j	                         j                  d       S )Ntz)pd	TimestampnowNY	normalizetz_localize     G/opt/rentech/trading_bot/RenTech/monitor/build_today_trades_snapshot.py_todayr3   W   s.    <<r",,.::4@@r1   c                   | d   j                  t              }| d   j                  t              }| d   j                  t              }|j                  d      }t        j                  ||z
  ||z
  j                         ||z
  j                         gd      j                  d      }|j                  dd      j                         S )Nclosehighlowr   )axis   )min_periods)	astypefloatshiftr*   concatabsmaxrollingmean)dfchlprevtrs         r2   _atr5rI   [   s    
75!A
6
% A
5	A771:D	QUa$h^^-D~~/?@q	I	M	MST	M	UB::aQ:',,..r1   c                    | j                         sdi iS 	 t        j                  | j                  d            }t        |t              r|S di iS # t        t        j
                  f$ r di icY S w xY w)N	positionsutf-8encoding)is_filejsonloads	read_textOSErrorJSONDecodeError
isinstancedict)pathr   s     r2   _load_staterX   d   sv    <<>R  !zz$..'.:; dD)4@R/@@ T))* !R  !s   %A A10A1c                D   i }|j                  d      xs i j                         D ]  \  }}t        |t              s|j                  d      dk(  r,t	        |      j                         }|j                  d      xs t        j                  |      |j                  d      xs t        j                  |      |j                  d      xs |j                  d      |j                  d      xs |j                  d	      |j                  d
      dd||<    | r| j                         rv| j                  d      D ]b  }|j                         j                         }|s$|j                  |t        j                  |      t        j                  |      ddddd       d |S )z9symbol -> {signal_date, entry_date, fill_price, atr_usd}.rK   statusrecommendedsignal_date
entry_date
fill_pricelimit_priceatr_at_signalatr_usdsharesstate)r\   r]   r^   ra   rb   source,Ncli)getitemsrU   rV   strupperr%   r&   stripsplit
setdefault)held_csvrc   outsymmetasparts          r2   _held_from_args_and_statert   n   sm   
 &(Cii,299; 
	T$%88H.HNN88M2Lo6I6I!6L((<0IN4F4Fq4I((<0KDHH]4Kxx0GDHHY4Ghhx(
A
 HNN$NN3' 	D

""$ANN#2#6#6q#9"0"4"4Q"7"&#"#
		 Jr1         ?
   )profit_atr_multhold_trading_daysc               F   | sg g fS t        |       }t        j                  ||t        j                  d      z
  j                  d      |t        j                  d      z   j                  d      dddd      }	 t        j                  |d	d
dd      }t        |j                  t        j                        r9|d   j                         j                  d   }t        |j                  d         }n*|d   j                  d   }t        |j                  d         }|t        j                  j                  d      z
  j!                         }	g }
g }|D ]K  }| |   }	 t        |j                  t        j                        r$||   j#                  d      j%                         }n |j#                  d      j%                         }|j                  D cg c]  }t        |      j'                          c}|_        t        j(                  |j                        j+                  d      |_        t-        |      }|j/                  d      xs t0        j/                  |      }|s-t3        |      dk\  r|j                  d   n|j                  d   }nt        j4                  |      }|j6                  d| j                  d   }t9        |j/                  d      xs |j6                  d| j                  d         }t9        |d         d|z  z
  }|j/                  d      rt9        |d         n|}|t9        |      |z  z   }|	|j                  v rt9        |j6                  |	df         }n(t9        |j6                  d|	 j                  d   d         }|j/                  d      xs0 t:        j/                  |      xs t        |j=                               }t?        t3        t        j@                  t        j4                  |      |                  }||tC        |dg       v rt9        ||         }nN|1tE        |d      r%t9        |j/                  |t9        d                  }nt9        |d   j                  d         }g }tG        jH                  |      r||k\  r|jK                  d       tG        jH                  |      r||kD  r|jK                  d       |t?        |      kD  r|jK                  d       |d d!|rd"nd#tG        jH                  |      rtM        |d$      ndtM        |d$      tM        |d$      |tM        |d$      tM        |d%      ||rd&nd||rd'| d(d)jO                  |       d*nd+| d,|d-d.|d-d/}|r|
jK                  |       n|jK                  |       N |
jQ                  d2 3       |jQ                  d4 3       |
|fS # t        $ r d}d}Y w xY wc c}w # t        $ r3}|jK                  |d d!d#d+| d0| d*t        |      d1       Y d}~d}~ww xY w)5z1Return (exits, holds) with levels and last price.Z   )daysz%Y-%m-%dr   TFticker)startendauto_adjustprogressgroup_bythreads1d1m)periodintervalr   r   CloseNall)howr\      ra   r5   g?r^   r6   r]   indexrg   nanprofit
prior_high	time_stopSELL
equity_dipEXITHOLDr      MOCzExit z (+)zHold u    — profit ≥ $z.2fz or close > $)symbolsidesleeveactionlast_pxprofit_targetr   	days_heldr^   ra   reasons
order_typeasofsummaryu    — could not price ()r   r   r   r   r   errorc                    | d   S Nr   r0   xs    r2   <lambda>z%_evaluate_open_dips.<locals>.<lambda>	  
    Qx[ r1   keyc                    | d   S r   r0   r   s    r2   r   z%_evaluate_open_dips.<locals>.<lambda>
  r   r1   ))sortedyfdownloadr*   	TimedeltastrftimerU   columns
MultiIndexffillilocri   r   	ExceptionoffsetsBDayr.   dropnacopylowerto_datetimer/   rI   rg   r%   lenr+   locr<   r&   dateintbdate_rangegetattrhasattrmathisfiniteappendroundjoinsort)heldtodayrw   rx   tickersrawpxlastr   
prior_sessexitsholdstrq   rC   rD   atrsig_ssig_tsrowatr_v	buy_limitfillr   prior_hient_sr{   r   r   tradeexcs                                  r2   _evaluate_open_dipsr      se    2vTlG
++r||,,66zBR\\q))33J?C
[[$Y^_bjj"--0g;$$&++B/Drxx|$Dg;##B'Drxx|$D "**//!,,779J"$E"$E LAwJ	#++r}}5V]]u]-224ZZEZ*//124**=Q#a&,,.=BJ~~bhh/;;DABH)CHH]+E/B/B1/EE),RA"288B<e,&&&/&&r*C$((9-J&1A1F1Fr1JKEc'l+cEk9I040F5l+,IDE/2U::FRXX% 
F(:!;< !4!9!9"!=f!EFHH\*Yn.@.@.CYs6;;=GYEs2>>",,u*=uEFGDAw)C$CQ.!gdE&:E%L 9:7 0 0 45!#G}}W%'V*;x(}}W%'H*<|,c+,,{+ &$+&04g0F5!,D!&vq!1#Ha0!#D!n ?"'.eD  A3b'!2 315 #4VCLhWZ^\#E( U#U#CL\ 
JJ(J)	JJ(J)%<u  " >v  
	LL"*$!&qc)?uAF X	 	
	s?   ;B!W A6W$ W2N,W$WWW$$	X -(XX c                   g }t        | ||      }t        | |||      }	t        |d      t        |	d      |t        |      t        |d      ||dz  k\  d}
|s|
d   st        |      |k\  r|
d   rdndt        |       d| d	}|j	                  d
| d       t               \  }}dD ci c]  }||j                  |       c}|
d<   g }|d d D ]u  }|j	                  |d   ddd|j                  d      |j                  d      t        |	d      ddd|d    d|j                  d       d| d	|j                  d      d       w ||
d<   g |
|fS t               \  }}dD ci c]  }||j                  |       c}|
d<   t        || ||||      }g }|D ]  }|j                  d      dk7  r|j                  d       xs i }|j	                  |j                  d!      ddd"|j                  d      |j                  d      |j                  d#      ddd |j                  d      |j                  d$      |j                  d%      d&       |j                  d      s|j                  d#      st        |d         }|d'kD  st        d(t        t        |d#         |z              |d)   d*<    ||
|fS c c}w c c}w )+Nmax_holdingsr   ffffff?)r   per_name_budget_usdr   
open_countopen_mv_usdover_budgetr   zover sleeve budgetzat max holdings (/r   u   Skip new dip entries — .)rZ   n_candidatesr]   rd   scan   r|   BUYr   WATCHr_   r   LMTDAYzWatch z LMT $u    (do not enter — drop_pct)r   r   r   r   r_   r   notional_usdr   time_in_forcer   r   watch_candidates)fund_navfund_weight
fund_scaler   open_symbolsr   ADDdetailr   ENTERtarget_notional_usdra   r   )r   r   r   r   r_   r   r   r   r   rb   r   ra   r   r   r   r   rb   )r   r   r   r   r   r   rg   r   r<   r@   r   )navr   
dip_weightr   r   r   skip_entriesnotesr   per_namerq   reasonsigs	scan_metakwatchrr   actionsentersadetlims                         r2   _entry_tradesr    s    EsJ
;F&sJ
Q]^H"61-$Xq1$,'[!,"ftm3D tM*c,.?<.O M" !$S%6$7qaH 	
 	0:;.0i5gh9==++hVbq 	ALLk!*%#$55#7%&UU?%;$)(A$6"'%*!'(}F155;O:PPcdjckklm !j 1	  $) 4*,OD)1cdAAy}}Q''dDL!!G $&F \55?e#eeHo#%%/&!"ww}5!$!9 #(= >#!&GGJ/779-55+	
" 77=!cgg.C&DM*+CQw'*1c%<Q8R2SVY2Y.Z'[r
8$1\2 4u i. es   )J6"J;c                x    t        |       j                         }|dk(  r|rt        |      j                         S |S )NSPY)ri   rj   )rp   	spy_proxyrr   s      r2   _map_spy_proxyr  i  s3    CAEzi9~##%%Hr1   c           	     R   t        | D ch c]  }|s|dk7  s| c}      }|si S 	 t        j                  |ddd      }t        |j                  t
        j                        r!|d   j                         j                  d   }n|d   j                  d   }i }|D ]c  }	 |t        |dg       v rt        ||         n#t        |j                  |t        d	                  }t        j                  |      r
|d
kD  r|||<   e |S c c}w # t        $ r Y xw xY w# t        $ r i cY S w xY w)NCASH5dTF)r   r   r   r   r   r   r   r   )r   r   r   rU   r   r*   r   r   r   r   r<   rg   r   r   r   )symbolsrr   symsr   r   ro   vs          r2   _last_pricesr  p  s'   g;qF{1;<D	[[duMbjj"--0g;$$&++B/Dg;##B'D " 	A&'74"+E&EE$q'N5QUQYQYZ[]bch]iQjKk==#ACF		 
# <    	sF   DDDA7D  A D	 D 		DD DD D&%D&VOOr  allowed_sleevesc               h	   ||nt         }t        | j                  d      xs d      }t        | j                  d      xs d      }t        | j                  d      xs i       }t        | j                  d      xs i       }t        | j                  d      xs i       }g }	i }
i }|j	                         D ]H  \  }}t        |      d	k  r||vr|d
k(  r!|j                  |      xs i }t        |j                  d      xs i       }t        |j                  |      xs t        |t        |      |            }|j                  d|rdnd      t        |      t        |d      t        j                  ||      |j	                         D ci c]  \  }}|t        t        |      d       c}}d|j	                         D ci c]  \  }}|dvs|| c}}||<   |s.|j	                         D ]  \  }}t        t        |      |      }|t        |      z  }|
j                  |d      |z   |
|<   |	j                  |t        |      j                         |d	k\  rdnd|t        j                  ||      dt        t        |      d      t        |d      dt        j                  ||       d|d	k\  rdnd d| dt        t        |            dd|t        |      j                         k7  rdndz   d 
       
 K t        t        |
j                               |	D cg c]  }|d!   	 c}z         }|	D ]  }|j                  |d!         }|rt        |d      nd|d"<   t        |j                  d#      xs d      }|rA|d	kD  r<t        |      |k\  r.t!        t        t        |      |z              |d	k\  rd$nd%z  |d&<   d|d&<    g }t#        |
j	                         d' (      D ]  \  }}t        |      d)k  r|j                  |      }d}|r@|d	kD  r;t        |      |d*z  k\  r*t!        t        t        |      |z              |d	k\  rd$nd%z  }|j                  ||d	k\  rdndd+dt        |d      ||rt        |d      nddd,|d	k\  rdnd d| d-	        ||	|fS c c}}w c c}}w c c}w ).z
    Build net portfolio + per-sleeve rows from offline ``build_stock_only_signals``.

    Returns (net_rows, by_sleeve_rows, sleeves_meta).
    Nfund_nav_usd        r         ?fund_weightssignalssleeve_budgets_usdr   r   targetsrZ   okemptyr   r   )rZ   weight
budget_usdlabelr$  )r$  r   r   r   MKTz: longshort u    · z.1%z
 of sleevez (VOO for SPY) )
r   model_symbolr   r   sleeve_labelr   target_weightr   r   r   r   r   r   r   r   rb   c                     t        | d          S )Nr   )r?   r   s    r2   r   z4_portfolio_from_stock_only_signals.<locals>.<lambda>  s    C!I: r1   r      ru   net_bookzNet stock-only )	r   r   r   r   r   rb   r   r   r   )r   r<   rg   rV   rh   r   r   r   r  ri   r   rj   r?   r  listkeysr   r   )payloadr  r  allowr   scaleweightsr"  budgets	by_sleevenetsleeves_metabookwsigr$  sleeve_budgetr  r  rp   tw	trade_symnotionalrpricesr   nnet_rowsrb   s                                r2   "_portfolio_from_stock_only_signalsrJ    s     /:O@YE
N+2s
3C'++l+2s3E7;;~.4"5G7;;y)/R0G7;;34:;G&(IC#%L==? ,a8q=u<kk$%2swwy)/R0gkk$/Z3DS%PQ(TY3Z[gghWEAhq1(,,T48:A--/J$!Q5q1--J
 !$		E1q/Dq!tE
T }} 	GC&s3x;I$uRy0H WWY4x?C	N'$'HNN$4%-]E"$7$;$;D$$G$%*59a%8$)(A$6"'.224>?r%-]6@) M!%)nS1= 09CHNN<L/L+RTV		-,^ $sxxz*9-Maak-MMNF ZZ($')uR|t)!%%'.3/"q&SVr\eCFRK01!q&QbIAhKAhK &(H		1EF 
Xx=2ZZ_"q&S]b3h6s8}r123HMqrRF!)QF$  %h 2 +-5Q<4#%Af7%K1SER	

. Y,,A KE: .Ns    R#R)
R)
$R/
c           	     F   | xs t         }|j                         st        |z  j                         }|j	                         sdg ddS 	 t        j                  |j                  d            }t        |j                  d      xs g       }|j                  d	 
       i }|D ]A  }t        |j                  d      xs d      }|j                  |g       j                  |       C t        |j!                         d      D cg c]  }|||   t#        ||         d }}|j                  dd      |j                  dd      |j                  dd      |j                  dd      t#        |      t#        |      ||dS # t        $ r}dg d| dcY d}~S d}~ww xY wc c}w )zFCurated chat-era tickets since Jul 23 (+ optional live appends later).r   zNo history file.)r}   eventsnoterL   rM   zHistory load failed: NrL  c                    t        | j                  d      xs d      t        | j                  d      xs d      t        | j                  d      xs d      fS )Nr   r.  r   r   )ri   rg   es    r2   r   z_load_history.<locals>.<lambda>  sK    s155=#6B7QUU8_=RPR9SUXYZY^Y^_gYhYnlnUop r1   r   r   r.  T)reverse)r   rL  rH  r}   r)  Historyrd   chat_recommendationsrM  )r}   r)  rd   rM  n_eventsn_daysr{   rL  )DEFAULT_HISTORYis_absolute_REPOresolveexistsrP   rQ   rR   r   r5  rg   r   ri   rm   r   r   r6  r   )	rW   pr   r   rL  by_daterP  dr{   s	            r2   _load_historyr^    s   A==?QY!88:%=OPP\jjg67 #''(#)r*F
KKpKq/1G ,f#$1b!((+,
 5 gajs71:?D 
 ,/),''($:;#Kd)	 	  \%?TUXTY=Z[[\s$   	%E? F?	FFFFtactical_awma_slope_inversevol_edgetsmom)r  r  DBCSHSVIXVIXYSVXYUUPEFAEEMIEFTLTGLD_CORE_SYMBOL_TO_SLEEVEc                   t        | D ch c]:  }|st        |      j                         dvs"t        |      j                         < c}      }|st        j                         S 	 t        j                  ||ddd      }||j                  rt        j                         S t        |j                  t        j                        r|d   j                         }n|dg   j                         }|d   g|_
        t        j                  |j                        j                  d      j!                         |_        |j#                         j%                         }|S c c}w # t        $ r t        j                         cY S w xY w)z@Daily close panel from Yahoo (auto-adjusted), columns = tickers.r  BOOKTF)r}   r   r   r   Nr   r   )r   ri   rj   r*   	DataFramer   r   r   r&  rU   r   r   r   r   r   r/   r.   
sort_indexr   )r  r}   rr   r  r   r5   s         r2   _close_panelrt  %  s+   7caaCFLLNRb<b3q6<<>cdD||~	kk
 {cii||~#++r}}-G!!#WI##%a	..-99$?IIKEK$$&EL- d  ||~s!   EEE'E   F ?F c                F   | j                   s|| j                  vry t        j                  |      j	                         }| j
                  d ||f   j                         }|j                   ry t        |j                  d         }t        j                  |      r|dkD  r|S d S )Nr   r   )r&  r   r*   r+   r.   r   r   r<   r   r   r   )panelrp   daysubr  s        r2   _px_onry  @  s    {{c.
,,s

%
%
'C
))DSD#I

%
%
'C
yychhrlAa QU144r1   c                <   t        | j                  d      xs d      j                         }t        | j                  d      xs d      j                         }|dk(  ry|t        v r|S |dk(  rt
        j                  |d      S t
        j                  ||xs d      S )Nr   r.  r   r   core_etfr_  other)ri   rg   rk   rj   r   rn  )eventr   rp   s      r2   _resolve_sleever~  K  s    8$*+113F
eii!'R
(
.
.
0C**%))#}==!%%c6+<W==r1   )r  c                 ' t        | j                  d      xs d      }t        | j                  d      xs g       }|s |t        |j                               dg dddS t	               }|D ]Q  }t        |j                  d      xs d	      j                         }|s2|d
vs7|j                  t        ||             S t        t        |      |      }	i }
i 'd+'fd}t        |d       }|D ]  }t        |j                  d      xs d	      j                         }t        |j                  d      xs d	      j                         }|r|d
v rct        ||      }t        i |d|i      }t        j                  t        |j                  d                  j                         }t        |j                  d      xs d      j                         }|dk7  rdnd}|dv rS|j                  d      }|
|t        t        |            z  }|j                  d      }|@|j                  d      r/|r-	 t        t        |d               t        t        |            z  }|t#        |	||      }|,t%        j&                  t        |            rt        |      dk  rt        |      }|dk(  s||
vr|||d|
|<   |
|   }t        |d         }||z   }t        |      dk  r|
j)                  |d       ||z  dk\  r)|t        |d          z  ||z  z   |z  |d <   ||d<   ||d<   =|||d|
|<   H|d!k(  sO|
j                  |      }|sdt        |d         }t        |d          }t#        |	||      }||j                  d"      t        |d"         }||t        |      |z
  z  } |t        |j                  d      xs |      |       |
j)                  |d        i }i }t        j                  |      j                         }|
j+                         D ]  \  }}t        |d         }t        |d          }t        |j                  d      xs d#      }t#        |	||      }|P|t        |      |z
  z  }|j                  |d      |z   ||<   |j                  |d      |t        |      z  z   ||<    t        t	        '      t	        |      z  t	        |      z  t	        t,              z        } g }!d}"| D ]  }|t,        vr	|'vr||vrt        'j                  |d            }#t        |j                  |d            }$|#|$z   }|"|z  }"t        |j                  |      xs d      }%|%d$kD  r||%z  d%z  nd}&|!j/                  |t1        j                  ||      |%rt3        |%d&      ndt3        |#d&      t3        |$d&      t3        |d&      |&t3        |&d&      ndt3        t        |j                  |d            d&      d'        |!j5                  d(        |t        |j                               dd)t3        |"d&      |!d*S # t         $ r d}Y w xY w),z
    Illustrative PnL since history start from chat tickets (Yahoo marks).

    ENTER / REBALANCE set positions; EXIT realizes at that day's close.
    Open lots marked to latest close. Core ETF symbols are attributed to sleeves.
    r}   r   rL  chat_tickets_yahoo_mtmr  zNo history events to mark.)r}   as_ofmethodrowstotal_pnl_usdrM  r   r.  rp  )r}   r   c                H    j                  | d      t        |      z   | <   y )Nr  )rg   r<   )r   pnlrealizeds     r2   _add_realizedz*_sleeve_performance.<locals>._add_realized{  s!    #<<4uSzAr1   c                    t        | j                  d      xs d      dddddj                  t        | j                  d      xs d      j                         d	      t        | j                  d
      xs d      fS )Nr   r.  r   r   r   r   )r   	REBALANCEr   r   r   	   r   )ri   rg   rj   rO  s    r2   r   z%_sleeve_performance.<locals>.<lambda>  si    f#$aA>BB3quuXG\Z\C]CcCcCeghih%2&
 r1   r   r   r   r   r   r   g      ?g      )r   r  rb   Nr_   r   r   r  )rb   avg_costr   g&.>r  r   r   r|  r   g      Y@r   )r   r)  r(  realized_pnl_usdunrealized_pnl_usdpnl_usd
return_pctr   c                R    t        t        | j                  d      xs d             S )Nr  r  )r?   r<   rg   r   s    r2   r   z%_sleeve_performance.<locals>.<lambda>  s!    SquuY'7'>3!?@@ r1   zIllustrative mark-to-market since live start using chat ENTER/EXIT/REBALANCE tickets and Yahoo closes. Not your IBKR fill ledger. VOO attributed to Tactical AW; dip sleeve uses ticket limits / exit-day closes.r}   r  r  rM  r  r  )r   ri   r  r<   returnNone)ri   rg   r5  r   setrj   addr  rt  r   r~  r*   r+   r.   r?   r<   r   ry  r   r   poprh   r   r   r   r   r   )(historyr;  r  r  r}   rL  r  rP  rp   rv  lotsr  chronologicalr   sym_rawr   rw  r   signed
shares_absrb   r   rG   old_shnew_shlotshcostr  
unrealizedopen_mvlast_daysleevesr  	total_pnlrF  ubudgetret_pctr  s(                                          @r2   _sleeve_performancer  W  sU    G$45E'++h'-2.F&. 0
 	
 G 8!%%/'R(..03..KKsI678 6E ')D!#HB 
M  : QUU8_*+113aeeHo+,224'%55Wi0 !9A!9x!9:ll3quuV}-.88:155=)E*002D++xJ!c%
"344F}%BzaeeN3
U1^#456U:=N9OOB zE3,zuRy!9U2Y!^rB$4'-2PS	 CytH~.&v;%HHS$'F?a'(.tJ7G1H(H6TV;(VZ`'`D$%+DN%+DN+1rV TDIv((3-Cs8}%BZ)DsC(BzaeeO4@1_-.zb	D()C#cggh/96:C@HHS$u: z $&J "G||E",,.HJJL 	DS3x=!S_%SWWX&1'2E3):E"I$%'^^FC83>
6!++fc2R%)^C	D S]S_4s7|CcJcFddeG!#DI 
22vX7MRX`jRj(,,vs+,*..-.!eS	w{{6*1c2,2QJ3<%'D ,00@28eFA.d$)!QK&+Aqk a=3:3FeGQ/D$U7;;vs+C%DaH		

* 	II@IA UZZ\"*^ y!, c ! Bs   8,YY! Y!     @F)r  approx_per_name_mvskip_new_entriesc                (   t               }t        t        j                  dd            }	t        }
t        |j                               }t        ||	|      }t        ||	||
      }|r|dkD  rt        |      t        |      z  }n|t        |      z  }t        ||      \  }}t        |||	|
|||      \  }}}||dz  k\  r|j                  dd|d	d
|d	d       t               }	 t        j                  t!        d |||dd            }t#        ||t$              \  }}}|j+                         D ]m  \  }}|j                  d      dv s|dvs|j                  d      xs |j                  d      }|j)                  t-        j                  ||       d| d       o d|	t/        |d      t/        |d      |
t        |      t1        |      t/        |d      ||dz  k\  t-        j                  dd      d	dD ci c]  }||v s|||    c}i|}t3               }t5        |j                  d      xs i       } d| vrt/        |d      | d<   	 t7        || ||      }!| |t/        |d      ||t9        |j;                               d!|r|j                  d"      n|| |!t=        |       |||||||D "cg c]  }"|"j                  d#      d$k(  s|" c}"|d%|d&d'}t>        tA        jB                  tD        (      jG                  d)*      d+d,|gd-S # t&        $ r'}|j)                  d|        i }g g i }}}Y d }~d }~ww xY wc c}w # t&        $ r>}|j                  dd      t9        |j;                               dd| d g d }!Y d }~)d }~ww xY wc c}"w ).Nr   g(\?r   r   )r   )r   r   r   r   r   r   r  r   zDip sleeve over budget (~$z,.0fz
 open vs $z	 target).TF)r!  r   r   	use_yahoorenormalize_weightsr  zStock-only book engine failed: rZ   )r&  r   )r   r   z: no targets (z).r   z
Equity Dip)	r'  r(  per_name_usdr   r   r   r   r   r)  )r   r   r#  )r;  r  r  r}   r   zPerformance calc failed: r  recommend_onlyr!  r   r_  )	portfolior<  exitenterholdall_weatherr  u   Research / education only. Not investment advice. Recommend-only — place orders yourself in your own brokerage account. Portfolio = core ETF book (AW + TSMOM + vol edge + SH + QS) + CM dips. History = chat tickets since 2026-07-23. Performance = illustrative Yahoo MTM on those tickets.)
account_idr)  nav_usdr   r  
as_of_datemoder!  r#  performancestrategy_guider  tradesr  
disclaimerr(   seconds)timespecrentech_today_tradesA_shareable_dashboard)schema_versiongenerated_atproductstagebooks)$r3   r<   r
   rg   r	   r  r6  r   r   r   r   r  insertr   asynciorunr   rJ  r   r   r   rh   r   r   r   r^  rV   r  ri   r   r   SCHEMA_VERSIONr   r,   r-   	isoformat)#r  r)  r   r   r   r  r  r  r   dip_wmax_h	open_symsr   r  r  r   r   r
  dip_metar  core_w
so_payloadrI  by_sleeve_rowsr>  r   r?  rq   errr  sleeves_outr  r;  r  rF  s#                                      r2   build_snapshotr    s    HE$((t<=E$EDIIK IsE:6F&sE:ERH014*+c)n<S^+&t59LE5+%FHe &4-Q4WTN*VTXMYbcd '(F<[[$#%$)	

 2T52
.., #((* X
d88H!33O8S((7#9txx'9CLL/33D$?@seSUVWX 	*!(A.!i."9- !,"ftm3(,,\<H
 (DU!qH}q(1+~U
# #K  oG:>>"67=2>G7" %fa 0
)	
" !a= %**,' :D
~6&%"5g>!''5Z!xM9YAZ	
 E3DD ) +55y5I)( a  <6se<=
13R,.<* V   
[[,7&/u5!

< [sH   &:L :	M M M 0N&
N&	L=L88L=	N3NNc                    t        j                  t        j                  d      d         } | j	                  dt
        t               | j	                  dt
        t               | j	                  dd	       | j	                  d
d	       | j	                  dt        d       | j	                  dt        d       | j	                  dd	       | j	                  ddd       | j	                  dt        dd       | j	                  ddd       | j                         }t        |j                        }t        |j                  xs d |      }|s|j                  dk(  rt        ddi i      }t        t        |j                         t        |j"                        t        |j$                        t        |j&                        |t        |j(                        |j*                  dkD  rt        |j*                        nd t-        |j.                               }|j0                  }|j3                         st4        |z  j7                         }|j8                  j;                  d!d!"       |j=                  t?        j@                  |d#$      d%z   d&'       |d(   d   }tC        t?        j@                  d!t        |      |d)   tE        |d*   d+         tE        |d*   d,         tE        |d*   d-         |d.   d/   d0   |d1   d2d#$             y )3Nz

r   )descriptionz--out)typedefaultz--statez--account-iddemo)r  z--labelzStock-only bookz--navg     j@z--fund-scaler   z--spy-proxyr  z--heldr.  z@Comma tickers currently held as CM dips (merged with state file))r  helpz--approx-per-name-mvr  z?Approx MV per open dip for budget gate (0 = use model per-name))r  r  r  z--skip-new-entries
store_truez'Force watch-only for new dip candidates)r   r  z'AMZN,QCOM,AXP,INTC,LRCX,AMAT,MU,AMD,GEVrK   )r  r)  r   r   r   r  r  r  T)parentsexist_okr   )indent
rL   rM   r  r  r  r  r  r  r  r   r   r  )r%  ro   r  n_exitn_entern_holdr   r  )#argparseArgumentParser__doc__rl   add_argumentr   DEFAULT_OUTDEFAULT_STATEr<   
parse_argsrX   rc   rt   r   r  ri   r  r)  r   r   r  r  boolr  ro   rW  rX  rY  parentmkdir
write_textrP   dumpsprintr   )apargsrc   r   snapro   r?  s          r2   mainr    s   		 	 W]]6-B1-E	FBOOG$O<OOID-O@OONFO3OOI'8O9OOG%O:OONO<OOM5O1OOO  
 OON	   OO6  
 ==?D

#E$TYY%6$>DDIIO(5"

 t'$**o$((O)dnn%=A=T=TWX=X5!8!89^bd334	D ((C??s{##%JJTD1NN4::d1-4wNG=D	

3x"<0d8nV45tH~g67d8nV45#I|<]Kg	 	
r1   __main__)r  pd.Timestamp)rC   pd.DataFramer  z	pd.Series)rW   r   r  dict[str, Any])rn   z
str | Nonerc   r  r  dict[str, dict[str, Any]])
r   r  r   r  rw   r<   rx   r   r  z1tuple[list[dict[str, Any]], list[dict[str, Any]]])r   r<   r   r<   r   r<   r   r   r   zset[str]r   r<   r  r  r  z6tuple[list[dict[str, Any]], dict[str, Any], list[str]])rp   ri   r  ri   r  ri   )r  	list[str]r  dict[str, float])r7  r  r  ri   r  zfrozenset[str] | Noner  zAtuple[list[dict[str, Any]], list[dict[str, Any]], dict[str, Any]])N)rW   zPath | Noner  r  )r  r  r}   ri   r  r  )rv  r  rp   ri   rw  r  r  float | None)r}  r  r  ri   )
r  r  r;  r  r  r  r  ri   r  r  )r  ri   r)  ri   r   r<   r   r<   r   r  r  ri   r  r  r  r  r  r  )r  r  )Br  
__future__r   r  r  rP   r   sysr   pathlibr   typingr   zoneinfor   pandasr*   yfinancer   __file__rY  r  rX  ri   rW   r  RenTech.live.stock_book_utilsr	   r
   r   r   r   r   r   r   RenTech.live.stock_only_signalsr   r   r   r-   LOGSr  r  rV  r  r%   __annotations__r&   r3   rI   rX   rt   r   r  r  r  rJ  r^  rn  rt  ry  r~  r  r  r  __name__r0   r1   r2   <module>r     sy  $ #     
      X ((+u:SXXHHOOAs5z"	 	 	   !y6!F*11	!F*\9<SS)#i/(:=XX 

# 
 

" 
A/A$$$ $V !v
#v v 	v
 v 7vrX	X X 	X
 X X X X <Xv4 -1	g-g- g- +	g-
 Gg-TH 
*  "65	>" `` ` 	`
 ` `T '-"MM M 
	M
 M $M M %M M M`CL zF r1   