
    pj                   n   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
Z
ddlmZmZ ddlmZmZmZ ddlmZ ddlmZmZ dd	lmZ  ee      j3                         j4                  d
   Z ee      ej:                  vr"ej:                  j=                  d ee             	 ddlm Z 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.m/Z/ dZ0dZ1dZ2dZ3dZ4dZ5dZ6dZ7dZ8dZ9dZ:dZ;dZ<dZ=dZ>dZ?dZ@dZAdZBd ZCd!ZDd"ZEdZFdZGdZHdZIdZJd#ZKd$ZLdZMd$ZNdZOdZPd%ZQed&   ZRdaSd'eTd(<   d]d)ZU ee      j3                         j                  d*z  ZWd+ZXd,ZYd-ZZd.Z[ ed/      Z\ed0z  d1z  d2z  d3z  Z]ed0z  d1z  d2z  d4z  Z^d5Z_d"Z`d6Zad7Zbd8Zcd^d9Zdd_d:Zed_d;Zfe G d< d=             Zgd`d>Zhdad?Zidbd@Zje^fdcdAZkdddBZldedCZm	 	 df	 	 	 	 	 	 	 	 	 	 	 dgdDZn	 	 	 	 dh	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 didEZo	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 djdFZp	 dk	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dldGZqdmdHZrdndIZsdodJZtdpdKZudqdLZvdrdMZw	 	 	 	 	 	 dsdNZx	 dt	 	 	 	 	 	 	 dudOZydvdPZzdwdQZ{dxdRZ|dydSZ}dzdTZ~	 	 	 	 d{dUZd|dVZd}dWZd~dXZddYZ	 	 	 	 d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZZdd[Zed\k(  r e(j                   e              yy# e)$ rZ* e)d      e*dZ*[*ww xY w)u  
live_ibkr_trader.py
===================

V1 daily runner for the 4-regime VRP strategy on Interactive Brokers (``ib_insync``).

**Schedule:** Designed for cron ~**3:45 PM America/New_York** (adjust to your process).

**Mirrors** ``RenTech/strategy_stack/vrp_backtester.py``:
  - **Cash/Wait** if SPY **<** 200-day SMA (no new risk).
  - **R1–R4** by VIX when SPY **>=** SMA (R1 = weekly long strangle; R2 = R2a diagonal + R2b PCS; sleeve % from ``sleeve_risk_fractions.json``, same as ``vrp_backtest_theta.py`` / ``vrp_backtester``).

**Exits**
  - **Take profit:** GTC limit on the **closing** combo right after entry fill.
  - **Stop / time:** This script runs ``manage_open_positions()`` **before** entries; sends
    **Market** close on breach. Cancels the sibling GTC id when possible.

**State:** ``live_vrp_state.json`` in this directory.

**Audit:** ``--audit`` compares SPY option legs implied by state vs IB open positions (conId + signed qty)
and reports missing GTC order ids; optional ``--state-path``.

**Deps:** ``pip install ib_insync``

**Connect:** TWS / IB Gateway **paper** port **7497**, ``clientId=1``.

**Parity:** optional ``--strategy-config`` (default ``RenTech/strategy_stack/sleeve_risk_fractions.json``)
loads sleeve risk fractions + ``strategy_params`` into ``vrp_backtester`` module constants and re-syncs
this file’s mirrored constants + per-sleeve sizing (same JSON as ``vrp_backtest_theta.py``).

DISCLAIMER: Prototype / educational. Validate in paper. Not financial advice.
    )annotationsN)defaultdict)asdict	dataclass)datedatetime	timedelta)Path)AnyLiteral)ZoneInfo   )	IBComboLegContractIndex
LimitOrderMarketOrderOptionStockutilz(Install ib_insync: pip install ib_insync)DEFAULT_STRATEGY_CONFIG_PATH.apply_strategy_params_to_vrp_backtester_moduleload_strategy_config_file.sync_live_constants_from_vrp_backtester_moduleg      Y@{Gz?g      9@g      (@g      4@g      >@         ?g      g?g
ףp=
ǿ   -   g333333ӿg333333ÿg      I@g     b      g)\(̿{Gz?g         g)pmccdiagonal	r2_spreadnakedcredit_spreadr   _PARITY_CFGc                    t         ;t        t         j                  j                  |t                    }t        |       |z  S t        |       t        t              z  S )zHPer-sleeve risk budget (USD) from parity JSON or legacy single fraction.)r*   floatsleeve_risk_fractionsgetRISK_FRACTION_PER_TRADE)net_liqsleevefrs      C/opt/rentech/trading_bot/RenTech/strategy_stack/live_ibkr_trader.py_risk_budget_usdr4   s   sJ    ;4488AXYZW~"">E"9:::    zlive_vrp_state.jsonz	127.0.0.1iI     z15:40zAmerica/New_YorkRenTechdatalogszibkr_trade_recommendation.jsonzlive_signal_state.jsong      ?g?      ?x   c                d    ddt        j                  | t        j                  d      z        z   z  S )Nr         ?       @)matherfsqrtxs    r3   	_norm_cdfrD      s(    #TYYs^!34455r5   c                    |dk  r	|| k  rdS dS t        |d      }|t        j                  |      z  }t        j                  | |z        |d|z  |z  z   |z  z   |z  }t	        |      S )N:0yE>r=           -C6?r   maxr?   rA   logrD   spotstriket_yearsrateivsrtd1s          r3   bs_call_deltarT      sp    $tms,,	RB
tyy!
!C
((4&=
!TC"HrM%9W$D
D	KBR=r5   c                    |dk  r	|| kD  rdS dS t        |d      }|t        j                  |      z  }t        j                  | |z        |d|z  |z  z   |z  z   |z  }t	        |      dz
  S )NrF         rG   rH   r   r=   rI   rL   s          r3   bs_put_deltarW      su    $}t-#-	RB
tyy!
!C
((4&=
!TC"HrM%9W$D
D	KBR=3r5   c                  ^    e Zd ZU ded<   ded<   ded<   ded<   ded<   ded	<   ded
<   ded<   y)LegStateRichintconIdstractionratiosymbolexpiryr,   rN   rightentry_price_per_shareN)__name__
__module____qualname____annotations__ r5   r3   rY   rY      s+    JKJKKMJ  r5   rY   c                      t        t              S N)_load_state_path
STATE_PATHrg   r5   r3   _load_staterl      s    J''r5   c                @   | j                         sdg iS 	 t        | d      5 }t        j                  |      }d d d        t	        t
              rd|v r|S dg iS # 1 sw Y   #xY w# t        j                  t        f$ r}t        d| d       dg icY d }~S d }~ww xY w)N
strategiesutf-8encodingz[WARN] State read failed (z); using empty strategies.)	is_fileopenjsonload
isinstancedictJSONDecodeErrorOSErrorprint)pathfr8   es       r3   rj   rj      s    <<>b!!"$) 	 Q99Q<D	 !$-,$2Ft^\[]L^^	  	    '* "*1#-GHIb!!"s9   A' AA' A' A$ A' 'B BBBc                    t         j                  d      }t        |dd      5 }t        j                  | |d       d d d        |j                  t                y # 1 sw Y   xY w)N	.json.tmpwro   rp   r   indent)rk   with_suffixrs   rt   dumpreplace)r8   tmpr|   s      r3   _save_stater      sQ    

 
 
-C	c3	) %Q		$!$%KK
% %s   AA$c                   	 |j                         j                         }|j                  j                  dd       |j	                  d      }t        |dd      5 }t        j                  | |d       d	d	d	       |j                  |       y	# 1 sw Y   xY w# t        $ r}t        d
| d       Y d	}~y	d	}~ww xY w)zOPersist a lightweight runtime monitor snapshot for the standalone live website.Tparentsexist_okr   r   ro   rp   r   r   Nz*[WARN] Could not write live signal state ())
expanduserresolveparentmkdirr   rs   rt   r   r   ry   rz   )payloadout_pathoutr   r|   r}   s         r3   _write_live_signal_stater      s    A!!#++-

5ook*#sW- 	,IIgq+	,C	, 	,  A:1#Q?@@As0   AB B5B BB 	B=$B88B=c                   K   | j                          d{   }|D ]7  }|j                  dk(  s|j                  dv s"t        |j                        c S  t        d      7 Kw)z
    Read NetLiq using async-only IB calls.

    Calling ``ib.accountSummary()`` inside our running event loop triggers
    nested ``util.run(...)`` in ib_insync and raises:
    ``RuntimeError: This event loop is already running``.
    NNetLiquidation)USDBASEzNetLiquidation (USD) not found.)accountSummaryAsynctagcurrencyr,   valueRuntimeError)ibvalsavs      r3   get_net_liquidationr      sa      ''))D #66%%"++*H?"# 8
99	 *s   A$A"A$A$$A$c           	     |  K   | j                  |dddddd       d{   }t        |      d	k  r | j                  |dd
dddd       d{   }t        |      d	k  rt        dt        |       d      |D cg c]  }t        |j                         }}t        |dd       dz  }|d   }||fS 7 7 hc c}w w)zReturn (sma200, last_close). z2 Yz1 dayTRADESTr6   )endDateTimedurationStrbarSizeSetting
whatToShowuseRTH
formatDateN   z1 YzInsufficient SPY history: z barsi8g      i@)reqHistoricalDataAsynclenr   r,   closesum)r   spybarsbclosessmalasts          r3   get_spy_sma200r      s      ** +  D 4y3.." / 
 
 4y37D	{%HII&*+eAGGn+F+
fTUm
u
$C":D91
 ,s3   B<B3-B<B5.B<;B7B<5B<7B<c                   K   | j                  |ddd      }t        j                  |       d {    | j                  |       g }dD ]F  }t	        ||d       }	 t        |      }	|	dkD  r&t        j                  |	      s|j                  |	       H 	 t        |j                               }
|
dkD  r&t        j                  |
      s|j                  |
       t        |      dk\  rmt	        |dd       }t	        |dd       }	 t        |      t        |      }}|dkD  r7|dkD  r2t        j                  |      st        j                  |      sd||z   z  S |D ]  }	|	dkD  s	|	c S  |:	 t        |      }|dkD  r)t        j                  |      rt        d	| d
|d       |S t!        d|       7 }# t        t        f$ r Y xw xY w# t        $ r Y w xY w# t        t        f$ r Y w xY w# t        t        f$ r Y \w xY ww)Nr   F)r   r   bidaskr   r   r   r   r   z[WARN] No live snapshot for z; using fallback=.4fzNo price for )
reqMktDataasynciosleepcancelMktDatagetattrr,   r?   isnanappend	TypeError
ValueErrormarketPrice	Exceptionr   isfiniterz   r   )r   clabeltimeoutfallbackt
candidatesattrvfvmpr   abfaffbs                   r3   snapshot_pricer      s     	aUE*A
--
   Q J/ AtT"	qBAvdjjn!!"%1==?#6$**R.b! :!Aud#Aud#	1XuQxBAv"q&B

2b2g&  6I 	xBAv$--+4UG;LRPSHUV	 ug.
//O ! :& 		   :& 		 :& 		s   -G>F,)G>6F/G>AG (G> AG G>G>%8G) G>/G>G>GG>	GG>GG>G&#G>%G&&G>)G;8G>:G;;G>c
                  K   | j                  |       d{   }
|
st        d      |
d   j                  j                  }| j	                  ddd|       d{   }|st        d      t        |      }t        j                         }g }|j                  D ]_  }	 t        |dd       t        |dd	       t        |d	d
       }}}t        |||      |z
  j                  }|dkD  r|j                  ||f       a |st        d      |r|D cg c]  \  }}||vs||f }}}|st        d      t        |fd      \  }}t        t        |dd       t        |dd	       t        |d	d
             }t        d||z
  j                  dz        }t!        |      }|'|D cg c]  }t#        |      t#        |      k\  s| }}|	'|D cg c]  }t#        |      t#        |	      k  s| }}|st%        |j&                  D ch c]  }t#        |       c}      }|'|D cg c]  }t#        |      t#        |      k\  s| }}|	'|D cg c]  }t#        |      t#        |	      k  s| }}|rt%        |fd      }t%        |dd       }nt        d      t)        t+        |dd      xs d      j-                         }t)        t+        |dd      xs d      j-                         }ddi} |r|| d<   |r|| d<   d}!g }"|D ]  }t)        |      j/                         j1                  d      rt3        t#        |      ||!d      }nt5        t#        |      ||!d      }|"j                  t7        ||z
        t#        |      f        |"j9                  d        |rg }#|"dt:         D ]  \  }}t=        d|||dfi | }$| j?                  |$       d{   }%|%s|#j                  d| d       G|%d   }&| jA                  |&       d{   }'tC        jD                  d       d{    |'r|'d   nd}(|(|#j                  d| d        tG        |(      \  })}*}+},}-|)r|&c S |#j                  d| d!|* d"|+d#d$|,d#d%|-|-n
t#        d&      d#
        t        d'd(jI                  |#dd)       z         |D cg c]  }t=        d|||dfi |  }.} | j>                  |.  d{   }/|/st        d*       | j@                  |/  d{   }0tC        jD                  d+       d{    d}1tK        |/|0      D ]T  \  }2}3d}4|3jL                  r5|3jL                  jN                  t#        |3jL                  jN                        }4d}5|3jL                  r@|3jL                  jP                  r*t        t#        |3jL                  jP                        d,      }5n0|3jR                  r$|3jR                  dkD  rt#        |3jR                        }5|4mt)        |      j/                         j1                  d      r#t3        t#        |2jT                        ||!|5      }4n"t5        t#        |2jT                        ||!|5      }4t7        |4|z
        }6|1
|6|1d   k  sQ|6|2f}1W |1J |1d-   S 7 7 D# t        t        f$ r Y w xY wc c}}w c c}w c c}w c c}w c c}w c c}w 7 7 7 c c}w 7 7 7 íw).u   
    Pick qualified ``Option`` with delta closest to ``target_delta`` (puts: negative).
    Uses ``modelGreeks`` when populated; else Black–Scholes with IV from ticker or 0.25.
    NSPY contract details missingr   SPYr   STKNo option chain params         No future expiriesz.No future expiries after avoid_expiries filterc                &    t        | d   z
        S Nr6   absrC   
target_dtes    r3   <lambda>z#get_target_option.<locals>.<lambda>X      c!A$2C.D r5   keyg6qf?     v@c                     t        | z
        S ri   r   rC   rM   s    r3   r   z#get_target_option.<locals>.<lambda>i  s    c!d(m r5   y   z4No strike candidates left after strike bounds filtertradingClass
multiplierr   r   皙?C      ?c                    | d   S Nr   rg   rB   s    r3   r   z#get_target_option.<locals>.<lambda>}  s
    ad r5   SMARTzK=z:unqualified333333?z
:no_ticker::b=.2f:a=:m=nanzFNo qualifying liquid option candidate in recommendation mode; checked=;    z&qualifyContracts failed for candidates?rH   r6   )+reqContractDetailsAsyncr   contractr[   reqSecDefOptParamsAsync_pick_spy_chainr   todayexpirationsrZ   daysr   r   
IndexErrorminrJ   _strike_candidates_for_chainr,   sortedstrikesr\   r   stripupper
startswithrT   rW   r   sortDELTA_FALLBACK_CANDIDATESr   qualifyContractsAsyncreqTickersAsyncr   r   _leg_quote_qualityjoinzipmodelGreeksdelta
impliedVolimpliedVolatilityrN   )7r   r   rM   r   target_deltara   avoid_expiriesrecommend_only
min_strike
max_strikedetsuidchainschainr  expiriesexpymddter}   best_exp_exp_daterO   cand_kksfulltcmult
opt_kwargsrP   rankedcheckedoqoqtkstkokreasonr   r   midopts	qualifiedtickersbestopttickerdelta_mrQ   errs7     ``                                                   r3   get_target_optionrF  /  s      ++C00D9::
q'


 
 C--eRDDF344F#EJJLE&(H   	#bq'lCAaM3s1Qx=!qA1a=5(..CQwc
+ /00'/Ktq!1N3JQFKKKLLh$DEKHaC!%s8Aa='93x!};MNH)h.44u<=G)%6F#EuQx53D'D!EE#EuQx53D'D!EE7AuQx78!#E!uQx53D'DAEDE!#E!uQx53D'DAEDE$$;<DD#J'FUVV	WUNB/52	6	<	<	>BwulB/526<<>D",e!4J	%'
>"#'
< DF 9u:((-dE!HgtTBAT58WdDAAs1|+,eAh789 KKNK#556 	yDAquh5'HZHA..q11AA3l341B**2..C--%%%QDBzA3j12(:2(>%BS#	NNRs!F83s3is3s)3sdijodpruFvwx!	y" TW[W`W`ahiljlamWnn
 	
 OUUF5(AugDDUDU.b..55ICDD&B&&	22G
--
(,D9g. V&"4"4":":"FF..445G&"4"4"?"?U6--8894@B%%&*B*BQ*Fv//0B?5z!,,S1'eCJJ.?$PRS&tU3::->rR'L()<3a=:D!" 7Ng 1 E J' 		
 L FE 8EE: 2
 /% V5 3s*  [.ZA[.ZA[.AZ":[.Z8Z8#B[.%Z>Z>[.[+[/[.[[.%[[[.[+[/E'[.[5[.[[.)[*B[.<[ [.'[%(#[.[([.([+)E![.[.[."Z51[.4Z55#[.[.[. [.([.+[.c                  K   | j                  |       d{   }|st        d      |d   j                  j                  }| j	                  ddd|       d{   }	|	st        d      t        |	      }
t        |
|      }|D cg c]%  }t        |      t        |      k  st        |      ' }}|st        d      t        |fd	
      }t        t        |
dd      xs d      j                         }t        t        |
dd      xs d      j                         }ddi}|r||d<   |r||d<   |r|dt        dt        |             D ]  }t        d||ddfi |}| j                  |       d{   }|s/|d   }| j!                  |       d{   }t#        j$                  d       d{    |r|d   nd}|vt'        |      \  }}}}}|s|c S  t        d      d}|dt        dt        |             D ]4  }t        d||ddfi |}| j                  |       d{   }|s/|d   } n |t        d      |S 7 .7 c c}w 7 7 7 7 /w)z
    R2b long leg: **same expiry** as short; strike strictly below short; closest to ``ideal_long_strike``.
    Mirrors backtest ``_r2b_select_long_put_same_expiry``.
    Nr   r   r   r   r   r   z2No put strikes below short strike for R2b long legc                2    t        | t              z
        S ri   )r   r,   )r.  ideal_long_strikes    r3   r   z,get_r2b_long_put_on_expiry.<locals>.<lambda>  s    Q7H1I-I)J r5   r   r   r   r   r   <   Pr   r   z1No qualifying R2b long put in recommendation modeP   zCould not qualify R2b long put)r  r   r  r[   r  r  r
  r,   r  r\   r   r  r	  r   r   r  r  r   r   r  )r   r   rM   expiry_yyyymmddrI  short_striker  r   r!  r"  r#  r-  r.  belowr4  r1  r2  r3  r6  r7  r8  r9  r:  r;  r<  r   r   r=  best_os       `                        r3   get_r2b_long_put_on_expiryrQ    s     ++C00D9::
q'


 
 C--eRDDF344F#E)%6F%H!qE,4G)GU1XHEHOPPEJKF	WUNB/52	6	<	<	>BwulB/526<<>D",e!4J	%'
>"#'
< .#b#f+./ 	Auoq#wM*MA..q11A1B**2..C--%%%QDBz(:2(>%BS#		 NOO F*c"c&k*+ 5/1c7IjI**1--qTF ~;<<Ma 1 E
 I  2 /% .s   IIAII	,II$I1CI3I4 III1I2#IAI'I(I/I	IIIIIc           
     
  ,-K   | j                  |       d{   }|st        d      |d   j                  j                  }| j	                  ddd|       d{   }	|	st        d      t        |	      }
t        j                         }g }|
j                  D ]_  }	 t        |dd       t        |dd	       t        |d	d
       }}}t        |||      |z
  j                  }|dkD  r|j                  ||f       a |st        d      t        |fd      \  }}t        t        |dd       t        |dd	       t        |d	d
             }t        d||z
  j                  dz        -t!        |
      }t#        t%        |
dd      xs d      j'                         }t#        t%        |
dd      xs d      j'                         }ddi}|r||d<   |r||d<   d,|rt)        ,-fd|D        d       }t)        ,-fd|D        d       }dx}}|dd D ]5  \  }}| j+                  t-        d||ddfi |       d{   }|s0|d   } n |dd D ]5  \  }}| j+                  t-        d||ddfi |       d{   }|s0|d   } n ||Qt        d      |D cg c]  }t-        d||ddfi | }}|D cg c]  }t-        d||ddfi | } } | j*                  || z     d{   }!|!st        d       | j.                  |!  d{   }"t1        j2                  d       d{    d}#d}$t5        |!|"      D ]  \  }%}&t#        |%j6                        j9                         }'|'j;                  d      }(d})|&j<                  r5|&j<                  j>                  tA        |&j<                  j>                        })d }*|&j<                  r@|&j<                  jB                  r*t        tA        |&j<                  jB                        d!      }*n0|&jD                  r$|&jD                  dkD  rtA        |&jD                        }*|)G|(r#tG        tA        |%jH                        -,|*      })n"tK        tA        |%jH                        -,|*      })|(r tM        |)z
        }+|#
|+|#d   k  sa|+|%f}#gtM        |)z
        }+|$
|+|$d   k  s|+|%f}$ |#|$t        d"      |#d#   |$d#   }}tA        |jH                        tA        |jH                        k\  rt        d$      ||fS 7 7 # t        t        f$ r Y w xY w7 7 c c}w c c}w 7 ]7 <7 "w)%ug   
    Same listed expiry closest to ``target_dte``: long call (higher Δ) + long put (further OTM).
    Nr   r   r   r   r   r   r   r   r   r   c                &    t        | d   z
        S r   r   r   s    r3   r   z-get_weekly_strangle_options.<locals>.<lambda>  r   r5   r   r   r   r   r   r   r   r   c           
   3  |   K   | ]3  }t        t        t        |      d       z
        t        |      f 5 ywr   N)r   rT   r,   ).0r.  call_target_deltarP   rM   rO   s     r3   	<genexpr>z.get_weekly_strangle_options.<locals>.<genexpr>&  s:     uijc-eAhtDGXXY[`ab[cdu   9<c                    | d   S r   rg   rB   s    r3   r   z-get_weekly_strangle_options.<locals>.<lambda>'  
    !A$ r5   c           
   3  |   K   | ]3  }t        t        t        |      d       z
        t        |      f 5 ywrU  )r   rW   r,   )rV  r.  put_target_deltarP   rM   rO   s     r3   rX  z.get_weekly_strangle_options.<locals>.<genexpr>*  s:     sghc,tU1XwdCFVVWY^_`YabsrY  c                    | d   S r   rg   rB   s    r3   r   z-get_weekly_strangle_options.<locals>.<lambda>+  r[  r5   (   r   r   rK  z6Could not resolve strangle legs in recommendation modez/qualifyContracts failed for strangle candidatesr   r   rH   zCould not resolve strangle legsr6   z.Strangle requires put strike below call strike)'r  r   r  r[   r  r  r   r  r  rZ   r  r   r   r  r	  rJ   r
  r\   r   r  r  r  r   r  r   r   r  ra   r  r  r  r  r,   r  r  rT   rN   rW   r   ).r   r   rM   r   rW  r]  r  r   r!  r"  r#  r  r$  r%  r&  r'  r(  r)  r*  r+  r,  r-  r1  r2  r3  ranked_cranked_pc_optp_optr.  r7  opts_copts_pr?  r@  best_cbest_prB  rC  r0is_callrD  rQ   rE  rP   rO   s.     ````                                      @@r3   get_weekly_strangle_optionsrj    sv     ++C00D9::
q'


 
 C--eRDDF344F#EJJLE&(H   	#bq'lCAaM3s1Qx=!qA1a=5(..CQwc
+ /00h$DEKHaC!%s8Aa='93x!};MNH)h.44u<=G)%6F	WUNB/52	6	<	<	>BwulB/526<<>D",e!4J	%'
>"#'
< Duntu
 slrs
 SbM 	DAq..veXq#w/eZd/effA!		
 SbM 	DAq..veXq#w/eZd/effA!		
 =EMWXXRXYQ&!S'HZHYYRXYQ&!S'HZHYY2"22Vf_FF	PQQ***I66mmC   .2.2y'2 	(KCSYY%%'BmmC(GG!!f&8&8&>&>&J 2 2 8 89B!!f&8&8&C&Cv11<<=tD))f.F.F.J6334+D%

2CWdTVWG*4szz1BGTSUVG'$556>S6!9_!3ZF'$445>S6!9_!3ZF/	(0 >V^@AAay&)uU\\eELL11KLL5>A 1 E J' 		: g
 g ZYF 7 s   UT!AUT$ AU"AT'>EUT=U5UU U	U%U<UUU0U1#UUU1U2E3U'UAU$U'T:6U9T::U UUUUc                    | D cg c]6  \  }}}t        t        |j                        ||j                         d      8 }}}}t	        dddd|      S c c}}}w )Nr   )r[   r^   r]   exchanger   BAGr   )r_   secTyperl  r   	comboLegs)r   rZ   r[   r  r   )legsr6  r   rclss        r3   	build_bagrs  d  s`      Aq! 	s177|1QWWYQC  5%'E]`aa	s   ;Ac           
     P   | st        d      | D cg c],  }t        t        |dd            j                         dk(  s+|. c}xs t	        |       }dd}ddh}|D ]I  }t        t        |dd      xs d      j                         j                         }||v s> ||      sG|c S  |D ]]  } ||      st        t        |dd      xs d      j                         j                         }|r|j                  d	      rV|d
v r[|c S  |D ]  } ||      s|c S  |d   S c c}w )z
    Prefer standard SPY option classes; avoid odd adjusted classes (e.g. 2SPY)
    that often fail qualification for generic strike grids.
    r   rl  r   r   c                Z    t        t        | dd      xs d      j                         }|dv S )Nr   r   >   r   100)r\   r   r  )r   r'  s     r3   mult_okz _pick_spy_chain.<locals>.mult_oku  s.    <,2399;Kr5   r   SPYWr   )
0123456789>   2SPYr   )r   r   returnbool)r   r\   r   r  listr  r  )r"  r   smartrw  preferred_tcr1  s         r3   r  r  l  s=   
 344U1#gaR&@"A"G"G"IW"TQUeY]^dYeE  6?L NB/526<<>DDF'!*H  qzNB/526<<>DDFR]]#UV>  1:H 8O5 Vs
   ,D#D#c           
     0   t        | j                  D ch c]  }t        |       c}      }dz  dz  }}|D cg c]  }||cxk  r|k  sn n| c}xs |}t        |      dk  r|S t        t	        ||dd       D 	ch c]  \  }}	|	|z
  dkD  st        |	|z
  d       c}	}      }
|
s|S |
d   }d	|cxk  rd
k  r.n n+|D cg c]  }t        |t        |      z
        dk  s|! }}nmd|cxk  rdk  rbn n_|D cg c]  }t        |t        |      z
        dk  s|! }}|xs1 |D cg c]%  }t        t        d|z        d|z  z
        dk  s$|' c}}t        |fd      }t        |dd       S c c}w c c}w c c}	}w c c}w c c}w c c}w )zfStrike list near spot; drop half-dollar strikes when the chain is on a $1 grid (reduces IB error 200).g?g?r   r6   Nư>r   r   gGz?g)\(?r   g\(\?gRQ?c                     t        | z
        S ri   r   r   s    r3   r   z._strike_candidates_for_chain.<locals>.<lambda>  s    c!d(m r5   r   =   )r  r  r,   r   r  roundr   )r#  rM   r/  r  lohir.  candr   r   gapsstepintss    `           r3   r
  r
    s   61eAh67GD[$+B0!"-R-A0;GD
4y1}s4ab/BUtq!q1uPTn5Q?UVD7Dtt<a3q58|#4t#;<<			<a3q58|#4t#;<<L4La3uQU|a!e/C+Dt+KL$34D$s)# 70 V
 = =Ls@   E9E>E>F
F
F	'F	 F F.%FFc                   t        | j                  xs d      t        | j                  xs d      }}|dkD  r7|dkD  r2t        j                  |      rt        j                  |      rd||z   z  S dD ]9  }t        | |d       }	 t        |      }|dkD  rt        j                  |      r|c S ; 	 t        | j                               }|dkD  rt        j                  |      r|S y # t        t        f$ r Y w xY w# t        $ r Y y w xY w)Nr   r   )r   r   )
r,   r   r   r?   r   r   r   r   r   r   )r:  r   r   r   r   r   r   s          r3   _opt_mid_from_tickerr    s    1uRVV[q1qA1uQ4==+a0@a!e}! Bd#	qBAv$--+	2>>#$6dmmB'I  :& 		  s$   &C$.4C9 $C65C69	DDc                    	 t        | j                  xs d      }	 t        | j                  xs d      }t	        |       }t        j                  |      r$t        j                  |      r|dkD  r
|dkD  r||kD  sdd|||fS |t        k  rddt         |||fS ||z
  }|t        t        |xs d      d      z  }|t        kD  rddt         |||fS |t        kD  rddt        d	|||fS d
d|||fS # t        $ r d}Y w xY w# t        $ r d}Y w xY w)z#Return (ok, reason, bid, ask, mid).rG   r   Fmissing_bid_askzbid_too_small<r  zspread_abs>zspread_pct>r   Tr;  )r,   r   r   r   r  r?   r   MIN_LEG_BID_USDrJ   r   MAX_LEG_SPREAD_ABS_USDMAX_LEG_SPREAD_PCT)r:  r   r   r=  sprspr_pcts         r3   r  r    sA   BFFMc"BFFMc" r
"CMM#4==#5#'cAgRUX[R[(#sC88
_'893SII
)CCCJ3..G
##%;$<=sCMM##%7$<=sCMM$S#&&#    s"   C. C? .C<;C<?DDc                    t        t        | j                        t        |j                        z
        t        z  }t	        t        |      d      t        z  }t	        t        ||z         t
              S )u   
    Conservative 1-lot diagonal risk proxy aligned to backtest ``TwoLegSpreadPosition.max_margin``:
      width*100 + max(0, debit_paid)
    where debit_paid ≈ combo_mid_per_share*100 when entry action is BUY.
    rG   )r   r,   rN   CONTRACT_MULTIPLIERrJ   SIZING_MIN_MAX_RISK_USD)	short_putlong_putcombo_mid_per_share	width_usd	debit_usds        r3   _diag_risk_per_contract_usdr    s]     E)**+eHOO.DDEH[[IE-.47JJIuY*+-DEEr5   c                  K   |D cg c]  \  }}}|
 }}} | j                   |  d{   }t        j                  d       d{    d}d}g }t        ||      D ]  \  \  }}	}
}t	        |      \  }}}}}|Lt        d|j                  xs |j                   d|j                   d|j                   |j                         |j                   d|j                   t        |j                        d}|j                  | d| d	|d
d|d
d|d
	       |sd}t        |
      }|	j                         dk(  r	|||z  z  }|||z  z  } | }|dd||fS c c}}w 7 57 w)u   
    Signed combo mid from leg mids (matches typical IB BAG sign: credit → negative mid when entry is SELL).
    Returns (mid, 0.0, 0.0, liquid_ok, leg_notes).
    N333333?rG   TzLeg mid unavailable for  z.1fr   r   r   r   r   FSELL)r  r   r   r  r  r   localSymbolr_   lastTradeDateOrContractMonthrN   ra   r,   r   rZ   r  )r   openedr6  r+  r>  r@  net	liquid_oknotesactr^   r:  r;  r<  r   r   r'  leg_lblrq  r=  s                       r3   _synthetic_combo_midr    s     $$'!QA$D$&B&&--G
--

CIE"673 C"4R"8FCa9!9!--:S1889TTUVWVtVtUuuvwxww  wA  BC  BI  BI  AJ   K  L  L334AaggYuQXXs>STy&SISS	QsGLMIJ99;& 1q5LC1q5LC $CS)U**) %-s,   E%EE%EE%E"DE%"E%c                  K   | j                  |ddd      }t        j                  d       d{    t        |dd      t        |dd      }}	 |t	        |      n
t	        d      }	 |t	        |      n
t	        d      }t        j                  |      xr< t        j                  |      xr% t        |      dkD  xr t        |      dkD  xr ||kD  }|r	d	||z   z  }	n't	        |j                  xs |j                  xs d
      }	| j                  |       |r7t        j                  |	      r"t        |	      dkD  r|	||dd|dd|dd|	dgfS |r`	 t        | |       d{   \  }
}}}}t        j                  |
      r0t        |
      dkD  r"|rdnd}t        d|	 d|
dd|        |
||||fS t        j                  |	      rt        |	      dk  r#|j                  s|j                  st        d      |	||dd|	dgfS 7 # t
        $ r t	        d      }Y w xY w# t
        $ r t	        d      }Y w xY w7 # t
        $ r}t        d|        Y d}~d}~ww xY ww)zgReturn (mid, bid, ask, quality): quality in {"live_bag_mid", "synthetic_fallback", "stale_last_close"}.r   Fr:   Nr   r   r   rF   r   rG   live_bag_midzbag_two_sided:b=r   r   r   synthetic_liquidsynthetic_fallbackz&[WARN] BAG quote missing/invalid (mid=z); using synthetic mid=r   z	 quality=z#[WARN] Synthetic combo mid failed: zCombo mid unavailablestale_last_closezbag_last_close_only:m=)r   r   r   r   r,   r   r?   r   r   r   r   r   r  rz   r   )r   bagr  r   bid_rawask_rawr   r   bag_has_two_sidedr=  smsbsar  r  r7  r}   s                    r3   combo_quote_midr    s     	c2ue,A
--
q%.5$0GWG ' 3eGnu ' 3eGnu
 	c 	MM#	HtO	 HtO	 #I  S3YAFF,agg,-ST]]3/CHtOCn1A#c#cRUYVYZ]^aYb/c.ddd	=1Eb&1Q+Q(BB	5}}R SWt^*3&9M>seCZ[]^aZbbklmknop2r1e++ ==ST!1!''677S,1GCy/Q.RRRK   El  El& ,R
  	=7s;<<	=s   -I"HI"H (H!  CI"H> !H<"AH> 0AI"HI"HI"!H95I"8H99I"<H> >	III"II"c                    d}| D ]  }|j                  |j                  d      }|j                  }|j                  j	                         dk(  r |||z
  t
        z  |j                  z  |z  z  }h|||z
  t
        z  |j                  z  |z  z  } |S )NrG   r  )r.   r[   rb   r]   r  r  r^   )rp  midsqtytotallegr=  ents          r3   unrealized_pnl_dollarsr  )  s    E Ihhsyy#&''::'cCi#66BSHHEcCi#66BSHHEI Lr5   c           	     .  K   g }|D ]]  }t        |j                  |j                  |j                  |j                  dd      }|j
                  |_        |j                  |       _  | j                  |  d {   }t        j                  d       d {    i }t        ||      D ]  \  }}t        |j                  xs d      t        |j                  xs d      }	}|dkD  r|	dkD  rd||	z   z  ||j
                  <   X|j                  r2|j                  dkD  r#t        |j                        ||j
                  <   |j                  r2|j                  dkD  r#t        |j                        ||j
                  <   d||j
                  <    |S 7 7 w)Nr   r   r   r  r   r   rG   )r   r_   r`   rN   ra   r[   r   r  r   r   r  r,   r   r   r   r   )
r   rp  r>  r  r6  r@  r   r:  r   r   s
             r3   leg_midsr  5  sT    D 
JJJJJJII
 ))A
 'B&&--G
--
CtW% 	!RRVV[q!51#51q5QU AE]C		NWW1"277^C		NXX"((Q,"288_C		N C		N	! J .s%   A7F9F:FFC:FFc                $   	 | j                         D ]F  }|j                  j                  |k(  s| j                  |j                         t	        d|         y  t	        d| d       y # t
        $ r}t	        d| d|        Y d }~y d }~ww xY w)Nz)[ORDER] Cancelled GTC / working order id=z[WARN] No open order id=z
 to cancelz[WARN] cancel order : )
openTradesorderorderIdcancelOrderrz   r   )r   order_idtrr}   s       r3   _cancel_order_by_idr  R  s    6--/ 	Bxx8+rxx(A(LM		
 	(
*=> 6$XJb4556s"   ,A+ *A+ A+ +	B4B

Bc           	       K   g }|D ]  }t        |j                  |j                  |j                  |j                  dd      }|j
                  |_        | j                  |       d{    |j                  j                         dk(  rdnd}|j                  |||j                  f        t        |      }t        |j                  d            }	|	rdnd}
| j                  |t        |
|            }t!        d|
 d	| d
       y7 w)zXFlip each leg action; BUY to close credit-opened strategies, SELL to close debit-opened.r   r   r  Nr  BUYentry_was_debitz[ORDER] Emergency close  xz on BAG)r   r_   r`   rN   ra   r[   r  r]   r  r   r^   rs  r  r.   
placeOrderr   rz   )r   rawrp  r  closingr  r6  car  entry_debitr  r+  s               r3   close_strategy_marketr  ^  s     -/G +JJJJJJII
 ))&&q)))jj&&(F2U2syy)*+ G
Csww012K&UC
c;sC01A	$SEC5
89 	*s   A&D
(D)B D
c                  K   g }|j                  dg       D ]  }	 |d   D cg c]u  }t        t        |d         t        |d         t        |d         t        |d         t        |d         t	        |d         t        |d	         t	        |d
               w }}t        |d         }t        j                  |d         }t	        |d         }	t        | |       d{   }
t        ||
|      }||k\  }||	k  }|s|s|j                  |       |rdnd}t        d|d    d|d    d| d|dd|	d
       t        | |||       d{    |j                  d      }|t        | t        |             t        j                  d       d{     ||d<   t!        |       yc c}w 7 7 d7 !# t        $ r}t        d|        Y d}~d}~ww xY ww)z)Stops & time stops only (GTC handles TP).rn   rp  r[   r]   r^   r_   r`   rN   ra   rb   r[   r]   r^   r_   r`   rN   ra   rb   r  time_stop_datesl_threshold_unrealizedN	time_stop	stop_lossz
[EXIT] id=id regime=regimer  z pnl=$z,.0fz thr=$gtc_order_idr=   z$[ERROR] Dropping corrupt state row: )r.   rY   rZ   r\   r,   r   fromisoformatr  r  r   rz   r  r  r   r   r   r   )r   r8   r  keptr  rC   rp  r  ts_endsl_thrr  pnltime_hitstop_hitr   gtcr}   s                    r3   manage_open_positionsr  v  s	    !#Dxxb) +*	 V  aj/q{+aj/q{+q{+ 8-aj/*/2I0J*K	D  c%j/C'',<(=>F389:F!"d++D(tS9CHf}HHC !)+{CSYKxHau EDzt}6
 (Cs;;;''.)C#BC1--$$$O+Z DY" , <
 % 	8<=	s~   GF6A:F+AF6"F0#0F6G9F6F2AF6F4F6G+F62F64F66	G?GGGGc                4   i }t        t              }| j                  dg       D ]e  }t        |j                  dd            }t        |j                  dd            }t	        |j                  dd            }|j                  dg       D ]  }t	        |d         }t	        |j                  d	d            }	t        |j                  d
d            j                         }
|
dk(  rt        ||	z        nt        ||	z         }|j                  |d      |z   ||<   |j                  dd       d|j                  dd       d|j                  dd       |j                  dd       d|
 d|	 
}||   j                  | d| d|         h |t        |      fS )z
    From ``live_vrp_state.json`` strategies, compute net IB-style position per conId
    (long +qty contracts, short -qty) for each leg.
    rn   r  ?r  r  r6   rp  r[   r^   r]   r   r  rG   r_   r  r`   rN   ra      ×/r  )	r   r  r.   r\   rZ   r  r,   r   rw   )r8   expectedr  r  sidregr  rC   cidr^   r  inc	leg_labels                r3   )_expected_spy_option_positions_from_stater    s    "$H"-d"3Exxb) ;#''$$%#''(C()#''%#$$ 
	;Aaj/Cgq)*EaeeHb)*002C(+u%e$5u;M:MC$LLc2S8HSM552&'qx)<(=QquuXr?R>STUTYTYZaceTfSggh%r%"  #JQse2i[9:
	;	; T%[  r5   c                   i }i }i }| j                         D ]  }|j                  }t        |t              s t	        |j
                  xs d      }|dk  r?t        |j                        }t        |      dk  rc|||<   t        t        |dd      xs d      }|dk(  r|j                  |d      |z   ||<   |||<    |||fS )z_SPY option conId -> position, other symbols' options -> position, conId -> contract for labels.r   g&.>r_   r   r   rG   )	positionsr  rv   r   rZ   r[   r,   positionr   r\   r   r.   )	r   r   other	contractspr   r  possyms	            r3   _ib_spy_option_position_mapsr    s    C E#%I\\^ JJ!V$!'',Q!8AJJs8d?	#'!Xr*0b1%<wwsC(3.CHE#J  y  r5   c                    | j                         D ch c]!  }t        |j                  j                        # c}S c c}w ri   )r  rZ   r  r  )r   r  s     r3   _open_order_idsr    s+    ,.MMO<bC  !<<<s   &<c                 K   t        |      }t        |      \  }}t        |       \  }}}t        |       }d}	g }
g }t	        d       t	        d|j                                 t	        dt        |j                  dg                     t	        dt        |              t	        d       t        t        |      t        |      z        }|D ]  }t        |j                  |d            }t        |j                  |d            }t        ||z
        |	k  rd}nd	}|
j                  d
| d|dd|d       |j                  |      }d}|Cd|j                  xs |j                   d|j                   d|j                    |j"                   }||v r!dj%                  |j                  |g             nd}t	        d| d| |        t	        d|dd|dd|         |rt	        d       t	        dt        |       d       t        |j'                         d d      D ]l  \  }}|j                  |      }|r4|j                   d|j                   d|j                    |j"                   n
t)        |      }t	        d| d|d d!|        n t	        d       t	        d"       d#}|j                  dg       D ]  }|j                  d$      }|d}t+        |      }||v }|rd%nd&}|s9|j                  d'| d(|j                  d)       d*|j                  d+       d,       t	        d| d-|j                  d)       d*|j                  d+       d.|         |st	        d/       |j                  d      s|st	        d0       t	        d       |r-t	        d1t        |       d2       |D ]  }t	        d3|         |
r.t	        d4t        |
       d5       |
D ]  }t	        d3|         y6t	        d7       y8w)9z
    Print comparison of state-file strategies vs IB SPY option positions (by conId).
    Returns 0 if SPY legs align within tolerance, else 1.
    r   H========================================================================z# IB vs state audit  |  state file: z State strategies: rn   z, IB SPY option positions (non-zero conIds): rG   OKMISMATCHzconId=z state=r   z ib=r   r  r   z(not in state)z  [z] conId=z         state_net=z+.4fz	  ib_net=z  |  zH------------------------------------------------------------------------z# Non-SPY option positions at IB (n=z); not compared to VRP state:c                    t        | d         S r   r   )kvs    r3   r   z$run_ib_state_audit.<locals>.<lambda>	  s    BqE
 r5   T)r   reversez	   conId=z pos=z+.2fz  z= GTC take-profit orders referenced in state vs IB openTrades:Fr  OPENMISSINGzgtc_order_id=
 strategy=r  r  r  u9    (not in openTrades — filled/cancelled or stale state?)z] strategy id=z gtc_order_id=z.  (no gtc_order_id fields in state strategies)z3  (no state strategies and no SPY option inventory)z
WARNINGS (z):z  - u!   AUDIT FAILED — position drift (z issue(s)):r6   z7AUDIT OK: SPY option legs match state within tolerance.r   )rj   r  r  r  rz   r   r   r.   r  setr,   r   r   r  r_   r  rN   ra   r  itemsr\   rZ   )r   
state_pathr8   r  	exp_notesib_spyib_otherib_contractsopen_idstolissuesgtc_warningsall_cidsr  r}   gr   r   c_labnoter  labany_gtcr  oidoid_ir;  stlines                                r3   run_ib_state_auditr%    s)    
 J'DCDIHi%A"%E"FHlr"H
CF L	(O	/
0B0B0D/E
FG	DHH\2$> ?@
AB	8V
FG	(Oc(mc&k12H J(,,sC()&**S#&'q1u:CCMMF3%wqgT!CABS!=12!A4R4R3SSTUVU]U]T^_`_f_f^ghE4794DtyysB/0JZC5eW-.#Ad89QtHE$HIJ  h3CM?B_`ax~~/5JTXY 	;HC  %AXYQXXJa > >?q
177)T_bcf_gCIcU%DzC59:	;
 
(O	
IJGxxb) gggn%;ChVywjxPXHYGZ [K K 	B4~cggdm_HSWWX=N<O~^c]defg >?88L!&CD	(O
3|,-R01  	!DD- 	!1#f+kJK 	!DD- 	!	
CDs   O?Pc                @    | t         k  ry| t        k  ry| t        k  ryy)Nr%   r&   r(   r)   )
VIX_R1_MAX
VIX_R2_MAX
VIX_R3_MAX)vixs    r3   regime_from_vixr+  3  s&    
Z
j
jr5   c
                H"  K   |j                  d      r|s|	st        d       yt        j                         }
g }t        }|dk(  rGt        |d      }t        | ||t        t        t        |       d{   \  }}|ddf|ddfg}t        }n|dk(  rt        |d      }t        | ||t        t        d	|       d{   }t        t        |j                        h      }t        | ||t         t"        d	||
       d{   }t%        |j&                  xs d      t%        |j&                  xs d      k(  rt        d       yt        |j                        t        |j                        k(  rt        d       y|ddf|ddfg}t(        }n|dk(  r3t        |d      }t        | ||t*        t,        d	|       d{   }t/        dt1        t3        |      t3        t4              z              }t3        |j6                        |z
  }t9        | ||t        |j                        |t3        |j6                        |       d{   }t        |j                        t        |j                        k7  rt        d       yt3        |j6                        t3        |j6                        k\  rt        d       y|ddf|ddfg}t:        }n|dk(  r;t        |d      }t        | ||t<        t>        d	|       d{   }|ddfg}t@        }n`t        |d      }t        | ||tB        tD        d	|       d{   }t        | ||tB        tF        d	|       d{   }|ddf|ddfg}tH        }|D ]  \  }}}| jK                  |       d{    ! tM        |      }	 tO        | ||       d{   \  }}}}}tS        jT                  |      rtW        |      dkD  s/|r|dk(  rd}d}dg}t        d|dd       nt        d | d!       yd}d"} d"}!|dk(  r^tW        |      tX        z  }"|"d#k  rt        d$       y|"}!t/        dt%        tS        jZ                  ||"z                    }t\        |"z  |z  } nq|dk(  rU|d   d   |d   d   }}t_        |||      }#|#}!t/        dt%        tS        jZ                  ||#z                    }t`        |z  } n|dk(  r|d   d   |d   d   }}tW        t3        |j6                        t3        |j6                        z
        }$|dk  rt/        | d"      tX        z  nt/        |d"      tX        z  }%t/        |$tX        z  |%z
  tb              }&|&}!t/        dt%        tS        jZ                  ||&z                    }d%|&z  |z  } nQ|dk(  r|dk  rt/        | d"      tX        z  nt/        |d"      tX        z  }%|%d#k  rt/        d&tX        z  d      }%t/        d'|%z  d      }'|'}!t/        dt%        tS        jZ                  ||'z                    }td        |%z  |z  } n|d   d   |d   d   }}tW        t3        |j6                        t3        |j6                        z
        }$|dk  rt/        | d"      tX        z  nt/        |d"      tX        z  }%t/        |$tX        z  |%z
  tb              }&|&}!t/        dt%        tS        jZ                  ||&z                    }d%|&z  |z  } |#t%        |      dkD  rtg        |t%        |            }|!r|!dkD  rt3        |      t3        |!      z  n
t3        d(      }(|dk(  xr |(t3        th              k  })|dkD  rdnd}*d)}+t1        |*dk(  r||+z   n||+z
  d*      },|rg }-|D ]p  \  }}.}/|-jk                  |jl                  |j                  |jn                  t3        |j6                        |.t%        |/      t%        |j&                  xs d      d+       r i d,d-d.|d/vrd0n|)rd1nd2d3tq        jr                         ju                         jw                         d4|d5t3        |      d6t3        |      d7t3        |      d8tS        jT                  t3        |!            rt3        |!      dkD  rt3        |!      ndd9t3        th              d:tS        jT                  t3        |(            rt3        |(      ndd;|d<tS        jT                  t3                    rt3        |      ndd=tS        jT                  t3                    rt3        |      ndd>|d?|*d@t3        |,      dAt3        |      |)s|d/vrdn
t%        |      |t%        |      nd|)s|d/vrd"n
t3        |       t%        |      |d/vrdBndCdD|ddE|!d|-dF}0ty        jz                  |0d*G      }1t        dH       t        |1       |_|j}                         j                         }|j                  j                  dIdIJ       |j                  |1dKz   dLM       t        dN|        y|)r t        dO|dPdQ|!dPdR|(dSdTth        d       yd}2|}3t        dU      D ]x  }4t1        |*dk(  r||+z   n||+z
  d*      }5tS        jT                  |5      st        dV|5 d!        yt        |*|3|5dWdXY      }6t        dZ| d[|* d\|3 d]|5 d^|dd_       | j                  ||6      }2t        d`      D ]9  }t        j                  d       d{    |2j                  j                  dav s9 n |2j                  j                  dbk(  r|3} ndcj                  dd t        |2deg       xs g D              }7df|7v xs dg|7v xs dh|7j                         v }8|8r+|3dkD  r&t/        d|3d*z        }9|9|3k  r|9}3t        di|3        Wt        dj|2j                  j                           y |2J t3        |2j                  j                        }:t        dk|:dldm       g };|D ]  \  }}.}/| j                  |       d{   d   }<t        j                  dn       d{    t3        |<j                  xs d      t3        |<j                  xs d      }>}=|=r
|>rdo|=|>z   z  n&t3        |<j                  xs |<j                  xs d      }?|;jk                  t        t%        |j&                        |.|/|jl                  |j                  t3        |j6                        |jn                  |?p              |*dk(  }@|dk(  rAtW        |:      tX        z  |z  }At\        |Az  } t1        tW        |:      dt        z   z  d*      }Bd}Cn |dk(  rst3        t`              |z  } |*dk(  }@|@r#t1        tW        |:      dt        z   z  d*      }Bd}Cnt/        |: d"      }D|Dt        tX        z  z
  }Et1        t/        |Ed&      d*      }Bd}Cn|dk(  rt/        |: d"      tX        z  }%tW        t3        |d   d   j6                        t3        |d   d   j6                        z
        }$t/        |$tX        z  |%z
  tb              }Fd%|Fz  |z  } t1        t/        |: dt        z
  z  d&      d*      }Bd}CdX}@n|dk(  rGt/        |: d"      }G|GtX        z  }Htd        |Hz  |z  } t1        t/        |Gdt        z
  z  d&      d*      }Bd}CdX}@nt/        |: d"      tX        z  }%tW        t3        |d   d   j6                        t3        |d   d   j6                        z
        }$t/        |$tX        z  |%z
  tb              }Fd%|Fz  |z  } t1        t/        |: dt        z
  z  d&      d*      }Bd}CdX}@|D IJKcg c]  \  }I}J}K|I|Jdk(  rdndKf }L}J}I}KtM        |L      }Mt        C|BdqdXY      }N| j                  |M|N      }Ot        j                  do       d{    Oj                  j                  }Pt        t        j                               ddr }Q|Q|||;D Rcg c]  }Rt        |R       c}R|
jw                         |
t        |s      z   jw                         t3        |:      @t3        |       t%        P      t3        B      Cdt}0|j                  dg       jk                  |0       t        |       t        du|C d\| d]|B dv|P dwQ 
       y7 =7 7 7  7 }7 7 7 w7 H7 (# tP        $ r1}|r#|dk(  rd}d}d| g}t        d| d|dd       n Y d}~Ud}~ww xY w7 7 7 c c}K}J}Iw 7 `c c}Rw w)xa}  
    Build the regime structure, send limit @ mid (slight price improvement), wait for fill,
    persist JSON state, and rest a GTC take-profit on the **closing** combo.

    IB combo sign convention (typical):
      * **Debit** (you pay): positive ``avgFillPrice`` on a **BUY** of the BAG.
      * **Credit** (you collect): negative ``avgFillPrice`` on a **SELL** of the BAG.
    rn   zO[SKIP] Strategy slot(s) already tracked in state; avoid stacking risk same day.Nr%   )r  r  r6   r&   rK  )r  r  r   z?[SKIP] Diagonal legs resolved to same contract; skipping entry.z7[SKIP] Diagonal legs share same expiry; skipping entry.r  r'   r=   z6[SKIP] R2b spread legs did not resolve to same expiry.z;[SKIP] R2b requires long put strike below short put strike.r(   r)   g{Gzr  z
exception:z7[WARN] Combo quote unavailable in recommend-only mode (z); using fallback mid=r   z for sizing ticket.r  invalid_combo_mid_fallbackz-[WARN] Invalid combo mid; using fallback mid=z for diagonal recommendation.z,[SKIP] Combo quote unavailable/invalid (mid=z); no entry order sent.rG   gMbP?z[SKIP] R1 strangle debit ~0rV   r#   g      @infr   r   )r_   r`   ra   rN   open_actionr^   r[   moder  decision)r  r  NO_QUOTESKIP_BUDGET_TOO_SMALLENTER
created_atr  net_liq_usd	spy_pricerisk_budget_usdrisk_per_contract_usd!min_budget_to_risk_ratio_for_1lotbudget_to_risk_ratioquote_qualitycombo_bid_per_sharecombo_ask_per_sharequote_notesentry_actionentry_limit_per_sharer  !requires_live_or_synthetic_liquidr;  z1qty=floor(risk_budget_usd/risk_per_contract_usd)=r  )proposed_qtymax_entry_qtystop_threshold_unrealized_usdtime_stop_daysquote_gate_reasonsizing_formularp  r   z[RECOMMENDATION]Tr   
ro   rp   z[RECOMMENDATION] wrote -> z+[SKIP] Budget too small for 1 lot: budget=$,.2fz, risk_per_contract=$z, ratio=z.3f <    z#[SKIP] Entry limit non-finite (lim=DAYF)tif
outsideRthz[ENTRY] z BAG r  z @ z (mid r   Z   )Filled	CancelledInactiverQ  r  c              3  N   K   | ]  }t        |j                  xs d         yw)r   N)r\   message)rV  les     r3   rX  z'place_entry_with_gtc.<locals>.<genexpr>A  s&      
 

 b!
s   #%rK   z	Error 201zInitial Marginzmargin requirementsz7[WARN] Margin rejection (qty); retrying entry with qty=z[WARN] Entry not filled: z[FILL] avgFillPrice=r   z" (signed: +debit / -credit per IB)g?r   r  GTCr   )r  )r  r  r  rp  opened_dater  entry_net_per_sharer  r  r  tp_limit_price_per_sharegtc_close_actionz	[GTC] TP z	 orderId=r  )ar.   rz   r   r  R1_TIME_STOP_DAYSr4   rj  R1_STRANGLE_DTER1_CALL_DELTAR1_PUT_DELTArF  R2_SHORT_DTER2_SHORT_DELTA	frozensetr\   r  R2_LONG_DTER2_LONG_DELTArZ   r[   R2_TIME_STOP_DAYSR2B_SHORT_DTER2B_SHORT_DELTArJ   r  r,   R2B_WIDTH_FRAC_OF_SPOTrN   rQ  R2B_TIME_STOP_DAYSR3_TARGET_DTER3_TARGET_DELTAR3_TIME_STOP_DAYSR4_SHORT_DTER4_SHORT_DELTAR4_LONG_DELTAR4_TIME_STOP_DAYSr  rs  r  r   r?   r   r   r  floor
R1_SL_FRACr  R2_SL_PER_CONTRACTr  
R3_SL_FRACr	  !MIN_BUDGET_TO_RISK_RATIO_FOR_1LOTr   r_   ra   r   now
astimezone	isoformatrt   dumpsr   r   r   r   
write_textranger   r  r   r   orderStatusstatusr  r   loweravgFillPricer  r   r   r   r   rY   
R1_TP_FRACR2_TP_PER_CONTRACTR2B_TP_FRAC
R3_TP_FRAC
R4_TP_FRACr  r  uuiduuid4r   r	   
setdefaultr   )Sr   r8   r  r0   r   spy_pxrD  r  recommendation_outignore_state_checkr  r  rF  target_riskcall_oput_oshortpavoidlongp	width_pts
ideal_longr   r6  r+  r  r=  _bid_askr<  r?  r}   r  r  r9  debit_per_unitdiag_risk_per_contractwidthcredit_per_unitmax_lossrpcr;  budget_too_smallr@  tickpreview_limitlegs_previewr  r^   rectxttradeattempt_qty
margin_trylimentrylog_textmargin_rejectnqavg
leg_statesr:  r   r   lmr  debit_totaltp_limit	close_actec
target_paymax_loss_percrprem_o_a_r
close_legsbag_cr  	gtc_tradegtc_idr  rC   sS                                                                                      r3   place_entry_with_gtcr  =  s    ( xxn=O_`JJLE,.F&N&w79V_m\Zh
 
 5!$ueQ&78*	:	&w
;(V\>3~
 
 3vBBCDE'V[-Ucq
 
 v|| q!S)9%::STv223s5;];]7^^KL61%ua'89*	;	&w<(V]OSQ_
 
 U5=59O3P#PQR	6==)I5
0334&-- )
 
 v223s5;];]7^^JK%"66OP61%ua'89+	7	&w8#V]OSQ_
 
 fa.!*&w@(V\>3~
 
 (V\=#n
 
 61%ua'89* *1a&&q)))* F
C
<KBPSU[<\6\3T4 MM#3s8d?f
2C0M78KA#cJghi@E\]^ CFS$77D /0 .!SK.$@ABCn,s2	:	q	!fQil!<VUC!P 6!SK2H$HIJK#c)	;	q	!fQilE&--(5+>>?BE(#sdC.+>>PSTWY\P]`sPsu22_DF]^ (!SK($:;<=3&	7	BE(#sdC.+>>PSTWY\P]`sPsT!!$)<"<cBO#'. #!SK#$5678o-3q	!fQilE&--(5+>>?BE(#sdC.+>>PSTWY\P]`sPsu22_DF]^ (!SK($:;<=3& S%7!%;#s=)* !%:Q%> 	kU#8995\ 
 axc$85Ab;c$c  !G5LD(=#*3:qQM-/# 	MAsEhh<<WW#AHHo#& Z A.
	
$
}<`'`  CSg~  Y`
 (,,.335??A
 f	

 5>
 v
 u[1
 $=='<!=>5I^C_bcCc +,
 07X1Y
 #4==QVWkQlCmE*>$?sw
 ]
  "$--d2L5;RV!
" "$--d2L5;RV#
$ ;%
& L'
( $U=%9)
* "5:+
, #3mKo6oAvyz}v~3@3LS/RV5E  _C  JCS  JO  PV  JW!.1IV  _C  JC"E  IMCKPSCTTUVkloUpq =
@ jjQ' !c
)"--/779AHHNN4$N7LLtgL6.qc239+d9K L""7!=XFZ[^E_ `2379	

 	EKAh !
,%"7C$JS4ZK}}S!7u<STU<cuQVWl^2k]#cU&QTUXPYYZ[\c5)r 	A--$$$  ''+NN	 ##x/C88 
eUB/52
 

 8# 98+9$(88 	
 [1_Qq()BK OP[}]^)%*;*;*B*B)CDEC!F 
!!..
/C	 S	)K
LM%'J 
3&&q))1-mmC   RVV[q!51#51ASAE]51IBHH1I+J!''lxx55QXXgg&(		

& #e+O#h!44s:k)SS:%56:		:	)*S0&%/SXz)9:A>HIcT3B03FFFJST2A6HI	;	sdC.+>>E&)A,--.vay|7J7J1KKL5#66HJab$s*cTS;%67>B		7	#s^''d"S(R3#34d;Q?	sdC.+>>E&)A,--.vay|7J7J1KKL5#66HJab$s*cTS:%56=qA	PVWW*"b"2fu&"=WJWj!E
YX5U
KCeS)I
--
__$$F
djjl
BQ
C$./q/( 9.#AALLN$Sz*#(=F$)(O%C 	OOL"%,,S1	Ii[3%s8*IfXZPSu
UVg






&


 	* 7] f
2C0M's+,KKA3Ndehildm  nA  B  C Cr %> * x X  0s  A0AD"2AB/3AAD":AB2;AAD"<AB5=B;AD"8AB89BAD">AB;?B1AD"0AB>1:AD"+AC,!AD"AC1AD"?AC AD"AC "AC
#
AC -]AD".AD
/AD"D
AD"ADAD"6AD7L#AD"AD1A	AD":AD;AAD"<AD
@B"AD"B2AD"B5AD"B8AD"B;AD"B>AD"CAD"CAD"CAD"C
AC C	ADC&ADC<AD"DADDAD"DAD"DAD"DAD"DAD"c                 2  K   t        d       t        dt        j                         j                         j	                                t        d       t        j                  d      } | j                  dt        t        dt         d       | j                  d	t        t        d
t                | j                  dt        t        dt         d       | j                  dt        t        dt         d       | j                  ddd       | j                  ddd       | j                  dt        d dt         d       | j                  ddd       | j                  dt        dd       | j                  dt        d d       | j                  dt        d d        | j                  d!dd"       | j                  d#t        t         d$t          d       | j#                         }|j$                  |j$                  j'                         nt(        }|j+                         rat-        |      at1        t.        j2                         t5        t6        j8                  t:                  t        d%|j=                                 nd at        d&|j=                          d'       t?               }	 |jA                  |jB                  t        |jD                        t        |jF                        d()       d {    t        d*|jB                   d+t        |jD                         d,t        |jF                                |jI                  d-       tK        |jL                        r|jO                          tQ        jR                  d.       d {    |jT                  (|jT                  j'                         j=                         nt        }tW        ||/       d {   }tY        |      t[        d0d1d2      }|j]                  |       d {    t_        d3d4d2      }	 |j]                  |       d {    	 tc        |       d {   }te        ||       d {   \  }	}
tg        ||d0|
7       d {   }tg        ||d3       d {   }t        d8|d9d:|d;d<|
d;d=|	d;d>|d;
       ti               }tk        jl                         }tK        |jn                        stq        |||       d {    nt        d?       t        j                  tr              }t        |jt                        jw                  d+d@      D cg c]  }t        |       c}\  }}|jy                  ||dAdAB      }tK        ||	k\        }tK        |jz                        xs tK        ||k\        }tK        |j}                  dC            }t        |      }t        i dD|j	                         dEtK        |jn                        dFtK        |j                        dGtK        |jz                        dHt        |jt                        dItK        |      dJt        |      dKt        |      dLt        |
      dMt        |	      dNtK        |      dOt        |      dPt        |      dQtK        |      dRt        t        |j}                  dCg                   dSt        t        j=                               dTt        |j                  j'                         j=                               t        |j                  j'                         j=                         j                  |j                  j'                         j=                         j                  dUz   |j                  j'                         j=                         j                  z               t        |j                  j'                         j=                         j                  |j                  j'                         j=                         j                  dVz   |j                  j'                         j=                         j                  z               gdW|sdXn|sdYn|rtK        |jn                        sdZnd[i       ||	k  rt        d\       tK        |j                        s.	 |j                         r|j                          t        d]       y y tQ        jR                  t        d^t        |j                                     d {    t        |      }t        d_|j                          d`|d;d       |j}                  dC      rt        dat        |dC          db       tK        |jz                        s||k  rt        dc|j                  dd       de|j                  df       dg       tK        |j                        s.	 |j                         r|j                          t        d]       y y tQ        jR                  t        d^t        |j                                     d {    |dhk(  r|j                  }|j                  }|j                  j'                         j=                         }tK        |jn                        rV|j                  |j                  dUz   |j                  z         }|j                  |j                  dVz   |j                  z         }t        ||dh||||j                  tK        |jn                        |i	       d {    t        ||dj||||j                  tK        |jn                        |d6k
       d {    tK        |jn                        r	 dAd lP}|j+                         r!|j                  |j                  dlm            nd }|j+                         r!|j                  |j                  dlm            nd }dEt        j                         j                         j	                         dhdnt        |t              r:|j}                  do      dpk(  r&t        |t              r|j}                  do      dpk(  rdpndqt        |      t        |      ||dr	}|j                  j                  d6d6s       |j                  |j                  |dtu      dvz   dlm       t        dw|        nCt        |||||||j                  tK        |jn                        |j                  i	       d {    tK        |j                        s.	 |j                         r|j                          t        d]       y y t        dy       tQ        jR                  t        d^t        |j                                     d {    	^7 
7 
7 	7 	7 	p# t`        $ r, t_        d3d4d25      }|j]                  |       d {  7   Y 	w xY w7 	7 	7 	o7 	]7 c c}w 7 7 7 7 # t        $ r}t        dx| d       Y d }~d }~ww xY w7 7 # t`        $ r*}t        dzt        |      j:                   d{|         d }~ww xY w# |j                         r|j                          t        d]       w w xY ww)|Nr  u    VRP live_ibkr_trader — startz,Run live VRP trader via Interactive Brokers.)descriptionz--hostzIB host (default: r   )typedefaulthelpz--portz1IB socket port (paper=7497, live=7496). Default: z--client-idzIB clientId (default: z--entry-after-etz:Only allow NEW entries after this ET time HH:MM (default: z).z--force-entry-now
store_truez:Bypass end-of-day time gate and allow immediate new entry.)r]   r  z--auditzYCompare live_vrp_state.json SPY option legs to IB open positions; then exit (no entries).z--state-pathz!State JSON for --audit (default: z--watchzDKeep process alive; poll until entry gate opens (then attempt once).z--poll-secondsrJ  z-Polling interval in watch mode (default: 60).z--max-entry-qtyz[Hard cap on contracts per new BAG entry (useful when IB initial margin blocks larger size).z--strategy-configz]Parity JSON (default: RenTech/strategy_stack/sleeve_risk_fractions.json if that file exists).z--recommend-onlyzTCompute and print/write recommended entry ticket only; never place/cancel IB orders.z--recommend-outz+Output JSON for --recommend-only (default: z[PARITY] Loaded z[PARITY] No config at u    — using built-in constants   )clientIdr   z[IB] Connected r   z
 clientId=   r:   )r  r   r   r   VIXCBOE)rl  r   T)r   z[DATA] NetLiq=$rJ  z  SPY(live)=r   z  SPY(last bar)=z	  SMA200=z  VIX=zX[RECOMMEND] recommend-only mode: skipping stop/time management (no live orders touched).r6   r   )hourminutesecondmicrosecondrn   r5  r  
watch_modeforce_entry_nowentry_after_etentry_time_gate_passr6  spy_livespy_last_barsma200spy_gt_sma200vix_live
regime_nowhas_open_state_positionsopen_state_position_countr  recommendation_paths_r2a_diagonal_r2b_spreaddecision_hint	WAIT_BEARWAIT_TIME_GATESKIP_HAS_STATEEVALUATE_ENTRYzYBear Market Detected (SPY < 200 SMA). Regime: Cash/Wait. No new positions will be opened.z[IB] Disconnected.rL  z	[REGIME] z (VIX=z[INFO] z2 strategy(ies) in state (GTC TP + SL/time checks).z[TIME] Entry gate active: now=z%H:%M:%S %ZrK  z%H:%M %Zz ; skipping NEW entries.r&   )rD  r  r  r'   )rD  r  r  r  ro   rp   R2_PAIRr1  r4  r2  )	r0  r5  r  	compositer1  r2a_filer2b_filer2ar2br   r   r   rI  z'[RECOMMENDATION] wrote aggregate R2 -> z4[WARN] Could not write aggregate R2 recommendation (zE[WATCH] Entry attempt complete; continuing to monitor open positions.z[FATAL] r  )[rz   r   rv  rw  rx  argparseArgumentParseradd_argumentr\   IB_HOSTrZ   IB_PORT	CLIENT_IDENTRY_AFTER_ETr
   rk   RECOMMEND_OUT_DEFAULT
parse_argsstrategy_configr   r   rr   r   r*   r   strategy_paramsr   sysmodulesrc   r   r   connectAsynchostport	client_idreqMarketDataTyper  auditreqPositionsr   r   r  r%  
SystemExitr   r  r   r   r   r   r   rl   r   r  r  r  NY_TZr  splitr   r  r.   r+  r   watchr,   r   recommend_out	with_namestemsuffixisConnected
disconnectrJ   poll_secondsr  strftimer  rD  rt   loads	read_textrv   rw   r   r   rz  ry  ry   r  ) apargscfg_pathr   spcoder   r*  r  r  spy_hist_closer  r  stater  now_etrC   hhmmgater  r  has_state_positionsr  rec_arec_bbase_jsonrarbaggr}   s                                    r3   
async_mainr    s    	(O	
+X\\^-F-F-H-R-R-TU	(O		 	 -[	\BOOH3@RSZR[[\>]O^OOH3@qryqz>{O|OOMYG]^g]hhiEjOkOOI.IYY[\	   OOI  
 OOh  
 OO0B?	   OOS  
 OO<	   OOj	   OOl	   OOc  
 OO%:;P:QQST	   ==?D
 + 	'')) 
 /96{7R7RS6s{{87LM !1!1!3 456&x'7'7'9&::WXY	B|(oodiiTYY#dnnBU_aobbb		{!C		N+;:c$..FYEZ[\ 	Q

OO--$$$;???;V++-557\fB+B2>>DT""E7E*&&s+++E65)	0**3///
 +B//C+9"c+B%B"FN+BU^TTH+BU;;H!#d<~EUVdehUi j VHS>;
  MEJJLE++,+Bu===pq\\%(F&)$*=*=&>&D&DS!&LMc!fMFB>>r"QA>ND V!34M#'(<(<#=#UfPTnAU "&uyy'>"?!(+C$ &"2"2"4$d4+>+>&? !$tzz"2 &tD,@,@'A	
 %c$*=*=&> +D1E,F "5: h #E.$9 eFm $T-%8 h !#c( /5H0I 0S<QS9T5U1V  !#j&8&8&:";!" +D..99;CCEFD..99;CCEOOPTPbPbPmPmPoPwPwPyP~P~  BQ  QQ  TX  Tf  Tf  Tq  Tq  Ts  T{  T{  T}  TD  TD  QD  E  FD..99;CCEOOPTPbPbPmPmPoPwPwPyP~P~  BO  QO  RV  Rd  Rd  Ro  Ro  Rq  Ry  Ry  R{  RB  RB  QB  C  D-#, $+81E).A$tObObJc*iy3> & 7 DJJ'H >>MMO&' G mmC3t/@/@+A$BCCC!(+CIciik]&#a@Ayy&E,$7 899klm--.FTM4V__]5S4T Uz233KM DJJ'h >>MMO&' g mmC3t/@/@+A$BCCCj ****))446>>@++, NN499+F+TUE NN499}+Dt{{+RSE*"&"4"4#'(;(;#<',
 
 
 +"&"4"4#'(;(;#<','+   ++,[,OT}}U[[')JKdhOT}}U[[')JKdh$4*2,,.*C*C*E*O*O*Q&0)2 %/r4$8RVVJ=OSZ=Z%/D%9bffZ>PT[>[ !( &0(+E
(+E
#%#%  ))$)FC(BT(IT[\ GvNO +"&"4"4#'(;(;#<'+'9'9
 
 
 

# >>MMO&'  YZ--As4+<+<'= >???y / 	c %> 	, 0 	0?C**3///	0
 0%BT; >
 NX D  D
N # [ TUVTWWXYZZ[
 @ a))*"QC01 >>MMO&' s  J1z4Ax0 <v=Bx0 v!Ax0 "v$#0x0 v'x0 &v- :v*;v- ?x0 w%x0 "w(#x0 <w+=x0 w.A&x0 8w19Ax0 	w4Mx0 9-z&5x0 w9B=x0 -z5x0 <w<=C+x0 (w?)9x0 "x#x0 >Ex ?x0 x+x0 *-zA x0 x.x0 !x0 $x0 'x0 *v- -+w"ww"x0 !w""x0 (x0 +x0 .x0 1x0 4x0 <x0 ?x0 x0 	x(x#x0 #x((x0 .x0 0	y#9%yy##y& &.zz__main__)r0   r,   r1   r\   r  r,   )rC   r,   r  r,   )rM   r,   rN   r,   rO   r,   rP   r,   rQ   r,   r  r,   )r  dict[str, Any])r{   r
   r  r  )r8   r  r  None)r   r  r   r
   r  r  )r   r   r  r,   )r   r   r   r   r  ztuple[float, float])r>   N)r   r   r   r   r   r\   r   r,   r   float | Noner  r,   )NFNN)r   r   r   r   rM   r,   r   rZ   r  r,   ra   r\   r  zfrozenset[str] | Noner  r  r  r  r  r  r  r   )r   r   r   r   rM   r,   rM  r\   rI  r,   rN  r,   r  r  r  r   )F)r   r   r   r   rM   r,   r   rZ   rW  r,   r]  r,   r  r  r  ztuple[Option, Option])rp  list[tuple[Option, str, int]]r  r   )r"  z	list[Any]r  r   )r#  r   rM   r,   r  zlist[float])r:  r   r  r  )r:  r   r  z:tuple[bool, str, float | None, float | None, float | None])r  r   r  r   r  r,   r  r,   )r   r   r  r  r  z+tuple[float, float, float, bool, list[str]]ri   )r   r   r  r   r  z$list[tuple[Option, str, int]] | Noner  ztuple[float, float, float, str])rp  list[LegStateRich]r  dict[int, float]r  rZ   r  r,   )r   r   rp  r   r  r!  )r   r   r  rZ   r  r  )
r   r   r  r  rp  r   r  rZ   r  r  )r   r   r8   r  r  r   r  r  )r8   r  r  z-tuple[dict[int, float], dict[int, list[str]]])r   r   r  z<tuple[dict[int, float], dict[int, float], dict[int, Option]])r   r   r  zset[int])r   r   r  r
   r  rZ   )r*  r,   r  
RegimeName)NFNF)r   r   r8   r  r  r"  r0   r,   r   r   r  r,   rD  z
int | Noner  r  r  zPath | Noner  r  r  r  )r  r  )__doc__
__future__r   r  r   rt   r?   r  collectionsr   r  dataclassesr   r   r   r   r	   pathlibr
   typingr   r   zoneinfor   __file__r   r   
_REPO_ROOTr\   r{   insert	ib_insyncr   r   r   r   r   r   r   r   r   ImportErrorr}   *RenTech.strategy_stack.vrp_strategy_configr   r   r   r   r  r/   r  r'  r(  r)  r\  r  rr  r]  r^  r_  r`  rc  ra  rd  r  rs  re  rf  rg  rh  r  ri  rj  rk  r  rt  rl  r  rp  rm  rn  ro  r"  r*   rf   r4   r   rk   r  r  r  r  r  r  LIVE_SIGNAL_STATE_OUTru  r  r  r  r  rD   rT   rW   rY   rl   rj   r   r   r   r   r   rF  rQ  rj  rs  r  r
  r  r  r  r  r  r  r  r  r  r  r  r  r  r%  r+  r  r  rc   runrg   r5   r3   <module>r2     s]  B #     
 #  ) . .   (^##%--a0
z?#(("HHOOAs:'Ieee     


 

      

 
 NO
S ; (^##%,,/DD


	#$"Y.7&@Ccc "Y.7&@C[[ $( !   6 ! ! !(	" H] 
A:F !/0
/0/0 /0 	/0
 /0 /0r -1 ##C
C	C C 	C
 C C *C C C C CL=
=	= = 	=
 = = = =N !l
l	l l 	l
 l l l l^b!H,*'0F+
+1+0+> KO*S
*S*S#G*S$*SZ	:	6:01h!
!2!6!0=Od" !% &*$qW
qW
qW qW 	qW
 
qW qW qW qW $qW qW 
qWhO(d zDHHZ\ W4  I
@
AqHIs   (J! !J4&	J//J4