Claude Skills cho Tài chính — Dashboard, portfolio, phân tích
Điểm nổi bật
Nhấn để đến mục tương ứng
- 1 Hành động cụ thể: pip install anthropic pandas numpy yfinance matplotlib plotly openpyxl. Phần này hướng dẫn bạn cách triển khai thực tế, không chỉ lý thuyết suông.
- 2 Một điều ít người đề cập: import anthropic import json import yfinance as yf import pandas as pd import numpy as np from datetime import. Hiểu rõ bối cảnh áp dụng sẽ quyết định 80% thành công khi triển khai.
- 3 Điểm nhấn quan trọng: import plotly.graphobjects as go from plotly.subplots import makesubplots def createfinancialdashboardportfoliodata:. Đây là phần mang lại giá trị thực tiễn cao nhất trong toàn bài viết.
- 4 Tận dụng Claude hiệu quả: def rundcfanalysiscompanydata: dict -> dict: """Discounted Cash Flow analysis với Claude""" response = — mẹo quan trọng là cung cấp đủ ngữ cảnh để AI trả về kết quả chính xác hơn 80% so với prompt chung chung.
- 5 Thành thật mà nói: def generatemonthlyreportportfolio: dict, month: str -> str: """Tạo báo cáo tháng đầy đủ: phân tích + Excel +. Phương pháp này hiệu quả trong hầu hết trường hợp, nhưng bạn cần điều chỉnh cho phù hợp ngữ cảnh riêng.
Phân tích tài chính truyền thống đòi hỏi chuyên gia với Excel phức tạp, Python scripts tùy chỉnh, và nhiều giờ làm việc thủ công. Claude kết hợp với financial libraries thay đổi hoàn toàn điều này — từ việc giải thích dữ liệu đến tự động tạo báo cáo chuyên sâu.
Setup môi trường
pip install anthropic pandas numpy yfinance matplotlib plotly openpyxl
Module 1: Portfolio Analyzer
import anthropic
import json
import yfinance as yf
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
client = anthropic.Anthropic()
class PortfolioAnalyzer:
def __init__(self):
self.client = anthropic.Anthropic()
def analyze_portfolio(self, holdings: dict) -> dict:
"""
holdings = {
"AAPL": {"shares": 100, "avg_cost": 150.0},
"MSFT": {"shares": 50, "avg_cost": 280.0},
"GOOGL": {"shares": 20, "avg_cost": 2800.0}
}
"""
# Fetch market data
market_data = self._fetch_market_data(list(holdings.keys()))
# Calculate portfolio metrics
portfolio_metrics = self._calculate_metrics(holdings, market_data)
# Claude phân tích và đưa ra insights
analysis = self._ai_analysis(portfolio_metrics)
return {
"metrics": portfolio_metrics,
"analysis": analysis,
"recommendations": self._generate_recommendations(portfolio_metrics, analysis)
}
def _fetch_market_data(self, symbols: list) -> dict:
data = {}
end_date = datetime.now()
start_date = end_date - timedelta(days=365)
for symbol in symbols:
try:
ticker = yf.Ticker(symbol)
hist = ticker.history(start=start_date, end=end_date)
info = ticker.info
data[symbol] = {
"current_price": hist['Close'].iloc[-1] if not hist.empty else 0,
"price_52w_high": hist['Close'].max() if not hist.empty else 0,
"price_52w_low": hist['Close'].min() if not hist.empty else 0,
"ytd_return": self._calculate_ytd_return(hist),
"volatility": hist['Close'].pct_change().std() * np.sqrt(252) * 100 if not hist.empty else 0,
"pe_ratio": info.get('trailingPE', 'N/A'),
"sector": info.get('sector', 'Unknown'),
"prices_30d": hist['Close'].tail(30).tolist() if not hist.empty else []
}
except Exception as e:
data[symbol] = {"error": str(e), "current_price": 0}
return data
def _calculate_ytd_return(self, hist: pd.DataFrame) -> float:
if hist.empty:
return 0
year_start = hist[hist.index.year == datetime.now().year]
if year_start.empty:
return 0
first_price = year_start['Close'].iloc[0]
last_price = hist['Close'].iloc[-1]
return ((last_price - first_price) / first_price) * 100
def _calculate_metrics(self, holdings: dict, market_data: dict) -> dict:
total_cost = 0
total_value = 0
positions = []
for symbol, holding in holdings.items():
mdata = market_data.get(symbol, {})
shares = holding["shares"]
avg_cost = holding["avg_cost"]
current_price = mdata.get("current_price", 0)
cost_basis = shares * avg_cost
market_value = shares * current_price
gain_loss = market_value - cost_basis
gain_loss_pct = ((current_price - avg_cost) / avg_cost * 100) if avg_cost > 0 else 0
total_cost += cost_basis
total_value += market_value
positions.append({
"symbol": symbol,
"shares": shares,
"avg_cost": avg_cost,
"current_price": current_price,
"market_value": market_value,
"cost_basis": cost_basis,
"gain_loss": gain_loss,
"gain_loss_pct": round(gain_loss_pct, 2),
"weight": 0, # Will calculate after totals
"sector": mdata.get("sector", "Unknown"),
"pe_ratio": mdata.get("pe_ratio", "N/A"),
"ytd_return": mdata.get("ytd_return", 0),
"volatility": mdata.get("volatility", 0)
})
# Calculate weights
for pos in positions:
pos["weight"] = (pos["market_value"] / total_value * 100) if total_value > 0 else 0
# Portfolio-level metrics
portfolio_return = ((total_value - total_cost) / total_cost * 100) if total_cost > 0 else 0
# Sector allocation
sector_allocation = {}
for pos in positions:
sector = pos["sector"]
sector_allocation[sector] = sector_allocation.get(sector, 0) + pos["weight"]
return {
"total_cost": total_cost,
"total_value": total_value,
"total_gain_loss": total_value - total_cost,
"portfolio_return_pct": round(portfolio_return, 2),
"positions": positions,
"sector_allocation": sector_allocation,
"num_positions": len(positions),
"largest_position": max(positions, key=lambda x: x["weight"])["symbol"] if positions else None
}
def _ai_analysis(self, metrics: dict) -> str:
positions_summary = "
".join([
f"- {p['symbol']}: {p['weight']:.1f}% weight, {p['gain_loss_pct']:+.1f}% return, volatility {p['volatility']:.1f}%"
for p in metrics["positions"]
])
response = self.client.messages.create(
model="claude-opus-4-5",
max_tokens=2000,
system="You are a senior portfolio manager and financial analyst. Provide clear, actionable analysis.",
messages=[{
"role": "user",
"content": f"""Analyze this investment portfolio:
Total Value: ${metrics['total_value']:,.2f}
Total Return: {metrics['portfolio_return_pct']:+.2f}%
Number of Positions: {metrics['num_positions']}
Positions:
{positions_summary}
Sector Allocation:
{json.dumps(metrics['sector_allocation'], indent=2)}
Provide analysis on:
1. Portfolio diversification (concentrated? well-diversified?)
2. Risk assessment (high volatility positions, sector concentration)
3. Performance highlights (winners and laggards)
4. Key risks to watch
5. Overall portfolio health score (1-10) with brief explanation"""
}]
)
return response.content[0].text
def _generate_recommendations(self, metrics: dict, analysis: str) -> list:
response = self.client.messages.create(
model="claude-haiku-4-5",
max_tokens=1000,
messages=[{
"role": "user",
"content": f"""Based on this portfolio analysis, provide 3-5 specific, actionable recommendations.
Analysis:
{analysis}
Portfolio Stats:
- Total Return: {metrics['portfolio_return_pct']:+.2f}%
- Positions: {metrics['num_positions']}
- Sectors: {list(metrics['sector_allocation'].keys())}
Format each recommendation as:
ACTION: [BUY/SELL/HOLD/REBALANCE]
TICKER: [if applicable]
RATIONALE: [1-2 sentences]
PRIORITY: [HIGH/MEDIUM/LOW]"""
}]
)
return response.content[0].text.strip().split("
")
Module 2: Financial Dashboard Generator
import plotly.graph_objects as go
from plotly.subplots import make_subplots
def create_financial_dashboard(portfolio_data: dict, output_html: str):
"""Tạo interactive HTML dashboard với Plotly"""
positions = portfolio_data["metrics"]["positions"]
sector_alloc = portfolio_data["metrics"]["sector_allocation"]
fig = make_subplots(
rows=2, cols=2,
subplot_titles=[
"Portfolio Composition",
"Sector Allocation",
"Gain/Loss by Position",
"Risk vs Return"
],
specs=[
[{"type": "pie"}, {"type": "pie"}],
[{"type": "bar"}, {"type": "scatter"}]
]
)
# 1. Portfolio composition (by market value)
fig.add_trace(
go.Pie(
labels=[p["symbol"] for p in positions],
values=[p["market_value"] for p in positions],
name="Portfolio"
),
row=1, col=1
)
# 2. Sector allocation
fig.add_trace(
go.Pie(
labels=list(sector_alloc.keys()),
values=list(sector_alloc.values()),
name="Sectors"
),
row=1, col=2
)
# 3. Gain/Loss bar chart
colors = ['green' if p["gain_loss"] >= 0 else 'red' for p in positions]
fig.add_trace(
go.Bar(
x=[p["symbol"] for p in positions],
y=[p["gain_loss"] for p in positions],
marker_color=colors,
name="Gain/Loss"
),
row=2, col=1
)
# 4. Risk vs Return scatter
fig.add_trace(
go.Scatter(
x=[p["volatility"] for p in positions],
y=[p["gain_loss_pct"] for p in positions],
mode='markers+text',
text=[p["symbol"] for p in positions],
textposition="top center",
marker=dict(
size=[p["weight"] * 2 for p in positions], # Size by weight
color=[p["gain_loss"] for p in positions],
colorscale='RdYlGn',
showscale=True
),
name="Risk/Return"
),
row=2, col=2
)
fig.update_layout(
title=f"Portfolio Dashboard — Total Value: ${portfolio_data['metrics']['total_value']:,.2f}",
height=800,
showlegend=False
)
fig.write_html(output_html)
print(f"Dashboard saved to: {output_html}")
return output_html
Module 3: Financial Modeling với Claude
def run_dcf_analysis(company_data: dict) -> dict:
"""Discounted Cash Flow analysis với Claude"""
response = client.messages.create(
model="claude-opus-4-5",
max_tokens=3000,
system="You are a CFA-level financial analyst expert in DCF valuation.",
messages=[{
"role": "user",
"content": f"""Perform a DCF (Discounted Cash Flow) analysis for:
Company: {company_data.get('name')}
Industry: {company_data.get('industry')}
Current Revenue: ${company_data.get('revenue', 0):,.0f}
Revenue Growth (3-year avg): {company_data.get('revenue_growth', 0):.1f}%
Operating Margin: {company_data.get('operating_margin', 0):.1f}%
Current P/E: {company_data.get('pe_ratio', 'N/A')}
Shares Outstanding: {company_data.get('shares', 0):,.0f}
Provide:
1. 5-year revenue and FCF projections (base/bull/bear scenarios)
2. Discount rate (WACC) estimate with reasoning
3. Terminal value calculation
4. Intrinsic value per share (all 3 scenarios)
5. Margin of safety at current price: ${company_data.get('current_price', 0):.2f}
6. Investment verdict: UNDERVALUED / FAIRLY VALUED / OVERVALUED
Format key numbers clearly."""
}]
)
return {"analysis": response.content[0].text}
Tích hợp đầy đủ: Monthly Report Generator
def generate_monthly_report(portfolio: dict, month: str) -> str:
"""Tạo báo cáo tháng đầy đủ: phân tích + Excel + Dashboard"""
analyzer = PortfolioAnalyzer()
# 1. Phân tích portfolio
print("Analyzing portfolio...")
analysis_result = analyzer.analyze_portfolio(portfolio)
# 2. Tạo Excel report
import openpyxl
wb = openpyxl.Workbook()
ws = wb.active
ws.title = f"Portfolio {month}"
headers = ["Symbol", "Shares", "Avg Cost", "Current Price",
"Market Value", "Gain/Loss", "Return%", "Weight%", "Sector"]
for col, h in enumerate(headers, 1):
ws.cell(row=1, column=col, value=h)
for row, pos in enumerate(analysis_result["metrics"]["positions"], 2):
ws.cell(row=row, column=1, value=pos["symbol"])
ws.cell(row=row, column=2, value=pos["shares"])
ws.cell(row=row, column=3, value=pos["avg_cost"])
ws.cell(row=row, column=4, value=pos["current_price"])
ws.cell(row=row, column=5, value=pos["market_value"])
ws.cell(row=row, column=6, value=pos["gain_loss"])
ws.cell(row=row, column=7, value=pos["gain_loss_pct"])
ws.cell(row=row, column=8, value=round(pos["weight"], 2))
ws.cell(row=row, column=9, value=pos["sector"])
excel_path = f"/tmp/portfolio_{month}.xlsx"
wb.save(excel_path)
# 3. Tạo HTML dashboard
dashboard_path = f"/tmp/dashboard_{month}.html"
create_financial_dashboard(analysis_result, dashboard_path)
# 4. AI Summary
summary_response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=500,
messages=[{
"role": "user",
"content": f"""Write a brief monthly portfolio summary for {month}:
Performance: {analysis_result['metrics']['portfolio_return_pct']:+.2f}%
Total Value: ${analysis_result['metrics']['total_value']:,.2f}
Analysis highlights:
{analysis_result['analysis'][:500]}
Write 3-4 sentences suitable for an executive briefing."""
}]
)
return {
"excel": excel_path,
"dashboard": dashboard_path,
"summary": summary_response.content[0].text,
"recommendations": analysis_result["recommendations"]
}
# Chạy report
holdings = {
"AAPL": {"shares": 100, "avg_cost": 150.0},
"MSFT": {"shares": 50, "avg_cost": 280.0},
"VNM.VN": {"shares": 1000, "avg_cost": 75.0}
}
report = generate_monthly_report(holdings, "2025-03")
print(f"Report generated: {report['summary']}")
Tổng kết
Với Claude + Python financial libraries, bạn có thể xây dựng công cụ phân tích tài chính mạnh mẽ:
- Portfolio Analyzer — metrics tự động + AI insights
- Dashboard Generator — interactive charts với Plotly
- DCF Modeling — valuation analysis với Claude làm financial analyst
- Monthly Reports — Excel + dashboard + executive summary tự động
Khám phá tiếp: Tạo Custom Skills cho Claude để đóng gói các tools này thành skills tái sử dụng.
Bài viết liên quan
Bai viet co huu ich khong?
Bản quyền thuộc về tác giả. Vui lòng dẫn nguồn khi chia sẻ.




