
    	#j"                        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mZ ddl	m
Z
 g dZg dZg dZd	 Zd
 Zd Zd Zd ZddZddZddZedk    r e e                      dS )a+  Calibrate market regimes from roughly 10 years of historical prices.

Outputs:
- historical_regime_config.json: regime return parameters and transition matrix
- historical_regime_stats.csv: human-readable regime statistics
- historical_regime_calibration_report.md: summary for the dashboard/manual
    )annotationsN)datetimetimezone)Path)SPYQQQIWMSMHSOXXSOXLSOXSNVDAAVGOAMDMUTSMASML^VIX)basketqualityleadersoxlsoxs)risk_on	selectivechopselloffreboundcrashc                *    |                                  S N)
pct_change)seriess    'outputs/historical_regime_calibrator.pyr"   r"   )   s        c                   | d         }| d         }| d         }| d         }t          |          }|                     d          }|                     d          }|                     d          }|                     d          }	|                     d          }
|                     d          }|                     d          }|                     d          }|                    d                                          }|                    d	                                          }|                    d                                          }|                    d
                                          }||z  dz
  }i }| j        D ]X}t          d |j        |         |j        |         |j        |         |j        |         |j        |         |j        |         |j        |         |j        |         |j        |         f	D                       r|j        |         dk    s3|
j        |         dk    s"|j        |         dk    r|j        |         dk     rd}n|j        |         |j        |         k     rB|j        |         |j        |         k     r&|j        |         dk     s|j        |         dk    rd}n$|j        |         dk     r%|j        |         dk    r|	j        |         dk    rd}n|j        |         |j        |         k    r]|j        |         |j        |         k    rA|j        |         |j        |         k    r%|j        |         dk    r|j        |         dk    rd}nu|j        |         |j        |         k    s|j        |         |j        |         k    r;|j        |         |j        |         k    s|j        |         |j        |         k    rd}nd}|||<   Z|S )Nr   r
   r   r            2      <   g      ?c              3  >   K   | ]}t          j        |          V  d S r!   )mathisnan).0xs     r$   	<genexpr>z#classify_regimes.<locals>.<genexpr>D   s:       
 
tz!}} 
 
 
 
 
 
r%   g333333gzGế#   gQ롿r   gQ?r   gg?gQ?r   r   r   r   r   )r"   rollingmeanmaxindexanyloc)closeqqqsmhspyvix	qqq_ret_1	qqq_ret_3	qqq_ret_5
qqq_ret_20	smh_ret_3	smh_ret_5
smh_ret_20
spy_ret_20vix_change_5qqq_ma50	qqq_ma200smh_ma50qqq_high_60qqq_drawdown_60regimesidxregimes                         r$   classify_regimesrP   -   s_   
,C
,C
,C
-C3Iq!!Iq!!I##Jq!!Iq!!I##J##J>>!$$L{{2##%%HC  %%''I{{2##%%H++b//%%''KK'#-OG{   
 
M#M#N3N3S!LM#L$
'
 
 
 
 
 
 	 M#&((IM#,>&,H,HSWUX\]_M_M_dmdqrudvyddFFgclX\#...373<(,sBS3S3SYbYfgjYkntYtYt  yE  yI  JM  yN  QU  yU  yUFF %--)-2Du2L2LQZQ^_bQcfkQkQkFFWS\HL---#'#,sAS2S2SX[X_`cXdgogstwgxXxXx  ~H  ~L  MP  ~Q  TU  ~U  ~U  Zd  Zh  il  Zm  pq  Zq  ZqFFgclX\#...#'#,cAR2R2RYcYghkYloyo}  B  pC  ZC  ZC  GQ  GU  VY  GZ  ]g  ]k  lo  ]p  Gp  Gp FFFNr%   c                >   |                                  i }g d                             d          |d<   ddg                             d          |d<   fdd	D             }|                             d          |d
<   d         |d<   d         |d<   |S )N)r   r   r	   r
      )axisr   r   r   r   c                &    g | ]}|j         v |S  columns)r0   tickerreturnss     r$   
<listcomp>z'build_asset_returns.<locals>.<listcomp>g   s(    rrrfX^bibqXqXq6XqXqXqr%   )r   r   r   r   r   r   r   r   r   r   r   )r"   r5   )r:   outleader_colsrY   s      @r$   build_asset_returnsr]   b   s      G
C8889>>A>FFCMeU^,11q199C	Nrrrr(TrrrKK(--1-55CM&/CK&/CKJr%   c                "   d | D             }|sdS t          |          t          |          z  t          fd|D                       t          t          |          dz
  d          z  }t          t          j        |          d          fS )Nc                8    g | ]}||k    t          |          S rU   )float)r0   vs     r$   rZ   zmean_std.<locals>.<listcomp>o   s#    000!aU1XXr%   )g        g{Gz?c              3  (   K   | ]}|z
  d z  V  dS )   NrU   )r0   r1   r5   s     r$   r2   zmean_std.<locals>.<genexpr>s   s+      22qAH?222222r%   rR   g-C6?)sumlenr6   r.   sqrt)valuescleanvariancer5   s      @r$   mean_stdrj   n   s    00v000E yu::E

"D2222E22222SUa5K5KKHTYx((&1111r%   c                   d t           D             }d t          |                                 d           D             }t          ||dd                    D ]\  }}||         |xx         dz  cc<   i }|                                D ]=\  }t	                                                    fdt           D             ||<   >|S )Nc                2    i | ]}|d  t           D             S )c                    i | ]}|d S )rR   rU   )r0   dsts     r$   
<dictcomp>z7smooth_transition_counts.<locals>.<dictcomp>.<dictcomp>x   s    333sC333r%   )REGIME_ORDER)r0   srcs     r$   ro   z,smooth_transition_counts.<locals>.<dictcomp>x   s)    LLLc33l333LLLr%   c                    g | ]\  }}|S rU   rU   )r0   _rO   s      r$   rZ   z,smooth_transition_counts.<locals>.<listcomp>y   s    ___)!Vv___r%   c                    | d         S )Nr   rU   )items    r$   <lambda>z*smooth_transition_counts.<locals>.<lambda>y   s    VZ[\V] r%   )keyrR   c                *    g | ]}||         z  fS rU   rU   )r0   rn   
dst_countstotals     r$   rZ   z,smooth_transition_counts.<locals>.<listcomp>   s'    SSSsS*S/E"9:SSSr%   )rp   sorteditemsziprd   rg   )regime_seriescountsorderedrq   rn   transitionsry   rz   s         @@r$   smooth_transition_countsr   w   s    LL|LLLF__vm.A.A.C.CI]I]'^'^'^___G--  SsCAK!<<>> T TZJ%%''((SSSSSlSSSCr%   periodstrc                   dd l }|                    t          | ddd          }|j        rt	          d          d|v r|d                             d          n|                    d          fd	t          D             }|rt	          d
|                               g d          t                    t                    i }g }t          D ]fd	                                D             }i |<   t          D ]rfd|D             }t          |          \  }}	||	g|         <   |                    t          |          ||	|dz  |	t          j        d          z  d           st!                    }
fdt          D             }t#          j        t&          j                                                  | dt          |||
g dd}||fS )Nr   TF)r   auto_adjustprogressthreadsz No data downloaded from yfinanceCloseall)howc                &    g | ]}|j         v|S rU   rV   )r0   rX   r:   s     r$   rZ   zcalibrate.<locals>.<listcomp>   s%    KKK&vU]/J/Jv/J/J/Jr%   z$Missing tickers in downloaded data: )r   r   r
   r   r   r   r   )subsetc                &    g | ]\  }}|k    |S rU   rU   )r0   datelabelrO   s      r$   rZ   zcalibrate.<locals>.<listcomp>   s"    TTT+$EVOOOOOr%   c                T    g | ]$}|         j         v          j        |         %S rU   )r7   r9   )r0   r   assetasset_returnss     r$   rZ   zcalibrate.<locals>.<listcomp>   s:    mmm$R_`eRfRlJlJlmE*.t4JlJlJlr%      )rO   r   daysmean_daily_returnstdev_daily_returnannualized_mean_simpleannualized_vol_simplec                z    i | ]7}|t                                                                        |          8S rU   )listrg   count)r0   rO   regimes_by_dates     r$   ro   zcalibrate.<locals>.<dictcomp>   s=    ^^^vfd?113344::6BB^^^r%   zyfinance adjusted close)z3Historical calibration is a guide, not a guarantee.zbSOXL/SOXS are daily leveraged products; long-horizon simulation still requires daily revalidation.z>Classification uses QQQ/SMH/SOXX/VIX trend and drawdown rules.)	as_of_utcr   sourcetickersregime_countsrM   r   notes)yfinancedownloadTICKERSemptyRuntimeErrordropnarP   r]   rp   r|   ASSETSrj   appendre   r.   rf   r   r   nowr   utc	isoformat)r   yfdatamissingregime_config
stats_rowsdatesrg   r5   stdevr   r   payloadr   r   r:   rO   r   s                @@@@@r$   	calibrater      sZ   ;;wv4%Y^;__Dz ?=>>>$W$$$//&&KKKKGKKKG MK'KKLLLLL U U ULVVE&u--O'..MMJ  TTTT)>)>)@)@TTT "f 	 	EmmmmmmmmF"6**KD%,0%=M&!%( F%)&+*.*).3)?     		 +?;;K^^^^Q]^^^F\(,//99;;+ "
 
 
 G Jr%   out_dirr   c                \   |dz  }|dz  }|dz  }|                     t          j        | dd                     |                    dd	          5 }t	          j        |t          |d
                                                             }|                                 |	                    |           d d d            n# 1 swxY w Y   | d         }t          |                                          }	ddd| d          d| d          d| d          ddddddg}
t          D ]3}||         }|	r||	z  nd
}|
                    d| d| d|dd           4|
                    dddddddd dd!| d"d#| d"g           |                     d$                    |
          d$z              d S )%Nzhistorical_regime_config.jsonzhistorical_regime_stats.csvz'historical_regime_calibration_report.mdFrc   ensure_asciiindentw )newliner   )
fieldnamesr   z&# Historical Regime Calibration Reportz- As of UTC: r   z
- Period: r   z
- Source: r   zZ- Purpose: calibrate 1-year strategy simulations from the last 10 years of market regimes.z## Regime Mixz| Regime | Days | Share |z| --- | ---: | ---: |z| z | z.2%z |z## Required Usez<- Strategy simulations should run at least 252 trading days.z- Chart and trend analysis should reference this 10-year regime calibration before selecting ATTACK/GUARDED ATTACK/DEFENSE/REST.zP- If live data download fails, use the last saved calibration and mark it stale.z## Filesz- Config: ``z
- Stats: `
)
write_textjsondumpsopencsv
DictWriterr   keyswriteheader	writerowsrd   rg   rp   r   extendjoin)r   r   r   config_path
stats_pathreport_pathhandlewriterr   rz   linesrO   r   shares                 r$   write_outputsr      sT   ;;K88JEEK4:gE!LLLMMM	b	)	) %V4
18J8J8L8L3M3MNNN$$$% % % % % % % % % % % % % % %
 _%F  E0
.,..(WX&(((WX&((d

#E  = =f~ %,u1;&;;T;;e;;;;<<<<	LL

F 	KZ

$k$$$"Z"""    499U++d233333s   A%CC	Creturnintc                    t          j                    } |                     dd           |                                 }t	          t
                                                    j        }t          |j	                  \  }}t          |||           t          t          j        |d         |d         |d         ddd	
                     dS )Nz--period10y)defaultr   r   r   )r   r   r   Frc   r   r   )argparseArgumentParseradd_argument
parse_argsr   __file__resolveparentr   r   r   printr   r   )parserargsr   r   r   s        r$   mainr      s    $&&F

E222D8nn$$&&-G#DK00GZ':w///	$*(#[) 1  !	% % % & & &
 1r%   __main__)r   r   )r   r   )r   r   )__doc__
__future__r   r   r   r   r.   r   r   pathlibr   r   r   rp   r"   rP   r]   rj   r   r   r   r   __name__
SystemExitrU   r%   r$   <module>r      sO    # " " " " "  



   ' ' ' ' ' ' ' '        " 
9	8	8NNN  2 2 2j	 	 	2 2 2	 	 	7 7 7 7t-4 -4 -4 -4`    z
*TTVV

 r%   