#!/usr/bin/env python # coding: utf-8 # # Riskfolio-Lib Tutorial: #
__[Financionerioncios](https://financioneroncios.wordpress.com)__ #
__[Orenji](https://www.orenj-i.net)__ #
__[Riskfolio-Lib](https://riskfolio-lib.readthedocs.io/en/latest/)__ #
__[Dany Cajas](https://www.linkedin.com/in/dany-cajas/)__ # Buy Me a Coffee at ko-fi.com # # ## Tutorial 42: Higher L-Moments OWA Portfolio Optimization # # ## 1. Downloading the data: # In[1]: import numpy as np import pandas as pd import yfinance as yf import warnings warnings.filterwarnings("ignore") pd.options.display.float_format = '{:.4%}'.format # Date range start = '2016-01-01' end = '2019-12-30' # Tickers of assets assets = ['JCI', 'TGT', 'CMCSA', 'CPB', 'MO', 'APA', 'MMC', 'JPM', 'ZION', 'PSA', 'BAX', 'BMY', 'LUV', 'PCAR', 'TXT', 'TMO', 'DE', 'MSFT', 'HPQ', 'SEE', 'VZ', 'CNP', 'NI', 'T', 'BA'] assets.sort() # Downloading data data = yf.download(assets, start = start, end = end) data = data.loc[:,('Adj Close', slice(None))] data.columns = assets # In[2]: # Calculating returns Y = data[assets].iloc[-300:,:].pct_change().dropna() display(Y.head()) # ## 2. Estimating Higher L-Moments OWA Portfolios # # The OWA portfolio model proposed by __[Cajas (2021)](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=3988927)__ . This model gives an alternative formulation to risk measures that can be expressed using the OWA operator. The Higher L-Moments portfolio is a special case of the OWA portfolio where the weights are determined following __[Cajas (2023)](https://papers.ssrn.com/sol3/papers.cfm?abstract_id=4393155)__. # # It is recommended to use MOSEK to optimize OWA portfolios, due to it requires more computing power for the number of constraints and variables the model use. # # Instructions to install MOSEK are in this __[link](https://docs.mosek.com/9.2/install/installation.html)__, is better to install using Anaconda. Also you will need a license, I recommend you that ask for an academic license __[here](https://www.mosek.com/products/academic-licenses/)__. # # ### 2.1 Calculating the portfolio that minimize a risk measure that includes Higher L-Moments # In[3]: import riskfolio as rp import mosek # Building the portfolio object port = rp.Portfolio(returns=Y) # Calculating optimum portfolio # Select method and estimate input parameters: method_mu='hist' # Method to estimate expected returns based on historical data. method_cov='hist' # Method to estimate covariance matrix based on historical data. port.assets_stats(method_mu=method_mu, method_cov=method_cov, d=0.94) # Estimate optimal portfolios: port.solvers = ['MOSEK'] # It is recommended to use mosek when optimizing GMD port.sol_params = {'MOSEK': {'mosek_params': {mosek.iparam.num_threads: 2}}} obj = 'MinRisk' # Objective function, could be MinRisk, MaxRet, Utility or Sharpe rf = 0 # Risk free rate l = 0 # Risk aversion factor, only useful when obj is 'Utility' owa_w = rp.owa_l_moment_crm(len(Y), k=4) w = port.owa_optimization(obj=obj, owa_w=owa_w, rf=rf, l=l) display(w.T) # ### 2.2 Plotting portfolio composition # In[4]: # Plotting the composition of the portfolio ax = rp.plot_pie(w=w, title='Min Higher L-moment OWA Risk Measure', others=0.05, nrow=25, cmap="tab20", height=6, width=10, ax=None)