
    p`jl                    L   d Z ddlmZ ddlmZ ddlZddlZddl	m
Z
mZmZmZ  ed       G d d	             Z ed       G d
 d             Z ed       G d d             Z	 	 	 	 	 	 	 	 ddZdddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 ddZ	 	 	 	 	 	 	 	 	 	 	 	 ddZddZddZddZy)z5Out-of-sample validation for adaptive lag selections.    )annotations)	dataclassN)AdaptiveLagCorrelationEngineLagCorrelationConfig	Transformtransform_seriesT)frozenc                  J    e Zd ZU ded<   dZded<   dZded<   d	Zded
<   ddZy)WalkForwardConfigr   	estimator   intevaluation_strideNpd.Timestamp | str | Nonestart_atr   source_availability_delayc                l    | j                   dk  rt        d      | j                  dk  rt        d      y )Nr   zevaluation_stride must be >= 1r   &source_availability_delay must be >= 0)r   
ValueErrorr   )selfs    N/Users/jameslopez/projects/TradingBot25/strategies/adaptive_lag_walkforward.py__post_init__zWalkForwardConfig.__post_init__   s;    !!A%=>>))A-EFF .    )returnNone)__name__
__module____qualname____annotations__r   r   r   r    r   r   r   r      s/    ##s*.H'.%&s&Gr   r   c                  6    e Zd ZU ded<   ded<   ded<   ded<   y)ForwardSummaryr   observationszfloat | Nonecorrelationdirectional_hit_ratemean_lagNr   r   r   r   r    r   r   r"   r"       s    &&r   r"   c                  "    e Zd ZU ded<   ded<   y)WalkForwardResultzpd.DataFramerecordsr"   summaryNr'   r    r   r   r)   r)   (   s    r   r)   c           
     (   t        | |       | j                  |j                        }t        ||j                  j
                        }t        ||j                  j
                        }t        |j                        }g }t        |j                  |j                  |j                        D ]  }|j                  |||j                  |         }	|	j                  0||	j                  z   }
|
t        |      k\  rN|j                  |   }|j                  |
   }t        j                   |      rt        j                   |      s|j#                  |j                  |   |j                  |
   |	j                  |	j$                  ||d        t'        |      S )zGSelect lag at t, then score source[t] against target[t + selected_lag].evaluated_at
matures_atselected_lagselected_correlationsource_valuetarget_value)_validate_alignedshiftr   r   r   	transformr   _evaluation_positionsindexr   r   estimate_atbest_laglenilocnpisfiniteappendbest_correlation_result)sourcetargetconfigavailable_sourcesource_valuestarget_valuesenginerowspositionestimatematurity_positionr2   r3   s                r   evaluate_adaptive_lagrM   .   sd    ff%||F$D$DE$%5v7G7G7Q7QRM$VV-=-=-G-GHM)&*:*:;FD)&,,8P8PRXRaRab%%&6X@VW$$x'8'88F+$))(3$))*;<{{<(L0I &X 6$ll+<= ( 1 1(0(A(A , ,		
 c* 4=r   r   )strider   r   c          
     T   t        | |       |dk  rt        d      |dk  rt        d      |dk  rt        d      t        | j                  |      |      }t        ||      }g }	t	        |j
                  ||      D ]  }
|
|z   }|t        |      k\  r|j                  |
   }|j                  |   }t        j                  |      rt        j                  |      s`|	j                  |j
                  |
   |j
                  |   |t        j                  ||d        t        |	      S )zBScore a predeclared lag with the exact same forward-pair protocol.r   zlag must be >= 0r   zstride must be >= 1r   r-   )r4   r   r   r5   r7   r8   r;   r<   r=   r>   r?   nanrA   )rB   rC   lagr6   rN   r   r   rF   rG   rI   rJ   rL   r2   r3   s                 r   evaluate_fixed_lagrR   P   s!    ff%
Qw+,,z.// 1$ABB$V\\2K%LiXM$VY7MD)&,,I$sNF+$))(3$))*;<{{<(L0I &X 6$ll+<= #(* , ,		
 J$ 4=r   c                  t        j                  | t              t        j                  |t              }}t        j                  |      t        j                  |      z  }||   ||   }}t	        |      dk  s
|dk  s|dk  rt        d      t        |t	        |            }t        j                  t	        |      |z
  dz         }t         j                  j                  |      }	g }
t        t        j                  t	        |      |z              }t        |      D ]  }|	j                  ||d      }t        j                  |D cg c]  }t        j                  |||z          c}      dt	        |       }|
j                  t        t        j                   ||   ||         d                 t#        d	 t        j$                  |
d
dg      D              S c c}w )zIReturn a deterministic 95% moving-block bootstrap interval for Pearson r.)dtype   r   zMneed at least two observations, positive block_length, and positive resamplesT)sizereplaceNr   r   c              3  2   K   | ]  }t        |        y w)N)float).0values     r   	<genexpr>z5moving_block_bootstrap_correlation.<locals>.<genexpr>   s     U+T%u+Ts   g?g333333?)r=   asarrayrZ   r>   r;   r   minarangerandomdefault_rngr   ceilrangechoiceconcatenater?   corrcoeftuplequantile)rB   rC   block_length	resamplesseedxyvalidstartsrngcorrelationsblocks_needed_sampled_startsstartindicess                   r   "moving_block_bootstrap_correlationrx   z   s    ::fE*BJJvU,KqAKKNR[[^+EU8QuXqA
1vz\A%Qhii|SV,LYYs1v,q01F
))


%CLA 567M9FM..Vd!eVdU"))E5<3G"HVd!efgoilmniopE"++aj!G*"Ed"KLM  U2;;|eU^+TUUU "fs    G
c                P   |t        j                  |      n| d   }| j                  (|j                  |j                  | j                        }n)| j                  |j                  |j                  d       }t	        t        | j                  |            t        |       |      S )Nr   )pd	Timestamptztz_localizerd   r   searchsortedr;   )r8   rN   r   rv   s       r   r7   r7      s    &.&:BLL"aExx 0!!%((+		ehh2!!$'U''./UVDDr   c                ,   t        j                  |       }|j                  rt        |t	        dd d d             S |d   |d   }}t        |      dkD  r"t        t        j                  ||      d         nd }|dk7  |dk7  z  }|j                         rHt        t        j                  ||         t        j                  ||         k(  j                               nd }t        |t	        t        |      ||t        |d   j                                           S )Nr   r2   r3   r   rX   r0   )rz   	DataFrameemptyr)   r"   r;   rZ   r=   rg   anysignmean)rI   r*   rB   rC   r$   nonzerohit_rates          r   rA   rA      s    ll4 G}} .D$*MNN^,gn.EFF>A'lQ>N%FF3D9:TXK{v{+GW^WbWbWdubggfWo."''&/2JJPPRSjnHs7|[(E'.BYB^B^B`<ab r   c                   t        | j                  t        j                        r%| j                  j	                  |j                        st        d      | j                  j                  r| j                  j                  st        d      y )Nz3source and target must share the same DatetimeIndexz4series index must be unique and monotonic increasing)
isinstancer8   rz   DatetimeIndexequalsr   is_monotonic_increasing	is_unique)rB   rC   s     r   r4   r4      se    fllB$4$45V\\=P=PQWQ]Q]=^NOO<<//v||7M7MOPP 8Nr   )rB   	pd.SeriesrC   r   rD   r   r   r)   )rB   r   rC   r   rQ   r   r6   r   rN   r   r   r   r   r   r   r)   )rB   r   rC   r   rj   r   rk   r   rl   r   r   ztuple[float, float])r8   zpd.DatetimeIndexrN   r   r   r   )rI   z
list[dict]r   r)   )rB   r   rC   r   r   r   )__doc__
__future__r   dataclassesr   numpyr=   pandasrz   #strategies.adaptive_lag_correlationr   r   r   r   r   r"   r)   rM   rR   rx   r7   rA   r4   r    r   r   <module>r      sK   ; " !    $
G 
G 
G $   $  
(2CP *.%&''' 
	'
 ' ' ('  #' 'TVV(V;>VKNVVYVV*EQr   