
    pj~4                        U d Z ddlmZ ddlmZ ddlmZmZ ddlZ	ddl
ZddlmZmZmZmZmZmZmZ ddlmZ dd	d
dZded<   ed   Zed   Zed   Z ed       G d d             Ze G d d             Zy)u  
Standalone **inverse SPY ETF** bear hedge via dual MA-slope + SPY regime gates.

Firmed-up rules (vs legacy inverse-ETF-slope-only):
  * **SPY regime gate** — only hedge when SPY is in a bear state (dual negative
    slope and/or below SMA200).
  * **Sticky SPY exit** — stay hedged until SPY bull resumes, not on inverse-ETF
    bounce whipsaws.
  * **SH default** — −1x instrument avoids 2x/3x decay.

Separate from the S&P 500 top-N long sleeve.
    )annotations)	dataclass)DictLiteralN)ExitModeMaSlopeConfigMaSlopeEngine
compute_macompute_ma_slopecompute_slope_rank_scorecompute_vol_scale)_align_panel_frameszProShares Short S&P500 (-1x)z!ProShares UltraShort S&P500 (-2x)z%ProShares UltraPro Short S&P500 (-3x))SHSDSSPXUzdict[str, str]INVERSE_SPY_ETFS)
all_activetop_n)nonebear_dual_slopebelow_sma200bear_dual_or_sma200)inverse_signalspy_fast_slope_positivespy_regime_offspy_slope_or_sma200spy_bull_bothT)frozenc                  .   e Zd ZU dZded<   dZded<   dZded<   dZded<   d	Zd
ed<   dZ	ded<   dZ
ded<   dZded<   dZded<   dZded<   dZded<   dZded<   dZded <   dZded!<   d"Zd#ed$<   d%Zd
ed&<   d'Zd
ed(<   d)Zd
ed*<   d+Zded,<   d-Zd
ed.<   d1d/Zy0)2MaSlopeInverseConfig
   intfast_period2   slow_periodfast_lookback   slow_lookback        floatentry_slope_minTboolprice_above_ma
slope_flipr   	exit_moder   SelectionMode	selection   )r   ztuple[str, ...]tickers_preferredr   	SpyRegime
spy_regime   spy_sma_windowr   SpyExitspy_exitrequire_inverse_momentumbinarystrsizing_modeg333333?
target_volg      ?vol_scale_floorg      ?vol_scale_cap   
vol_windowg{Gz?cash_annual_yieldc                    | j                   rdnd}| j                   d| j                   d| d| j                   | j                   ddj                  | j                         
S )Ninvreqspybear_,)r:   r5   r9   r1   r   joinr3   )selfinvs     J/opt/rentech/trading_bot/RenTech/strategy_stack/ma_slope_inverse_sleeve.pyslugzMaSlopeInverseConfig.slugJ   s`    77hYqqQ~~tzzl!CHHT5K5K,L+MO	
    N)returnr<   )__name__
__module____qualname__r#   __annotations__r%   r&   r(   r+   r-   r/   r1   r   r3   r5   r7   r9   r:   r=   r>   r?   r@   rB   rC   rM    rN   rL   r    r    2   s    KKM3M3 OU ND&Ix&&I}&E3N)001J	1NC-Hg-%)d)KJ OU M5J#u#
rN   r    c                      e Zd ZU  e       Zded<   ddZddZddZ	 	 	 	 	 	 ddZ	dd	 	 	 	 	 	 	 dd	Z
	 	 	 	 	 	 dd
Zy)MaSlopeInverseSleever    configc                    | j                   }t        d|j                  |j                  d|j                  |j
                  d|j                  d|j                  |j                  d      S )Nemapct	long_onlydual_timeframer;   )ma_type	ma_periodslope_lookbackslope_methodr+   r-   	directionr/   signal_modeslow_ma_periodslow_slope_lookbackr=   )	rW   r   r#   r&   r+   r-   r/   r%   r(   )rJ   cs     rL   _engine_configz#MaSlopeInverseSleeve._engine_configV   s\    KKmm??--++!kk(== ! 
 	
rN   c                <   | j                   }|d   j                  t        j                        }t	        |d|j
                        }t	        |d|j                        }t        ||j                        }t        ||j                        }|j                  |j                  |j                        j                         }|dk  |dk  z  }	||k  }
|j                  dk(  r"t        j                  d|j                   	      }nQ|j                  d
k(  r|	}n?|j                  dk(  r|
}n-|j                  dk(  r|	|
z  }nt#        d|j                        |j$                  dk(  r|dkD  }n|j$                  dk(  r| }n|j$                  dk(  r|dkD  ||kD  z  }nd|j$                  dk(  r|dkD  ||kD  z  }nI|j$                  dk(  r"t        j                  d|j                   	      }nt#        d|j$                        |j'                  d      ||j'                  d      fS )zCReturn (bear_regime, fast_slope, exit_signal) aligned to spy index.closerY   )r]   period)lookback)min_periodsr   r   Tindexr   r   r   zunknown spy_regime: r   r   r   r   r   Fzunknown spy_exit: )rW   astypenpfloat64r
   r#   r%   r   r&   r(   rollingr7   meanr5   pdSeriesrm   
ValueErrorr9   fillna)rJ   spy_dfcfgrh   fast_maslow_ma
fast_slope
slow_slopesma	bear_dual	below_smabearr9   s                rL   _compute_spy_regimez(MaSlopeInverseSleeve._compute_spy_regimeg   s   kkw&&rzz2UE#//JUE#//J%g8I8IJ
%g8I8IJ
mmC..C<N<NmOTTV!^
Q7	CK	>>V#99T5D^^00D^^~-D^^44y(D3CNN3EFGG<<44!A~H\\--uH\\22"Q53;7H\\_,"Q53;7H\\--yyekk:H1#,,1ABCC{{5!:xu/EEErN   c                &   | j                   }t        | j                               }g }g }t        |j	                               D ]  \  }}||j
                  rt        j                  |j                        j                  d       }|j                         }	||	_        |	j                         }	|j                  |	      }
t        |	d   j                  t        j                         |j"                  |j$                  |j&                  |j(                  |j*                  |j,                  d      }|
d   j                  t        j                         dkD  }|d   j/                  |t        j0                        }|j3                  |j                  t        j                         j5                  |             |j3                  |j5                  |              t7        |      \  }}t7        |      \  }}|j                         |j                         fS )NrW   rh   dual_product)r#   r%   r&   r(   r+   r-   rank_metrictarget_positionr   
rank_score)rW   r	   rf   sorteditemsemptyrs   to_datetimerm   tz_localizecopy
sort_index	transformr   rn   ro   rp   r#   r%   r&   r(   r+   r-   wherenanappendrenamer   )rJ   etf_dictrx   eng
active_pan	score_pantdfidxdfxframescoredactivescore	active_dfrG   score_dfs                    rL   _inverse_active_panelz*MaSlopeInverseSleeve._inverse_active_panel   s   kk4#6#6#89&(
%'	HNN,- 	.EArzRXX..*66t<C'')CCI.."CMM#&E-G##BJJ/OOOO!//!// # 3 3"11*	F ,-44RZZ@1DF<(..vrvv>EfmmBJJ7>>qABU\\!_-+	., +:6	1))4!##%x':':'<<<rN   c                
   |st        d      | j                  }| j                  |      \  }}| j                  |      \  }}}|j                  j                  |j                        j                         }	|j                  |	      j                  d      }|j                  |	      }|j                  |	      j                  d      }|j                  |	      j                  d      }t        |j                        }
t        |
      }t        |	      }t        j                  ||ft        j                        }t        j                   d|	      }|j"                  dk(  s|j$                  rt'        | j)                               }t+        |
      D ]  \  }}||   }t        j,                  |j                        j/                  d      }|j1                         }||_        |j3                  |j5                               }||d	   j                  |	      j                  d      z  } d
}t7        |      D ]  }|d
k(  rXt9        |j:                  |         }|j$                  r/t9        |j:                  |   j=                         d
kD        }|xr |}|rd}n||j"                  dk(  rt9        |j:                  |         rUd
}nRt9        |j:                  |         rd
}n7|j$                  r+t9        |j:                  |   j=                         d
kD        sd
}|d
k(  rt        j>                  |j:                  |   jA                  t        j                        d
kD        d
   }|j$                  r|jB                  d
k(  rF|j$                  sP|jD                  D cg c]	  }||
v s| }}|s|
dd }|D ]$  }dt        |      z  |||
j	                  |      f<   & |jF                  dk(  r%|D ]  }dtI        t        |            z  |||f<     |j:                  |   jA                  t        j                        }||   }t        jJ                  |      |d
kD  z  }|jM                         rT||   } tO        tQ        |jR                        | jB                        }!t        jT                  ||    |!dz
        d|! }"| |"   }#n,|dtO        tQ        |jR                        |jB                         }#|#D ]  }dtI        t        |#            z  |||f<      t        jV                  ||	|
      }$|$jY                  d      j                  d      }$|$|fS c c}w )z}
        Daily weights per inverse ETF using SPY regime state machine.

        Returns (weights, rank_score_panel).
        zetf_dict cannot be emptyr)   Fdtyperl   r   r   N	long_exitr   r2         ?r   )rm   columns)-ru   rW   r   r   rm   unionsort_valuesreindexrv   listr   lenro   zerosrp   rs   rt   r9   r:   r	   rf   	enumerater   r   r   r   r   ranger,   ilocmaxnonzeroto_numpysizer3   r1   r*   isfiniteanyminr"   r   argpartition	DataFrameshift)%rJ   r   rw   rx   r   r   r   rG   r9   mastertickersn_tn_dout_arrinv_exit_anyr   jr   r   r   r   r   stateientry_okinv_any
active_idxchosen_namesnamesc_rowsub_scvalidcandkpickchosenweightss%                                        rL   build_weight_panelz'MaSlopeInverseSleeve.build_weight_panel   s    788kk"88B	8 44V<a&&tzz2>>@%%f-44S9	##F+||F#**51##F+2259y(()'l&k((C:RZZ8 yyf5<<++s/K/Kt':':'<=C!'* a1a[nnRXX.::4@ggi	cnn&67+u[/A/I/I&/Q/X/XY^/_`a s .	=Az		!-//"9>>!#4#8#8#:Q#>?G'3GHE<<#33L--a01 !(--*+E11$y~~a?P?T?T?VYZ?Z:[EzINN1$5$>$>RZZ$>$PST$TUVWXJ++
10D//+.+@+@QaALQQ##*2A;L( ND69C<M6MGAw}}T223N,.# AA$'%J*@$@GAqDMA "q)222D
+F+vz:99;%e,DC		NDII6A??F5M>1q5A"1ED!$ZF'(N#c#))njoo*NOF =A$'%F*<$<GAqDM=[.	=` ,,wfgF--"))#.  1  Rs   	U	U	T)verbosec                  g }t        |j                               D ]  \  }}||j                  sd|j                  vr#t	        j
                  |j                        j                  d       }|j                         }||_        |j                  |d   j                  t        j                        j                  |              |st        d      t        |      \  }	}
| j!                  ||      \  }}
|j#                  |	j                        j%                  d      }|	j                  j'                         }|	j#                  |      j%                  d      }	|j#                  |      j%                  d      }t)        | j*                  j,                        dz  }|j/                  t        j                        }|	j/                  t        j                        }||z  j1                  d      }|j1                  d      }| j*                  j2                  d	k(  rt	        j4                  |t        j6                  dd
|z
        |z  z   |      }t9        || j*                  j:                  | j*                  j<                  | j*                  j>                  | j*                  j@                        }||jC                  d      j%                  d
      z  }n|t        j6                  dd
|z
        |z  z   }|rt)        |j1                  d      dkD  jE                               }| jG                  |      \  }}
}
t)        |j#                  |      j%                  d      jE                               }tI        d| j*                  jJ                   d| j*                  jL                   dtO        |jQ                                d|dd|d
d       t	        j4                  ||dt        j                        S )Nretzno ETF return series)r   r)   g     o@r   r2   )axis	vol_scaler   rl   )r>   windowfloorcapr   Fz  Bear hedge: regime=z exit=z | ETFs=z | invested z.1%z | SPY bear T)flushma_slope_inverse_ret)rm   r   r   ))r   r   r   r   rs   r   rm   r   r   r   rn   ro   rp   r   ru   r   r   r   rv   r   r*   rW   rC   r   sumr=   rt   maximumr   r>   rB   r?   r@   r   rr   r   printr5   r9   r   keys)rJ   r   rw   r   ret_panr   r   r   r   ret_dfrG   r   r   daily_rfwrcorewsumprescaleoutinvestedr   	bear_fracs                           rL   generate_returnsz%MaSlopeInverseSleeve.generate_returns	  s4    $&HNN,- 	DEArzRXXbjj)@..*66t<C'')CCINN3u:,,RZZ8??BC	D 344'0	,,Xv>
//&../9@@E))+'..s3//&)005667%?2::.OO"**O-A{{{"uu!u};;""k1))D2::c3:#>#IIQWXC%;;11{{--kk11KK--E A--c22CCt4x??Caeeema/5578H11&9JD!Qdll6299%@EEGHI'(>(>'?vdkkFZFZE[ \X]]_-.l8C. I%c?, 	 yyF1GrzzZZrN   c                   | j                  ||      \  }}| j                  |      \  }}}|j                  |j                        j	                  d      }g }|j                  D ]  }|j
                  D ]  }	t        |j                  ||	f         }
|
dk  r#|	|j
                  v r|j                  ||	f   n
t        d      }|j                  t        j                  |      j                  d      |	|
t        j                  |      rt        |      n
t        d      t        |j                  |         d         t        j                  |      S )NFr   r   z%Y-%m-%d)datetickerweightr   spy_bear_regime)r   r   r   rm   rv   r   r*   locr   rs   	Timestampstrftimero   r   r,   r   )rJ   r   rw   r   scoresr   rG   rowsdttkrr   scs               rL   generate_position_logz*MaSlopeInverseSleeve.generate_position_logC  s"   
 11(FC--f5
a||GMM*11%8-- 	B '++b#g./6,/6>>,AVZZC(uU| "R 0 9 9* E"%"#35;;r?eBie+/+=	 ||D!!rN   N)rO   r   )rw   pd.DataFramerO   z&tuple[pd.Series, pd.Series, pd.Series])r   Dict[str, pd.DataFrame]rO   !tuple[pd.DataFrame, pd.DataFrame])r   r   rw   r   rO   r   )r   r   rw   r   r   r,   rO   z	pd.Series)r   r   rw   r   rO   r   )rP   rQ   rR   r    rW   rS   rf   r   r   r   r   r   rT   rN   rL   rV   rV   R   s    #7#9F 9
"%FN=>Z!)Z! Z! 
+	Z!B 8[)8[ 8[
 8[ 
8[t")" " 
	"rN   rV   )__doc__
__future__r   dataclassesr   typingr   r   numpyro   pandasrs   &RenTech.strategy_stack.ma_slope_enginer   r   r	   r
   r   r   r   -RenTech.strategy_stack.multi_strategy_managerr   r   rS   r0   r4   r8   r    rV   rT   rN   rL   <module>r     s    # !       N ).3$ .  -.TU	
 $
 
 
> H" H" H"rN   