
    pj-                    >   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mZ  e
e      j                         j                   d   Zedz  d	z  d
z  Zed   Zh dZded<   ddZddZddZ ed       G d d             ZdddZddZddZdd dZy)!uY  
Shared **VRP strategy + sleeve risk** configuration for parity between:

* ``vrp_backtester.py`` (Theta / iVol / synthetic backtests)
* ``live_ibkr_trader.py`` (IBKR)

Single JSON file (default ``sleeve_risk_fractions.json``) holds:

* ``sleeve_risk_fractions`` — per-regime risk fractions (same keys as ``Regime``)
* ``overlay_risk_fractions`` — reserved for future in-engine overlays (passed to ``VRPBacktester``)
* ``overlay_risk_cap_frac`` / ``total_risk_cap_frac`` — optional caps
* ``strategy_params`` — optional scalars / leg-spec lists mirrored onto ``vrp_backtester`` module globals
    )annotationsN)	dataclass)Path)AnyLiteral   RenTechstrategy_stackzsleeve_risk_fractions.json)pmccdiagonal	r2_spreadnakedcredit_spread>   r   r   r   r   r   zset[str]_VALID_SLEEVESc           	     >   i }| j                         D ]  \  }}t        |      j                         }|t        vrt	        d| dt        t                     t        |      }t        j                  |      rd|cxk  rdk  sn t	        d| d|       |||<    |S )NzUnknown sleeve 'z
'; valid:               ?zsleeve_risk_fractions[''] must be in (0, 1], got )	itemsstrstripr   
ValueErrorsortedfloatmathisfiniterawoutkvkkfvs         F/opt/rentech/trading_bot/RenTech/strategy_stack/vrp_strategy_config.py_validate_sleeve_fracsr%       s    C		 1V\\^^#/t:f^>T=UVWW1Xb!cBo#o6rd:TUVTWXYYB J    c                   i }| j                         D ]n  \  }}t        |      j                         }|st        d      t	        |      }t        j                  |      rd|cxk  rdk  sn t        d| d|       |||<   p |S )Nz*overlay_risk_fractions key cannot be emptyr   r   zoverlay_risk_fractions['r   )r   r   r   r   r   r   r   r   s         r$   _validate_overlay_fracsr(   -   s    C		 1V\\^IJJ1Xb!cBo#o7t;UVWUXYZZB Jr&   c          	        t        | t              rt        |       dk  rt        | d      g }t	        |       D ]  \  }}t        |t        t
        f      rt        |      dk  rt        | d| d      t        |d         }t        |d         }t        |d         j                         j                         }|dvrt        | d| d	|d         |j                  |||f        |S )
Nr   z9 must be a list of at least two [dte, delta, action] rows   [z] must be [dte, delta, action]r      )buysellz] action must be buy/sell, got )
isinstancelistlenr   	enumeratetupleintr   r   r   lowerappend)r   labelr   irowdtedeltaacts           r$   _coerce_credit_leg_specsr=   :   s    c4 CHqLE7"[\]](*CC. &3#e}-SAwas*HIJJ#a&kc!f#a&k!'')o%was*I#a&TUU

C$%& Jr&   T)frozenc                  N    e Zd ZU dZded<   ded<   ded<   ded<   ded	<   d
ed<   y)VRPStrategyConfigFilez4Parsed ``sleeve_risk_fractions.json`` (and friends).r   pathdict[str, float]sleeve_risk_fractionsoverlay_risk_fractionszfloat | Noneoverlay_risk_cap_fractotal_risk_cap_fracdict[str, Any]strategy_paramsN)__name__
__module____qualname____doc____annotations__ r&   r$   r@   r@   J   s(    >
J++,,''%%##r&   r@   c                   | t        |       j                         nt        }|j                         st	        d|       t        j                  |j                  d            }t        |t              st        d|       |j                  di       }t        |t              st        d      t        |      }|j                  di       }|t        |t              st        d      t        |xs i       }|j                  d	      }|t        |      nd }|"d
|cxk  rdk  st        d       t        d      |j                  d      }	|	t        |	      nd }
|
"d
|
cxk  rdk  st        d       t        d      |j                  di       }|t        |t              st        d      t        |xs i       }t        |j!                         ||||
|      S )NzStrategy config not found: zutf-8)encodingzConfig must be a JSON object: rC   z)'sleeve_risk_fractions' must be an objectrD   z5'overlay_risk_fractions' must be an object or omittedrE   r   r   z'overlay_risk_cap_frac must be in (0, 1]rF   z%total_risk_cap_frac must be in (0, 1]rH   z.'strategy_params' must be an object or omitted)rA   rC   rD   rE   rF   rH   )r   
expanduserDEFAULT_STRATEGY_CONFIG_PATHis_fileFileNotFoundErrorjsonloads	read_textr/   dictr   getr%   r(   r   r@   resolve)rA   ppayload
sleeve_rawsleevesov_rawoverlaysocoverlay_captc	total_capsprH   s                r$   load_strategy_config_filerf   V   s   #'#3T
9UA99;"=aS ABBjjg67Ggt$9!=>>4b9Jj$'DEE$Z0G[[126F*VT":PQQ&v|4H	,	-B!~%)4Kk(@S(@BCC )ABCC	*	+B^b	IcI&<&<@AA '=@AA	&	+B	~jT2IJJ28nO YY[%')%' r&   c                B    t        |       }t        |j                        S )zJBackward-compatible helper: return only ``sleeve_risk_fractions`` mapping.)rf   rX   rC   )rA   cfgs     r$   $load_sleeve_risk_fractions_from_jsonri      s    
#D
)C))**r&   c           	          syddl mc m} i dt        dt        dt        dt        dt        dt        d	t        d
t        dt        dt        dt        dt        dt        dt        dt        dt        dt        t        t        t        t        t        t        t        d}dD ]%  \  }}| vr||   }t        || | |                ' d v rt         d   d      |_        nSt         fddD              r?t	         d         t         d         dft	         d         t         d         dfg|_        d  v rt         d    d       |_	        d! v rt	         d!         |_
        d" v rt         d"         |_        d# v rt         d#         |_        d$ v rt         d$   d$      |_        d% v rt         d%   d%      |_        yy)&z
    Mutate ``vrp_backtester`` module-level constants from ``strategy_params`` JSON.

    This keeps ``VRPBacktester`` logic unchanged while allowing one JSON file to drive
    both Theta backtests and live trading parity.
    Nr   
vix_r1_max
vix_r2_max
vix_r3_maxr1_strangle_dter1_call_deltar1_put_deltar1_time_stop_days
r1_tp_frac
r1_sl_fracrisk_fraction_per_trader2_put_spread_risk_fractionr2_risk_per_contractr2_tp_per_contractr2_sl_per_contractr2_time_stop_daysr2_spread_tp_fracr2_spread_time_stop_days)
r3_tp_frac
r3_sl_fracr3_time_stop_days
r4_tp_fracr4_time_stop_dayssizing_min_max_risk_usdcontract_multiplier))rk   
VIX_R1_MAX)rl   
VIX_R2_MAX)rm   
VIX_R3_MAX)rn   R1_STRANGLE_DTE)ro   R1_CALL_DELTA)rp   R1_PUT_DELTA)rq   R1_TIME_STOP_DAYS)rr   
R1_TP_FRAC)rs   
R1_SL_FRAC)rt   RISK_FRACTION_PER_TRADE)ru   R2_PUT_SPREAD_RISK_FRACTION)rv   R2_RISK_PER_CONTRACT)rw   R2_TP_PER_CONTRACT)rx   R2_SL_PER_CONTRACT)ry   R2_TIME_STOP_DAYS)rz   R2_SPREAD_TP_FRAC)r{   R2_SPREAD_TIME_STOP_DAYS)r|   
R3_TP_FRAC)r}   
R3_SL_FRAC)r~   R3_TIME_STOP_DAYS)r   
R4_TP_FRAC)r   R4_TIME_STOP_DAYS)r   SIZING_MIN_MAX_RISK_USD)r   CONTRACT_MULTIPLIERr2_diag_leg_specs)r7   c              3  &   K   | ]  }|v  
 y wNrN   ).0r    paramss     r$   	<genexpr>zAapply_strategy_params_to_vrp_backtester_module.<locals>.<genexpr>   s     eQQ&[es   )r2_short_dter2_short_deltar2_long_dter2_long_deltar   r   r.   r   r   r-   r2_credit_leg_specsr2_spread_target_dter2_spread_short_deltar2_spread_width_frac_of_spotr3_credit_leg_specsr4_credit_leg_specs)%RenTech.strategy_stack.vrp_backtesterr
   vrp_backtesterr   r4   setattrr=   R2_DIAG_LEG_SPECSallR2_CREDIT_LEG_SPECSR2_SPREAD_TARGET_DTER2_SPREAD_SHORT_DELTAR2_SPREAD_WIDTH_FRAC_OF_SPOTR3_CREDIT_LEG_SPECSR4_CREDIT_LEG_SPECS)r   msimple_float_intjson_keyattrcasters   `     r$   .apply_strategy_params_to_vrp_backtester_moduler      su    55ee 	e 	3	
 	 	 	S 	e 	e 	"5 	&u 	 	e 	e 	S  	U!" 	#C#$   #($16 3$4 6!!(+4x 012;3@ f$6v>Q7RZmn	e"de	e'(%7G0H*I6R&'vo/F)GO

 & 8()1F!
 '!$V,B%C!D&("'/F(G"H%/).v6T/U)V&& 8()1F!
 & 8()1F!
 'r&   c                4   ddl mc m} | xs t        j                  d      }|j
                  }g d}|D ]  }t        ||      st        ||      ||<     t        |j                        dk\  rxt        |j                  d   d         |d<   t        |j                  d   d         |d<   t        |j                  d   d         |d	<   t        |j                  d   d         |d
<   t        |j                        dk\  r<t        |j                  d   d         |d<   t        |j                  d   d         |d<   t        |j                        dk\  rZt        |j                  d   d         |d<   t        |j                  d   d         |d<   t        |j                  d   d         |d<   t        |d      rt        |j                        |d<   t        |d      rt        |j                        |d<   t        |d      rt        |j                         |d<   yy)a  
    Copy mirrored module-level constants from ``vrp_backtester`` into the live trader module globals.

    Call **after** :func:`apply_strategy_params_to_vrp_backtester_module`.

    Parameters
    ----------
    target
        Module object to patch (use ``sys.modules[__name__]`` when running ``live_ibkr_trader.py``
        as a script so ``__main__`` receives the constants).
    r   Nz'RenTech.strategy_stack.live_ibkr_trader)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   R2_SHORT_DTEr,   R2_SHORT_DELTAR2_LONG_DTER2_LONG_DELTAR3_TARGET_DTER3_TARGET_DELTAR4_SHORT_DTER4_SHORT_DELTAR4_LONG_DELTAr   R2B_SHORT_DTEr   R2B_SHORT_DELTAr   R2B_WIDTH_FRAC_OF_SPOT)r   r
   r   	importlibimport_module__dict__hasattrgetattrr1   r   r4   r   r   r   r   r   r   )targetvblivegnamesns         r$   .sync_live_constants_from_vrp_backtester_moduler      s    76WY,,-VWDAE.  "2q>2q>AaD"
 2 A% 4 4Q 7 :;.#B$8$8$;A$>?
r33A6q9:-"2#7#7#:1#=>/ 2!!"a' !7!7!:1!=>/$R%;%;A%>q%AB

2!!"a' 6 6q 9! <=.#B$:$:1$=a$@A
"2#9#9!#<Q#?@/r)* !8!89/r*+$R%=%=>
r12&+B,K,K&L
"# 3r&   )r   rG   returnrB   )r   r   r7   r   r   zlist[tuple[int, float, str]]r   )rA   zstr | Path | Noner   r@   )rA   z
str | Pathr   rB   )r   zdict[str, Any] | Noner   None)r   ztypes.ModuleType | Noner   r   )rL   
__future__r   r   rU   r   typesdataclassesr   pathlibr   typingr   r   __file__rZ   parents_REPOrR   	RegimeStrr   rM   r%   r(   r=   r@   rf   ri   r   r   rN   r&   r$   <module>r      s    #     !  X ((+$y03CCFbb MN	V V

  $$ $ $(V+b
J@Mr&   