Compute portfolio average long-term rating¶
The following case-study demonstrates how to compute the average long-term rating of your portfolio.
Preliminary tasks¶
As a first step, we are going to import a portfolio into a pd.DataFrame
. We'll call
it port_df
. This dataframe comprises a number of securities with respective weights
and ratings.
import pandas as pd
import pyratings as rtg
port_df = pd.read_excel("portfolio.xlsx", sheet_name="long_term_ratings_worst")
port_df.head()
ISIN | weight | worst_rtg | |
---|---|---|---|
0 | ISIN00000001 | 0.518515 | AAA |
1 | ISIN00000002 | 0.950810 | AA+ |
2 | ISIN00000003 | 0.497176 | AA |
3 | ISIN00000004 | 0.648453 | AA- |
4 | ISIN00000005 | 0.674328 | AA- |
Translating ratings into numerical scores¶
The column worst_rtg will be used in order to translate the ratings into scores according to the following table.
We will use
get_scores_from_ratings
to translate the human-readable ratings into numerical scores. The function needs a
rating provider (here: "S&P") in order to select an appropriate translation dictionary.
port_scores_df = pd.concat(
[
port_df,
rtg.get_scores_from_ratings(
ratings=port_df["worst_rtg"],
rating_provider="S&P")
],
axis=1
)
port_scores_df
ISIN | weight | worst_rtg | rtg_score_worst_rtg | |
---|---|---|---|---|
0 | ISIN00000001 | 0.518515 | AAA | 1.0 |
1 | ISIN00000002 | 0.950810 | AA+ | 2.0 |
2 | ISIN00000003 | 0.497176 | AA | 3.0 |
3 | ISIN00000004 | 0.648453 | AA- | 4.0 |
4 | ISIN00000005 | 0.674328 | AA- | 4.0 |
... | ... | ... | ... | ... |
82 | ISIN00000083 | 2.321185 | BBB+ | 8.0 |
83 | ISIN00000084 | 1.389043 | BBB+ | 8.0 |
84 | ISIN00000085 | 2.296711 | BBB+ | 8.0 |
85 | ISIN00000086 | 1.015105 | AAA | 1.0 |
86 | ISIN00000087 | 0.964399 | AA | 3.0 |
87 rows × 4 columns
Here, the get_scores_from_ratings
function has been used to translate the worst_rtg column into numerical scores.
That is, we used a column that has already been consolidated.
pyratings offers some convenience functions that consolidate multiple ratings and directly compute the respective numerical rating scores. These functions are
Finally, we need to compute a weighted average rating score, which we subsequently
convert back into a human-readable rating. For the former, we use the
get_weighted_average
function and for the latter the
get_ratings_from_scores
function.
avg_rtg_score = rtg.get_weighted_average(
data=port_scores_df["rtg_score_worst_rtg"],
weights=port_scores_df["weight"] / 100,
)
print(f"Average rating score: {avg_rtg_score:.2f}")
Average rating score: 4.39
avg_rtg = rtg.get_ratings_from_scores(
rating_scores=avg_rtg_score,
rating_provider="S&P"
)
print(f"Average portfolio rating: {avg_rtg}")
Average portfolio rating: AA-
There you go. The average rating of the portfolio is AA-.
Do you prefer to show the rating using Moody's rating scale? — It's as simple as
changing the rating_provider
argument to "Moody".
avg_rtg = rtg.get_ratings_from_scores(
rating_scores=avg_rtg_score,
rating_provider="Moody"
)
print(f"Average portfolio rating: {avg_rtg}")
Average portfolio rating: Aa3