04. Ken French Data and Pandas DataReader¶
Pandas DataReader is a powerful tool that provides easy access to various financial data sources through a consistent API. The Ken French Data Library, accessible through pandas_datareader, offers a comprehensive collection of:
- Historical stock returns organized into various portfolios
- Risk factors (like market, size, value, momentum)
- Pre-calculated research datasets commonly used in empirical asset pricing
In this notebook, we'll explore how to access and use these datasets using pandas_datareader.
Browsing the Data¶
First, let's see what datasets are available:
import warnings
import pandas as pd
from pandas_datareader.famafrench import get_available_datasets
import pandas_datareader.data as web
len(get_available_datasets())
297
get_available_datasets()
['F-F_Research_Data_Factors', 'F-F_Research_Data_Factors_weekly', 'F-F_Research_Data_Factors_daily', 'F-F_Research_Data_5_Factors_2x3', 'F-F_Research_Data_5_Factors_2x3_daily', 'Portfolios_Formed_on_ME', 'Portfolios_Formed_on_ME_Wout_Div', 'Portfolios_Formed_on_ME_Daily', 'Portfolios_Formed_on_BE-ME', 'Portfolios_Formed_on_BE-ME_Wout_Div', 'Portfolios_Formed_on_BE-ME_Daily', 'Portfolios_Formed_on_OP', 'Portfolios_Formed_on_OP_Wout_Div', 'Portfolios_Formed_on_OP_Daily', 'Portfolios_Formed_on_INV', 'Portfolios_Formed_on_INV_Wout_Div', 'Portfolios_Formed_on_INV_Daily', '6_Portfolios_2x3', '6_Portfolios_2x3_Wout_Div', '6_Portfolios_2x3_weekly', '6_Portfolios_2x3_daily', '25_Portfolios_5x5', '25_Portfolios_5x5_Wout_Div', '25_Portfolios_5x5_Daily', '100_Portfolios_10x10', '100_Portfolios_10x10_Wout_Div', '100_Portfolios_10x10_Daily', '6_Portfolios_ME_OP_2x3', '6_Portfolios_ME_OP_2x3_Wout_Div', '6_Portfolios_ME_OP_2x3_daily', '25_Portfolios_ME_OP_5x5', '25_Portfolios_ME_OP_5x5_Wout_Div', '25_Portfolios_ME_OP_5x5_daily', '100_Portfolios_ME_OP_10x10', '100_Portfolios_10x10_ME_OP_Wout_Div', '100_Portfolios_ME_OP_10x10_daily', '6_Portfolios_ME_INV_2x3', '6_Portfolios_ME_INV_2x3_Wout_Div', '6_Portfolios_ME_INV_2x3_daily', '25_Portfolios_ME_INV_5x5', '25_Portfolios_ME_INV_5x5_Wout_Div', '25_Portfolios_ME_INV_5x5_daily', '100_Portfolios_ME_INV_10x10', '100_Portfolios_10x10_ME_INV_Wout_Div', '100_Portfolios_ME_INV_10x10_daily', '25_Portfolios_BEME_OP_5x5', '25_Portfolios_BEME_OP_5x5_Wout_Div', '25_Portfolios_BEME_OP_5x5_daily', '25_Portfolios_BEME_INV_5x5', '25_Portfolios_BEME_INV_5x5_Wout_Div', '25_Portfolios_BEME_INV_5x5_daily', '25_Portfolios_OP_INV_5x5', '25_Portfolios_OP_INV_5x5_Wout_Div', '25_Portfolios_OP_INV_5x5_daily', '32_Portfolios_ME_BEME_OP_2x4x4', '32_Portfolios_ME_BEME_OP_2x4x4_Wout_Div', '32_Portfolios_ME_BEME_INV_2x4x4', '32_Portfolios_ME_BEME_INV_2x4x4_Wout_Div', '32_Portfolios_ME_OP_INV_2x4x4', '32_Portfolios_ME_OP_INV_2x4x4_Wout_Div', 'Portfolios_Formed_on_E-P', 'Portfolios_Formed_on_E-P_Wout_Div', 'Portfolios_Formed_on_CF-P', 'Portfolios_Formed_on_CF-P_Wout_Div', 'Portfolios_Formed_on_D-P', 'Portfolios_Formed_on_D-P_Wout_Div', '6_Portfolios_ME_EP_2x3', '6_Portfolios_ME_EP_2x3_Wout_Div', '6_Portfolios_ME_CFP_2x3', '6_Portfolios_ME_CFP_2x3_Wout_Div', '6_Portfolios_ME_DP_2x3', '6_Portfolios_ME_DP_2x3_Wout_Div', 'F-F_Momentum_Factor', 'F-F_Momentum_Factor_daily', '6_Portfolios_ME_Prior_12_2', '6_Portfolios_ME_Prior_12_2_Daily', '25_Portfolios_ME_Prior_12_2', '25_Portfolios_ME_Prior_12_2_Daily', '10_Portfolios_Prior_12_2', '10_Portfolios_Prior_12_2_Daily', 'F-F_ST_Reversal_Factor', 'F-F_ST_Reversal_Factor_daily', '6_Portfolios_ME_Prior_1_0', '6_Portfolios_ME_Prior_1_0_Daily', '25_Portfolios_ME_Prior_1_0', '25_Portfolios_ME_Prior_1_0_Daily', '10_Portfolios_Prior_1_0', '10_Portfolios_Prior_1_0_Daily', 'F-F_LT_Reversal_Factor', 'F-F_LT_Reversal_Factor_daily', '6_Portfolios_ME_Prior_60_13', '6_Portfolios_ME_Prior_60_13_Daily', '25_Portfolios_ME_Prior_60_13', '25_Portfolios_ME_Prior_60_13_Daily', '10_Portfolios_Prior_60_13', '10_Portfolios_Prior_60_13_Daily', 'Portfolios_Formed_on_AC', '25_Portfolios_ME_AC_5x5', 'Portfolios_Formed_on_BETA', '25_Portfolios_ME_BETA_5x5', 'Portfolios_Formed_on_NI', '25_Portfolios_ME_NI_5x5', 'Portfolios_Formed_on_VAR', '25_Portfolios_ME_VAR_5x5', 'Portfolios_Formed_on_RESVAR', '25_Portfolios_ME_RESVAR_5x5', '5_Industry_Portfolios', '5_Industry_Portfolios_Wout_Div', '5_Industry_Portfolios_daily', '10_Industry_Portfolios', '10_Industry_Portfolios_Wout_Div', '10_Industry_Portfolios_daily', '12_Industry_Portfolios', '12_Industry_Portfolios_Wout_Div', '12_Industry_Portfolios_daily', '17_Industry_Portfolios', '17_Industry_Portfolios_Wout_Div', '17_Industry_Portfolios_daily', '30_Industry_Portfolios', '30_Industry_Portfolios_Wout_Div', '30_Industry_Portfolios_daily', '38_Industry_Portfolios', '38_Industry_Portfolios_Wout_Div', '38_Industry_Portfolios_daily', '48_Industry_Portfolios', '48_Industry_Portfolios_Wout_Div', '48_Industry_Portfolios_daily', '49_Industry_Portfolios', '49_Industry_Portfolios_Wout_Div', '49_Industry_Portfolios_daily', 'ME_Breakpoints', 'BE-ME_Breakpoints', 'OP_Breakpoints', 'INV_Breakpoints', 'E-P_Breakpoints', 'CF-P_Breakpoints', 'D-P_Breakpoints', 'Prior_2-12_Breakpoints', 'Developed_3_Factors', 'Developed_3_Factors_Daily', 'Developed_ex_US_3_Factors', 'Developed_ex_US_3_Factors_Daily', 'Europe_3_Factors', 'Europe_3_Factors_Daily', 'Japan_3_Factors', 'Japan_3_Factors_Daily', 'Asia_Pacific_ex_Japan_3_Factors', 'Asia_Pacific_ex_Japan_3_Factors_Daily', 'North_America_3_Factors', 'North_America_3_Factors_Daily', 'Developed_5_Factors', 'Developed_5_Factors_Daily', 'Developed_ex_US_5_Factors', 'Developed_ex_US_5_Factors_Daily', 'Europe_5_Factors', 'Europe_5_Factors_Daily', 'Japan_5_Factors', 'Japan_5_Factors_Daily', 'Asia_Pacific_ex_Japan_5_Factors', 'Asia_Pacific_ex_Japan_5_Factors_Daily', 'North_America_5_Factors', 'North_America_5_Factors_Daily', 'Developed_Mom_Factor', 'Developed_Mom_Factor_Daily', 'Developed_ex_US_Mom_Factor', 'Developed_ex_US_Mom_Factor_Daily', 'Europe_Mom_Factor', 'Europe_Mom_Factor_Daily', 'Japan_Mom_Factor', 'Japan_Mom_Factor_Daily', 'Asia_Pacific_ex_Japan_MOM_Factor', 'Asia_Pacific_ex_Japan_MOM_Factor_Daily', 'North_America_Mom_Factor', 'North_America_Mom_Factor_Daily', 'Developed_6_Portfolios_ME_BE-ME', 'Developed_6_Portfolios_ME_BE-ME_daily', 'Developed_ex_US_6_Portfolios_ME_BE-ME', 'Developed_ex_US_6_Portfolios_ME_BE-ME_daily', 'Europe_6_Portfolios_ME_BE-ME', 'Europe_6_Portfolios_ME_BE-ME_daily', 'Japan_6_Portfolios_ME_BE-ME', 'Japan_6_Portfolios_ME_BE-ME_daily', 'Asia_Pacific_ex_Japan_6_Portfolios_ME_BE-ME', 'Asia_Pacific_ex_Japan_6_Portfolios_ME_BE-ME_daily', 'North_America_6_Portfolios_ME_BE-ME', 'North_America_6_Portfolios_ME_BE-ME_daily', 'Developed_25_Portfolios_ME_BE-ME', 'Developed_25_Portfolios_ME_BE-ME_daily', 'Developed_ex_US_25_Portfolios_ME_BE-ME', 'Developed_ex_US_25_Portfolios_ME_BE-ME_daily', 'Europe_25_Portfolios_ME_BE-ME', 'Europe_25_Portfolios_ME_BE-ME_daily', 'Japan_25_Portfolios_ME_BE-ME', 'Japan_25_Portfolios_ME_BE-ME_daily', 'Asia_Pacific_ex_Japan_25_Portfolios_ME_BE-ME', 'Asia_Pacific_ex_Japan_25_Portfolios_ME_BE-ME_daily', 'North_America_25_Portfolios_ME_BE-ME', 'North_America_25_Portfolios_ME_BE-ME_daily', 'Developed_6_Portfolios_ME_OP', 'Developed_6_Portfolios_ME_OP_Daily', 'Developed_ex_US_6_Portfolios_ME_OP', 'Developed_ex_US_6_Portfolios_ME_OP_Daily', 'Europe_6_Portfolios_ME_OP', 'Europe_6_Portfolios_ME_OP_Daily', 'Japan_6_Portfolios_ME_OP', 'Japan_6_Portfolios_ME_OP_Daily', 'Asia_Pacific_ex_Japan_6_Portfolios_ME_OP', 'Asia_Pacific_ex_Japan_6_Portfolios_ME_OP_Daily', 'North_America_6_Portfolios_ME_OP', 'North_America_6_Portfolios_ME_OP_Daily', 'Developed_25_Portfolios_ME_OP', 'Developed_25_Portfolios_ME_OP_Daily', 'Developed_ex_US_25_Portfolios_ME_OP', 'Developed_ex_US_25_Portfolios_ME_OP_Daily', 'Europe_25_Portfolios_ME_OP', 'Europe_25_Portfolios_ME_OP_Daily', 'Japan_25_Portfolios_ME_OP', 'Japan_25_Portfolios_ME_OP_Daily', 'Asia_Pacific_ex_Japan_25_Portfolios_ME_OP', 'Asia_Pacific_ex_Japan_25_Portfolios_ME_OP_Daily', 'North_America_25_Portfolios_ME_OP', 'North_America_25_Portfolios_ME_OP_Daily', 'Developed_6_Portfolios_ME_INV', 'Developed_6_Portfolios_ME_INV_Daily', 'Developed_ex_US_6_Portfolios_ME_INV', 'Developed_ex_US_6_Portfolios_ME_INV_Daily', 'Europe_6_Portfolios_ME_INV', 'Europe_6_Portfolios_ME_INV_Daily', 'Japan_6_Portfolios_ME_INV', 'Japan_6_Portfolios_ME_INV_Daily', 'Asia_Pacific_ex_Japan_6_Portfolios_ME_INV', 'Asia_Pacific_ex_Japan_6_Portfolios_ME_INV_Daily', 'North_America_6_Portfolios_ME_INV', 'North_America_6_Portfolios_ME_INV_Daily', 'Developed_25_Portfolios_ME_INV', 'Developed_25_Portfolios_ME_INV_Daily', 'Developed_ex_US_25_Portfolios_ME_INV', 'Developed_ex_US_25_Portfolios_ME_INV_Daily', 'Europe_25_Portfolios_ME_INV', 'Europe_25_Portfolios_ME_INV_Daily', 'Japan_25_Portfolios_ME_INV', 'Japan_25_Portfolios_ME_INV_Daily', 'Asia_Pacific_ex_Japan_25_Portfolios_ME_INV', 'Asia_Pacific_ex_Japan_25_Portfolios_ME_INV_Daily', 'North_America_25_Portfolios_ME_INV', 'North_America_25_Portfolios_ME_INV_Daily', 'Developed_6_Portfolios_ME_Prior_12_2', 'Developed_6_Portfolios_ME_Prior_250_20_daily', 'Developed_ex_US_6_Portfolios_ME_Prior_12_2', 'Developed_ex_US_6_Portfolios_ME_Prior_250_20_daily', 'Europe_6_Portfolios_ME_Prior_12_2', 'Europe_6_Portfolios_ME_Prior_250_20_daily', 'Japan_6_Portfolios_ME_Prior_12_2', 'Japan_6_Portfolios_ME_Prior_250_20_daily', 'Asia_Pacific_ex_Japan_6_Portfolios_ME_Prior_12_2', 'Asia_Pacific_ex_Japan_6_Portfolios_ME_Prior_250_20_daily', 'North_America_6_Portfolios_ME_Prior_12_2', 'North_America_6_Portfolios_ME_Prior_250_20_daily', 'Developed_25_Portfolios_ME_Prior_12_2', 'Developed_25_Portfolios_ME_Prior_250_20_daily', 'Developed_ex_US_25_Portfolios_ME_Prior_12_2', 'Developed_ex_US_25_Portfolios_ME_Prior_250_20_daily', 'Europe_25_Portfolios_ME_Prior_12_2', 'Europe_25_Portfolios_ME_Prior_250_20_daily', 'Japan_25_Portfolios_ME_Prior_12_2', 'Japan_25_Portfolios_ME_Prior_250_20_daily', 'Asia_Pacific_ex_Japan_25_Portfolios_ME_Prior_12_2', 'Asia_Pacific_ex_Japan_25_Portfolios_ME_Prior_250_20_daily', 'North_America_25_Portfolios_ME_Prior_12_2', 'North_America_25_Portfolios_ME_Prior_250_20_daily', 'Developed_32_Portfolios_ME_BE-ME_OP_2x4x4', 'Developed_ex_US_32_Portfolios_ME_BE-ME_OP_2x4x4', 'Europe_32_Portfolios_ME_BE-ME_OP_2x4x4', 'Japan_32_Portfolios_ME_BE-ME_OP_2x4x4', 'Asia_Pacific_ex_Japan_32_Portfolios_ME_BE-ME_OP_2x4x4', 'North_America_32_Portfolios_ME_BE-ME_OP_2x4x4', 'Developed_32_Portfolios_ME_BE-ME_INV(TA)_2x4x4', 'Developed_ex_US_32_Portfolios_ME_BE-ME_INV(TA)_2x4x4', 'Europe_32_Portfolios_ME_BE-ME_INV(TA)_2x4x4', 'Japan_32_Portfolios_ME_BE-ME_INV(TA)_2x4x4', 'Asia_Pacific_ex_Japan_32_Portfolios_ME_BE-ME_INV(TA)_2x4x4', 'North_America_32_Portfolios_ME_BE-ME_INV(TA)_2x4x4', 'Developed_32_Portfolios_ME_INV(TA)_OP_2x4x4', 'Developed_ex_US_32_Portfolios_ME_INV(TA)_OP_2x4x4', 'Europe_32_Portfolios_ME_INV(TA)_OP_2x4x4', 'Japan_32_Portfolios_ME_INV(TA)_OP_2x4x4', 'Asia_Pacific_ex_Japan_32_Portfolios_ME_INV(TA)_OP_2x4x4', 'North_America_32_Portfolios_ME_INV(TA)_OP_2x4x4', 'Emerging_5_Factors', 'Emerging_MOM_Factor', 'Emerging_Markets_6_Portfolios_ME_BE-ME', 'Emerging_Markets_6_Portfolios_ME_OP', 'Emerging_Markets_6_Portfolios_ME_INV', 'Emerging_Markets_6_Portfolios_ME_Prior_12_2', 'Emerging_Markets_4_Portfolios_BE-ME_OP', 'Emerging_Markets_4_Portfolios_OP_INV', 'Emerging_Markets_4_Portfolios_BE-ME_INV']
For this short demo, let's focus on 25_Portfolios_OP_INV_5x5_daily
, which is a dataset of 25 portfolios of stocks 25 sorted based on Operating Profitability and Investment
Note that there are 3 that are very similar:
25_Portfolios_OP_INV_5x5
25_Portfolios_OP_INV_5x5_Wout_Div
25_Portfolios_OP_INV_5x5_daily
You can find more information these portfolios here:
Univariate Sort Portfolios Formed on Investment
Daily Returns: July 1, 1963 - November 30, 2024
Monthly Returns: July 1963 - November 2024
Annual Returns: 1964 - 2023
Construction: The portfolios, which are constructed at the end of each June, are the intersections of 5 portfolios formed on profitability (OP) and 5 portfolios formed on investment (Inv). OP for June of year t is annual revenues minus cost of goods sold, interest expense, and selling, general, and administrative expenses divided by book equity for the last fiscal year end in t-1. The OP breakpoints are NYSE quintiles. Investment is the change in total assets from the fiscal year ending in year t-2 to the fiscal year ending in t-1, divided by t-2 total assets. The Inv breakpoints are NYSE quintiles. Please be aware that some of the value-weight averages of operating profitability for deciles 1 and 10 are extreme. These are driven by extraordinary values of OP for individual firms. We have spot checked the accounting data that produce the extraordinary values and all the numbers we examined accurately reflect the data in the firm's accounting statements. Stocks: The portfolios for July of year t to June of t+1 include all NYSE, AMEX, and NASDAQ stocks for which we have (positive) BE for t-1, total assets data for t-2 and t-1, non-missing revenues data for t-1, and non-missing data for at least one of the following: cost of goods sold, selling, general and administrative expenses, or interest expense for t-1.
DISCUSSION: Why characteristic-based portfolios?¶
Suppose I thought that stocks with, say, high operating profitability and low investment are more likely to be undervalued. Why would I be interested in forming portfolios based off of this characteristic rather just choose 1 or two stocks of companies that have high operating profitability and low investment?
- Testing theories?
- Diversification?
with warnings.catch_warnings():
warnings.filterwarnings(
"ignore",
category=FutureWarning,
message="The argument 'date_parser' is deprecated",
)
ds = web.DataReader('25_Portfolios_OP_INV_5x5_daily', 'famafrench')
ds.keys()
dict_keys([0, 1, 2, 3, 'DESCR'])
ds
{0: LoOP LoINV OP1 INV2 OP1 INV3 OP1 INV4 LoOP HiINV OP2 INV1 \ Date 2020-02-05 0.39 2.01 1.20 1.11 -0.57 1.85 2020-02-06 -0.64 0.24 0.32 0.72 0.76 0.62 2020-02-07 -0.84 -0.43 -0.71 -1.26 -0.68 -0.35 2020-02-10 0.92 0.66 0.09 1.36 1.36 0.70 2020-02-11 0.49 0.66 0.07 0.62 0.14 1.20 ... ... ... ... ... ... ... 2024-12-24 0.98 0.94 0.47 0.96 1.70 0.94 2024-12-26 1.49 0.14 -0.33 0.20 0.08 0.32 2024-12-27 -1.80 -0.72 -1.40 -1.44 -2.26 -0.68 2024-12-30 -1.16 -1.85 -1.08 -1.42 -1.90 -0.96 2024-12-31 -0.31 -0.65 -0.32 -0.30 -1.30 0.20 OP2 INV2 OP2 INV3 OP2 INV4 OP2 INV5 ... OP4 INV1 OP4 INV2 \ Date ... 2020-02-05 2.78 -1.19 0.90 1.31 ... 1.84 0.83 2020-02-06 -0.62 0.03 -0.26 -0.23 ... 0.33 0.14 2020-02-07 -0.87 -0.72 -0.49 -0.51 ... -1.14 -0.93 2020-02-10 0.20 0.50 0.42 0.76 ... 0.27 0.22 2020-02-11 0.90 0.54 0.07 0.78 ... 1.01 1.62 ... ... ... ... ... ... ... ... 2024-12-24 0.95 0.85 0.78 1.04 ... 0.37 1.67 2024-12-26 0.08 0.15 0.28 -0.11 ... -0.18 0.01 2024-12-27 -0.54 -0.80 -0.92 -0.94 ... -1.96 -1.05 2024-12-30 -0.89 -0.92 -0.83 -1.03 ... 0.25 -0.96 2024-12-31 0.21 0.03 0.21 -0.24 ... -2.10 -0.15 OP4 INV3 OP4 INV4 OP4 INV5 HiOP LoINV OP5 INV2 OP5 INV3 \ Date 2020-02-05 1.11 2.34 0.74 0.93 1.23 1.24 2020-02-06 0.23 -0.43 0.24 0.17 0.54 0.13 2020-02-07 -0.39 -1.08 -0.11 -1.07 -1.06 -0.75 2020-02-10 0.12 0.26 0.59 0.41 0.36 0.82 2020-02-11 0.55 0.92 -0.41 0.47 -0.17 0.02 ... ... ... ... ... ... ... 2024-12-24 0.65 0.97 1.31 0.41 1.28 0.72 2024-12-26 0.17 -0.07 -0.42 0.29 0.67 0.09 2024-12-27 -0.42 -1.18 -1.06 -0.77 -1.15 -0.51 2024-12-30 -0.80 -0.88 -1.11 -1.05 -1.49 -0.90 2024-12-31 0.66 -0.52 -0.71 0.25 -0.49 0.30 OP5 INV4 HiOP HiINV Date 2020-02-05 1.00 0.33 2020-02-06 0.86 0.77 2020-02-07 -0.35 0.13 2020-02-10 1.51 1.92 2020-02-11 -0.79 0.57 ... ... ... 2024-12-24 0.91 0.81 2024-12-26 0.00 -0.18 2024-12-27 -0.62 -1.37 2024-12-30 -0.91 -1.22 2024-12-31 0.11 -0.47 [1235 rows x 25 columns], 1: LoOP LoINV OP1 INV2 OP1 INV3 OP1 INV4 LoOP HiINV OP2 INV1 \ Date 2020-02-05 1.35 1.57 1.32 0.98 1.09 1.60 2020-02-06 -0.33 -0.75 -0.26 0.10 0.18 -0.15 2020-02-07 -1.92 -1.18 -0.31 -1.66 -1.38 -0.99 2020-02-10 0.95 0.18 0.04 0.82 0.83 0.53 2020-02-11 0.41 1.22 0.30 1.11 0.00 0.64 ... ... ... ... ... ... ... 2024-12-24 1.29 0.74 0.46 0.91 1.14 2.18 2024-12-26 3.27 2.65 1.96 1.49 2.78 0.87 2024-12-27 -0.03 0.03 -1.61 0.01 -0.95 -0.34 2024-12-30 1.08 -0.59 -0.74 0.09 1.36 -1.03 2024-12-31 -0.48 1.16 1.14 0.03 -0.46 0.46 OP2 INV2 OP2 INV3 OP2 INV4 OP2 INV5 ... OP4 INV1 OP4 INV2 \ Date ... 2020-02-05 2.19 1.71 1.40 1.79 ... 2.54 2.04 2020-02-06 -1.00 -0.55 -0.41 -0.46 ... -0.07 -0.74 2020-02-07 -1.26 -0.92 -0.78 -0.89 ... -0.24 -1.54 2020-02-10 0.02 0.05 -0.03 -0.28 ... -0.47 0.42 2020-02-11 0.49 0.42 0.29 0.49 ... 1.27 2.29 ... ... ... ... ... ... ... ... 2024-12-24 1.13 0.58 0.81 0.93 ... 0.47 0.98 2024-12-26 0.53 0.84 0.67 0.67 ... 0.63 0.54 2024-12-27 -0.92 -1.02 -1.15 -0.98 ... -1.02 -1.18 2024-12-30 -0.42 0.03 -0.57 -0.28 ... -0.42 -0.54 2024-12-31 0.34 -0.15 0.11 -0.18 ... 0.96 0.37 OP4 INV3 OP4 INV4 OP4 INV5 HiOP LoINV OP5 INV2 OP5 INV3 \ Date 2020-02-05 1.76 1.18 1.97 2.79 1.41 2.09 2020-02-06 -0.35 -0.62 -0.14 -0.73 0.06 -0.54 2020-02-07 -0.94 -1.40 -1.41 -1.85 -1.27 -1.99 2020-02-10 0.08 0.47 0.44 -0.32 -0.13 0.39 2020-02-11 1.24 0.72 0.78 1.07 0.59 0.44 ... ... ... ... ... ... ... 2024-12-24 1.16 0.71 1.10 0.60 0.86 0.89 2024-12-26 1.09 0.43 0.81 0.82 1.03 0.62 2024-12-27 -1.24 -0.95 -1.24 -1.26 -0.82 -0.67 2024-12-30 -0.35 -0.45 -0.69 -0.96 -1.08 -0.54 2024-12-31 0.33 0.21 0.13 0.94 0.21 0.36 OP5 INV4 HiOP HiINV Date 2020-02-05 2.32 2.64 2020-02-06 -0.56 -0.49 2020-02-07 -1.15 -0.96 2020-02-10 0.35 -0.32 2020-02-11 1.02 0.83 ... ... ... 2024-12-24 0.79 0.52 2024-12-26 0.39 0.35 2024-12-27 -0.91 -0.96 2024-12-30 -0.90 -0.19 2024-12-31 0.33 0.27 [1235 rows x 25 columns], 2: LoOP LoINV OP1 INV2 OP1 INV3 OP1 INV4 LoOP HiINV OP2 INV1 \ Date 2020-02-05 388 121 111 113 479 74 2020-02-06 388 121 111 113 478 74 2020-02-07 388 121 111 113 478 74 2020-02-10 388 121 111 113 478 74 2020-02-11 388 121 111 113 477 74 ... ... ... ... ... ... ... 2024-12-24 702 128 122 105 343 87 2024-12-26 700 128 122 105 343 87 2024-12-27 700 128 122 105 343 87 2024-12-30 700 127 122 105 343 87 2024-12-31 700 126 122 105 343 87 OP2 INV2 OP2 INV3 OP2 INV4 OP2 INV5 ... OP4 INV1 OP4 INV2 \ Date ... 2020-02-05 85 119 153 174 ... 64 62 2020-02-06 85 119 153 174 ... 64 62 2020-02-07 85 119 153 174 ... 64 62 2020-02-10 85 119 153 174 ... 64 62 2020-02-11 85 119 153 174 ... 64 62 ... ... ... ... ... ... ... ... 2024-12-24 98 106 88 132 ... 54 64 2024-12-26 98 106 88 132 ... 54 64 2024-12-27 98 106 88 132 ... 54 64 2024-12-30 98 106 88 132 ... 54 64 2024-12-31 98 106 88 132 ... 54 64 OP4 INV3 OP4 INV4 OP4 INV5 HiOP LoINV OP5 INV2 OP5 INV3 \ Date 2020-02-05 75 79 101 65 63 56 2020-02-06 75 79 101 65 63 56 2020-02-07 74 79 101 65 63 56 2020-02-10 74 79 101 65 63 56 2020-02-11 74 79 101 65 63 56 ... ... ... ... ... ... ... 2024-12-24 84 89 117 60 76 53 2024-12-26 84 89 117 60 76 53 2024-12-27 84 89 117 59 76 53 2024-12-30 84 89 117 59 76 53 2024-12-31 84 89 117 59 76 53 OP5 INV4 HiOP HiINV Date 2020-02-05 100 90 2020-02-06 100 90 2020-02-07 100 90 2020-02-10 100 90 2020-02-11 100 90 ... ... ... 2024-12-24 77 97 2024-12-26 77 97 2024-12-27 77 97 2024-12-30 77 97 2024-12-31 77 97 [1235 rows x 25 columns], 3: LoOP LoINV OP1 INV2 OP1 INV3 OP1 INV4 LoOP HiINV OP2 INV1 \ Date 2020-02-05 822.45 2761.01 7017.46 1193.36 2430.49 4702.58 2020-02-06 825.62 2816.27 7101.44 1206.21 2420.34 4789.74 2020-02-07 820.36 2823.17 7124.19 1214.85 2438.73 4819.28 2020-02-10 813.47 2810.98 7073.26 1198.86 2422.18 4802.43 2020-02-11 820.51 2829.54 7079.49 1215.18 2459.34 4836.09 ... ... ... ... ... ... ... 2024-12-24 755.91 4982.45 5622.35 4213.50 3850.76 6901.70 2024-12-26 765.50 5029.47 5648.95 4254.10 3916.15 6966.67 2024-12-27 776.93 5036.71 5630.17 4262.76 3919.15 6988.85 2024-12-30 762.91 5039.90 5551.12 4201.55 3830.57 6917.10 2024-12-31 754.07 4985.05 5491.08 4141.99 3757.81 6850.58 OP2 INV2 OP2 INV3 OP2 INV4 OP2 INV5 ... OP4 INV1 OP4 INV2 \ Date ... 2020-02-05 9827.72 8835.41 4538.10 4529.95 ... 15336.04 12582.00 2020-02-06 10100.57 8730.44 4578.95 4589.28 ... 15618.69 12686.76 2020-02-07 10037.77 8732.36 4566.93 4578.29 ... 15667.23 12702.06 2020-02-10 9948.81 8667.70 4544.57 4554.62 ... 15488.41 12583.12 2020-02-11 9925.11 8711.23 4563.43 4589.13 ... 15530.89 12610.76 ... ... ... ... ... ... ... ... 2024-12-24 11314.20 10431.20 6046.16 15235.29 ... 69851.25 32286.12 2024-12-26 11421.64 10519.42 6093.38 15394.02 ... 70112.82 32823.91 2024-12-27 11430.52 10535.57 6110.30 15377.59 ... 69987.09 32826.84 2024-12-30 11367.09 10451.69 6054.05 15232.30 ... 68616.63 32481.43 2024-12-31 11265.86 10355.41 6001.94 15075.99 ... 68787.22 32170.27 OP4 INV3 OP4 INV4 OP4 INV5 HiOP LoINV OP5 INV2 OP5 INV3 \ Date 2020-02-05 28521.02 11313.54 16058.16 24146.93 54504.70 37572.88 2020-02-06 28837.61 11577.93 16176.69 24370.89 55175.99 38039.70 2020-02-07 29283.35 11526.80 16215.38 24411.37 55472.57 38063.77 2020-02-10 29168.11 11400.92 16197.00 24149.69 54808.62 37776.91 2020-02-11 29204.51 11426.54 16292.44 24248.11 55004.12 38087.62 ... ... ... ... ... ... ... 2024-12-24 22184.58 54419.43 46492.63 17483.37 95752.12 36417.73 2024-12-26 22328.98 54945.23 47102.88 17554.88 96974.62 36680.62 2024-12-27 22366.21 54907.25 46904.17 17893.08 97622.37 36714.18 2024-12-30 22272.35 54257.39 46405.80 17754.52 96503.22 36525.86 2024-12-31 22094.27 53781.82 45888.70 17567.67 95066.15 36196.36 OP5 INV4 HiOP HiINV Date 2020-02-05 28408.59 26085.65 2020-02-06 28691.51 26165.64 2020-02-07 28935.35 26366.20 2020-02-10 28834.14 26401.19 2020-02-11 29268.54 26906.90 ... ... ... 2024-12-24 49624.57 64865.71 2024-12-26 50078.46 65389.67 2024-12-27 50076.08 65275.09 2024-12-30 49765.53 64381.23 2024-12-31 49311.55 63595.46 [1235 rows x 25 columns], 'DESCR': '25 Portfolios OP INV 5x5 daily\n------------------------------\n\nThis file was created by CMPT_ME_BEME_OP_INV_RETS_DAILY using the 202412 CRSP database. It contains value- and equal-weighted returns for portfolios formed on OP and INV. The portfolios are constructed at the end of June. OP is operating profits (sales - cost of goods sold - selling, general and administrative expenses - interest expense) divided by book at the last fiscal year end of the prior calendar year. INV is the change in total assets from the fiscal year ending in year t-2 to the fiscal year ending in t-1, divided by t-2 total assets. Annual returns are from January to December. Missing data are indicated by -99.99 or -999. Please be aware that some of the value-weight averages of operating profitability for deciles 1 and 10 are extreme. These are driven by extraordinary values of OP for individual firms. We have spot checked the accounting data that produce the extraordinary values and all the numbers we examined accurately reflect the data in the firm’s accounting statements. The break points include utilities and include financials. The portfolios include utilities and include financials. Copyright 2024 Eugene F. Fama and Kenneth R. French\n\n 0 : Average Value Weighted Returns -- Daily (1235 rows x 25 cols)\n 1 : Average Equal Weighted Returns -- Daily (1235 rows x 25 cols)\n 2 : Number of Firms in Portfolios (1235 rows x 25 cols)\n 3 : Average Firm Size (1235 rows x 25 cols)'}
print(ds["DESCR"])
25 Portfolios OP INV 5x5 daily ------------------------------ This file was created by CMPT_ME_BEME_OP_INV_RETS_DAILY using the 202412 CRSP database. It contains value- and equal-weighted returns for portfolios formed on OP and INV. The portfolios are constructed at the end of June. OP is operating profits (sales - cost of goods sold - selling, general and administrative expenses - interest expense) divided by book at the last fiscal year end of the prior calendar year. INV is the change in total assets from the fiscal year ending in year t-2 to the fiscal year ending in t-1, divided by t-2 total assets. Annual returns are from January to December. Missing data are indicated by -99.99 or -999. Please be aware that some of the value-weight averages of operating profitability for deciles 1 and 10 are extreme. These are driven by extraordinary values of OP for individual firms. We have spot checked the accounting data that produce the extraordinary values and all the numbers we examined accurately reflect the data in the firm’s accounting statements. The break points include utilities and include financials. The portfolios include utilities and include financials. Copyright 2024 Eugene F. Fama and Kenneth R. French 0 : Average Value Weighted Returns -- Daily (1235 rows x 25 cols) 1 : Average Equal Weighted Returns -- Daily (1235 rows x 25 cols) 2 : Number of Firms in Portfolios (1235 rows x 25 cols) 3 : Average Firm Size (1235 rows x 25 cols)
ds[0].tail()
LoOP LoINV | OP1 INV2 | OP1 INV3 | OP1 INV4 | LoOP HiINV | OP2 INV1 | OP2 INV2 | OP2 INV3 | OP2 INV4 | OP2 INV5 | ... | OP4 INV1 | OP4 INV2 | OP4 INV3 | OP4 INV4 | OP4 INV5 | HiOP LoINV | OP5 INV2 | OP5 INV3 | OP5 INV4 | HiOP HiINV | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Date | |||||||||||||||||||||
2024-12-24 | 0.98 | 0.94 | 0.47 | 0.96 | 1.70 | 0.94 | 0.95 | 0.85 | 0.78 | 1.04 | ... | 0.37 | 1.67 | 0.65 | 0.97 | 1.31 | 0.41 | 1.28 | 0.72 | 0.91 | 0.81 |
2024-12-26 | 1.49 | 0.14 | -0.33 | 0.20 | 0.08 | 0.32 | 0.08 | 0.15 | 0.28 | -0.11 | ... | -0.18 | 0.01 | 0.17 | -0.07 | -0.42 | 0.29 | 0.67 | 0.09 | 0.00 | -0.18 |
2024-12-27 | -1.80 | -0.72 | -1.40 | -1.44 | -2.26 | -0.68 | -0.54 | -0.80 | -0.92 | -0.94 | ... | -1.96 | -1.05 | -0.42 | -1.18 | -1.06 | -0.77 | -1.15 | -0.51 | -0.62 | -1.37 |
2024-12-30 | -1.16 | -1.85 | -1.08 | -1.42 | -1.90 | -0.96 | -0.89 | -0.92 | -0.83 | -1.03 | ... | 0.25 | -0.96 | -0.80 | -0.88 | -1.11 | -1.05 | -1.49 | -0.90 | -0.91 | -1.22 |
2024-12-31 | -0.31 | -0.65 | -0.32 | -0.30 | -1.30 | 0.20 | 0.21 | 0.03 | 0.21 | -0.24 | ... | -2.10 | -0.15 | 0.66 | -0.52 | -0.71 | 0.25 | -0.49 | 0.30 | 0.11 | -0.47 |
5 rows × 25 columns
ds[0].info()
<class 'pandas.core.frame.DataFrame'> DatetimeIndex: 1235 entries, 2020-02-05 to 2024-12-31 Data columns (total 25 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 LoOP LoINV 1235 non-null float64 1 OP1 INV2 1235 non-null float64 2 OP1 INV3 1235 non-null float64 3 OP1 INV4 1235 non-null float64 4 LoOP HiINV 1235 non-null float64 5 OP2 INV1 1235 non-null float64 6 OP2 INV2 1235 non-null float64 7 OP2 INV3 1235 non-null float64 8 OP2 INV4 1235 non-null float64 9 OP2 INV5 1235 non-null float64 10 OP3 INV1 1235 non-null float64 11 OP3 INV2 1235 non-null float64 12 OP3 INV3 1235 non-null float64 13 OP3 INV4 1235 non-null float64 14 OP3 INV5 1235 non-null float64 15 OP4 INV1 1235 non-null float64 16 OP4 INV2 1235 non-null float64 17 OP4 INV3 1235 non-null float64 18 OP4 INV4 1235 non-null float64 19 OP4 INV5 1235 non-null float64 20 HiOP LoINV 1235 non-null float64 21 OP5 INV2 1235 non-null float64 22 OP5 INV3 1235 non-null float64 23 OP5 INV4 1235 non-null float64 24 HiOP HiINV 1235 non-null float64 dtypes: float64(25) memory usage: 250.9 KB
Benchmark Data¶
Let's also download some benchmark data.
with warnings.catch_warnings():
warnings.filterwarnings(
"ignore",
category=FutureWarning,
message="The argument 'date_parser' is deprecated",
)
dbs = web.DataReader('F-F_Research_Data_Factors_daily', 'famafrench')
dbs.keys()
dict_keys([0, 'DESCR'])
print(dbs["DESCR"])
F-F Research Data Factors daily ------------------------------- This file was created by CMPT_ME_BEME_RETS_DAILY using the 202412 CRSP database. The Tbill return is the simple daily rate that, over the number of trading days compounds to 1-month TBill rate. The 1-month TBill rate data until 202405 are from Ibbotson Associates. Starting from 202406, the 1-month TBill rate is from ICE BofA US 1-Month Treasury Bill Index. Copyright 2024 Eugene F. Fama and Kenneth R. French 0 : (1235 rows x 4 cols)
dbs[0].tail()
Mkt-RF | SMB | HML | RF | |
---|---|---|---|---|
Date | ||||
2024-12-24 | 1.11 | -0.09 | -0.05 | 0.017 |
2024-12-26 | 0.02 | 1.04 | -0.19 | 0.017 |
2024-12-27 | -1.17 | -0.66 | 0.56 | 0.017 |
2024-12-30 | -1.09 | 0.12 | 0.74 | 0.017 |
2024-12-31 | -0.46 | 0.00 | 0.71 | 0.017 |
Note, based on the description provided, Ken French's 5x5 portfolios are formed using independent sorts, but with an important nuance:
The breakpoints (quintiles) for both Operating Profitability and Investment are determined using NYSE stocks only
However, the portfolios themselves include all stocks (NYSE, AMEX, and NASDAQ) that meet the data requirements
This methodology means:
- The breakpoints are not influenced by the typically smaller AMEX and NASDAQ stocks
- When all stocks are sorted into the portfolios using these NYSE-based breakpoints, the resulting portfolios will likely NOT have equal value weights
- This is intentional - it helps address issues with microcaps while still including the broader universe of stocks
This is different from what you described with median cuts where you might expect equal weights. The use of NYSE breakpoints but all-stock portfolios means some portfolios (especially those containing small NASDAQ stocks) might end up with more firms but smaller total market cap than others.
This methodology has become standard in the empirical asset pricing literature precisely because it handles the size-based peculiarities of the US stock market in a systematic way.
Performance Analysis¶
Now, let's analyze the performance of one of these portfolios. Let's create a tear sheet for the portfolio. A "tear sheet" is a comprehensive summary of portfolio performance that includes key metrics and visualizations. Common components include:
- Risk metrics (Sharpe ratio, maximum drawdown, Value at Risk)
- Return statistics (CAGR, monthly/annual returns, win rates)
- Risk-adjusted performance measures (Sortino ratio, Calmar ratio)
- Visual analytics (drawdown plots, return distributions, rolling statistics)
The QuantStats package is just a small, demo package that provides some quick analytics for use to work with. It combines statistical analysis with visualization capabilities, making it easy to create portfolio reports. The package can also generate HTML tear sheets that include a nice array of metrics and plots. In the future, you'll want to create your own customized code to create tear sheets. But, for now, let's use theirs.
Here's a simple example.
First, let's create a dataframe with the portfolio returns and the benchmark returns.
portfolio_returns = ds[0][["HiOP LoINV"]]
portfolio_returns.tail()
HiOP LoINV | |
---|---|
Date | |
2024-12-24 | 0.41 |
2024-12-26 | 0.29 |
2024-12-27 | -0.77 |
2024-12-30 | -1.05 |
2024-12-31 | 0.25 |
df = pd.concat([portfolio_returns, dbs[0]], axis=1)
df["Mkt"] = df["Mkt-RF"] + df["RF"]
# df.index = df.index.to_timestamp()
df = df/100
df.tail()
HiOP LoINV | Mkt-RF | SMB | HML | RF | Mkt | |
---|---|---|---|---|---|---|
Date | ||||||
2024-12-24 | 0.0041 | 0.0111 | -0.0009 | -0.0005 | 0.00017 | 0.01127 |
2024-12-26 | 0.0029 | 0.0002 | 0.0104 | -0.0019 | 0.00017 | 0.00037 |
2024-12-27 | -0.0077 | -0.0117 | -0.0066 | 0.0056 | 0.00017 | -0.01153 |
2024-12-30 | -0.0105 | -0.0109 | 0.0012 | 0.0074 | 0.00017 | -0.01073 |
2024-12-31 | 0.0025 | -0.0046 | 0.0000 | 0.0071 | 0.00017 | -0.00443 |
# import quantstats as qs
import quantstats_lumi as qs
# qs.extend_pandas()
# Generate HTML tear sheet comparing the portfolio to the S&P 500
qs.reports.basic(df["HiOP LoINV"], benchmark=df["Mkt"], rf=df["RF"].mean())
Performance Metrics
Benchmark Strategy --------------------- ----------- ---------- Start Period 2020-02-05 2020-02-05 End Period 2024-12-31 2024-12-31 Risk-Free Rate % 0.01% 0.01% Time in Market % 100.0% 100.0% Total Return 89% 66% CAGR% (Annual Return) 13.8% 10.92% Sharpe 0.84 0.69 RoMaD 0.4 0.37 Corr to Benchmark 1.0 0.83 Prob. Sharpe Ratio % 93.58% 89.48% Sortino 1.17 0.97 Sortino/√2 0.83 0.69 Omega 1.11 1.11 Max Drawdown % -34.27% -29.38% Longest DD Days 766 1039 MTD % -2.82% -6.04% 3M % 3.71% -1.83% 6M % 9.53% 10.35% YTD % 25.02% 17.73% 1Y % 25.02% 17.73% 3Y (ann.) % 11.59% 0.81% 5Y (ann.) % 13.8% 10.92% 10Y (ann.) % 13.8% 10.92% All-time (ann.) % 13.8% 10.92% Avg. Drawdown % -2.15% -5.52% Avg. Drawdown Days 20 67 Recovery Factor 2.2 2.16 Ulcer Index 0.11 0.14 Serenity Index 0.5 0.24
Strategy Visualization
qs.reports.full(df["HiOP LoINV"], benchmark=df["Mkt"], rf=df["RF"].mean())
Performance Metrics
Benchmark Strategy --------------------------- ----------- ---------- Start Period 2020-02-05 2020-02-05 End Period 2024-12-31 2024-12-31 Risk-Free Rate % 0.01% 0.01% Time in Market % 100.0% 100.0% Total Return 89% 66% CAGR% (Annual Return) 13.8% 10.92% Sharpe 0.84 0.69 RoMaD 0.4 0.37 Corr to Benchmark 1.0 0.83 Prob. Sharpe Ratio % 93.58% 89.48% Smart Sharpe 0.73 0.6 Sortino 1.17 0.97 Smart Sortino 1.02 0.85 Sortino/√2 0.83 0.69 Smart Sortino/√2 0.72 0.6 Omega 1.11 1.11 Max Drawdown % -34.27% -29.38% Longest DD Days 766 1039 Volatility (ann.) % 26.5% 27.36% R^2 0.69 0.69 Information Ratio -0.01 -0.01 Calmar 0.4 0.37 Skew -0.57 -0.26 Kurtosis 11.6 5.78 Expected Daily %% 0.05% 0.04% Expected Monthly %% 1.08% 0.87% Expected Yearly %% 13.53% 10.71% Daily Value-at-Risk % -2.22% -2.3% Expected Shortfall (cVaR) % -2.22% -2.3% MTD % -2.82% -6.04% 3M % 3.71% -1.83% 6M % 9.53% 10.35% YTD % 25.02% 17.73% 1Y % 25.02% 17.73% 3Y (ann.) % 11.59% 0.81% 5Y (ann.) % 13.8% 10.92% 10Y (ann.) % 13.8% 10.92% All-time (ann.) % 13.8% 10.92% Best Day % 9.35% 7.7% Worst Day % -11.99% -9.01% Best Month % 13.58% 13.54% Worst Month % -13.25% -9.88% Best Year % 26.5% 36.04% Worst Year % -20.24% -16.64% Avg. Drawdown % -2.15% -5.52% Avg. Drawdown Days 20 67 Recovery Factor 2.2 2.16 Ulcer Index 0.11 0.14 Serenity Index 0.5 0.24 Avg. Up Month % 4.89% 5.66% Avg. Down Month % -4.92% -5.36% Win Days 670.63 666.86 Loss Days 564.37 568.14 Win Days %% 54.3% 54.0% Win Month %% 62.71% 55.93% Win Quarter %% 70.0% 60.0% Win Year %% 80.0% 60.0% Beta - 0.86 Alpha - -0.0 Correlation - 82.91% Treynor Ratio - 77.42%
None
Worst 5 Drawdowns
Start | Valley | End | Days | Max Drawdown | 99% Max Drawdown | |
---|---|---|---|---|---|---|
1 | 2020-02-07 | 2020-03-23 | 2020-07-30 | 175 | -29.377975 | -23.940079 |
2 | 2022-01-04 | 2022-09-30 | 2024-11-07 | 1039 | -27.869052 | -26.614982 |
3 | 2020-09-02 | 2020-10-30 | 2020-12-16 | 106 | -15.406723 | -15.119105 |
4 | 2021-01-27 | 2021-03-04 | 2021-04-14 | 78 | -11.041882 | -11.007360 |
5 | 2021-09-08 | 2021-10-04 | 2021-11-17 | 71 | -9.565579 | -8.582184 |
Strategy Visualization
/opt/homebrew/Caskroom/mambaforge/base/envs/finm/lib/python3.12/site-packages/quantstats_lumi/_plotting/core.py:358: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead min_val = float(returns.min()) /opt/homebrew/Caskroom/mambaforge/base/envs/finm/lib/python3.12/site-packages/quantstats_lumi/_plotting/core.py:359: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead max_val = float(returns.max())
/opt/homebrew/Caskroom/mambaforge/base/envs/finm/lib/python3.12/site-packages/quantstats_lumi/_plotting/core.py:358: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead min_val = float(returns.min()) /opt/homebrew/Caskroom/mambaforge/base/envs/finm/lib/python3.12/site-packages/quantstats_lumi/_plotting/core.py:359: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead max_val = float(returns.max())
/opt/homebrew/Caskroom/mambaforge/base/envs/finm/lib/python3.12/site-packages/quantstats_lumi/_plotting/core.py:358: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead min_val = float(returns.min())
/opt/homebrew/Caskroom/mambaforge/base/envs/finm/lib/python3.12/site-packages/quantstats_lumi/_plotting/core.py:359: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead max_val = float(returns.max())
/opt/homebrew/Caskroom/mambaforge/base/envs/finm/lib/python3.12/site-packages/quantstats_lumi/_plotting/core.py:358: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead min_val = float(returns.min()) /opt/homebrew/Caskroom/mambaforge/base/envs/finm/lib/python3.12/site-packages/quantstats_lumi/_plotting/core.py:359: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead max_val = float(returns.max())
/opt/homebrew/Caskroom/mambaforge/base/envs/finm/lib/python3.12/site-packages/quantstats_lumi/_plotting/core.py:358: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead min_val = float(returns.min()) /opt/homebrew/Caskroom/mambaforge/base/envs/finm/lib/python3.12/site-packages/quantstats_lumi/_plotting/core.py:359: FutureWarning: Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead max_val = float(returns.max())