Maison  >  Article  >  développement back-end  >  Stratégies de trading et analyse de portefeuille avec Python

Stratégies de trading et analyse de portefeuille avec Python

王林
王林avant
2023-05-18 13:13:061847parcourir

Nous mesurerons les performances des stratégies de trading dans cet article. Et développera une stratégie de trading dynamique simple qui utilisera quatre classes d'actifs : obligations, actions et immobilier. Ces classes d’actifs ont de faibles corrélations, ce qui en fait d’excellentes options d’équilibrage des risques.

Stratégies de trading et analyse de portefeuille avec Python

Momentum Trading Strategy

Cette stratégie est basée sur le momentum car les traders et les investisseurs sont depuis longtemps conscients du momentum. L'impact peut être visible sur un large éventail de marchés et de périodes. Nous appelons donc cela une stratégie dynamique. Le suivi de tendance ou l'élan des séries chronologiques (TSM) est un autre nom pour l'utilisation de ces stratégies sur un seul instrument. Nous allons créer une stratégie de dynamique de base et la tester sur TCS pour voir comment elle fonctionne.

Analyse de stratégie TSM

Tout d'abord, nous allons importer quelques bibliothèques

import numpy as np
 import pandas as pd
 import matplotlib.pyplot as plt
 import yfinance as yf
 import ffn
 %matplotlib inline

Nous construisons la fonction de stratégie de dynamique de base TSMStrategy. La fonction renverra les performances attendues via le retour logarithmique de la série chronologique, la période d'intérêt et une variable booléenne indiquant si la vente à découvert est autorisée.

def TSMStrategy(returns, period=1, shorts=False):
if shorts:
position = returns.rolling(period).mean().map(
lambda x: -1 if x <= 0 else 1)
else:
position = returns.rolling(period).mean().map(
lambda x: 0 if x <= 0 else 1)
performance = position.shift(1) * returns
return performance
 ticker = 'TCS'
 yftcs = yf.Ticker(ticker)
 data = yftcs.history(start='2005-01-01', end='2021-12-31')
 returns = np.log(data['Close'] / data['Close'].shift(1)).dropna()
 performance = TSMStrategy(returns, period=1, shorts=False).dropna()
 years = (performance.index.max() - performance.index.min()).days / 365
 perf_cum = np.exp(performance.cumsum())
 tot = perf_cum[-1] - 1
 ann = perf_cum[-1] ** (1 / years) - 1
 vol = performance.std() * np.sqrt(252)
 rfr = 0.02
 sharpe = (ann - rfr) / vol
 print(f"1-day TSM Strategy yields:" +
f"nt{tot*100:.2f}% total returns" +
f"nt{ann*100:.2f}% annual returns" +
f"nt{sharpe:.2f} Sharpe Ratio")
 tcs_ret = np.exp(returns.cumsum())
 b_tot = tcs_ret[-1] - 1
 b_ann = tcs_ret[-1] ** (1 / years) - 1
 b_vol = returns.std() * np.sqrt(252)
 b_sharpe = (b_ann - rfr) / b_vol
 print(f"Baseline Buy-and-Hold Strategy yields:" +
f"nt{b_tot*100:.2f}% total returns" +
f"nt{b_ann*100:.2f}% annual returns" +
f"nt{b_sharpe:.2f} Sharpe Ratio")

Le résultat de la fonction est le suivant :

1-day TSM Strategy yields:
 -45.15% total returns
 -7.10% annual returns
 -0.17 Sharpe Ratio
 Baseline Buy-and-Hold Strategy yields:
 -70.15% total returns
 -13.78% annual returns
 -0.22 Sharpe Ratio

En termes de rendements annualisés raisonnables, la stratégie TSM sur 1 jour est meilleure que la stratégie d'achat et de conservation. Étant donné qu’une analyse rétrospective sur un jour peut contenir de nombreuses fausses tendances, nous avons essayé différentes périodes pour voir comment elles se comparent. Ici, le modèle sera exécuté en boucle pendant 3, 5, 15, 30 et 90 jours.

 import matplotlib.gridspec as gridspec
 periods = [3, 5, 15, 30, 90]
 fig = plt.figure(figsize=(12, 10))
 gs = fig.add_gridspec(4, 4)
 ax0 = fig.add_subplot(gs[:2, :4])
 ax1 = fig.add_subplot(gs[2:, :2])
 ax2 = fig.add_subplot(gs[2:, 2:])
 ax0.plot((np.exp(returns.cumsum()) - 1) * 100, label=ticker, linestyle='-')
 perf_dict = {'tot_ret': {'buy_and_hold': (np.exp(returns.sum()) - 1)}}
 perf_dict['ann_ret'] = {'buy_and_hold': b_ann}
 perf_dict['sharpe'] = {'buy_and_hold': b_sharpe}
 for p in periods:
log_perf = TSMStrategy(returns, period=p, shorts=False)
perf = np.exp(log_perf.cumsum())
perf_dict['tot_ret'][p] = (perf[-1] - 1)
ann = (perf[-1] ** (1/years) - 1)
perf_dict['ann_ret'][p] = ann
vol = log_perf.std() * np.sqrt(252)
perf_dict['sharpe'][p] = (ann - rfr) / vol
ax0.plot((perf - 1) * 100, label=f'{p}-Day Mean')
 
 ax0.set_ylabel('Returns (%)')
 ax0.set_xlabel('Date')
 ax0.set_title('Cumulative Returns')
 ax0.grid()
 ax0.legend()
 _ = [ax1.bar(i, v * 100) for i, v in enumerate(perf_dict['ann_ret'].values())]
 ax1.set_xticks([i for i, k in enumerate(perf_dict['ann_ret'])])
 ax1.set_xticklabels([f'{k}-Day Mean'
if type(k) is int else ticker for
k in perf_dict['ann_ret'].keys()],
rotation=45)
 ax1.grid()
 ax1.set_ylabel('Returns (%)')
 ax1.set_xlabel('Strategy')
 ax1.set_title('Annual Returns')
 _ = [ax2.bar(i, v) for i, v in enumerate(perf_dict['sharpe'].values())]
 ax2.set_xticks([i for i, k in enumerate(perf_dict['sharpe'])])
 ax2.set_xticklabels([f'{k}-Day Mean'
if type(k) is int else ticker for
k in perf_dict['sharpe'].keys()],
rotation=45)
 ax2.grid()
 ax2.set_ylabel('Sharpe Ratio')
 ax2.set_xlabel('Strategy')
 ax2.set_title('Sharpe Ratio')
 plt.tight_layout()
 plt.show()

Stratégies de trading et analyse de portefeuille avec Python

En regardant les résultats sur le graphique, nous pouvons voir que l'indicateur de momentum sur 15 jours fournit les meilleurs résultats. Toutefois, les résultats pour les autres périodes sont mitigés. Cela montre que notre stratégie n’est pas fiable. Nous pouvons donc également quitter la transaction en utilisant un stop ou un stop suiveur près du sommet, plutôt que de le faire lorsque le graphique sur 15 jours est en baisse ou à plat.

PORTfolio Analysis

Jusqu'à présent, nous avons créé une stratégie de trading en Python. Ci-dessous, nous mesurerons et tracerons les caractéristiques communes du portefeuille pour faciliter notre observation et notre analyse.

PORTfolio Analysis

Tout d'abord, nous allons importer quelques bibliothèques importantes et observer l'exécution des données.

import pandas_datareader.data as web
 stocks = ['SPY','GLD','TLT','HYG']
 
 data = web.DataReader(stocks,data_source='yahoo',start='01/01/2019')['Adj Close']
 data.sort_index(ascending=True,inplace=True)
 perf = data.calc_stats()
 perf.plot()

Stratégies de trading et analyse de portefeuille avec Python

Log return

Le retour du journal est utilisé pour calculer le taux de croissance exponentielle. Au lieu de calculer le pourcentage de variation de prix pour chaque sous-période, nous calculons l'indice de croissance organique pour cette période. Créez d'abord un df qui contient le retour journal de chaque cours d'action dans les données, puis nous créons un histogramme pour chaque retour journal.

 returns = data.to_log_returns().dropna()
 print(returns.head())
 
 
 Symbols SPY GLD TLT HYG
 Date
 2019-01-03 -0.024152 0.009025 0.011315 0.000494
 2019-01-04 0.032947 -0.008119 -0.011642 0.016644
 2019-01-07 0.007854 0.003453 -0.002953 0.009663
 2019-01-08 0.009351 -0.002712 -0.002631 0.006470
 2019-01-09 0.004663 0.006398 -0.001566 0.001193

L'histogramme est le suivant :

ax = returns.hist(figsize=(20, 10),bins=30)

Stratégies de trading et analyse de portefeuille avec Python

Histogramme montrant la distribution normale pour les quatre classes d'actifs. Un échantillon avec une distribution normale a une moyenne arithmétique et une distribution égale au-dessus et au-dessous de la moyenne (la distribution normale également connue sous le nom de distribution gaussienne est symétrique). Si les rendements sont normalement distribués, plus de 99 % des rendements devraient se situer dans une fourchette de trois écarts types par rapport à la moyenne. Ces caractéristiques de distribution normale en forme de cloche permettent aux analystes et aux investisseurs de faire de meilleures déductions statistiques sur les rendements et les risques attendus d'une action. Les actions avec une courbe en cloche sont généralement des valeurs sûres avec une volatilité faible et prévisible.

Taux de retracement maximum DRAWDOWN

DRAWDOWN fait référence à la valeur tombant à un niveau relativement bas. Il s’agit d’un facteur de risque important à prendre en compte par les investisseurs. Dessinons une représentation visuelle de la stratégie décroissante.

ffn.to_drawdown_series(data).plot(figsize=(15,10))

Stratégies de trading et analyse de portefeuille avec Python

Les quatre actifs ont diminué au premier semestre 2020, SPY ayant enregistré la plus forte baisse de 0,5 %. Puis, au premier semestre 2020, tous les actifs se sont immédiatement redressés. Cela indique un taux élevé de récupération des actifs. Ces actifs ont culminé vers juillet 2020. Suivant cette tendance, toutes les classes d’actifs ont connu de légères baisses une fois la reprise attelée. Selon les résultats, le TLT connaîtra la plus forte baisse de 0,5 % au second semestre 2022 avant de se redresser début 2023.

MARKOWITZ Optimisation moyenne-variance

En 1952, Markowitz (MARKOWITZ) a proposé la théorie du portefeuille moyenne-variance, également connue sous le nom de théorie moderne du portefeuille. Les investisseurs peuvent utiliser ces concepts pour construire un portefeuille qui maximise les rendements attendus en fonction d'un niveau de risque donné. Grâce à la méthode de Markowitz, nous pouvons générer un « portefeuille optimal ».

returns.calc_mean_var_weights().as_format('.2%')
 #结果
 SPY 46.60%
 GLD 53.40%
 TLT 0.00%
 HYG 0.00%
 dtype: object

Statistiques de corrélation

La corrélation est une méthode statistique utilisée pour mesurer la relation entre les titres. Ces informations sont mieux visualisées à l’aide de cartes thermiques. Les Heatmaps nous permettent de voir les corrélations entre les titres.

returns.plot_corr_heatmap()

Stratégies de trading et analyse de portefeuille avec Python

最好在你的投资组合中拥有相关性较低的资产。除了SPY与HYG,这四个资产类别的相关性都很低,这对我们的投资组合是不利的:因为如果拥有高度相关的不同资产组,即使你将风险分散在它们之间,从投资组合构建的角度来看,收益也会很少。

总结

通过分析和绘制的所有数据进行资产配置,可以建立一个投资组合,极大地改变基础投资的风险特征。还有很多我没有提到的,但可以帮助我们确定交易策略价值的起点。我们将在后续文章中添加更多的技术性能指标。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer