Outils d’agent pour l’analyse de portefeuille
Calcul des rendements, ratio de Sharpe et analyse du recul maximal grâce à du code exécuté par l’agent.
Outils d’agent pour l’analyse de portefeuille est une leçon AI Agents gratuite sur CoddyKit. Ceci est la leçon 2 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage AI Agents, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours AI Agents comprend 4 leçons au total.
Analyse de portefeuille sous forme d’outils d’agent
Les agents d’analyse financière ont besoin d’un ensemble d’outils de calcul que le LLM peut appeler : rendements, mesures du risque, corrélation et suggestions de rééquilibrage. Chaque outil est une fonction Python dotée d’une signature claire et renvoie un objet JSON structuré que l’agent peut interpréter.
Calculer les rendements en pourcentage
Il s’agit du fondement de l’analyse de portefeuille. pct_change() calcule les rendements d’un jour sur l’autre. À partir de ces valeurs, calculez le rendement cumulé sur la période d’analyse.
import pandas as pd
import yfinance as yf
def calculate_returns(ticker: str, period: str = '1y') -> dict:
hist = yf.Ticker(ticker).history(period=period)['Close']
if hist.empty:
return {'error': f'No data for {ticker}'}
daily_returns = hist.pct_change().dropna()
cumulative = (1 + daily_returns).cumprod() - 1
return {
'ticker': ticker,
'period': period,
'total_return_pct': round(float(cumulative.iloc[-1]) * 100, 2),
'avg_daily_return': round(float(daily_returns.mean()) * 100, 4),
'best_day_pct': round(float(daily_returns.max()) * 100, 2),
'worst_day_pct': round(float(daily_returns.min()) * 100, 2)
}Ratio de Sharpe
Le ratio de Sharpe mesure le rendement ajusté au risque : le rendement excédentaire obtenu par unité de risque (volatilité). Plus il est élevé, mieux c’est. Un ratio de Sharpe supérieur à 1,0 est considéré comme bon ; au-dessus de 2,0, il est excellent.
import numpy as np
import yfinance as yf
def sharpe_ratio(ticker: str, period: str = '1y',
risk_free_annual: float = 0.05) -> dict:
hist = yf.Ticker(ticker).history(period=period)['Close']
daily_returns = hist.pct_change().dropna()
risk_free_daily = risk_free_annual / 252 # annualized to daily
excess_returns = daily_returns - risk_free_daily
if daily_returns.std() == 0:
return {'error': 'Zero volatility — cannot compute Sharpe ratio'}
sharpe = float(excess_returns.mean() / excess_returns.std() * np.sqrt(252))
return {
'ticker': ticker,
'sharpe_ratio': round(sharpe, 3),
'interpretation': 'excellent' if sharpe > 2 else 'good' if sharpe > 1 else 'acceptable' if sharpe > 0 else 'poor'
}Perte maximale
La perte maximale (MDD) est la plus forte baisse de la valeur d’un portefeuille, du sommet au creux. Elle représente la perte la plus importante qu’un investisseur aurait subie s’il avait acheté au sommet et vendu au creux.
import yfinance as yf
import numpy as np
def max_drawdown(ticker: str, period: str = '1y') -> dict:
hist = yf.Ticker(ticker).history(period=period)['Close']
if hist.empty:
return {'error': 'No data'}
rolling_max = hist.cummax()
drawdown = (hist - rolling_max) / rolling_max
mdd = float(drawdown.min())
mdd_date = str(drawdown.idxmin().date())
return {
'ticker': ticker,
'max_drawdown_pct': round(mdd * 100, 2),
'drawdown_date': mdd_date,
'interpretation': 'severe' if mdd < -0.30 else 'moderate' if mdd < -0.15 else 'mild'
}Matrice de corrélation
Une matrice de corrélation montre comment les actifs évoluent ensemble. Une corrélation faible ou négative entre les actifs procure un avantage de diversification : si l’un baisse, l’autre peut ne pas baisser. Cela guide la sélection des actifs et les décisions de rééquilibrage.
import pandas as pd
import yfinance as yf
def correlation_matrix(tickers: list[str], period: str = '1y') -> dict:
prices = yf.download(tickers, period=period)['Close']
returns = prices.pct_change().dropna()
corr = returns.corr().round(3)
# Convert to JSON-serializable format
result = {}
for t1 in tickers:
result[t1] = {}
for t2 in tickers:
if t1 in corr.columns and t2 in corr.index:
result[t1][t2] = float(corr.loc[t2, t1])
return {'correlation': result, 'period': period}Volatilité et bêta
La volatilité annualisée (écart type ajusté à 252 jours de cotation) mesure le risque absolu. Le bêta mesure le risque par rapport au marché (généralement le S&P 500) : bêta > 1 = plus volatil que le marché.
import numpy as np
import yfinance as yf
def volatility_and_beta(ticker: str, benchmark: str = 'SPY',
period: str = '1y') -> dict:
data = yf.download([ticker, benchmark], period=period)['Close'].pct_change().dropna()
if ticker not in data.columns or benchmark not in data.columns:
return {'error': 'Insufficient data'}
t_ret = data[ticker]
b_ret = data[benchmark]
vol_annualized = float(t_ret.std() * np.sqrt(252))
cov = np.cov(t_ret, b_ret)
beta = float(cov[0][1] / cov[1][1]) if cov[1][1] != 0 else 0.0
return {
'ticker': ticker,
'annual_vol_pct': round(vol_annualized * 100, 2),
'beta': round(beta, 3),
'market_sensitivity': 'high' if beta > 1.3 else 'market' if beta > 0.7 else 'low'
}Rendement et risque à l’échelle du portefeuille
Analysez un portefeuille entier en calculant les rendements et la volatilité pondérés. Grâce à la diversification, le portefeuille peut présenter un risque inférieur à celui de chacun de ses actifs pris individuellement.
import pandas as pd, numpy as np
import yfinance as yf
def portfolio_metrics(holdings: dict, period: str = '1y') -> dict:
tickers = list(holdings.keys())
weights = np.array(list(holdings.values()))
weights /= weights.sum() # normalize to 1.0
prices = yf.download(tickers, period=period)['Close'].pct_change().dropna()
port_ret = (prices * weights).sum(axis=1)
cov_matrix = prices.cov() * 252 # annualized
port_return = float(port_ret.mean() * 252)
port_vol = float(np.sqrt(weights @ cov_matrix.values @ weights))
port_sharpe = port_return / port_vol if port_vol > 0 else 0
return {
'annual_return_pct': round(port_return * 100, 2),
'annual_vol_pct': round(port_vol * 100, 2),
'sharpe_ratio': round(port_sharpe, 3),
'holdings': {t: round(float(w), 3) for t, w in zip(tickers, weights)}
}Suggestion de rééquilibrage
La dérive du portefeuille se produit lorsque les différents actifs progressent à des rythmes différents. L’outil de rééquilibrage calcule les pondérations actuelles et cibles, puis suggère des transactions pour rétablir l’allocation cible.
def rebalancing_suggestion(current_values: dict, target_weights: dict) -> dict:
total_value = sum(current_values.values())
current_weights = {t: v / total_value for t, v in current_values.items()}
trades = {}
for ticker in target_weights:
current_w = current_weights.get(ticker, 0)
target_w = target_weights[ticker]
diff_w = target_w - current_w
diff_usd = diff_w * total_value
if abs(diff_w) > 0.01: # only suggest if drift > 1%
trades[ticker] = {
'action': 'BUY' if diff_usd > 0 else 'SELL',
'amount_usd': round(abs(diff_usd), 2),
'from_weight': round(current_w, 4),
'to_weight': round(target_w, 4)
}
return {'total_portfolio': round(total_value, 2), 'trades': trades}
if __name__ == '__main__':
current = {'AAPL': 6000, 'BND': 2000, 'VTI': 2000}
target = {'AAPL': 0.4, 'BND': 0.3, 'VTI': 0.3}
result = rebalancing_suggestion(current, target)
print('Total portfolio: $%s' % result['total_portfolio'])
for ticker, trade in result['trades'].items():
print(f" {ticker}: {trade['action']} ${trade['amount_usd']} "
f"(weight {trade['from_weight']} -> {trade['to_weight']})")
Enregistrer les outils d’analyse pour le LLM
Enregistrez chaque fonction d’analyse comme outil d’agent. Le LLM les appelle dans l’ordre : récupérer d’abord les données, calculer ensuite les mesures, puis générer la suggestion de rééquilibrage.
FINANCIAL_TOOLS = [
{
'type': 'function',
'function': {
'name': 'calculate_returns',
'description': 'Calculate total and daily returns for a ticker.',
'parameters': {'type': 'object',
'properties': {
'ticker': {'type': 'string'},
'period': {'type': 'string', 'default': '1y'}
}, 'required': ['ticker']}
}
},
{
'type': 'function',
'function': {
'name': 'sharpe_ratio',
'description': 'Compute the annualized Sharpe ratio.',
'parameters': {'type': 'object',
'properties': {
'ticker': {'type': 'string'},
'period': {'type': 'string', 'default': '1y'}
}, 'required': ['ticker']}
}
}
]
if __name__ == '__main__':
print('Registered financial tools for the LLM:')
for tool in FINANCIAL_TOOLS:
fn = tool['function']
print(f" {fn['name']}: {fn['description']}")
Générer un résumé du portefeuille en langage clair
Après avoir calculé les mesures, demandez au LLM de traduire les nombres en explications exploitables. Les mesures sont des données d’entrée ; la sortie finale doit être compréhensible par un investisseur non spécialiste des méthodes quantitatives.
import openai, json
client = openai.OpenAI(api_key='YOUR_OPENAI_KEY')
def portfolio_narrative(metrics: dict, holdings: dict) -> str:
prompt = (
f'Portfolio metrics:\n{json.dumps(metrics, indent=2)}\n\n'
f'Holdings: {json.dumps(holdings)}\n\n'
f'Write a 3-sentence plain-language portfolio assessment for a retail investor.\n'
f'Include: overall performance, main risk, and one recommendation.'
)
resp = client.chat.completions.create(
model='gpt-4o',
messages=[{'role': 'user', 'content': prompt}]
)
return resp.choices[0].message.contentMettre en cache les mesures calculées
Les mesures calculées à partir des mêmes données sous-jacentes seront identiques. Mettez les mesures calculées en cache avec les données brutes afin d’éviter de recalculer les ratios de Sharpe et les pertes maximales à chaque tour de l’agent.
import time, hashlib, json
metrics_cache = {}
def cached_metric(func, *args, ttl: int = 3600):
key = hashlib.md5(f'{func.__name__}:{args}'.encode()).hexdigest()
entry = metrics_cache.get(key)
if entry and time.time() - entry['ts'] < ttl:
return entry['data']
result = func(*args)
metrics_cache[key] = {'data': result, 'ts': time.time()}
return result
# Usage:
# sharpe = cached_metric(sharpe_ratio, 'AAPL', '1y')
if __name__ == '__main__':
def slow_average(*nums):
return sum(nums) / len(nums)
r1 = cached_metric(slow_average, 1, 2, 3)
r2 = cached_metric(slow_average, 1, 2, 3)
print('First call result:', r1)
print('Second call result (served from cache):', r2)
print('Cache entries:', len(metrics_cache))
Que signifie un ratio de Sharpe supérieur à 2,0 ?
Le ratio de Sharpe est une mesure standard pour comparer les performances ajustées au risque de différents portefeuilles et actifs individuels.
Récapitulatif des outils d’analyse de portefeuille
La boîte à outils d’un agent financier comprend : pct_change() pour les rendements, le ratio de Sharpe pour la performance ajustée au risque, la perte maximale pour la perte dans le pire des cas, la matrice de corrélation pour la diversification, le bêta pour la sensibilité au marché et les suggestions de rééquilibrage pour la gestion du portefeuille.
Enregistrez chacun de ces éléments comme outil d’agent et mettez les résultats calculés en cache pour gagner en efficacité.
Questions Fréquemment Posées
La leçon « Outils d’agent pour l’analyse de portefeuille » est-elle gratuite ?
Oui — le texte complet de « Outils d’agent pour l’analyse de portefeuille » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours AI Agents, passe à CoddyKit PRO. Le cours AI Agents comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Outils d’agent pour l’analyse de portefeuille » ?
Calcul des rendements, ratio de Sharpe et analyse du recul maximal grâce à du code exécuté par l’agent. Tu pratiques AI Agents avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer AI Agents ?
Aucune expérience préalable n'est requise. AI Agents sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 2 sur 4.
Combien de temps prend la leçon « Outils d’agent pour l’analyse de portefeuille » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon AI Agents ?
Oui. Chaque leçon AI Agents inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Intégration d’API de données de marché
- Outils d’agent pour l’analyse de portefeuille
- Garde-fous de risque et de conformité
- Rétrosimulation des décisions de l’agent