
    M/j	                         S r SSKrSSKJs  Jr  SSKrSSKJ	r	J
r
  S rS rS rS rS rS	 rS
 r\R$                  R'                  S/ SQ5      S 5       rg)uE   Unit tests for bond risk scoring — matches PMChat test conventions.    N)compute_bond_risk_spread_scorec                  "   [        SSSS9n U R                  nSo!U:H  o3(       d  [        R                  " SU4SX45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      S	.-  nS
SU0-  n[        [        R                  " U5      5      eS =n=p2U R                  nSo!UL o3(       d  [        R                  " SU4SX45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      S	.-  nS
SU0-  n[        [        R                  " U5      5      eS =n=p2U R                  nSo!U:  o3(       d  [        R                  " SU4SX45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      S	.-  nS
SU0-  n[        [        R                  " U5      5      eS =n=p2g )NTEST1AAAg      >@isin	rating_spz_spreadzLOW RISK==z7%(py2)s
{%(py2)s = %(py0)s.composite_grade
} == %(py5)sresultpy0py2py5assert %(py7)spy7Tisz;%(py2)s
{%(py2)s = %(py0)s.is_investment_grade
} is %(py5)sK   )>=)z7%(py2)s
{%(py2)s = %(py0)s.composite_score
} >= %(py5)sr   composite_grade
@pytest_ar_call_reprcompare@py_builtinslocals_should_repr_global_name	_safereprAssertionError_format_explanationis_investment_gradecomposite_scorer   @py_assert1@py_assert4@py_assert3@py_format6@py_format8s         4/root/lseg-credit/backend/tests/test_bond_scoring.pytest_aaa_low_spread_is_low_riskr.      sp   F
 !!/Z/Z/////!//////6////6///!///Z///////%%-------%------6----6---%----------!!'R'R'''''!''''''6''''6'''!'''R'''''''    c                  "   [        SSSS9n U R                  nSo!U:H  o3(       d  [        R                  " SU4SX45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      S	.-  nS
SU0-  n[        [        R                  " U5      5      eS =n=p2U R                  nSo!UL o3(       d  [        R                  " SU4SX45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      S	.-  nS
SU0-  n[        [        R                  " U5      5      eS =n=p2U R                  nSo!U:  o3(       d  [        R                  " SU4SX45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      S	.-  nS
SU0-  n[        [        R                  " U5      5      eS =n=p2g )NTEST2Caa2g      @)r	   rating_moodysr   z	HIGH RISKr   r   r   r   r   r   Fr   r   #   )<)z6%(py2)s
{%(py2)s = %(py0)s.composite_score
} < %(py5)sr   r'   s         r-   !test_ccc_wide_spread_is_high_riskr6      sp   F
 !!0[0[00000!000000600006000!000[0000000%%.......%......6....6...%..........!!&B&B&&&&&!&&&&&&6&&&&6&&&!&&&B&&&&&&&r/   c                  x   [        SSSS9n U R                  nSS1o!U;   o3(       d  [        R                  " SU4SX45      S	[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS	[        R                  " U5      [        R                  " U5      S
.-  nSSU0-  n[        [        R                  " U5      5      eS =n=p2U R                  nSo!UL o3(       d  [        R                  " SU4SX45      S	[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS	[        R                  " U5      [        R                  " U5      S
.-  nSSU0-  n[        [        R                  " U5      5      eS =n=p2g )NTEST3BBBg     b@r   zMODERATE RISKzELEVATED RISK)in)z7%(py2)s
{%(py2)s = %(py0)s.composite_grade
} in %(py5)sr   r   r   r   Tr   r   )r   r   r   r   r   r    r!   r"   r#   r$   r%   r'   s         r-   test_bbb_moderate_riskr;      s   F
 !!Go%GG%GGGGGG!GGGGGG6GGGG6GGG!GGG%GGGGGGGG%%-------%------6----6---%----------r/   c                  v   [        SSSS9n U R                  nSo!U:H  o3(       d  [        R                  " SU4SX45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      S	.-  nS
SU0-  n[        [        R                  " U5      5      eS =n=p2U R                  nSo!U:H  o3(       d  [        R                  " SU4SX45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      S	.-  nS
SU0-  n[        [        R                  " U5      5      eS =n=p2g )NTEST4      Y@g     @@)r	   r   asset_swap_spreadr   r   z3%(py2)s
{%(py2)s = %(py0)s.spread_used
} == %(py5)sr   r   r   r   )z2%(py2)s
{%(py2)s = %(py0)s.spread_bps
} == %(py5)s)r   spread_usedr   r   r   r    r!   r"   r#   r$   
spread_bpsr'   s         r-   4test_spread_priority_z_spread_over_asset_swap_spreadrC   (   s    F
 +++++++++++++6++++6+++++++++++++%%%%%%%%%%%%%6%%%%6%%%%%%%%%%%%%r/   c                     [        SSS9n U R                  nSo!U:H  o3(       d  [        R                  " SU4SX45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      S.-  nS	S
U0-  n[        [        R                  " U5      5      eS =n=p2g )NTEST5g      i@r	   r   r   r   r@   r   r   r   r   )
r   rA   r   r   r   r    r!   r"   r#   r$   r'   s         r-    test_spread_fallback_to_z_spreadrG   2   s    F +++++++++++++6++++6+++++++++++++r/   c                  j   [        SSS9n U R                  nS o!UL o3(       d  [        R                  " SU4SX45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      S.-  nSS	U0-  n[        [        R                  " U5      5      eS =n=p2U R                  nS o!UL o3(       d  [        R                  " SU4S
X45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      S.-  nSS	U0-  n[        [        R                  " U5      5      eS =n=p2So`R                  ovU:*  nSoU	:*  o8(       a  U(       d  [        R                  " SX4SXgU	45      [        R                  " U5      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U	5      S.-  n
SSU
0-  n[        [        R                  " U5      5      eS =n=n=n=pyg )NTEST6      I@rF   r   )z4%(py2)s
{%(py2)s = %(py0)s.rating_score
} is %(py5)sr   r   r   r   )z4%(py2)s
{%(py2)s = %(py0)s.rating_grade
} is %(py5)sg        r>   )<=rK   )z7%(py1)s <= %(py6)s
{%(py6)s = %(py4)s.composite_score
}z7%(py6)s
{%(py6)s = %(py4)s.composite_score
} <= %(py8)s)py1py4py6py8zassert %(py10)spy10)r   rating_scorer   r   r   r    r!   r"   r#   r$   rating_grader&   )r   r(   r)   r*   r+   r,   @py_assert0@py_assert5@py_assert2@py_assert7@py_format9@py_format11s               r-   $test_no_rating_redistributes_weightsrY   :   s   F &$&$&&&&&&&&&&&6&&&&6&&&&&&$&&&&&&&&$&$&&&&&&&&&&&6&&&&6&&&&&&$&&&&&&&1((1(11E1E1111113E1113111111&1111&111(111E11111111r/   c                     [        SS9n U R                  nSo!U:H  o3(       d  [        R                  " SU4SX45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      S.-  nSS	U0-  n[        [        R                  " U5      5      eS =n=p2U R                  nS o!UL o3(       d  [        R                  " S
U4SX45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      S.-  nSS	U0-  n[        [        R                  " U5      5      eS =n=p2U R                  nSo!U:H  o3(       d  [        R                  " SU4SX45      S[        R
                  " 5       ;   d  [        R                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      [        R                  " U5      S.-  nSS	U0-  n[        [        R                  " U5      5      eS =n=p2g )NTEST7)r	   noner   r@   r   r   r   r   r   )z2%(py2)s
{%(py2)s = %(py0)s.spread_bps
} is %(py5)srJ   )z4%(py2)s
{%(py2)s = %(py0)s.spread_score
} == %(py5)s)r   rA   r   r   r   r    r!   r"   r#   r$   rB   spread_scorer'   s         r-   %test_all_missing_data_returns_neutralr^   D   se   G,F'''''''''''''6''''6'''''''''''''$$$$$$$$$$$$$6$$$$6$$$$$$$$$$$$$&$&$&&&&&&&&&&&6&&&&6&&&&&&$&&&&&&&r/   zbps,expected))   r>   )r   g     V@)   g     R@)i,  g     K@)i  g      D@)iX  g      9@)i  g      $@c                    [        U 5      o"U:H  o3(       GdC  [        R                  " SU4SX!45      S[        R                  " 5       ;   d  [        R
                  " [         5      (       a  [        R                  " [         5      OSS[        R                  " 5       ;   d  [        R
                  " U 5      (       a  [        R                  " U 5      OS[        R                  " U5      S[        R                  " 5       ;   d  [        R
                  " U5      (       a  [        R                  " U5      OSS.-  nSSU0-  n[        [        R                  " U5      5      eS =p#g )	Nr   )z0%(py3)s
{%(py3)s = %(py0)s(%(py1)s)
} == %(py5)sr   bpsexpected)r   rL   py3r   r   r   )	r   r   r   r   r    r!   r"   r#   r$   )rb   rc   rU   r)   r+   r,   s         r-   test_spread_score_thresholdsre   M   s     ))))))))))))=))))=))))))))))))))))))))))))))))))r/   )__doc__builtinsr   _pytest.assertion.rewrite	assertionrewriter   pytestapp.scoring.bondr   r   r.   r6   r;   rC   rG   rY   r^   markparametrizere    r/   r-   <module>rp      s_    K    =
('.&,2'  * **r/   