
    pjS{              	         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mZ ddlm	Z	 ddl
mZ ddlmZ ddlZ e	e      j#                         j$                  d   Z ee      ej*                  vr"ej*                  j-                  d ee             dd	lmZ dd
lmZ ddlmZ ddlmZ  ed      Zedz  dz  dz  Z e dz  Z!dddddddddZ"de#d<   e dz  Z$e dz  Z%e dz  Z&e d z  Z'e d!z  e d"z  e d#z  fZ(d$Z)e d%z  Z*d=d&Z+d>d'Z,d?d(Z-d)d*d+d,	 	 	 	 	 	 	 	 	 d@d-Z.dAd.Z/dBd/Z0dCd0Z1dDd1Z2	 	 	 	 	 	 	 	 	 	 	 	 	 	 dEd2Z3dFd3Z4	 	 	 	 	 	 	 	 dGd4Z5	 	 	 	 	 	 	 	 dHd5Z6dId6Z7dJd7Z8d8d8ddddd9	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dKd:Z9dLd;Z:e;d<k(  r e:        yy)Ma@  
Build a single JSON snapshot for the Best Ideas + IBKR command center UI.

Reads local artifacts (fund daily, recommendations, rebalance logs) and optionally
pulls live account + positions from TWS / IB Gateway.

Example::

    cd /Users/robzingale/trading_bot
    PYTHONUNBUFFERED=1 .venv/bin/python -m RenTech.monitor.build_command_center_snapshot --ibkr

    # Offline (no TWS): still loads recommendations + model targets
    PYTHONUNBUFFERED=1 .venv/bin/python -m RenTech.monitor.build_command_center_snapshot

Output: ``RenTech/data/logs/command_center_snapshot.json``
    )annotationsN)datetime)Path)Any)ZoneInfo   )build_signal_explanations)build_strategy_summaries) FUND_WEIGHT_TABLE_TACTICAL_TSMOM)SPDR_SECTOR_TICKERSzAmerica/New_YorkRenTechdatalogszcommand_center_snapshot.jsonzSPY Theta (lit4+VRP)zVXX Regime StackzVXX Long CallzMacro AW OptionszTactical All WeatherzTSMOM / Managed Futuresz
Equity DipzSector Momentum)	spy_theta
vxx_regimevxx_long_callmacro_awtactical_awtsmom
equity_dipsector_momentumzdict[str, str]SLEEVE_LABELSzbest_ideas_stack_10dd_plus_vxx_long_call_plus_macro_aw_plus_sector_momentum_plus_tactical_aw_plus_tsmom_plus_fund_plus_nav_q_mtm_daily.csvzbest_ideas_stack_10dd_plus_vxx_long_call_plus_macro_aw_plus_sector_momentum_plus_tactical_aw_plus_tsmom_plus_fund_plus_nav_q_mtm_meta.jsonzbest_ideas_stack_10dd_plus_vxx_long_call_plus_macro_aw_plus_sector_momentum_plus_tactical_aw_plus_tsmom_plus_fund_plus_nav_q_mtm_yearly.csvzbest_ideas_stack_plus_equity_dip_plus_vxx_long_call_plus_macro_aw_plus_sector_momentum_plus_tactical_aw_plus_fund_mtm_daily.csvzibkr_trade_recommendation.jsonz+ibkr_trade_recommendation_r2a_diagonal.jsonz)ibkr_trade_recommendation_r2b_spread.json)SPYTLTIEFGLDDBCzlive_fund_signals.jsonc                    | j                         sy 	 t        j                  | j                               S # t        j                  $ r Y y w xY wN)is_filejsonloads	read_textJSONDecodeError)paths    I/opt/rentech/trading_bot/RenTech/monitor/build_command_center_snapshot.py
_read_jsonr'   V   sA    <<>zz$..*++ s   "6 AAc                    | j                         sy t        | j                  d      d d      }|sy t        |d         }t	        |t
              r|d   j                  |d<   |S )Nzplatform_run_*.jsonc                6    | j                         j                  S r   )statst_mtime)ps    r&   <lambda>z&_latest_platform_run.<locals>.<lambda>b   s    affhFWFW     T)keyreverser   _source_file)is_dirsortedglobr'   
isinstancedictname)log_dirfilesr   s      r&   _latest_platform_runr:   _   s^    >>7<< 56<WaefEeAhD$$Qx}}^Kr.   c                 r  K   	 ddl m} m}m} ddlm} ddlm}  |       }d }	  | |j                         d {   } ||       d {     ||       d {   }|j                  D 	cg c]s  }	|	j                  |	j                  |	j                  |	j                  |	j                  |	j                   |	j"                  |	j$                  |	j&                  |	j(                  d
u }
}	|j*                  j-                         |j.                  |j0                  |j2                  |j4                  |j6                  |j8                  |j:                  |
t=        |
D 	ch c]  }	|	d   	 c}	      D ci c]  }||
D cg c]  }|d   |k(  s| c} c}}d
}|d f| ||       d {    S S # t        $ r}d d| fcY d }~S d }~ww xY w7 7 7 tc c}	w c c}	w c c}w c c}}w 7 A# t>        $ r+}d tA        |      fcY d }~| ||       d {  7   S S d }~ww xY w# | ||       d {  7   w w xY ww)	Nr   )
connect_ibdisconnect_ibensure_positions_loaded)load_platform_config)fetch_portfolio_snapshotzIB modules unavailable: )
symbolsec_typeexpirystrikerightpositionavg_costmarket_valueunrealized_pnlcon_idrA   )
as_ofnet_liquidation_usdavailable_funds_usdexcess_liquidity_usdmaintenance_margin_usdunrealized_pnl_usdrealized_pnl_today_usdmargin_utilization	positionspositions_by_symbol)!RenTech.live.ibkr_sessionr<   r=   r>   RenTech.live.platform_configr?   RenTech.live.portfolior@   ImportErrorbrokerrS   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   	isoformatrL   rM   rN   rO   rP   rQ   rR   r3   	Exceptionstr)r<   r=   r>   r?   r@   ecfgibsnapr,   rS   symxpayloads                 r&   _fetch_ibkr_portfoliord   k   s2    	4	
 	

 	FC 
 C	B'$cjj))%b)))-b11 ^^
  ((JJ((((JJJJ !"#"2"2((
	 
  ZZ))+#'#;#;#'#;#;$($=$=&*&A&A"&"9"9&*&A&A"&"9"9" "	"B11X;"BC$ AAakS.@aAA$
 } >### W  4/s3334 *)1
6 #C B$ $	  SV|>###  >### s  H7F* 	H7G' GG' 	G

G' GG' ,A8G$A2G' G"
G' ,
G6G G G	G' H7#G%$H7*	G3F?9G:H7?GH7G' 
G' G' 
G' GG' %H7'	H0H<H=H H7HH7HH H4,H/-H44H7effective_dateweightticker)date_col
weight_col
ticker_colc                  t        |       dd}| j                         si |fS t        j                  |       }|j                  r	d|d<   i |fS t        j
                  ||         j                  j                         ||<   t        j                  j                  t              j                         j                  d       }|||   |kD     }t        |      r||   j                         }d}	n|||   |k     |   j                         }d}	|||   |k(  ||   j                  t               dkD  z     }
|
j#                         D ci c]   \  }}t        ||         t!        ||         " }}}|
j$                  |
j'                  d	d
      dk(  |f   j                  t               j)                         }|||   |k(  |j'                  dd
      dk(  z     |   j                  t               j)                         }g }d|j*                  v rd|j*                  v r|||   |k(     j-                  d      }|j#                         D ]h  \  }}|j/                  t        ||         t1        |d         t        j2                  |d         rt!        |d         nd t!        ||         dkD  d       j |j5                  d|	t        t        j                  |      j7                               d|
v rt        |
d   j8                  d         nd ||t;        |j=                               |d|
j*                  v r&t        |
      rt1        |
d   j8                  d         ndd	       ||fS c c}}w )Nmissingr%   statusemptyrn   tzupcomingcurrentr   is_new_entryFTis_exit_from_prioraqr_momrank)rg   rw   rv   heldokperiod_end_datetop_k   )	rn   modere   rz   new_entriesexits_from_priortickersrankingsr{   )r\   r    pdread_csvro   to_datetimedt	normalize	TimestampnowNYtz_localizelenminmaxastypefloatiterrowslocgettolistcolumnssort_valuesappendintnotnaupdatedateiloclistkeys)r%   rh   ri   rj   metadftodayfutureeffr}   grp_rtargetsentriesexitsr   	snap_rowss                     r&   _etf_targets_from_rebalancesr      s7    %(ICD<<>4x	T	B	xx X4x>>"X,/22<<>BxLLL#--/;;DAE8u$%F
6{X""$H&'1557
blc!bn&;&;E&BQ&FG
HC LLNAq 	AjME!J-00G  ggcggne4<jHIPPQTU\\^G8#/CU(Kt(STUfSk&&( 
 &(HBJJ6RZZ#7r(|s*+77?	&&( 	DAqOO!!J-0&	N68hhq|6LuQy\2RV!!J-014		 	KK!",,s"3"8"8":;FW[^F^s3'8#9#>#>q#ABdh" %GLLN+ 29S[[2HSQTXSW**1-.[\
	
 D=Cs   %Mc           	        t        |       dd}| j                         si |fS t        j                  |       }|j                  r	d|d<   i |fS t        j
                  |d         j                  j                         |d<   t        j                  j                  t              j                         j                  d       }|d   |k  j                         r||d   |k     d   j                         n|d   j                         }||d   |k(     }|j                         D ci c]1  \  }}t        |d         dkD  rt        |d	         t        |d         3 }}}t!        |      rt        |d
   j"                  d         nd}	|j%                  dt        t        j                  |      j'                               |	t)        |j+                               d       ||fS c c}}w )Nrl   rm   ro   rn   r   rp   rf   r   rg   cash_weight        ry   )rn   rK   r   r   )r\   r    r   r   ro   r   r   r   r   r   r   r   anyr   r   r   r   r   r   r   r   r   )
r%   r   r   r   dr   r   r   r   cash_ws
             r&   _tactical_targetsr      s   $'ICD<<>4x	T	B	xx X4x6
+..88:BvJLL#--/;;DAE24V*2E1J1J1L2f:'++-RTU[R\R`R`RbA
RZ1_
C LLNAq8! 	AhK%(,,G 
 36c(U3}%**1-.FKKa--/0!GLLN+		
 D=s   $6G c                   | j                         sg S t        j                  |       }|j                  sd|j                  vrg S t        j
                  |d         j                  j                         |d<   t        j                  j                  t              j                         j                  d       }d|j                  v r<t        j
                  |d         j                  j                         |d<   |d   |k\  }n!t        j                  d|j                        }g }|j                  |   j                  d      j!                         D ]  \  }}|j#                  t%        |j'                  d|j'                  dd	                  t%        |d   j)                               d|v rt%        |d   j)                               nd	t%        |j'                  d
|j'                  dd	                  d        |S )N
entry_daterp   	exit_dateT)index   sleeve	structure 
underlyingrg   )r   r   r   r   )r    r   r   ro   r   r   r   r   r   r   r   r   Seriesr   r   tailr   r   r\   r   r   )r%   r   r   	open_maskrowsr   r   s          r&   _macro_upcomingr      s   <<>		T	B	xx<rzz1	~~b&67::DDFB|LL#--/;;DAEbjj ..K9<<FFH;{Ou,	IId"((3	Dy!&&r*335 
1aeeHaeeK.DEF!!L/"6"6"89;F!;KS;!4!4!67QS!!%%aeeHb6I"JK		

 Kr.   c                >   | si S i }| j                  dg       D ]  }t        |j                  dd            j                         dvr/t        |j                  dd            }|sM|j                  |d      t        |j                  dd      xs d      z   ||<    |S )	NrS   rB   r   )STKETFrA   r   rH   r   )r   r\   upperr   )	portfoliooutr,   ra   s       r&   _ib_stock_mvr     s    	C]];+ LquuZ$%++-^C!%%"%&773$uQUU>1-E-J'KKCL Jr.   c                    | sg S g }| j                  dg       D ]@  }t        |j                  dd            j                         dk7  r0|j                  |       B |S )NrS   rB   r   OPT)r   r\   r   r   )r   legsr,   s      r&   _ib_option_legsr   %  s_    	D]];+ quuZ$%++-6A Kr.   c                   g }|dkD  r||z  nd}t        |j                               }|j                         D 	
ci c]  \  }	}
t        |
      dkD  s|	|
 }}	}
t	        |j                         d       D ]  \  }}||z  }|j                  |d      }||dz  k  r:|j                  dd| |d	| d
|d|t        |d      t        |d      d|d       _|j                  dd| |d| d|dd|  d|t        |d      dd        |j                         D ]H  \  }}
||v r|t        v s	|t        v s|j                  dd| |d| d|  ddt        |
d      i|d       J |S c c}
}	w )zBSuggest ADD/REMOVE/HOLD for ETF sleeves vs IB stock market values.r   r   2   c                    | d    S )N    )rb   s    r&   r-   z#_compare_etf_book.<locals>.<lambda>?  s    1 r.   r/   g      ?r   ADDz	Increase z toward model weight z.1%r   )target_weighttarget_notional_usdib_market_value_usdpriorityactionbookrA   summarydetailP   HOLDzHold z (~z of z sleeve))r   r   
   REMOVEzFlat u    — not in current z modelr   )
setr   itemsabsr3   r   r   roundr   MACRO_TICKERS)r   r   ib_mvfund_navfund_weightr   actions
sleeve_navuniversesmvrx   ra   w
target_usdhaves                   r&   _compare_etf_bookr   0  s    %'G+3a<K'SJ7<<>"H${{}=eaB"ArE=D=o>  Q!^
xxS!*s""NN "# !!*3%/DQsGL)*/4Z/C/4T1~ 	  NN "$ !!&se3qgT$xH)*/4T1~
) D ::< R(?%%)=NN "& !!&se+?vVL4eBlKdK		 Ne >s   E$E$c                X   g }| D ]!  }t        |j                  d|j                  dd                  j                         }t        |j                  dd            }|j                  d      }d}|dv rd}n|d	v rd
}|j                  d      xs g }dj                  d |d d D              }|j	                  |dk(  rdnd|ddd|j                          d| d| |j                  d      |j                  d      |j                  d      |||j                  dd      dd       $ |S )Ndecisionentry_actionr   regimeproposed_qtyWATCH)enterbuyopenrecommend_enterr   )exitclosesellr   r   z; c              3    K   | ]w  }|j                  d d       d|j                  dd       d|j                  dd       d|j                  dd       d|j                  dd       d|j                  d	d        y y
w)open_actionr    ratior   u   × rA   rC   rE   rD   Nr   ).0ls     r&   	<genexpr>z0_actions_from_recommendations.<locals>.<genexpr>~  s      
  uu]2&'qwq)9(:#aeeHR>P=Qhr"#1QUU72%6$7qx9K8LN
s   A=A?   r      r   r   zVRP z: z qty=
created_atentry_limit_per_sharerisk_budget_usd_sourcerecommendation)r  r  r	  r   	legs_textsourcer   )r\   r   lowerjoinr   r   )	recsr   recr   r   qtyaction_typer   leg_txts	            r&   _actions_from_recommendationsr  r  sE   $&G 
swwz377>2+FGHNNPSWWXr*+ggn%BBK22"Kwwv$")) 
 "1X
 

 	!,!5A1%#!&,,.!1H:U3%H"%'',"7-0WW5L-M'*ww/@'A !(!ggi1AB	

@ Nr.   c                    | xs t         }|j                         st        j                         rt        }|xs t        }|j                         sd}|xs t        }|j                         sd}|||fS )zCPick canonical fund artifacts; fall back to legacy daily if needed.N)FUND_DAILY_DEFAULTr    FUND_DAILY_LEGACYFUND_META_DEFAULTFUND_YEARLY_DEFAULT)dailyr   yearlyr   mys         r&   _resolve_fund_pathsr    sf     	##A99;,446!!A99;%%A99;a7Nr.   c                h   | j                         sdt        |       dS t        j                  | dg      }|j                  rdt        |       dS |j                  d      }|rt        |      ni }t        |t              r|ni }t        |j                  dd            }|j                  d   }|d	   j                  t              }t        |j                  d   |z
        }t        |d   j                  d   |d   j                  d
   z
  j                  dz  d      }	|j                  d   d
kD  r$t        |j                  d         |z  d|	z  z  dz
  n
t        d      }
||j                         z  dz
  j!                         }d|j"                  v r|d   j                  t              n|j%                         j'                  d      }t        |j)                  d            }|dkD  rt        |j+                         |z  dz        n
t        d      }|j                  d      xs i }|j"                  D cg c]  }|j-                  d      s| }}i }|D ]  }|j/                  dd      }||   j'                  d      j                  t              }t        |j1                               }d| d}||v rt        ||         nd}||j"                  v rt        ||   j+                               nd}|j                  |      }|t3        j                  |      }t4        j                  ||      |t        |      nd||||v rt        ||         nd|||z  dz  |r||z  dz  ndd||<    g }|r|j                         rt        j                  |      }|j7                         D ]  \  }}|j9                  t;        |d         t        |j                  dd
            t        |j                  dd
            t        |j                  d d
            t        |j                  d!d
            t        |j                  d"d
            d#        nC|j<                  }t        j>                  |d         } tA        | jB                  jD                  jG                               D ]  }!| jB                  jD                  |!k(  }"|jH                  |"   }#t        |jK                  d      jH                  |#jL                  d
            }$t        jN                  |$      r|}$t        |jH                  |#jL                  d            }%|j9                  t;        |!      |%|$z  dz
  dz  d$|#j"                  v rt        |#d$   j1                               n|%|$z
  |%d%        g }&|D ]=  }|j/                  dd      }||   j'                  d      j                  t              }tA        |d   jB                  jD                  jG                               D ]  }!|d   jB                  jD                  |!k(  }"t        |jH                  |"   j1                               }'t        |jK                  d      jH                  |"   j                  d
         }(t        jN                  |(      s|(d
k  r|}(|&j9                  t;        |!      |t4        j                  ||      |'|'|(z  dz  d&        @ i d'd(d)t        |       d*|rt        |      ndd+|j                  d+d,      d-|j                  d-d.      d/|j                  d/      xs |j                  d      d0t        t        jP                  |d   j                  d
         jS                               d1t        t        jP                  |d         jS                               dt        t        jP                  |d         jS                               d|d2t        |j                  d	d
            d3t        |j                  d3|j                  d	d
                  d4t        |j                  dd
            d5t        |j                  d   |z  dz
        dz  d6t        |
      dz  d7|d8t        |      dz  |t        |j                  d9d
            d9|j"                  v rt        |d9   j+                               ndd9|j"                  v rt        |d9   j                               nd|j                  d:      t        |j                  d;d
            ||||&d<
S c c}w )=zFLoad Best Ideas fund-mode portfolio summary for the command center UI.rl   )rn   r%   r   )parse_datesro   capital_usd     j@equity_mtm_usdr   g     v@g&.>g      ?nandaily_return_mtmr   r   )ddofg-q=g_u~/@fund_weights	pnl_fund_r   	notional__usdNg      Y@)labelrf   notional_usdmean_notional_usdpnl_today_usdtotal_pnl_usdreturn_on_start_capital_pctpct_of_fund_pnlyearreturn_pct_chainedreturn_pct_constantpnl_usdend_equity_chainedmax_dd_pct_chained)r4  r5  r6  r7  r8  r9  pnl_best_ideas_mtm)r4  r5  r7  r8  )r4  r   r-  r7  return_pct_of_fund_navrn   ry   r%   	meta_pathcombine_modefund_nav_quarterly_sizedfund_nav_rebalance	quarterly
fund_scale
start_dateend_datefund_nav_usdnav_ref_usdfund_daily_returntotal_return_pctcagr_pctsharpemax_drawdown_pctmargin_combined_usdmin_account_size_usdbp_utilization_pct)
r1  rK  margin_combined_mean_usdmargin_combined_peak_usdrL  rM  r)  sleevesr  yearly_by_sleeve)*r    r\   r   r   ro   r   r'   r5   r6   r   r   r   r   r   dayscummaxr   r   
pct_changefillnastdmean
startswithreplacesumr   r   r   r   r   valuesr   r3   r   r4  uniquer   shiftr   isnar   r   ))
daily_pathr<  yearly_pathr   r   	start_caproweq	total_pnlyearscagrddretssdrI  r)  cpnl_colsrP  colr/   pnl_stotal_sleeve_pnlnotional_colnotionalmean_notionalr   yearly_rowsyrr   r   fund_eqdatesr  maskgstart_eqend_eqrQ  r,   	start_navs)                                            r&   _load_fund_portfolio_summaryr{    s    #S_==	ZfX	6B	xx!3z?;;		B$-:i 2DdD)4rDdhh}i89I
''"+C			$	$U	+BbggbkI-.IF$r&zq'99??&H$OEFHggbkTUoE"''"+*e<sB[`af[gD
ryy{
S
 	%	%	'B3E3S2 !((/Y[YfYfYhYoYopsYtD	txxQx	 B79EzU499;#z23uU|F88N+1rL::Cak)BCHC G 
kk+r*3s#**51 -"3%t,/;s/B5\*+.:bjj.HE"\"'')*d 	 S!9044S9A"&&sC0"#-eAhT$!.03s
U3s8_-+;i+G%+OGP/);eCVY	

. )+K{**,[[%KKM 
	DAq&	N*/6JA0N*O+07La1P+Q$QUU9a%89*/6JA0N*O*/6JA0N*O	
	 ))r&z*,,./ 	A88==A%DtARXXa[__QWWQZ89Hwwx $266!''"+./FF+1H+<s+Be*K+qyy8  %Q';%<%@%@%BC(**0		$ .0 kk+r*3s#**516
**1134 	Af:==%%*Deiio))+,Abhhqkood388;<Iwwy!Y!^%	##F!*..sC8 ./)me.C	& $ J  	yS^d  	1KL	 
 	dhh';[I  	dhh|,H0H  	c",,r&zq'9:??AB  	CS[16689  	BLLV-2245  	y  	cgg&6:;  	uSWW]CGG<La4PQR  	U377+=q#AB  	E"''"+	"9C"?@5H  	E$K%'   	&! " 	E"I-# $ #$SWW-BA%FG BJJ. %*"-B*C*H*H*J$K BJJ. %*"-B*C*G*G*I$J $)? @#CGG,@!$DE$,?   c Ds   5d/d/c                ~   | j                  d      dk7  r| S i }| j                  d      xs i j                         D ]K  \  }}|j                  d      |j                  d      |j                  d      |j                  d      d||<   M d| j                  d	      | j                  d
      | j                  d      |dS )zDBackward-compatible slice of portfolio summary for legacy UI fields.rn   ry   rP  rf   r.  r0  r1  )rf   allocated_usdr0  r1  r   rD  rF  )rn   r   rD  rF  rP  )r   r   )r   sleeves_outr/   sls       r&   _load_fund_latestr  :  s    {{8$"$KKK	*0b779 
RffX&VVN3VVO4VVO4	
C
 F#N3$[[)<= r.   c                   t        |       }d|d<   |j                  d      xs i j                  d      }|rdd|t        |      d|d<   t        |j                  d      xs i       }d	D ]%  }||j                  d      xs i v s|d   |   ||<   ' |j                  dd
      |d<   |j                  d      |d<   |j                  d      |d<   |j                  d      |d<   ||d<   t        |j                  d      xs g       }ddh}|j                  dg       D cg c]  }|j                  d      |v s| }	}t	        ||	z   d       |d<   t        |j                  d      xs i       }
t        |
j                  d      xs i       }|j                  d      |d<   |j                  d      |d<   ||
d<   d|
d<   |
|d<   |S c c}w )zROverlay IBKR-derived targets/actions; keep backtest fund performance as reference.ibkr_live_mergeddata_sourceibkrr   TN	connectederrorr   option_positionssignals)r   r   	spy_gates	vrp_cyclerecommendations	ibkr_livegenerated_atlive_fund_signals_atbars_fetchedbars_missingr   r   r   r   c                8    | d   | d   | j                  dd      fS Nr   r   r   r   r  as    r&   r-   z*_merge_live_fund_signals.<locals>.<lambda>j  s     q}ak1553DE r.   r   fundmodelrD  fund_nav_usd_live_ibkrr)  live_weightszTReturns/Sharpe from backtest CSV; targets and ADD/REMOVE from IBKR live_fund_signalsreference_note)r6   r   r   r   r3   )r`   liver   ibpsigr/   live_actions
keep_booksr  model_extrar  r  s               r&   _merge_live_fund_signalsr  O  s   
t*C+C88F!r
&
&{
3C
 / 4	
F swwy!'R
(C^ ,488I&,"-Is+CH, -=C"&((>":C((>2C((>2CC	N+1r2L
+J!ggi4Tf8S1TKT{"EC	N %2&D'"(b)E&*hh~&>E
"# HH^4E.DM^ 		 CKJ Us   G7GF)live_signalslive_signals_from_filelive_signals_path
fund_daily	fund_metafund_yearlyc                   t        j                  t              }d }|s|rc|xs t        }	|r,t	        |	      }
t        |
t              st        d|	       |
}n+ddlm	}m
} t        j                   |             } ||	|       d\  }}|r-|j                  d      xs i j                  d      r	|d   d   }n"| r t        j                  t                     \  }}t        |||      \  }}}|rt	        |      ni }t        |t              r|ni }t!        |||      }t#        ||      |d<   t%        |      }t'        |j                  dd	            }|j                  d
      xs% t(        D ci c]  }|t'        t(        |          c}}g }t*        D ]A  }t	        |      }
t        |
t              si |
d|j,                  i}
|j/                  |
       C t	        t0        dz        }t	        t2        dz        }t5        t0        dz        }t7        t0        dz        \  }}t9        t0        dz        \  }} t;        t0        dz        }!t=        |      }"g }#|#j?                  tA        |             |j                  dd      dkD  r0|#j?                  tC        d||"||j                  dd      |             |#j?                  tC        d||"||j                  dd      |              |#j/                  ddddddddddd       |!r)|#j/                  d d!d"dtE        |!       d#d$|!d d% id       |#jG                  d& '       t2        d(z  jI                         }$|jK                         |d u||tM        |      d)|$|xs i j                  d*      |xs i j                  d+      d,||d-|i|d-|i| d$|!i|d.|||tO        |      |rtO        |      nd d/|#d0}%|tQ        |%|      }%tS        |%      |%d1<   |%S c c}w )2NzMissing live fund signals: r   )run_live_fund_signals_asyncwrite_live_fund_signals)NNr  r   strategies_summaryrD  r#  r)  r
  zlive_signal_state.jsonz*RenTech/strategy_stack/live_vrp_state.jsonlive_platformz'sector_momentum_standard_rebalances.csvz$tactical_aw_standard_allocations.csvz(macro_aw_options_portfolio_eq_trades.csvr   r   )r   r   r   r   r   r   r   r   r   r   r   uE   Buy-the-dip: enter on ≥3% daily drop (top 5 SPX / top 10 R3k names)r  r   z%Not in default stack; optional sleeve)sp500_top_nrussell3000_top_n	hold_daysnoter   (   r   r   z( open Macro AW option structures (model)open_structures   c                8    | d   | d   | j                  dd      fS r  r  r  s    r&   r-   z build_snapshot.<locals>.<lambda>  s     *q{AEE&"<MN r.   r   zRenTech/live/config/KILL_SWITCHr  r1   risk)kill_switch_activeplatform_run_sourceplatform_riskr   )live_signal_state	vrp_stater   r   r   r  )r  r   target_weights	daily_csvmeta_csv)r  r  r  r  r  r   signal_explain)*r   r   r   LIVE_FUND_SIGNALS_PATHr'   r5   r6   FileNotFoundErrorRenTech.live.fund_signalsr  r  asynciorunr   rd   r  r{  r
   r  r   r   RECOMMENDATION_PATHSr7   r   LOGS_REPOr:   r   r   r   r   extendr  r   r   sortr    rZ   r   r\   r  r	   )&use_ibkrr  r  r  r  r  r  r   live_payloadr%   r   r  r  ib_portfolioib_errr_  r<  r`  combine_metar   r  r   kweightsr  r,   signal_stater  platform_runsector_targetssector_metatactical_targetstactical_meta
macro_openr   r   kill_switchr`   s&                                         r&   build_snapshotr  x  sM    ,,r
C*.L- :$:!d#DdD)'*EdV(LMMLf";;'B'DEL#D,7'L&))&17R<<[I#F+K8	&{{+@+BCf)<ZT_)`&J	;,5:i(2L#-lD#A<rL,ZKPI&>y,&WI"#Y'DY]]>9=>HmmN+ 10 	
51!4550G "$D! !}dD!.d.Iqvv.DKK	 d%==>L5#OOPI'(>?L">88#NK '855'#m !(R!RSJ&E$&GNN067{{$c*Q.&&!#KK(93? 		
 NN$M37	
	 NN ^ %'?		
   "!*o..VW,j!n=		
 LLNLO<<EEGK %T1% / =	
 #.$0$6B#;#;N#K*0b55f=
 "." )>I[I%'7I=I*J7#
 "%Z*3I
 9D< 'l;6t<D	Kc0s   *O/c                 L   t        j                  t        j                  d      d         } | j	                  ddd       | j	                  dt
        t        d	
       | j	                  dt
        d d
       | j	                  dt
        d d
       | j	                  ddd       | j	                  dt
        t        d
       | j	                  ddd       | j                         }t        t        |j                        xs t        |j                        t        |j                        t        |j                        |j                  |j                  |j                         }|j"                  j%                         j'                         }|j(                  j+                  dd       |j-                  t/        j0                  |dt2              dz          t5        d|        t5        d|d   d    dt7        |d           d!t7        |d   j9                  d"      xs i j9                  d#g                     |d   j9                  d$      rt5        d%|d   d$           |j9                  d&      d'k(  r/t5        d(|j9                  d)i       j9                  d*d+              y y ),Nz

r   )descriptionz--ibkr
store_truez@Connect to TWS/IB Gateway (requires ib_insync + running gateway))r   helpz--outzOutput JSON path)typedefaultr  z--fund-dailyzGOverride fund MTM daily CSV (default: best_ideas_stack_10dd fund+nav_q)z--fund-metazOverride fund MTM meta JSONz--live-signalszUse IBKR historical bars for tactical/sector targets (+ VRP recommend). Loads live_fund_signals.json if present; otherwise connects to IB and writes it.z--live-signals-pathz/Path for live fund signals JSON (read or write)z--live-signals-from-filezPMerge tactical/sector/VRP from existing live_fund_signals.json (no IB bar fetch))r  r  r  r  r  r  T)parentsexist_okr   )indentr  
zWrote z  IBKR connected: r  r  z  actions: r   z  positions: r   rS   r  z  IBKR note: r  r  z  Live signals: r  r  r   )argparseArgumentParser__doc__splitadd_argumentr   DEFAULT_OUTr  
parse_argsr  boolr  r  r  r  r  r  r   
expanduserresolveparentmkdir
write_textr!   dumpsr\   printr   r   )apargsr`   r   s       r&   mainr    s   		 	 W]]6-B1-E	FBOOO  
 OO	   OOV	   OO*	   OO[   OO&>	   OO"_  
 ==?Ddii;D):):$;$++,#D$?$?@00??..D ((



'
'
)CJJTD1NN4::d1c:TAB	F3%.	
T&\+67 8Y() *4<++K8>BCCKQSTUV	X
 F| d6l73456xx"44 )R!8!<!<=SUW!X YZ[ 5r.   __main__)r%   r   returnz
Any | None)r8   r   r  dict[str, Any] | None)r  z(tuple[dict[str, Any] | None, str | None])
r%   r   rh   r\   ri   r\   rj   r\   r  'tuple[dict[str, float], dict[str, Any]])r%   r   r  r  )r%   r   r  list[dict[str, Any]])r   r  r  dict[str, float])r   r  r  r  )r   r\   r   r  r   r  r   r   r   r   r   dict[str, Any]r  r  )r  r  r  r  )r  Path | Noner   r  r  r  r  z%tuple[Path, Path | None, Path | None])r_  r   r<  r  r`  r  r  r  )r   r  r  r  )r`   r  r  r  r  r  )r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  )r  None)<r  
__future__r   r  r  r!   sysr   pathlibr   typingr   zoneinfor   pandasr   __file__r  r  r  r\   r%   insertRenTech.monitor.signal_explainr	    RenTech.monitor.strategy_catalogr
   /RenTech.strategy_stack.combine_best_ideas_stackr   -RenTech.strategy_stack.multi_strategy_managerr   r   r  r  r   __annotations__r  r  r  r  r  r   r  r'   r:   rd   r   r   r   r   r   r   r  r  r{  r  r  r  r  __name__r   r.   r&   <module>r     s  " #    
     X ((+u:SXXHHOOAs5z" D E N !y6!F*33 ($$")&(	!~ 	 	 SS 
 	 SS 
 	 TT  	 HH  	++8866  4 88 	5$v %9
9 9 	9
 9 -9x:6?
? ? 	?
 ? ? ? ?D"J
  +	$NNN N 	Nb*&X #(%)"!#WW W !	W
 #W W W W Wt@\F zF r.   