:$idZddlZddlmcmZddlZddlm Z GddZ GddZ Gdd Z Gd d Z y) z] Test suite for WarrenAnalyzer Verifica calcoli score e fair value per prevenire regressioni N)WarrenAnalyzerc.eZdZdZdZdZdZdZdZy)TestCalculateScorezTest calculate_score() methodcX|j|}t|t}|s!tjddzdt j vstjtrtjtnddt j vstj|rtj|nddt j vstjtrtjtndtj|dz}ttj|d}d}||k}d }||k}|r|stjd ||fd |||ftj|dt j vstj|rtj|ndtj|d z} tjd |ddzd| iz} ttj| dx}x}x}}y)u4Stock normale di qualità dovrebbe avere score 60-80zScore deve essere intz7 >assert %(py4)s {%(py4)s = %(py0)s(%(py1)s, %(py2)s) } isinstancescoreint)py0py1py2py4N<P<=rz%(py1)s <= %(py4)sz%(py4)s <= %(py6)sr r py6Score u) fuori range atteso per stock di qualità >assert %(py8)spy8) calculate_scorerr @pytest_ar_format_assertmsg @py_builtinslocals_should_repr_global_name _safereprAssertionError_format_explanation_call_reprcompare) selfanalyzernormal_stock_datar @py_assert3 @py_format5 @py_assert0 @py_assert2 @py_assert5 @py_format7 @py_format9s >/mnt/ssd/data/python-lab/Trading/tests/test_warren_analyzer.pytest_score_quality_stockz+TestCalculateScore.test_score_quality_stock s4(():;%%>%>>'>>>>>>>z>>>z>>>>>>%>>>%>>>>>>>>>>>>%>>>>>>[rU [b[Ub [[[[rUb[[[r[[[[[[U[[[U[[[b[[[F5'1Z"[[[[[[[[c\|ji|ddi}|j|}d}||z }||k\}|stjd|fd||fdtjvstj |rtj |nddtjvstj |rtj |ndtj |dz}tjd d zd |iz} ttj| d x}x}}y ) z1Luxury brand (Ferrari) dovrebbe avere score boostsector Industrials >=)z%(py0)s >= (%(py2)s - %(py4)s) luxury_score normal_scorer r r z7Luxury brand dovrebbe avere score comparabile/superiore >assert %(py7)spy7N rrr!rrrrrrr ) r"r#luxury_stock_datar6r5r%r) @py_assert1 @py_format6 @py_format8s r,test_score_luxury_brandz*TestCalculateScore.test_score_luxury_brands//0^3D0^hP]0^_ //0AB /1k|b0k|00kkk|0kkkkkk|kkk|kkkkkk|kkk|kkkbkkk2kkkkkkkkr.c|j|}d}||k\}|stjd|fd||fdtjvstj |rtj |ndtj |dz}tjd|ddzd |iz}ttj|d x}}y ) zBBanca con debt alto non dovrebbe essere penalizzata eccessivamente2r3z%(py0)s >= %(py3)srr py3z+Banca con D/E 5.0 non dovrebbe avere score z < 50 >assert %(py5)spy5Nr:)r"r#financial_stock_datarr(r< @py_format4r=s r,test_score_financial_sectorz.TestCalculateScore.test_score_financial_sectors(()=>Vu{VVVuVVVVVVuVVVuVVVVVVI%PUVVVVVVVr.c|j|}d}||k}|stjd|fd||fdtjvstj |rtj |ndtj |dz}tjd|dzd|iz}ttj|d x}}y ) u.Stock bassa qualità dovrebbe avere score < 50rA<z%(py0)s < %(py3)srrCz1Low quality stock dovrebbe avere score < 50, got rErFNr:)r"r#low_quality_stock_datarr(r<rHr=s r,test_score_low_qualityz)TestCalculateScore.test_score_low_quality"s{(()?@VurzVVVurVVVVVVuVVVuVVVrVVVNugVVVVVVVr.c|j|}d}||k}d}||k}|r|stjd||fd|||ftj|dt j vstj |rtj|ndtj|dz}tjd|dd zd |iz} ttj| d x}x}x}}i|d d dd} |j| } d}|| k}d}| |k}|r|stjd||fd|| |ftj|dt j vstj | rtj| ndtj|dz}tjd| dd zd |iz} ttj| d x}x}x}}y )z$Score deve sempre essere tra 0 e 100rdrrrrrz fuori range 0-100rrNr2)pe_ratioroedebt_to_equity score_extreme rrr!rrrrrrr ) r"r#r$rr'r(r)r%r*r+ extreme_datarWs r,test_score_range_boundsz*TestCalculateScore.test_score_range_bounds(sW(():;DqE DSDES DDDDqESDDDqDDDDDDEDDDEDDDSDDDF5'1C"DDDDDDDDa+`T]_`  00> TqM(TSTMS(TTTTqMSTTTqTTTTTTMTTTMTTTSTTTF=/AS*TTTTTTTTr.N) __name__ __module__ __qualname____doc__r-r?rIrOrZr.r,rr s#'\lWW Ur.rc4eZdZdZdZdZdZdZdZdZ y) TestCalculateFairValuez"Test calculate_fair_value() methodc|j|}d}||kD}|stjd|fd||fdtjvstj |rtj |ndtj |dz}tjddzd|iz}ttj|d x}}y ) z&Fair value deve essere sempre positivor>z%(py0)s > %(py3)s fair_valuerCzFair value deve essere positivorErFN calculate_fair_valuerr!rrrrrrr )r"r#r$rfr(r<rHr=s r,test_fair_value_positivez/TestCalculateFairValue.test_fair_value_positive7st223DE @zA~@@@zA@@@@@@z@@@z@@@A@@@@@@@@@@r.c|j|}|d}d}||z}||k\}|stjd|fd||fdtjvstj |rtj |ndtj |tj |dz}tjd|d|dd zd |iz} ttj| d x}x}x}}y ) z3Growth positivo dovrebbe portare fair value > pricepriceg?r3z%(py0)s >= (%(py3)s * %(py5)s)rfr rDrF Fair value z troppo basso rispetto a price rrNrg) r"r#r$rfr( @py_assert4 @py_assert6r<r*r+s r,test_fair_value_growth_positivez6TestCalculateFairValue.test_fair_value_growth_positive=s223DE /w7 b# b7#= bz== bPaPa bz= b b[a[a b bIaIa b bXaXa b bXaXa8 b bXaXa;> b bPaPak*%DEVW^E_D` a b b bNaNa b b br.cj|j|}d}||kD}|stjd|fd||fdtjvstj |rtj |ndtj |dz}tjd|ddzd |iz}ttj|d x}}|d }d }||z} || k}|stjd |fd|| fdtjvstj |rtj |ndtj |tj |dz} tjd|ddzd| iz} ttj| d x}x}x}} y )z4Growth negativo NON deve causare fair value negativorrcrerfrCrnu* è negativo con growth -30%! Bug critico!rErFNrkg?rz%(py0)s <= (%(py3)s * %(py5)s)rmz troppo alto per stock in crisirrrg) r"r#crisis_stock_datarfr(r<rHr=rorpr*r+s r,test_fair_value_growth_negativez6TestCalculateFairValue.test_fair_value_growth_negativeFs223DE  QzA~ Q?P?P QzA Q QJP& Q Q8P8P Q QGPy Q QGPy Q Q?P?Pk*%O P Q Q Q=P=P Q Q/w7 F# F7#= Fz== F4E4E Fz= F F?Ev F F-E-E F F F F4E4Ek*%D E F F F2E2E F F Fr.ci|ddd}|j|}|d}d}||z}||k}|stjd|fd||fdtjvstj |rtj |ndtj |tj |d z} tjd |d |dd d zd| iz} ttj| dx}x}x}}y)z%Fair value non deve essere > 3x priceg?rTearnings_growthrkrsrtrfrmrnz > 3x price z (sanity cap failed)rrNrg) r"r#r$rYrfr(rorpr<r*r+s r, test_fair_value_sanity_cap_upperz7TestCalculateFairValue.test_fair_value_sanity_cap_upperRs,U+TtT 22<@ )'2 ^Q ^2Q6 ^z66 ^L]L] ^z6 ^ ^W]W] ^ ^E]E] ^ ^T]T] ^ ^T]T]3 ^ ^T]T]67 ^ ^L]L]k*\,w2G1HH\ ] ^ ^ ^J]J] ^ ^ ^r.ci|ddd}|j|}|d}d}||z}||k\}|stjd|fd||fdtjvstj |rtj |ndtj |tj |d z} tjd |d |dd d zd| iz} ttj| dx}x}x}}y)z&Fair value non deve essere < 20% pricerQrSryrkg?r3rlrfrmrnz < 20% price z (sanity floor failed)rrNrg) r"r#r$bad_datarfr(rorpr<r*r+s r, test_fair_value_sanity_cap_lowerz7TestCalculateFairValue.test_fair_value_sanity_cap_lower[s,T'SSUS228< %g. ] ].4 ]z44 ]K\K\ ]z4 ] ]V\V\ ] ]D\D\ ] ]S\S\ ] ]S\S\/ ] ]S\S\25 ] ]K\K\k*]8G3D2EE[ \ ] ] ]I\I\ ] ] ]r.c`i|ddi}|j|}|j|}d}||z}||k\}|stjd|fd||fdtjvstj |rtj |nddtjvstj |rtj |ndtj |dz} tjd d zd | iz} ttj| d x}x}}y ) uCLuxury brand dovrebbe avere fair value più alto (multipli premium)r0r1g?r3)z%(py0)s >= (%(py2)s * %(py4)s)fair_value_luxuryfair_value_normalr7z.Luxury brand dovrebbe avere fair value premiumr8r9Nrg) r"r#r; normal_datarrr%r)r<r=r>s r,test_fair_value_luxury_premiumz5TestCalculateFairValue.test_fair_value_luxury_premiumds(D*DHmD $99+F$99:KL9< =$5$; = $;; =+<+< = $; = =6rsG 7(U(UV9=9=x(^(^V N Nr.