
    i                     
   S SK rS SKJr  S SKr\" \5      R                  5       R                  S   r\S-  r	\
" \	5      \R                  ;  a!  \R                  R                  \
" \	5      5        S SKJr  S SKJr  S SKJr    SS	\S
\S-  4S jjrS\R,                  S\R.                  4S jrS\R,                  S\S\S\S\S\4S jr    SS	\S\S\S\4S jjrS\R,                  4S jr\S:X  a  \" SSSSS9r\" \5        gg)    N)Path   src)load_eurusd)load_eurusd_15m)build_rolling_beta_model       @	thresholdallowed_hoursc                    [        5       R                  5       n[        SSS9R                  5       nUR                  S5      R	                  SS9nUS   R
                  R                  5       US'   SS/nX4   R                  5       nUR                  USS	S
9nUS   R                  5       US'   US   R                  S5      US'   US   US   -
  US'   US   R                  SSS9R                  5       nUS   R                  SSS9R                  5       nUS   U-
  U-  US'   UR                  S/S9R	                  SS9nUS   R
                  R                  US'   Ub$  XUS   R                  U5         R                  5       nSUS'   SUR                   US   U :  S4'   SUR                   US   U * :*  S4'   XUS   S:g     R                  5       R	                  SS9nU$ )z
Clean hourly signal layer:
- 1H price data
- daily predicted return from rolling beta model
- lag signal built on 1H bars
- session filter applied ONLY to signal timestamps
x      )windowsmooth_spandatetimeTdropdatepredicted_return_1dleft)onhowclose   eurusd_return_24hlag_gap_24h_v3<   )min_periodslag_zscore_24h_v3)subsethourr   signal   )r   copyr   sort_valuesreset_indexdt	normalizemergeffill
pct_changerollingmeanstddropnar!   isinloc)	r
   r   h1daily_model
daily_colsdflag_meanlag_stdsignalss	            TC:\Users\paul_\OneDrive\fx_macro_intraday\src\research\truth_baseline_backtest_v1.pybuild_hourly_signal_layerr;      s    
			B*#2FKKMK	
	#	/	/T	/	:BJ"",,.BvJ/0J)..0K	+&f	5B "#8 9 ? ? AB !k44R8B 34r:M7NNB"#++BB+?DDFH!"**22*>BBDG!"23h>'IB	./	0	<	<$	<	GBJ""''BvJ 6
./446BxL=>BFF2!"i/9:>@BFF2!"yj0(:;H"#((*66D6AGN    m15tsc                 ^    U S   R                  USS9nU[        U 5      :  a  g[        U5      $ )z3
Find the first 15m bar index with datetime >= ts.
r   r   )sideN)searchsortedlenint)r=   r>   idxs      r:   get_first_m15_idx_at_or_afterrE   A   s4     j/
&
&r
&
7C
c#hs8Or<   	entry_idxr"   
hold_hoursstopspread_costc                    US-  n[        X-   [        U 5      S-
  5      nU R                  XS-    R                  5       nUR                  (       a  gUR                  S   n	UR                  S   n
U	S   nU
S   nUS:X  a0  US   R                  5       U-
  U-  nX* :  nX-  S-
  nU(       a  U* nO/US   R                  5       U-
  U-  nX:  nX-  S-
  * nU(       a  U* nX-  nU	S	   U
S	   UUUUS
.$ )z
Truth-path simulation:
- entry on 15m close at entry_idx
- hold for hold_hours worth of contiguous 15m bars
- stop checked against the full 15m high/low path
   r#   Nr   r$   r   lowhighr   )
entry_time	exit_timeentry_price
exit_pricer"   return)minrB   ilocr%   emptymax)r=   rF   r"   rG   rH   rI   	hold_barsexit_idxpath	entry_rowexit_rowrP   rQ   adversestop_hitrets                   r:   simulate_trade_on_m15_pathr_   K   s&    QI9(#c(Q,7H88I!|,113Dzz		!Iyy}HG$K'"J{;??${2kAU?&*%C<##%3{B>(1,-%CC  
+j)"  r<   {Gzd?0   -C6?c           
      z   [        [        SS5      5      n[        U US9n[        5       R	                  5       nUR                  S5      R                  SS9n/ nS nUR                  5        HY  u  pU
S   nUb  X:  a  M  [        Xk5      nUc  M$  [        UU[        U
S   5      UUUS9nUc  MC  UR                  U5        US	   nM[     [        R                  " U5      nUR                  (       a  [        S
5        U$ SUS   -   R!                  5       US'   US   R#                  5       US'   US   US   -  S-
  US'   U$ )N      )r
   r   r   Tr   r"   )r=   rF   r"   rG   rH   rI   rO   zNo trades found.r#   rR   equity_curverunning_peakdrawdown)setranger;   r   r%   r&   r'   iterrowsrE   r_   rC   appendpd	DataFramerU   printcumprodcummax)r
   rH   rG   rI   r   r9   r=   tradeslast_exit_time_sigsignal_timerF   trades                 r:   run_backtestrx      s`    a%M'#G
 

 
 
"C
//*
%
1
1t
1
<CFN""$*o %+*F1#C	*s8}%!#
 =e{+/ %2 \\&!F|| !&"22;;=F>#N3::<F>/&2HH1LF:Mr<   rr   c                 T   U R                   (       a  [        S5        g U S   S:  R                  5       nU S   R                  5       nU S   R                  5       nUS:w  a  X#-  OSnU S   R                  S   nU S   R                  5       nSnSnU S    H  n	U	S::  a  US-  n[        Xx5      nM  SnM     [        R                  " U S   5      R                  R                  U S	'   U R                  S	5      S   R                  5       n
[        S
5        [        S[        U 5      5        [        S[        US5      5        [        S[        US5      5        [        S[        US5      5        [        S[        US5      5        [        S[        US5      5        [        S[        US5      5        [        SU5        [        S[        U
R                  5       S5      5        [        S[        U
R                  5       S5      5        [        S5        [        U / SQ   R                  S5      5        g )NzNo trades to analyze.rR   r   rf   r$   rh   r#   rN   
entry_datez#
=== TRUTH BASELINE BACKTEST V1 ===zTrades:z	Win rate:rK   zAverage trade return:   zStd dev of trade returns:zSharpe proxy:zFinal equity multiple:zMax drawdown:zMax losing streak:z
Worst day:z	Best day:z
LAST 10 TRADES:)rN   rO   r"   rR   rf   rh   
   )rU   ro   r.   r/   rT   rS   rV   rm   to_datetimer(   r   groupbysumrB   roundtail)rr   win_rate
avg_return
std_returnsharpe_proxyfinal_equitymax_ddmax_losing_streakcurrent_streakrdaily_returnss              r:   analyze_resultsr      s   ||%&x 1$**,H!&&(J!%%'J.8Ao:*1L.)..r2LJ##%F NH6aN #$5 FN  >>&*>?BBGGF<NN<0:>>@M	
01	)S[!	+uXq)*	
!5Q#78	
%uZ';<	/5q12	
"E,$:;	/5+,	
 12	,m//1156	+u]..0!45	
	W	

$r(r<   __main__)r
   rH   rG   rI   )r	   N)r	   r`   ra   rb   )pandasrm   pathlibr   sys__file__resolveparents	BASE_PATHSRC_PATHstrrY   rl   ingestion.price_loaderr   ingestion.price_loader_15mr   models.rolling_beta_modelr   floatri   r;   rn   	TimestamprE   rC   r_   rx   r   __name__rr    r<   r:   <module>r      sY     
N""$,,Q/	ux= HHOOCM" . 6 >  $..:.br||  1	11 1 	1
 1 1j 	77
7 7 	7t+BLL +\ z	F F r<   