
    =`jd.                       d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	Z
ddlZ G d dee      Z G d	 d
ee      Z ed       G d d             Z ed       G d d             Z ed       G d d             Z ed       G d d             Zdddd	 	 	 	 	 	 	 	 	 	 	 ddZ G d d      ZddZd dZd!dZd"dZy)#a+  Causal, inspectable lag-correlation estimation for aligned time series.

The convention is deliberately one-way: lag ``L`` means a source observation
at grid position ``i - L`` is compared with the target observation at ``i``.
Thus a positive L says the source leads the target by L grid intervals.
    )annotations)	dataclass)Enum)MappingNc                      e Zd ZdZdZdZdZy)	Transformlevels
difference
pct_change
log_returnN)__name__
__module____qualname__LEVELS
DIFFERENCE
PCT_CHANGE
LOG_RETURN     N/Users/jameslopez/projects/TradingBot25/strategies/adaptive_lag_correlation.pyr   r      s    FJJJr   r   c                      e Zd ZdZdZdZy)SelectionModestrongest_positivestrongest_negativestrongest_absoluteN)r   r   r   STRONGEST_POSITIVESTRONGEST_NEGATIVESTRONGEST_ABSOLUTEr   r   r   r   r      s    ---r   r   T)frozenc                      e Zd ZU dZ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<   e
j                  Zded<   ej                  Zded<   dZded<   dZded<   ddZedd       Zy)LagCorrelationConfigzFEstimator configuration; all lag and window values are grid intervals.   intmin_lagx   max_lag   lag_step   windowmin_observationsr   	transformr   selection_modeg-q=floattie_tolerance   distinct_peak_exclusion_radiusc                   | j                   dk  rt        d      | j                  | j                   k  rt        d      | j                  dk  rt        d      | j                  dk  rt        d      d| j
                  cxk  r| j                  k  st        d       t        d      | j                  dk  rt        d	      | j                  dk  rt        d
      y )Nr   zmin_lag must be >= 0zmax_lag must be >= min_lagzlag_step must be > 0r'   zwindow must be > 1   z-min_observations must be between 2 and windowztie_tolerance must be >= 0z+distinct_peak_exclusion_radius must be >= 0)r$   
ValueErrorr&   r(   r*   r+   r/   r1   selfs    r   __post_init__z"LagCorrelationConfig.__post_init__-   s    <<!344<<$,,&9::==A344;;!122D))8T[[8LMM 9LMM!9::..2JKK 3r   c                ^    t        | j                  | j                  dz   | j                        S )Nr'   )ranger$   r&   r(   r5   s    r   lagszLagCorrelationConfig.lags=   s"    T\\4<<!#3T]]CCr   N)returnNone)r;   r9   )r   r   r   __doc__r$   __annotations__r&   r(   r*   r+   r   r   r,   r   r   r-   r/   r1   r7   propertyr:   r   r   r   r!   r!      s    PGSGSHcFCc$++Iy+$1$D$DNMD M5 *+"C+L  D Dr   r!   c                  ,    e Zd ZU ded<   ded<   ded<   y)CandidateCorrelationr#   lagr.   correlationobservationsN)r   r   r   r>   r   r   r   rA   rA   B   s    	Hr   rA   c                  b    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	<   ded
<   ded<   y)LagConfidencezFPeak separation, not a statistical probability of the economic thesis.
int | Nonerunner_up_lagfloat | Nonerunner_up_correlationmarginrelative_peak_separationdistinct_peak_lagdistinct_peak_correlationdistinct_peak_margin!distinct_peak_relative_separationN)r   r   r   r=   r>   r   r   r   rF   rF   I   s5    P''**!!++&&'33r   rF   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ddZy)LagEstimatezpd.Timestampevaluated_atr   r-   rG   best_lagrI   best_correlationrD   rF   
confidence"Mapping[int, CandidateCorrelation]spectrumc                h     |dk  rg S t         j                  j                          fd      d| S )zACandidates ordered by the configured criterion then shortest lag.r'   c                ^    t        | j                  j                         | j                  fS N)_scorerC   r-   rB   )itemr6   s    r   <lambda>z,LagEstimate.top_candidates.<locals>.<lambda>e   s(    HXHXZ^ZmZmAn@nptpxpx?yr   keyN)sortedrX   values)r6   limits   ` r   top_candidateszLagEstimate.top_candidatesa   sA    19Idmm**,2yz  |B  }B  C  	Cr   N)   )rc   r#   r;   zlist[CandidateCorrelation])r   r   r   r>   rd   r   r   r   rR   rR   W   s2    !!""00Cr   rR   1D)	frequencysource_forward_fillsource_fill_limitc                  t        | d       t        |d       | j                  t              j                  |      j	                         }|r|j                  |      }|j                  t              j                  |      j	                         }|j                  j                  |j                        j                         }|j                  |      |j                  |      fS )a  Resample two timestamped series deterministically onto a common grid.

    Each grid bucket receives its last observed value. Source values may be
    carried forward only from their availability timestamp; target values are
    never forward-filled. Callers must pass a source indexed by publication /
    availability time rather than a later-revised economic-period timestamp.
    sourcetarget)rc   )
_validate_seriesastyper.   resamplelastffillindexunionsort_valuesreindex)rk   rl   rg   rh   ri   source_gridtarget_gridrr   s           r   align_to_regular_gridrx   h   s     VX&VX&--&//	:??AK!''.?'@--&//	:??AK##K$5$56BBDEu%{':':5'AAAr   c                      e Zd ZddZddZ	 	 	 	 	 	 	 	 ddZddZddZddZ	 	 	 	 	 	 	 	 ddZ		 	 	 	 	 	 ddZ
dd	Zedd
       Zy)AdaptiveLagCorrelationEnginec                    || _         y r[   )config)r6   r|   s     r   __init__z%AdaptiveLagCorrelationEngine.__init__   s	    r   c                    | j                  ||       |j                  D cg c]  }| j                  |||       c}S c c}w )z=Return the causal estimate at every aligned target timestamp.)_validate_alignedrr   estimate_at)r6   rk   rl   	timestamps       r   estimatez%AdaptiveLagCorrelationEngine.estimate   s=    vv.MS\\Z\	  ;\ZZZs   >c           
        | j                  ||       t        j                  |      }||j                  vrt	        d      |j                  j                  |      }t        |t        t        j                  f      st	        d      t        || j                  j                        j                  t              }t        || j                  j                        j                  t              }t        dt        |      | j                  j                   z
  dz         }i }	| j                  j"                  D ]  }
t        j$                  |t        |      dz         }||
z
  }|dk\  }|||      }|||      }t        j&                  |      t        j&                  |      z  }|j)                         | j                  j*                  k  r||   ||   }}t        j,                  |      dk(  st        j,                  |      dk(  rt/        |
t        t        j0                  ||      d         t        |j)                                     |	|
<    |	s-t3        || j                  j4                  dddt7               |	      S t9        |	j;                         | j<                  	      }|d   |D cg c]  }| j?                  |      s| }}tA        |d
 	      tC        fd|D        d      }| jE                  ||	      }t3        || j                  j4                  jF                  jH                  jJ                  ||	      S c c}w )z?Estimate using observations at or before ``evaluated_at`` only.z-evaluated_at must be an index value in targetztarget index must be unique)dtyper   r'   )r   r'   )rB   rC   rD   Nr_   c                    | j                   S r[   rB   	candidates    r   r^   z:AdaptiveLagCorrelationEngine.estimate_at.<locals>.<lambda>   s    y}}r   c              3  V   K   | ]   }|j                   j                   k7  s| " y wr[   r   ).0r   bests     r   	<genexpr>z;AdaptiveLagCorrelationEngine.estimate_at.<locals>.<genexpr>   s!     V&YIMMTXX<Uy&s   )))&r   pd	Timestamprr   r4   get_loc
isinstancer#   npintegertransform_seriesr|   r,   to_numpyr.   maxr*   r:   arangeisfinitesumr+   stdrA   corrcoefrR   r-   _empty_confidencera   rb   	_rank_key_scores_tiedminnext_confidencerB   rC   rD   )r6   rk   rl   rS   r   endsource_valuestarget_valuesstartrX   rB   target_positionssource_positionsusablexyvalidrankedr   tiedrunnerrV   r   s                         @r   r   z(AdaptiveLagCorrelationEngine.estimate_at   s    	vv.LL.	FLL(LMMll""9-#RZZ01:;;(1F1FGPPW\P](1F1FGPPW\P]As3x$++"4"44q8946;;##C!yyC1=/#5%*F.v67A.v67AKKNR[[^3Eyy{T[[999U8QuXqAvvayA~a0!"++a"3D"9: -HSM $$ y$++*D*DdDRVXiXkmuvv)t~~>ay+1X6iT5F5FyRV5W	6X4<=V&VX\]%%dFH=
9dkk&@&@$((DL\L\^b^o^oq{  ~F  G  	G	 Ys   -MMc                V    | j                  |j                        }| |j                  fS r[   )_selection_scorerC   rB   )r6   r   scores      r   r   z&AdaptiveLagCorrelationEngine._rank_key   s)    %%i&;&;<	&&r   c                B    t        || j                  j                        S r[   )r\   r|   r-   )r6   rC   s     r   r   z-AdaptiveLagCorrelationEngine._selection_score   s    k4;;#=#=>>r   c                    t        | j                  |j                        | j                  |j                        z
        | j                  j                  k  S r[   )absr   rC   r|   r/   )r6   leftrights      r   r   z)AdaptiveLagCorrelationEngine._scores_tied   sU    4(()9)9:T=R=RSXSdSd=eefjnjuju  kD  kD  D  	Dr   c                   || j                  ||      nd }| j                  ||      }|| j                  ||      nd }t        t        |j                        t        j                  t              j                        }t        |r|j                  nd |r|j                  nd ||||z  nd |r|j                  nd |r|j                  nd ||
||z        S d       S )N)rH   rJ   rK   rL   rM   rN   rO   rP   )_margin_best_distinct_local_peakr   r   rC   r   finfor.   epsrF   rB   )r6   r   r   rX   rK   distinct_peakdistinct_margindenominators           r   r   z(AdaptiveLagCorrelationEngine._confidence   s     06/AdF+t66tXF?L?X$,,t];^b#d../%1D1DE(.&**D8>&"4"4D=C=OVk%9UY3@m//dCPm&?&?VZ!01@1L+-
 	
 SW
 	
r   c                   t        |j                         d       }g }t        |      D ]0  \  }}|r||dz
     nd }|dz   t        |      k  r||dz      nd }|rO| j	                  |j
                        | j	                  |j
                        | j                  j                  z
  k  r|rO| j	                  |j
                        | j	                  |j
                        | j                  j                  z
  k  r|r| j                  ||      rt        |j                  |j                  z
        | j                  j                  k  r |j                  |       3 |rt        || j                        S d S )Nc                    | j                   S r[   r   r   s    r   r^   zHAdaptiveLagCorrelationEngine._best_distinct_local_peak.<locals>.<lambda>   s    )--r   r_   r'   )ra   rb   	enumeratelenr   rC   r|   r/   r   r   rB   r1   appendr   r   )	r6   r   rX   orderedlocal_peakspositionr   r   r   s	            r   r   z6AdaptiveLagCorrelationEngine._best_distinct_local_peak   si    *0OP#,W#5Hi,478a<($D-5\CL-HGHqL)dE--i.C.CDtG\G\]a]m]mGnquq|q|  rK  rK  HK  K..y/D/DEH]H]^c^o^oHpsws~s~  tM  tM  IM  M)))T:9==488+,0Z0ZZy) $6 8Cs;DNN3LLr   c                    | j                  ||      ryt        d| j                  |j                        | j                  |j                        z
        S )Ng        )r   r   r   rC   )r6   r   
competitors      r   r   z$AdaptiveLagCorrelationEngine._margin   sJ    T:.3--d.>.>?$BWBWXbXnXnBooppr   c                    t        | d       t        |d       | j                  j                  |j                        st        d      y )Nrk   rl   z3source and target must share the same aligned index)rm   rr   equalsr4   )rk   rl   s     r   r   z.AdaptiveLagCorrelationEngine._validate_aligned   s=    **||""6<<0RSS 1r   N)r|   r!   r;   r<   )rk   	pd.Seriesrl   r   r;   zlist[LagEstimate])rk   r   rl   r   rS   zpd.Timestamp | strr;   rR   )r   rA   r;   ztuple[float, int])rC   r.   r;   r.   )r   rA   r   rA   r;   bool)r   rA   r   CandidateCorrelation | NonerX   rW   r;   rF   )r   rA   rX   rW   r;   r   )r   rA   r   rA   r;   r.   )rk   r   rl   r   r;   r<   )r   r   r   r}   r   r   r   r   r   r   r   r   staticmethodr   r   r   r   rz   rz      s    [
,G,G)2,GBT,G	,G\'?D
"
 ,
 5	

 

.M(M4VM	$M(q
 T Tr   rz   c            
     &    t        d d d d d d d d       S r[   )rF   r   r   r   r   r      s    tT4tT4HHr   c                j    |t         j                  u r| S |t         j                  u r|  S t        |       S r[   )r   r   r   r   )rC   modes     r   r\   r\      s7    }///}///|{r   c                H   t        | t        j                        st        | d      t        | j                  t        j
                        st        | d      | j                  j                  st        | d      | j                  j                  st        | d      y )Nz must be a pandas Seriesz index must be a DatetimeIndexz# index must be monotonic increasingz index must be unique)	r   r   Series	TypeErrorrr   DatetimeIndexr4   is_monotonic_increasing	is_unique)seriesnames     r   rm   rm     s    fbii(4& 89::fllB$4$45D6!?@AA<<//D6!DEFF<<!!D6!6788 "r   c                N   | j                  t              }|t        j                  u r|S |t        j                  u r|j                         S |t        j                  u r|j                  d       S |j                  |dkD        }t        j                  |      j                         S )N)fill_methodr   )rn   r.   r   r   r   diffr   r   wherer   log)r   r,   numericpositives       r   r   r     s    mmE"GI$$$I(((||~I(((!!d!33}}Wq[)H66(  ""r   )rk   r   rl   r   rg   strrh   r   ri   rG   r;   ztuple[pd.Series, pd.Series])r;   rF   )rC   r.   r   r   r;   r.   )r   r   r   r   r;   r<   )r   r   r,   r   r;   r   )r=   
__future__r   dataclassesr   enumr   typingr   numpyr   pandasr   r   r   r   r!   rA   rF   rR   rx   rz   r   r\   rm   r   r   r   r   <module>r      s,   # !    T .C . $D D DD $   $
4 
4 
4 $C C C(  $$(BBB 	B
 B "B !B2vT vTrI9	#r   