| Phân tích danh mục đầu tư với Python – Dữ li…

Được viết bởi Đặng Trí Thanh vào ngày 27/06/2026 lúc 23:56 | 34 lượt xem

Phân tích danh mục đầu tư với Python – Dữ liệu, hiệu suất, phân bổ

Phân tích danh mục đầu tư là một phần quan trọng trong quản lý tài chính. Với Python, chúng ta có thể thực hiện các phân tích phức tạp một cách hiệu quả. Bài viết này sẽ hướng dẫn bạn cách sử dụng Python để phân tích danh mục đầu tư từ việc thu thập dữ liệu đến đánh giá hiệu suất và tối ưu hóa phân bổ.

1. Thu thập dữ liệu

Cài đặt thư viện cần thiết

pip install yfinance pandas numpy matplotlib seaborn scipy

Sử dụng yfinance để lấy dữ liệu chứng khoán

import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.optimize import minimize

# Định nghĩa danh mục đầu tư
portfolio = {
    'AAPL': 0.3,  # Apple
    'MSFT': 0.3,  # Microsoft
    'GOOGL': 0.2, # Google
    'AMZN': 0.2   # Amazon
}

# Lấy dữ liệu lịch sử
data = pd.DataFrame()
for ticker in portfolio.keys():
    stock = yf.Ticker(ticker)
    hist = stock.history(period='1y')
    data[ticker] = hist['Close']

# Tính toán lợi nhuận hàng ngày
returns = data.pct_change()

# Hiển thị dữ liệu
print("Dữ liệu giá đóng cửa:")
print(data.head())
print("nLợi nhuận hàng ngày:")
print(returns.head())

Dữ liệu giá đóng cửa

2. Phân tích hiệu suất

Tính toán các chỉ số quan trọng

# Lợi nhuận trung bình hàng năm
annual_returns = returns.mean() * 252

# Độ lệch chuẩn (rủi ro)
volatility = returns.std() * np.sqrt(252)

# Tỷ lệ Sharpe (giả sử lãi suất phi rủi ro là 0.02)
risk_free_rate = 0.02
sharpe_ratio = (annual_returns - risk_free_rate) / volatility

# Tạo bảng tổng hợp
performance = pd.DataFrame({
    'Lợi nhuận hàng năm': annual_returns,
    'Độ biến động': volatility,
    'Tỷ lệ Sharpe': sharpe_ratio
})

# Hiển thị kết quả
print("nPhân tích hiệu suất:")
print(performance)

# Vẽ biểu đồ so sánh
plt.figure(figsize=(12, 6))
performance['Lợi nhuận hàng năm'].plot(kind='bar')
plt.title('Lợi nhuận hàng năm của các tài sản')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

Phân tích hiệu suất

3. Phân tích tương quan

Xem xét mối quan hệ giữa các tài sản

# Ma trận tương quan
correlation_matrix = returns.corr()

# Vẽ biểu đồ nhiệt
plt.figure(figsize=(10, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0)
plt.title('Ma trận tương quan giữa các tài sản')
plt.tight_layout()
plt.show()

# Vẽ biểu đồ phân tán
sns.pairplot(returns)
plt.suptitle('Phân tích phân tán giữa các tài sản', y=1.02)
plt.show()

Ma trận tương quan

4. Tối ưu hóa danh mục đầu tư

Sử dụng Modern Portfolio Theory (MPT)

def portfolio_volatility(weights, returns):
    return np.sqrt(np.dot(weights.T, np.dot(returns.cov() * 252, weights)))

def negative_sharpe(weights, returns, risk_free_rate):
    returns_array = returns.mean() * 252
    volatility = portfolio_volatility(weights, returns)
    return -(returns_array.dot(weights) - risk_free_rate) / volatility

# Tối ưu hóa danh mục
n_assets = len(portfolio)
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
bounds = tuple((0, 1) for _ in range(n_assets))
initial_weights = np.array([1/n_assets] * n_assets)

optimal_weights = minimize(
    negative_sharpe,
    initial_weights,
    args=(returns, risk_free_rate),
    method='SLSQP',
    bounds=bounds,
    constraints=constraints
)

# Hiển thị kết quả tối ưu
print("nPhân bổ tài sản tối ưu:")
for ticker, weight in zip(portfolio.keys(), optimal_weights.x):
    print(f"{ticker}: {weight:.2%}")

# Vẽ biểu đồ phân bổ
plt.figure(figsize=(10, 6))
plt.pie(optimal_weights.x, labels=portfolio.keys(), autopct='%1.1f%%')
plt.title('Phân bổ tài sản tối ưu')
plt.show()

Phân bổ tài sản tối ưu

5. Phân tích rủi ro

Đánh giá rủi ro danh mục

# Value at Risk (VaR)
def calculate_var(returns, weights, confidence_level=0.95):
    portfolio_returns = returns.dot(weights)
    return np.percentile(portfolio_returns, (1 - confidence_level) * 100)

# Expected Shortfall (ES)
def calculate_es(returns, weights, confidence_level=0.95):
    portfolio_returns = returns.dot(weights)
    var = calculate_var(returns, weights, confidence_level)
    return portfolio_returns[portfolio_returns <= var].mean()

# Tính toán các chỉ số rủi ro
var_95 = calculate_var(returns, optimal_weights.x)
es_95 = calculate_es(returns, optimal_weights.x)

print(f"nValue at Risk (95%): {var_95:.2%}")
print(f"Expected Shortfall (95%): {es_95:.2%}")

# Vẽ biểu đồ phân phối lợi nhuận
portfolio_returns = returns.dot(optimal_weights.x)
plt.figure(figsize=(10, 6))
sns.histplot(portfolio_returns, kde=True)
plt.axvline(var_95, color='r', linestyle='--', label=f'VaR (95%): {var_95:.2%}')
plt.axvline(es_95, color='g', linestyle='--', label=f'ES (95%): {es_95:.2%}')
plt.title('Phân phối lợi nhuận danh mục')
plt.xlabel('Lợi nhuận')
plt.ylabel('Tần suất')
plt.legend()
plt.show()

Phân tích rủi ro

6. Trực quan hóa kết quả

Tạo biểu đồ hiệu suất và phân bổ

# Biểu đồ hiệu suất tích lũy
cumulative_returns = (1 + returns).cumprod()
plt.figure(figsize=(12, 6))
for column in cumulative_returns.columns:
    plt.plot(cumulative_returns.index, cumulative_returns[column], label=column)
plt.title('Hiệu suất tích lũy của danh mục')
plt.xlabel('Ngày')
plt.ylabel('Hiệu suất tích lũy')
plt.legend()
plt.grid(True)
plt.show()

# Biểu đồ phân bổ tài sản
plt.figure(figsize=(10, 6))
plt.pie(optimal_weights.x, labels=portfolio.keys(), autopct='%1.1f%%')
plt.title('Phân bổ tài sản tối ưu')
plt.show()

# Biểu đồ so sánh hiệu suất
plt.figure(figsize=(12, 6))
performance['Lợi nhuận hàng năm'].plot(kind='bar')
plt.title('So sánh lợi nhuận hàng năm')
plt.xlabel('Tài sản')
plt.ylabel('Lợi nhuận hàng năm')
plt.xticks(rotation=45)
plt.grid(True)
plt.show()

Hiệu suất tích lũy

Kết luận

Phân tích danh mục đầu tư với Python cung cấp cho chúng ta các công cụ mạnh mẽ để:

  • Thu thập và xử lý dữ liệu thị trường
  • Đánh giá hiệu suất và rủi ro
  • Tối ưu hóa phân bổ tài sản
  • Trực quan hóa kết quả

Việc kết hợp các thư viện như pandas, numpy, yfinance và matplotlib cho phép chúng ta thực hiện các phân tích phức tạp một cách hiệu quả và dễ hiểu.

Tài liệu tham khảo

1. Tổng quan — Phân tích danh mục đầu tư với Python

Phân tích danh mục đầu tư là một phần quan trọng trong quản lý tài chính. Với Python, chúng ta có thể thực hiện các phân tích phức tạp một cách hiệu quả. Bài viết này sẽ hướng dẫn bạn cách sử dụng Python để phân tích danh mục đầu tư từ việc thu thập dữ liệu đến đánh giá hiệu suất và tối ưu hóa phân bổ.

2. Thu thập dữ liệu

Cài đặt thư viện cần thiết

pip install yfinance pandas numpy matplotlib seaborn scipy

Sử dụng yfinance để lấy dữ liệu chứng khoán

import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.optimize import minimize

# Định nghĩa danh mục đầu tư
portfolio = {
    'AAPL': 0.3,  # Apple
    'MSFT': 0.3,  # Microsoft
    'GOOGL': 0.2, # Google
    'AMZN': 0.2   # Amazon
}

# Lấy dữ liệu lịch sử
data = pd.DataFrame()
for ticker in portfolio.keys():
    stock = yf.Ticker(ticker)
    hist = stock.history(period='1y')
    data[ticker] = hist['Close']

# Tính toán lợi nhuận hàng ngày
returns = data.pct_change()
print("Dữ liệu giá đóng cửa:")
print(data.head())
print("Lợi nhuận hàng ngày:")
print(returns.head())

3. Phân tích hiệu suất

Tính toán các chỉ số quan trọng

# Lợi nhuận trung bình hàng năm
annual_return = returns.mean() * 252
# Độ lệch chuẩn (rủi ro) hàng năm
annual_vol = returns.std() * np.sqrt(252)

# Lợi nhuận của toàn danh mục
weights = np.array(list(portfolio.values()))
portfolio_return = np.dot(weights, annual_return)
portfolio_vol = np.sqrt(np.dot(weights.T, np.dot(returns.cov() * 252, weights)))

print("Lợi nhuận từng cổ phiếu:")
print(annual_return)
print("Rủi ro từng cổ phiếu:")
print(annual_vol)
print(f"Danh mục - Lợi nhuận: {portfolio_return:.4f}, Rủi ro: {portfolio_vol:.4f}")

Hiệu quả phân bổ — đa dạng hóa

Đa dạng hóa giúp giảm rủi ro: khi một cổ phiếu giảm, cổ phiếu khác có thể tăng. Ma trận tương quan cho biết mức độ phụ thuộc giữa các tài sản:

# Ma trận tương quan
corr = returns.corr()
# sns.heatmap(corr, annot=True, cmap='coolwarm')
# plt.show()

4. Đường biên hiệu quả (Efficient Frontier)

Một trong những khái niệm quan trọng nhất: với mức rủi ro cho trước, đâu là danh mục lợi nhuận tối đa? Python giúp tính toán dễ dàng:

def portfolio_performance(weights, mean_returns, cov_matrix):
    ret = np.dot(weights, mean_returns)
    vol = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))
    return ret, vol

def optimize_portfolio(mean_returns, cov_matrix):
    num = len(mean_returns)
    args = (mean_returns, cov_matrix)

    def neg_sharpe(weights):
        ret, vol = portfolio_performance(weights, mean_returns, cov_matrix)
        return -(ret - 0.02) / vol  # rf = 2%

    constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
    bounds = tuple((0, 1) for _ in range(num))
    result = minimize(neg_sharpe, num * [1. / num], method='SLSQP',
                      bounds=bounds, constraints=constraints)
    return result

# opt = optimize_portfolio(annual_return, returns.cov() * 252)
# print("Tỷ trọng tối ưu:", opt.x)

5. Phân tích rủi ro — VaR và Drawdown

Value at Risk (VaR)

VaR cho biết mức lỗ tối đa với xác suất nhất định trong một khoảng thời gian:

# VaR 95% từ phân phối lợi nhuận
var_95 = np.percentile(portfolio_returns, 5)
print(f"VaR 95% hàng ngày: {var_95:.4f}")

Drawdown

# Max drawdown của danh mục
cum = (1 + portfolio_returns).cumprod()
peak = cum.cummax()
drawdown = (cum - peak) / peak
max_dd = drawdown.min()
print(f"Max Drawdown: {max_dd:.4f}")

6. Tối ưu hóa phân bổ

Dựa trên hiệu quả, bạn có thể điều chỉnh tỷ trọng để đạt mục tiêu lợi nhuận/rủi ro. Ví dụ tăng tỷ trọng tài sản có tương quan thấp để giảm rủi ro, hoặc tăng tài sản có Sharpe cao.

7. Mở rộng — áp dụng cho crypto và bot trading

Kỹ thuật phân tích danh mục này áp dụng được cho cả crypto và bot trading:

  • Phân tích danh mục nhiều coin để giảm rủi ro.
  • Đánh giá hiệu suất bot theo Sharpe, drawdown, profit factor.
  • Tối ưu phân bổ vốn giữa các chiến lược.

8. FAQ — Phân tích danh mục

Cần biết nhiều toán không? Cần xác suất/thống kê cơ bản; Python xử lý phần nặng.

yfinance có miễn phí không? Có — dữ liệu cơ bản từ Yahoo Finance miễn phí.

Áp dụng cho VN được không? Được — dùng mã CK Việt qua yfinance hoặc thư viện khác.

Học ở đâu? Tại HNDL có khóa Python phân tích tài chính.

9. Kết luận

Python là công cụ mạnh mẽ để phân tích danh mục đầu tư: thu thập dữ liệu, đánh giá hiệu suất, tối ưu phân bổ và quản lý rủi ro. Nắm vững những kỹ thuật này giúp bạn quản lý tài chính cá nhân và xây dựng hệ thống giao dịch chuyên nghiệp.

📖 Lập trình Python Cơ bản · Algorithmic trading Việt Nam

10. Mở rộng — Sharpe Ratio và các chỉ số đánh giá

Ngoài lợi nhuận/rủi ro, cần các chỉ số chuẩn hóa để so sánh danh mục.

Sharpe Ratio

# [SHARPE - PYTHON]
rf = 0.02  # lãi suất phi rủi ro
sharpe = (portfolio_return - rf) / portfolio_vol
print(f"Sharpe: {sharpe:.2f}")
# Sharpe > 1 tốt, > 2 rất tốt

Sortino Ratio

Chỉ tính rủi ro theo chiều giảm (downside deviation) — phù hợp khi lợi nhuận không đối xứng.

11. Monte Carlo — mô phỏng rủi ro

Mô phỏng nhiều kịch bản tương lai dựa trên dữ liệu quá khứ:

# [MONTE CARLO - PYTHON]
import numpy as np

def simulate(returns, n_sim=1000, horizon=252):
    results = []
    mu = returns.mean()
    sigma = returns.std()
    for _ in range(n_sim):
        # mô phỏng lợi nhuận tích lũy
        path = np.random.normal(mu, sigma, horizon)
        results.append(np.prod(1 + path))
    return np.percentile(results, [5, 50, 95])

# lo, mid, hi = simulate(portfolio_returns)
# -> ước lượng dải kết quả

12. Tối ưu phân bổ vốn — thực hành

Quy trình tối ưu danh mục thực tế:

  1. Thu thập dữ liệu các tài sản.
  2. Tính return trung bình, cov matrix.
  3. Tìm danh mục tối ưu (max Sharpe / min vol).
  4. Kiểm tra kết quả ổn định không (robust).
  5. Điều chỉnh theo ràng buộc thực tế (tax, phí, thanh khoản).

13. Phân tích danh mục crypto và bot

Kỹ thuật này áp dụng cho crypto và đánh giá bot trading:

  • Nhiều coin → giảm rủi ro, tối ưu tỷ trọng.
  • Đánh giá bot: Sharpe, Sortino, max drawdown, profit factor.
  • So sánh bot với buy-and-hold.
  • Phân bổ vốn giữa các chiến lược để đa dạng hóa rủi ro.

14. Cảnh báo và hạn chế

  • Hiệu suất quá khứ không đảm bảo tương lai.
  • Dữ liệu ngắn dễ dẫn đến kết luận sai.
  • Phí, thuế, trượt giá ảnh hưởng kết quả thực.
  • Tương quan thay đổi theo thời gian (đặc biệt lúc khủng hoảng).

15. FAQ bổ sung

Cần bao nhiêu dữ liệu? Càng nhiều càng tốt; tối thiểu vài năm để có ý nghĩa.

Efficient frontier có áp dụng cho crypto không? Có, nhưng crypto biến động mạnh — kết quả kém ổn định hơn.

Có cần tối ưu mỗi tháng không? Không nên quá thường xuyên — rebalance định kỳ hợp lý.

Học ở đâu? Tại HNDL có khóa Python phân tích tài chính.

16. Kết luận bổ sung

Phân tích danh mục bằng Python giúp bạn đưa quyết định dựa trên dữ liệu thay vì cảm tính: đánh giá hiệu suất, tối ưu phân bổ, mô phỏng rủi ro. Đây là kỹ năng nền tảng cho quản lý tài chính cá nhân và xây dựng hệ thống giao dịch.

📖 Lập trình Python Cơ bản · Algorithmic trading Việt Nam

17. Mở rộng — Correlation và diversification

Đa dạng hóa hiệu quả phụ thuộc vào tương quan giữa các tài sản. Tương quan thấp → giảm rủi ro tốt hơn.

Đọc ma trận tương quan

# [CORRELATION - PYTHON]
corr = returns.corr()
# Giá trị 1.0: di chuyển cùng chiều hoàn hảo
# Giá trị -1.0: ngược chiều hoàn hảo
# Giá trị ~0: không tương quan
# Kết hợp tài sản tương quan thấp -> giảm rủi ro danh mục

Ví dụ: vàng và cổ phiếu công nghệ thường tương quan thấp — kết hợp giúp giảm biến động tổng thể.

18. Backtest danh mục — mô phỏng lại quá khứ

# [BACKTEST PORTFOLIO - PYTHON]
# Tính equity curve của danh mục theo tỷ trọng
weights = np.array([0.3, 0.3, 0.2, 0.2])
port_returns = returns.dot(weights)
equity = (1 + port_returns).cumprod()

# Đánh giá: total return, annualized, max DD, Sharpe

19. Rebalance — duy trì tỷ trọng mục tiêu

Theo thời gian, tỷ trọng lệch do giá thay đổi. Rebalance định kỳ (quý/năm) giúp giữ đúng rủi ro mong muốn.

# [REBALANCE - MÔ TẢ]
# Tỷ trọng mục tiêu: AAPL 30%, MSFT 30%, GOOGL 20%, AMZN 20%
# Sau 1 năm, AAPL tăng mạnh -> tỷ trọng thành 40%
# Bán bớt AAPL, mua thêm phần thiếu -> quay về mục tiêu
# Giúp "bán đắt mua rẻ" tự động và kiểm soát rủi ro

20. Áp dụng cho quyết định đầu tư cá nhân

  • Xác định khẩu vị rủi ro (risk profile).
  • Chọn danh mục phù hợp (thận trọng/cân bằng/tăng trưởng).
  • Phân bổ giữa tài sản tương quan thấp.
  • Rebalance định kỳ, không theo cảm xúc.
  • Đánh giá lại định kỳ bằng số liệu.

21. FAQ cuối

Tối ưu danh mục có đảm bảo lời không? Không — nó tối ưu rủi ro/lợi nhuận theo giả định; quá khứ không đảm bảo tương lai.

Nên rebalance bao lâu một lần? Tùy chi phí giao dịch; quý/năm là phổ biến.

Crypto có nên trong danh mục không? Có thể, tỷ trọng nhỏ do biến động cao.

Học ở đâu? Tại HNDL có khóa Python phân tích tài chính.

22. Kết luận cuối

Phân tích danh mục bằng Python là kỹ năng thiết yếu cho nhà đầu tư hiện đại: thu thập dữ liệu, đánh giá hiệu suất, tối ưu phân bổ, mô phỏng rủi ro và rebalance có kỷ luật. Kết hợp với tư duy quant, bạn sẽ quản lý tài chính thông minh và bền vững.

📖 Lập trình Python Cơ bản · Algorithmic trading Việt Nam · Xây dựng IB bằng Bot

23. Mở rộng — Phân tích danh mục với dữ liệu VN và crypto

Ngoài cổ phiếu Mỹ, bạn có thể áp dụng cho cổ phiếu Việt Nam và crypto.

Cổ phiếu Việt Nam

# [CK VIỆT NAM - PYTHON]
# import yfinance as yf
# Ticker VN dùng hậu tố .HN hoặc .VN tùy sàn
# Ví dụ: VNM.HN, VCB.HN, FPT.HN (HOSE)
# data = yf.download("FPT.HN", start="2023-01-01")
# Hoặc dùng thư viện riêng cho dữ liệu VN

Crypto

# [CRYPTO - PYTHON]
# import ccxt
# exchange = ccxt.binance({"enableRateLimit": True})
# ohlcv = exchange.fetch_ohlcv("BTC/USDT", "1d", limit=365)
# Dựng DataFrame từ ohlcv rồi phân tích tương tự

24. Xây dựng hệ thống đánh giá định kỳ

Thiết lập quy trình đánh giá danh mục định kỳ:

  1. Cuối mỗi tuần: cập nhật dữ liệu, tính hiệu suất.
  2. So với benchmark (VN-Index, S&P 500, BTC…).
  3. Kiểm tra tỷ trọng lệch, rebalance nếu cần.
  4. Đánh giá Sharpe, drawdown, tương quan.
  5. Ghi nhật ký quyết định để học hỏi.

25. Kết hợp với bot trading

Kỹ năng phân tích danh mục giúp bạn quản lý vốn giữa bot và đầu tư thủ công:

  • Phân bổ vốn giữa chiến lược bot và buy-and-hold.
  • Đánh giá bot bằng các chỉ số danh mục (Sharpe, DD).
  • So sánh bot với thị trường để biết có đáng chạy.
  • Kiểm soát tổng rủi ro toàn bộ danh mục.

26. Cảnh báo và hạn chế

  • Dữ liệu quá khứ không đảm bảo tương lai.
  • Phí, thuế, thanh khoản ảnh hưởng kết quả.
  • Tương quan thay đổi lúc khủng hoảng.
  • Không đặt toàn bộ vào một kết quả tối ưu.

27. FAQ cuối

Dữ liệu VN lấy ở đâu? yfinance (hạn chế), hoặc API từ các công ty chứng khoán.

Nên phân tích bao lâu? Tối thiểu vài năm để có ý nghĩa thống kê.

Crypto phân tích được không? Có — nhưng biến động cao, kết quả kém ổn định.

Học ở đâu? Tại HNDL có khóa Python phân tích tài chính.

28. Kết luận cuối

Phân tích danh mục với Python là kỹ năng thực dụng: áp dụng được cho cổ phiếu, crypto, và đánh giá bot. Kết hợp dữ liệu, chỉ số hiệu suất, tối ưu phân bổ và rebalance có kỷ luật giúp bạn quản lý tài sản thông minh và bền vững.

📖 Lập trình Python Cơ bản · Algorithmic trading Việt Nam · Xây dựng IB bằng Bot

Đặng Trí Thanh

Đặng Trí Thanh

Giám đốc Công nghệ · DNT Digital · Giảng viên HNDL
852 Bài viết
15.4k Người theo dõi
120k+ Lượt đọc

Đặng Trí Thanh — Founder & CTO · Hướng Nghiệp Dữ Liệu - DNT Digital. Chuyên đào tạo và triển khai thực chiến Python, MT5 và hệ thống bot auto trading / IB cho học viên và doanh nghiệp.