
    iY                    h   d Z ddlmZ ddlZddlmc mZ ddl	Z	ddl
Z
ddlmZ ddlZe
j                  j!                  d e ee      j'                         j(                  j(                               ddlmZ ddlmZmZmZ dddZd Zd	 Zd
 Zedk(  r e         e         e         e d       yy)zj
Cache candle-keyed: assert che build_tech_snapshot non rifaccia H1+H4
fetch per la stessa M5 candle key.
    )annotationsN)Path)FakeMarketDataProvider)_TECH_CACHEbuild_tech_snapshotclear_tech_cachec                   t        |       D cg c]  }|| dz
  |z
  dz  z
   }}t        j                  |t        |       D cg c]
  }d|dz  z    c}t        |       D cg c]
  }d|dz  z    c}t        |       D cg c]
  }d|dz  z    c}t        |       D cg c]
  }d|dz  z    c}t        |       D cg c]  }d|z   	 c}d	      S c c}w c c}w c c}w c c}w c c}w c c}w )
z+OHLCV bars con timestamp incrementali (M5).   ,  g     @      ?g     @g     @g     @i  )timeopenhighlowclosevolume)rangepd	DataFrame)nlast_tsitimess       5/home/work/apex_v16/tests/test_tech_snapshot_cache.py
_make_barsr      s    27(;QWA	S((;E;<<.3Ah76AH$7.3Ah76AH$7.3Ah76AH$7.3Ah76AH$7%*1X.4!8.   < 8777.s#   CC
 C>CC#:C(c                 d   t                t        d      t        d      t        d      d} t        |       }t        j                  t        d|dd             t        |j                        }d	}||k(  }|st        j                  d
|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       dz   d|iz  }t        t        j                   |            d x}}t        j                  t        d|dd             t        |j                        |z
  }d}||k(  }|st        j                  d
|fd||f      dt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      dz  }t        j                  d|       dz   d|iz  }t        t        j                   |            d x}}t#        d       y )N   d   2   )MES5min)r!   1hour)r!   4hourr!   r         ?symbolprovider	tick_size
tick_value   ==)z%(py0)s == %(py3)sfirst_call_count)py0py3z$first call: 3 fetches expected, got z
>assert %(py5)spy5r
   second_call_deltaz+cache hit must fetch only M5 (1 call), got z4OK: second call hits cache, only M5 probe re-fetched)r   r   r   asynciorunr   lencalls
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_saferepr_format_assertmsgAssertionError_format_explanationprint)barsr(   r.   @py_assert2@py_assert1@py_format4@py_format6r2   s           r    test_cache_hit_skips_h1_h4_fetchrF   $   s   $S/$S/$R.D
 &d+HKK#x4  8>>*  Bq  B0A0ABq B B;A6B B)A)A  B B8A	  B B8A	  ! B B0A0A
./?.@AB B B.A.AB B KK#x4  HNN+.>> ! J! J8I8IJ J JCI6J J1I1I  J J@I	  J J@I	 !" J J8I8I
56G5HIJ J J6I6IJ J	
@A    c                 ,   t                t        dd      t        d      t        d      d} t        |       }t        j                  t        d|dd	
             t        dd      t        d      t        d      d}t        |      }t        j                  t        d|dd	
             |j                  }t        |      }d}||k(  }|s6t        j                  d|fd||f      dt        j                         v st        j                  t              rt        j                  t              nddt        j                         v st        j                  |      rt        j                  |      ndt        j                  |      t        j                  |      t        j                  |      dz  }t        j                  dt        |j                               dz   d|iz  }	t        t        j                   |	            d x}x}x}}t#        d       y )Nr   逅tgr   r   r   r    r!   r   r%   r&   itgr+   r,   )zK%(py5)s
{%(py5)s = %(py0)s(%(py3)s
{%(py3)s = %(py1)s.calls
})
} == %(py8)sr5   	provider2)r/   py1r0   r1   py8u,   new candle → full re-fetch (3 calls), got z
>assert %(py10)spy10z(OK: new candle_time forces full re-fetch)r   r   r   r3   r4   r   r6   r5   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   )
bars_t0	provider1bars_t1rK   rB   @py_assert4@py_assert7@py_assert6@py_format9@py_format11s
             r   (test_cache_miss_when_candle_time_changesrW   >   s   $S*=$S/$R.G
 'w/IKK#y4 
 %S*=$S/$R.G
 'w/IKK#y4   N3 N1 N1$ N N<M<MN1 N NGMvN N5M5M  N NDMI  N NGMvN N5M5M  N NDMI  N NDMI  N NDMI   N NDMI $% N N<M<M
6s9??7K6LMN N N:M:MN N N	
45rG   c            	        t                ddlm}  | j                  }d| _        	 t	        d      D ]V  }t        dd|dz  z         t        d	      t        d
      d}t        j                  t        dt        |      dd             X t        t              }d}||k(  }|s$t        j                  d|fd||f      dt        j                         v st        j                   t              rt        j"                  t              nddt        j                         v st        j                   t              rt        j"                  t              ndt        j"                  |      t        j"                  |      dz  }t        j$                  dt        t                     dz   d|iz  }t'        t        j(                  |            d x}x}}t+        t        j,                               }	|	d   d   }
d}d}d}||z  }||z   }|
|k(  }|st        j                  d|fd|
|f      t        j"                  |
      t        j"                  |      t        j"                  |      t        j"                  |      dz  }t        j$                  d|	d          dz   d|iz  }t'        t        j(                  |            d x}
x}x}x}x}x}}|| _        t/        d       y # || _        w xY w) Nr   )tech_snapshotr+      r   rI   r   rJ   r   r   r    r!   r   r%   r&   r,   )z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py6)sr5   r   )r/   rL   r0   py6zLRU cap=3, got z
>assert %(py8)srM   r
      )z*%(py1)s == (%(py4)s + (%(py6)s * %(py8)s)))rL   py4r[   rM   z2oldest evicted, expected key starts at +600s; got z
>assert %(py12)spy12zOK: LRU evicts oldest entries)r   analysisrY   _TECH_CACHE_MAXr   r   r3   r4   r   r   r5   r   r7   r8   r9   r:   r;   r<   r=   r>   r?   listkeysr@   )ts_mod	saved_maxr   rA   rB   @py_assert5rR   @py_format7rU   rb   @py_assert0@py_assert3rS   @py_assert9@py_assert10rV   @py_format13s                    r   test_lru_evicts_oldestrl   Y   s   0&&IF+q 		A",S*q3w:N"O",S/",R.D
 KK+'=d'C4 		 ; 	11 	11$ 	1 	100	11 	1 	1*0&	1 	100  	1 	1'0y  	1 	1*0&	1 	100  	1 	1'0y  	1 	1'0y   	1 	1'0y $% 	1 	100oc+./0	1 	1 	100	1 	1K$$&'Awqz 	KZ 	K! 	Kc 	K!c' 	KZ'1 	Kz11 	K9J9J	Kz1 	K 	KAJ  	K 	KAJ ( 	K 	KAJ +, 	K 	KAJ /2 	K 	K9J9J@a	J	K 	K 	K7J7J	K 	K 	K "+	
)* "+s   J!K 	K"__main__zALL 3 TESTS PASSED)rI   )r   intr   rn   returnzpd.DataFrame)!__doc__
__future__r   builtinsr9   _pytest.assertion.rewrite	assertionrewriter7   r3   syspathlibr   pandasr   pathinsertstr__file__resolveparentanalysis.market_datar   analysis.tech_snapshotr   r   r   r   rF   rW   rl   __name__r@    rG   r   <module>r      s    #    
   3tH~--/66==> ? 7 
B466+4 z$&,.	
	 rG   