python-3.xoptimizationscikit-learnportfolio

skfolio how to set various parameters


I have started using skfolio using a portfolio given in skfolio.datasets (sp500). My idea is to run a portfolio of equally weighted names using the sp500 as my universe. For this I do the following:

import skfolio
from skfolio.datasets import load_sp500_dataset
from skfolio.preprocessing import prices_to_returns

prices=load_sp500_dataset()
X=prices_to_returns(prices)
X_train, X_test = train_test_split(X, test_size=0.33, shuffle=False)

model = skfolio.optimization.naive.EqualWeighted()

model.fit(X_train)

portfolio = model.predict(X_test)

print(portfolio.annualized_sharpe_ratio)
print(portfolio.summary())

So here I am using the data from the SP500 index and apply an equally weighted portfolio model. It returns various statistics on the portfolio (Skew, Kurtosis,...) and I can plot the cumulative returns with

portfolio.plot_cumulative_returns()

I have a few questions/issues with the above as it seems a lot of parameters have been defined "by default". I believe they could all relate to some kind of set_parameters function (?). In particular:


Solution

  • I’m one of the core developers of Skfolio.

    Answer to Points 1 and 3

    Your number of assets and start period are linked to your input X, which is your time series of asset returns.

    In your example, you use the EqualWeighted allocation model. This model allocates a weight of 1/20 to the 20 assets from your input returns X. To change it, you need to modify your input by removing columns (assets) or rows (dates).

    When using other models, such as MeanRisk, since these models support weight and cardinality constraints, you can control the number of invested assets with the model parameters: MeanRisk Cardinality Constraints.

    Another option is through pre-selection transformers: Pre-Selection Transformers.


    Answer to Point 2

    To use compounded returns for your portfolio evaluation (e.g., plots, risk stats, etc.), you need to set compounded=True:

    from skfolio.optimization import EqualWeighted
    from skfolio.datasets import load_sp500_dataset
    from skfolio.preprocessing import prices_to_returns
    
    prices = load_sp500_dataset()
    X = prices_to_returns(prices)
    
    # Without compounded returns
    model = EqualWeighted()
    ptf = model.fit_predict(X)
    ptf.cumulative_returns_df.tail()
    
    # With compounded returns
    model = EqualWeighted(portfolio_params=dict(compounded=True))
    ptf = model.fit_predict(X)
    ptf.cumulative_returns_df.tail()
    

    Answer to Point 4

    In terms of rebalancing, there are two different concepts that are sometimes both called “rebalancing”:

    1. Model Re-Fitting
      This changes the target weights, for example, re-fitting an MVO (Mean-Variance Optimization) model every month.
      Model re-fittings are performed using cross-validators: Cross-Validators Example.

    2. Rebalancing Towards Target Weights
      This refers to performing rebalancing between two re-fittings to avoid weight drift as asset prices diverge.


    The second type of rebalancing happens at the same frequency as your input data, so daily in your example.

    The reason is that portfolio models and cross-validators in Skfolio are used for model validation, selection, and parameter tuning. Therefore, the model evaluation must be homogeneous to the optimization process. For example, if you call model.fit_predict(X) with a MeanRisk model that has a 10% volatility constraint, your predicted portfolio on the same training set X must also have a 10% volatility. Otherwise, you will create issues later in terms of model selection, evaluation, and comparison.

    Mathematically, this means that in between re-fittings, portfolio returns are computed as the dot product of returns and weighs.

    More details are available here: Portfolio Models.


    Additional Note

    If you need more granularity to model weight drifts between re-fittings, Skfolio can be used with a backtesting package.


    Let me know if you have any other questions!