Académique Documents
Professionnel Documents
Culture Documents
1 : Analyse Simple
Tout d'abord, nous devons télécharger les données sur les prix de
Yahoo Finance. Assurez-vous d'avoir installé la bibliothèque
suivante :
#bibliothèques préalables
# ! pip installer yfinance
importer yfinance comme yf
importer des pandas en tant que pd
importer numpy comme np
Utilisez le code ci-dessous pour télécharger les données sur les prix
quotidiens :
stocknames = ['MSFT', 'AAPL', 'SPY'] #ticker
date de début = '2019-01-01'
date de fin = '2022-12-31'
intervalle = '1d'
The price data will be saved in respective CSV files. The next step is
to combine them into a single DataFrame df with only the “Adjusted
Close” prices.
def appending(cols=[], startdate='', enddate='') :
dates = pd.date_range(start=startdate, end=enddate)
df = pd.DataFrame(index=dates)
pour le stock dans les noms de stock :
df_stock = pd.read_csv('stocks_data\\{}.csv'.format(stock), index_col='Date', parse_dates=True,
usecols=cols, na_values=['NaN'])
df_stock = df_stock.rename(columns = {'Adj Close': stock})
df = df.join(df_stock)
df = df.loc[dates]
df.index.names = ['Date']
df = df.dropna()
retour df
'''
MSFT AAPL SPY
Date
2019-01-02 96.633 38.047 233.172
2019-01-03 93.078 34.257 227.608
2019-01-04 97.407 35.720 235.231
2019-01-07 97.531 35.640 237.086
2019-01-08 98.238 36.320 239.314
'''
Jetons un coup d'œil rapide aux prix dans une parcelle en utilisant
le code ci-dessous :
# ! pip install plotly --user
de plotly import express comme px
Pour ce faire, nous diviserons les prix de chaque colonne par le prix
du premier jour, de sorte que le prix de chaque jour (qu'il soit plus
élevé ou inférieur) soit relatif au prix du premier jour.
de matplotlib import pyplot comme plt
norm = df / df.iloc[0,:]
norm.plot(figsize=(10, 4.5))
plt.title('Plan de normalisation à l'aide de matplotlib')
plt.xlabel('Date')
plt.ylabel('Prix normalisé')
plt.tight_layout()
Le code tracera le graphique ci-dessous pour visualiser les prix
normalisés des 3 actions au fil du temps. Dans ce cas, les prix des
actions ont été normalisés en divisant chaque prix par le prix du
premier jour de l'ensemble de données. Cela signifie que tous les
prix de l'intrigue sont sur la même échelle, ce qui facilite la façon
dont ils ont changé au fil du temps.
L'intrigue montre que les prix des 3 actions ont augmenté au fil du
temps. Cependant, les prix des actions n'ont pas augmenté au même
rythme. L'action avec le symbole "AAPL" a augmenté le plus (de
1,00 $ à 3,40 $), tandis que l'action avec le symbole "SPY" a
augmenté le moins (de 1,00 $ à 1,60 $).
Rendements annualisés
'''
MSFT 0.277
AAPL 0,367
SPY 0,148
'''
Nous pouvons voir que SPY devrait augmenter de 14,8 % par an, de
sorte que sur 3 ans (1 * 1,148 * 1,148 * 1,148), nous obtenons 1,51, ce
qui est proche des 1,60 $ que nous avons vus précédemment.
D'un autre côté, pour que l'AAPL augmente de 36,7 % par an, c'est-
à-dire sur 3 ans (1 * 1,367 * 1,367 * 1,367), nous n'otenons que 2,55,
ce qui est différent de l'augmentation réelle du prix à 3,40 $.
La raison en est que, bien que les rendements annualisés puissent
donner les rendements (moyens) attendus par an, la volatilité de
l'action l'amettra à des prix différents. Le montant de
l'investissement perdu ou gagné au cours d'une année donnée est
interdépendant avec le montant des autres années.
Volatilité annualisée
'''
MSFT 0,317
AAPL 0,346
SPY 0.225
'''
En résumé,
• MSFT vs APPL
MSFT a un rendement plus faible et une volatilité légèrement
inférieure à celle de l'AAPL
• APPL vs SPY
APPL a un rendement plus élevé et une plus grande volatilité
que SPY
• SPY vs MSFT
SPY a un rendement et une volatilité plus faibles que MSFT
Une corrélation positive signifie que les deux actifs ont tendance à
se déplacer dans la même direction. Par exemple, si le prix de
l'action A augmente, le prix de l'action B est susceptible
d'augmenter également. Une corrélation négative signifie que les
deux actifs ont tendance à se déplacer dans des directions opposées.
Par exemple, si le prix de l'action A augmente, le prix de l'action B
est susceptible de baisser.
Les corrélations entre les 3 actions sont très élevées (environ 0,8),
ce qui signifie qu'elles ont tendance à se déplacer dans la même
direction. Cela signifie que si le marché boursier est haussier, le prix
des 3 actions est susceptible d'augmenter. Inversement, si le marché
boursier est baissier, les 3 actions sont susceptibles de baisser de
prix. Ce n'est pas surprenant car ces 3 actions sont dans la même
industrie technologique.
Étant donné que le marché boursier de la technologie est plutôt
haussier entre 2019 et 2022, toute combinaison de ces 3 actions se
traduira par des bénéfices. Cependant, différentes allocations
(proportion) d'actions produiront des niveaux de profit différents.
Portefeuille 1 vs Portefeuille 2
Portefeuille 2 :
30 % MSFT, 40 % AAPL, 30 % ESPION
def portval (allocations = [], start_value = 0) :
''' pour obtenir la valeur quotidienne du portefeuille en fonction de l'allocation'''
allocs = norm.copy() * allocations
pos_val = allocs * start_value
port_val = pos_val.sum(axis=1)
retour port_val
• Valeurs du portefeuille
• Ratio de rendement cumulé
• Rendements annualisés
• Volatilité annualisée
• Ratio de Sharpe
Valeurs du portefeuille
'''
Portefeuille 1 Valeur : 1979,81 $
Valeur du portefeuille 2 : 2596,75 $
'''
Ratio de rendement cumulé
'''
Le rendement cumulé du portefeuille 1 est de 98,0 %
Le rendement cumulé du portefeuille 2 est de 159,7 %
'''
Rendements annualisés
'''
Portefeuille 1 Rendements annualisés : 0,203
Portefeuille 2 Rendements Annualisés : 0,282
'''
Volatilité annualisée
'''
Portefeuille 1 Volatilité annualisée : 0,252
Volatilité annualisée du portefeuille 2 : 0,294
'''
Ratio de Sharpe
Sharpe Ratio est une mesure qui évalue le risque et les rendements
ensemble, afin d'aider les investisseurs dans la sélection d'un tel
investissement qui génère des rendements plus élevés pour le risque
optimal pris. Plus le ratio de Sharpe est élevé, meilleurs sont les
rendements.
portfolio_daily_returns1 = port_val1.pct_change()
SR1 = np.sqrt(252) * np.mean(portfolio_daily_returns1) / np.std(portfolio_daily_returns1)
print('Sharpe Ratio Portfolio 1 = {:.3f}%'.format(SR1))
portfolio_daily_returns2 = port_val2.pct_change()
SR2 = np.sqrt(252) * np.mean(portfolio_daily_returns2) / np.std(portfolio_daily_returns2)
print('Sharpe Ratio Portfolio 2 = {:.3f}%'.format(SR2))
'''
Portefeuille Sharpe Ratio 1 = 0,805 %
Portefeuille Sharpe Ratio 2 = 0,960%
'''
2 ANALYSE AVANCE
Sollons les données de prix pour les actions dans les différentes
industries en utilisant yf.download().
stocknames = ['MRNA', 'PFE', 'JNJ', 'GOOGL', 'META', 'AAPL', 'MSFT', 'COST', 'WMT', 'KR', 'JPM', 'BAC',
'HSBC', 'SPY', 'GLD', '^N225', 'CL=F', 'BTC-USD'] #ticker
date de début = '2019-01-01'
date de fin = '2022-12-31'
intervalle = '1d'
'''
Retour annuel attendu : 14,9 %
Volatilité annuelle : 12,0 %
Ratio de pointu : 1,07
{'GLD': 0.3285574294579892,
'^N225' : 0.20417293938457295,
'JNJ' : 0,0689269229258587,
'KR': 0.06353536844150041,
'PFE' : 0.05782346160864427,
'WMT' : 0.05636163167063827,
« COÛT » : 0.04601434327046138,
'HSBC' : 0.030885367472990262,
'JPM' : 0.021543028668782396,
'GOOGL' : 0.020846539574785265,
'SPY' : 0.020217120714651118,
'AAPL' : 0.01608647346814868,
'BAC': 0.014154600282063617,
'META': 0.012991563530249668,
'MRNA' : 0.012946352437141694,
'BTC-USD' : 0.011999189095048452,
'MSFT' : 0.010361598261625025,
'CL=F': 0.002576069734848656}
'''
latest_prices = get_latest_prices(df)
da_hrp = DiscreteAllocation(hrp_weights, latest_prices, total_portfolio_value=10000)
'''
Allocation discrète (HRP) : {'GLD' : 19, 'JNJ' : 4, 'KR' : 14, 'PFE' : 11, 'WMT' : 4, 'COST' : 1, 1, 'HSBC' :
10, 'JPM': 2, 'GOOGL' : 2, 2, 'SPY': 1, 1, 'AAPL': 2, 'BAC': 4, 'META': 1, 1, 'MRNA': 1, 'MSFT': 1, 1, 1CL=F':
1}
Fonds restants (HRP) : 1768,03 $
'''
p_ret.append(returns)
var = cov_matrix.mul(weights, axis=0).mul(weights, axis=1).sum().sum() #portfolio variance
sd = np.sqrt(var) #écart-type quotidien
ann_sd = sd*np.sqrt(250) #écart-type annuel = volatilité
p_vol.append(ann_sd)
#convertir les poids en valeurs d'allocation réelles (c'est-à-dire combien de chaque action à acheter)
avec un montant d'investissement de 10 000 $
latest_prices = get_latest_prices(df)
'''
Allocation discrète : {'PFE' : 14, 'BAC' : 12, 'KR' : 11, 'AAPL' : 8, 'MRNA' : 7, 'GLD' : 7, 7, 'WMT' : 7,
'HSBC' : 6, 6, 'GOOGL' : 5, 4, 'MSFT' : 4, 4, 4PM' : 4, 4, 'JNJ' : 2, 2A' : 'MA': 1, 1}
Fonds restants : 16,61 $
'''
#calculer la matrice de covariance et stocker les rendements calculés dans les variables S et mu
mu = expected_returns.mean_historical_return(df)
S = CovarianceShrinkage(df).ledoit_wolf()
ef = EfficientFrontier(mu, S)
poids = ef.max_sharpe()
ef.portfolio_performance(verbose=True)
cleaned_weights = ef.clean_weights()
'''
Retour annuel attendu : 45,1 %
Volatilité annuelle : 25,5 %
Ratio de pointu : 1,69
{'MRNA': 0.26443,
'AAPL' : 0.17975,
'BTC-USD' : 0.13273,
« COÛT » : 0.10265,
'MSFT' : 0.08056,
'KR' : 0,06656,
'GLD' : 0.04455,
'WMT': 0.0364,
'^N225': 0.03203,
'JNJ' : 0.03103,
'SPY' : 0.00984,
'JPM' : 0.00816,
'CL=F': 0.00766,
'PFE': 0.00366,
'GOOGL' : 0,0,
'META' : 0,0,
'BAC' : 0,0,
'HSBC' : 0,0}
'''
Méthode (2). Une autre façon consiste à fixer la volatilité cible (par
exemple 0,184) et à trouver le rendement maximal possible.
#nouvelle instance de la performance du portefeuille
ef2 = EfficientFrontier(mu, S)
ef2.efficient_risk(target_volatility=0.184)
ef2.portfolio_performance(verbose=True)
cleaned_weights2 = ef2.clean_weights()
cleaned_weights2
'''
Retour annuel attendu : 30,8 %
Volatilité annuelle : 18,4 %
Ratio de Sharpe : 1,57
{'MRNA': 0.14281,
'AAPL' : 0.10654,
« COÛT » : 0,08471,
'GLD': 0.08422,
'BTC-USD' : 0,07792,
'KR': 0.07723,
'^N225' : 0,07316,
'MSFT': 0.06242,
'WMT': 0.06032,
'JNJ' : 0.05863,
'PFE': 0.04197,
'SPY': 0.03759,
'JPM': 0.03189,
'GOOGL': 0.02568,
'BAC' : 0.01852,
'HSBC' : 0.0085,
'CL=F': 0.00787,
'META': 0.0}
'''
Méthode (3). Une autre façon est de fixer le rendement cible (par
exemple 0,261) et de trouver les poids pour la plus faible volatilité
possible.
de pypfopt import EfficientSemivariance
historical_returns = expected_returns.returns_from_prices(df)
ef3 = Semi-variance efficace(mu, historical_returns)
ef3.return_efficient(0.261)
ef3.portfolio_performance(verbose=True)
cleaned_weights3 = ef3.clean_weights()
cleaned_weights3
'''
Retour annuel attendu : 26,1 %
Semi-déviation annuelle : 10,5 %
Ratio de Sortino : 2,29
{'GLD': 0.34766,
'AAPL': 0.18535,
'^N225': 0.17654,
'MRNA': 0.10715,
« COÛT » : 0,08781,
'KR' : 0.08172,
'BTC-USD' : 0.01377,
'PFE' : 0,0,
'JNJ' : 0,0,
'GOOGL' : 0,0,
'META' : 0,0,
'MSFT' : 0,0,
'WMT': 0.0,
'JPM' : 0,0,
'BAC' : 0,0,
'HSBC' : 0,0,
'SPY' : 0,0,
'CL=F': 0.0}
'''
#convertir les poids en valeurs d'allocation réelles (c'est-à-dire combien de chaque action à acheter)
avec un montant d'investissement de 10 000 $
latest_prices = get_latest_prices(df)
da_ef = DiscreteAllocation(cleaned_weights3, latest_prices, total_portfolio_value=10000)
'''
Allocation discrète : {'GLD' : 20, 'KR' : 18, 'AAPL' : 14, 'MRNA' : 5, 'COST' : 2}
Fonds restants : 2192,27 $
'''