Consolidate ratings¶
Oftentimes, an individual security/entity has ratings from several rating agencies. For
example, a security might have a BBB- rating from S&P, a BBB rating from Fitch, and
a Ba1 rating from Moody's.
Now, let's imagine your investment guidelines only allow investments in securities
that have an investment grade rating, i.e. Baa3/BBB- at a minimum. You might wonder
which of the attached ratings is relevant? Is this particular security regarded as
investment grade (as S&P and Fitch are indicating) or is it already a junk bond (as
implied by Moody's)? — Well, there's no definitive answer, it simply depends.
There are several ways to answer this question. pyratings offers the following three functions in order to consolidate multiple ratings into a final rating:
get_best_ratings
Choose the best rating among all rating agencies. That's the aggressive way.get_second_best_ratings
Choose the second-best rating among all rating agencies. That's a less aggressive way.get_worst_ratings
Choose the worst rating among all rating agencies. That's the conservative way.
import pandas as pd
import numpy as np
import pyratings as rtg
ratings_df = pd.DataFrame(
data=(
{
"rating_S&P": ['AAA', 'AA-', 'AA+', 'BB-', 'C'],
"rating_Moody's": ['Aa1', 'Aa3', 'Aa2', 'Ba3', 'Ca'],
"rating_Fitch": ['AA-', 'AA-', 'AA-', 'B+', 'C'],
}
),
index=[f'security_{i}' for i in range(5)]
)
ratings_df
rating_S&P | rating_Moody's | rating_Fitch | |
---|---|---|---|
security_0 | AAA | Aa1 | AA- |
security_1 | AA- | Aa3 | AA- |
security_2 | AA+ | Aa2 | AA- |
security_3 | BB- | Ba3 | B+ |
security_4 | C | Ca | C |
best_ratings = rtg.get_best_ratings(
ratings=ratings_df, rating_provider_input=["S&P", "Moody", "Fitch"]
)
second_best_ratings = rtg.get_second_best_ratings(
ratings=ratings_df, rating_provider_input=["S&P", "Moody", "Fitch"]
)
worst_ratings = rtg.get_worst_ratings(
ratings=ratings_df, rating_provider_input=["S&P", "Moody", "Fitch"]
)
pd.concat([best_ratings, second_best_ratings, worst_ratings], axis=1)
best_rtg | second_best_rtg | worst_rtg | |
---|---|---|---|
security_0 | AAA | AA+ | AA- |
security_1 | AA- | AA- | AA- |
security_2 | AA+ | AA | AA- |
security_3 | BB- | BB- | B+ |
security_4 | CC | C | C |
Did you realize that the output dataframe only uses S&P/Fitch rating scales? If you
prefer to get the results in a different ratings scale, you can specify the
rating_provider_output
argument.
Also, if you don't specify rating_provider_input
, pyratings tries to infer the correct rating provider from ratings_df
column headers.
best_ratings = rtg.get_best_ratings(
ratings=ratings_df, rating_provider_output="Moody",
)
second_best_ratings = rtg.get_second_best_ratings(
ratings=ratings_df, rating_provider_output="Moody",
)
worst_ratings = rtg.get_worst_ratings(
ratings=ratings_df, rating_provider_output="Moody"
)
pd.concat([best_ratings, second_best_ratings, worst_ratings], axis=1)
best_rtg | second_best_rtg | worst_rtg | |
---|---|---|---|
security_0 | Aaa | Aa1 | Aa3 |
security_1 | Aa3 | Aa3 | Aa3 |
security_2 | Aa1 | Aa2 | Aa3 |
security_3 | Ba3 | Ba3 | B1 |
security_4 | Ca | C | C |