#!/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/)__
#
#
# ## 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)