Sử dụng Pandas để phân tích dữ liệu tài chính hiệu quả

2024-04-26 — QuantTrade

Sử dụng Pandas để phân tích dữ liệu tài chính hiệu quả

Hướng dẫn toàn diện về cách sử dụng thư viện Pandas của Python để phân tích, xử lý và trực quan hóa dữ liệu tài chính một cách hiệu quả.

Giới thiệu

Trong thời đại số hóa, việc phân tích dữ liệu tài chính đóng vai trò quan trọng trong việc ra quyết định đầu tư và phát triển chiến lược kinh doanh. Pandas, một thư viện mạnh mẽ của Python, đã trở thành công cụ không thể thiếu cho các nhà phân tích dữ liệu, nhà kinh tế học và các chuyên gia tài chính.

Bài viết này sẽ hướng dẫn bạn cách sử dụng Pandas để phân tích dữ liệu tài chính, từ việc nhập và làm sạch dữ liệu đến phân tích xu hướng và trực quan hóa kết quả.

Pandas là gì?

Pandas là một thư viện Python mã nguồn mở cung cấp các cấu trúc dữ liệu hiệu quả và các công cụ phân tích dữ liệu. Nó được xây dựng trên thư viện NumPy và cung cấp các tính năng:

  • Cấu trúc dữ liệu linh hoạt như DataFrame và Series
  • Xử lý dữ liệu thiếu hiệu quả
  • Nhập và xuất dữ liệu từ nhiều định dạng khác nhau (CSV, Excel, SQL, JSON,...)
  • Phân tích chuỗi thời gian và xử lý dữ liệu thời gian
  • Tích hợp với nhiều thư viện khác như Matplotlib, Seaborn để trực quan hóa dữ liệu

Cài đặt và thiết lập môi trường

Để bắt đầu với Pandas, bạn cần cài đặt Python và các thư viện cần thiết:

# Cài đặt pandas và các thư viện phân tích dữ liệu
pip install pandas numpy matplotlib seaborn yfinance

# Hoặc sử dụng conda
conda install pandas numpy matplotlib seaborn
conda install -c conda-forge yfinance

Để phân tích dữ liệu tài chính, chúng ta cũng sẽ cần một số thư viện bổ sung:

# Import các thư viện cần thiết
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import yfinance as yf
from datetime import datetime, timedelta

# Thiết lập để hiển thị biểu đồ
%matplotlib inline
plt.style.use('seaborn-darkgrid')

Thu thập dữ liệu tài chính

Pandas cho phép bạn thu thập dữ liệu tài chính từ nhiều nguồn khác nhau. Trong ví dụ này, chúng ta sẽ sử dụng Yahoo Finance thông qua thư viện yfinance:

# Xác định khoảng thời gian
end_date = datetime.now()
start_date = end_date - timedelta(days=365*5)  # Dữ liệu 5 năm

# Tải dữ liệu cho nhiều cổ phiếu
tickers = ['AAPL', 'MSFT', 'GOOGL', 'AMZN', 'META']
data = yf.download(tickers, start=start_date, end=end_date)

# Xem dữ liệu
print(data.columns)
data['Adj Close'].head()

Kết quả:

MultiIndex([('Open', 'AAPL'),
            ('Open', 'MSFT'),
            ('Open', 'GOOGL'),
            ('Open', 'AMZN'),
            ('Open', 'META'),
            ('High', 'AAPL'),
            ...

Xử lý và làm sạch dữ liệu

Dữ liệu tài chính thường có các giá trị thiếu hoặc không hợp lệ. Pandas cung cấp nhiều công cụ để xử lý vấn đề này:

# Kiểm tra giá trị null
print(data.isnull().sum())

# Làm sạch dữ liệu - lấp đầy giá trị thiếu
data_adj_close = data['Adj Close'].copy()
data_filled = data_adj_close.fillna(method='ffill')  # Sử dụng giá trị trước đó

# Hoặc xóa các hàng có giá trị null
data_cleaned = data_adj_close.dropna()

Phân tích dữ liệu tài chính cơ bản

1. Tính toán lợi nhuận hàng ngày và hàng tháng

# Tính lợi nhuận hàng ngày
daily_returns = data_filled.pct_change()
daily_returns.head()

# Tính lợi nhuận hàng tháng
monthly_data = data_filled.resample('M').last()
monthly_returns = monthly_data.pct_change()
monthly_returns.head()

2. Phân tích thống kê mô tả

# Thống kê mô tả cho lợi nhuận hàng ngày
stats = daily_returns.describe()
print(stats)

# So sánh hiệu suất giữa các cổ phiếu
print("Lợi nhuận trung bình hàng ngày:")
print(daily_returns.mean())

print("\nĐộ biến động (Rủi ro):")
print(daily_returns.std())

# Tính toán tỷ lệ Sharpe (giả sử lãi suất phi rủi ro là 0%)
sharpe_ratios = daily_returns.mean() / daily_returns.std() * np.sqrt(252)  # 252 ngày giao dịch trong năm
print("\nTỷ lệ Sharpe:")
print(sharpe_ratios)

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

# Tính ma trận tương quan
correlation = daily_returns.corr()

# Vẽ heatmap tương quan
plt.figure(figsize=(10, 8))
sns.heatmap(correlation, annot=True, cmap='coolwarm', linewidths=0.5)
plt.title('Ma trận tương quan giữa các cổ phiếu')
plt.savefig('./images/correlation_matrix.png', dpi=300, bbox_inches='tight')
plt.show()

Trực quan hóa dữ liệu tài chính

1. Biểu đồ giá cổ phiếu

# Chuẩn hóa dữ liệu để so sánh
normalized = data_filled / data_filled.iloc[0] * 100

# Vẽ biểu đồ
plt.figure(figsize=(14, 8))
for column in normalized.columns:
    plt.plot(normalized.index, normalized[column], label=column)

plt.title('So sánh hiệu suất cổ phiếu (Chuẩn hóa 100)')
plt.ylabel('Giá trị chuẩn hóa')
plt.legend()
plt.savefig('./images/stock_performance.png', dpi=300, bbox_inches='tight')
plt.show()

2. Phân tích biến động

# Tính toán biến động 30 ngày (độ lệch chuẩn cuộn)
volatility = daily_returns.rolling(window=30).std() * np.sqrt(30)

# Vẽ biểu đồ biến động
plt.figure(figsize=(14, 8))
for column in volatility.columns:
    plt.plot(volatility.index, volatility[column], label=column)

plt.title('Biến động 30 ngày')
plt.ylabel('Độ lệch chuẩn của lợi nhuận')
plt.legend()
plt.savefig('./images/volatility.png', dpi=300, bbox_inches='tight')
plt.show()

3. Phân tích lợi nhuận tích lũy

# Tính toán lợi nhuận tích lũy
cumulative_returns = (1 + daily_returns).cumprod() - 1

# Vẽ biểu đồ
plt.figure(figsize=(14, 8))
for column in cumulative_returns.columns:
    plt.plot(cumulative_returns.index, cumulative_returns[column] * 100, label=column)

plt.title('Lợi nhuận tích lũy (%)')
plt.ylabel('Lợi nhuận (%)')
plt.legend()
plt.savefig('./images/cumulative_returns.png', dpi=300, bbox_inches='tight')
plt.show()

Phân tích nâng cao

1. Mô hình giá trung bình di động

# Tính toán giá trung bình di động 
stock = data_filled['AAPL']  # Chọn 1 cổ phiếu để phân tích
short_window = 50
long_window = 200

# Tính toán SMA
short_sma = stock.rolling(window=short_window).mean()
long_sma = stock.rolling(window=long_window).mean()

# Tạo DataFrame cho biểu đồ
signals = pd.DataFrame(index=stock.index)
signals['price'] = stock
signals['short_sma'] = short_sma
signals['long_sma'] = long_sma

# Tạo tín hiệu giao dịch
signals['signal'] = 0
signals['signal'][short_window:] = np.where(signals['short_sma'][short_window:] > signals['long_sma'][short_window:], 1, 0)
signals['position'] = signals['signal'].diff()

# Vẽ biểu đồ
plt.figure(figsize=(14, 8))
plt.plot(signals.index, signals['price'], label='AAPL Price')
plt.plot(signals.index, signals['short_sma'], label=f'SMA {short_window}', alpha=0.7)
plt.plot(signals.index, signals['long_sma'], label=f'SMA {long_window}', alpha=0.7)

# Đánh dấu tín hiệu mua/bán
plt.plot(signals[signals['position'] == 1].index, 
         signals['short_sma'][signals['position'] == 1], 
         '^', markersize=10, color='g', label='Mua')
         
plt.plot(signals[signals['position'] == -1].index, 
         signals['short_sma'][signals['position'] == -1], 
         'v', markersize=10, color='r', label='Bán')

plt.title('Chiến lược giao dịch dựa trên SMA')
plt.ylabel('Giá ($)')
plt.legend()
plt.savefig('./images/trading_strategy.png', dpi=300, bbox_inches='tight')
plt.show()

2. Phân tích chỉ số tài chính

# Tải dữ liệu chỉ số tài chính
ticker = 'AAPL'
stock_info = yf.Ticker(ticker)

# Lấy thông tin tài chính
balance_sheet = stock_info.balance_sheet
income_statement = stock_info.income_stmt
cash_flow = stock_info.cashflow

# Tính toán một số chỉ số cơ bản
# P/E Ratio
earnings_per_share = income_statement.loc['Basic EPS']
latest_price = stock_info.history(period='1d')['Close'].iloc[0]
pe_ratio = latest_price / earnings_per_share.iloc[0]

# Debt-to-Equity
total_debt = balance_sheet.loc['Total Debt']
total_equity = balance_sheet.loc['Total Stockholder Equity']
debt_to_equity = total_debt / total_equity

# Return on Equity (ROE)
net_income = income_statement.loc['Net Income']
roe = net_income / total_equity

# Hiển thị kết quả
metrics = pd.DataFrame({
    'P/E Ratio': pe_ratio,
    'Debt-to-Equity': debt_to_equity.iloc[0],
    'ROE (%)': (roe.iloc[0] * 100)
}, index=[ticker])

print(metrics)

Phân tích danh mục đầu tư

# Giả định đầu tư 10,000 USD vào các cổ phiếu với tỷ trọng khác nhau
weights = np.array([0.2, 0.2, 0.2, 0.2, 0.2])  # Đầu tư đều vào các cổ phiếu

# Tính toán lợi nhuận hàng ngày của danh mục
portfolio_daily_return = daily_returns.dot(weights)

# Tính toán lợi nhuận tích lũy danh mục
portfolio_cumulative_return = (1 + portfolio_daily_return).cumprod() - 1

# Tính toán thống kê
portfolio_stats = pd.Series({
    'Annual Return (%)': portfolio_daily_return.mean() * 252 * 100,
    'Annual Risk (%)': portfolio_daily_return.std() * np.sqrt(252) * 100,
    'Sharpe Ratio': portfolio_daily_return.mean() / portfolio_daily_return.std() * np.sqrt(252)
})

print(portfolio_stats)

# Vẽ biểu đồ hiệu suất danh mục
plt.figure(figsize=(14, 8))
plt.plot(portfolio_cumulative_return.index, portfolio_cumulative_return * 100)
plt.title('Lợi nhuận tích lũy của danh mục đầu tư (%)')
plt.ylabel('Lợi nhuận (%)')
plt.savefig('./images/portfolio_performance.png', dpi=300, bbox_inches='tight')
plt.show()

Tối ưu hóa danh mục đầu tư với Pandas

# Tính toán ma trận phương sai-hiệp phương sai
cov_matrix = daily_returns.cov() * 252  # Chuyển đổi lên mức năm

# Định nghĩa hàm tính toán lợi nhuận và rủi ro cho một danh mục
def portfolio_performance(weights, returns, cov):
    # Lợi nhuận kỳ vọng
    portfolio_return = np.sum(returns.mean() * weights) * 252
    # Rủi ro
    portfolio_std_dev = np.sqrt(np.dot(weights.T, np.dot(cov, weights)))
    return portfolio_return, portfolio_std_dev

# Tính lợi nhuận kỳ vọng hàng năm (annualized)
expected_returns = daily_returns.mean() * 252

# Giả lập 5,000 danh mục ngẫu nhiên
num_portfolios = 5000
results = np.zeros((num_portfolios, 3))  # Mảng để lưu trữ kết quả (return, std dev, sharpe)

for i in range(num_portfolios):
    # Tạo trọng số ngẫu nhiên
    random_weights = np.random.random(len(tickers))
    random_weights /= np.sum(random_weights)  # Chuẩn hóa tổng trọng số = 1
    
    # Tính lợi nhuận và rủi ro của danh mục
    portfolio_r, portfolio_std = portfolio_performance(random_weights, expected_returns, cov_matrix)
    
    # Tính tỷ lệ Sharpe (giả sử lãi suất phi rủi ro = 0)
    sharpe_ratio = portfolio_r / portfolio_std
    
    # Lưu kết quả
    results[i, 0] = portfolio_r * 100  # Đổi sang phần trăm
    results[i, 1] = portfolio_std * 100  # Đổi sang phần trăm
    results[i, 2] = sharpe_ratio

# Chuyển đổi kết quả sang DataFrame
df_results = pd.DataFrame(results, columns=['Return (%)', 'Risk (%)', 'Sharpe Ratio'])

# Tìm danh mục tối ưu (Sharpe Ratio cao nhất)
optimal_idx = df_results['Sharpe Ratio'].idxmax()
optimal_port = df_results.iloc[optimal_idx]

print("Danh mục đầu tư tối ưu:")
print(f"Lợi nhuận kỳ vọng: {optimal_port['Return (%)']:.2f}%")
print(f"Rủi ro: {optimal_port['Risk (%)']:.2f}%")
print(f"Tỷ lệ Sharpe: {optimal_port['Sharpe Ratio']:.2f}")

# Vẽ biểu đồ đường biên hiệu quả
plt.figure(figsize=(14, 8))
plt.scatter(df_results['Risk (%)'], df_results['Return (%)'], 
           c=df_results['Sharpe Ratio'], cmap='viridis', 
           marker='o', s=10, alpha=0.5)

plt.scatter(optimal_port['Risk (%)'], optimal_port['Return (%)'], 
           color='r', marker='*', s=300, label='Danh mục tối ưu')

plt.colorbar(label='Tỷ lệ Sharpe')
plt.xlabel('Rủi ro (%)')
plt.ylabel('Lợi nhuận kỳ vọng (%)')
plt.title('Đường biên hiệu quả của các danh mục đầu tư')
plt.legend()
plt.savefig('./images/efficient_frontier.png', dpi=300, bbox_inches='tight')
plt.show()

Kết luận

Pandas là một công cụ mạnh mẽ cho phân tích dữ liệu tài chính, cung cấp các tính năng cần thiết để xử lý, phân tích và trực quan hóa dữ liệu một cách hiệu quả. Bài viết này đã giới thiệu các kỹ thuật cơ bản và nâng cao sử dụng Pandas để phân tích dữ liệu tài chính, bao gồm:

  • Thu thập và xử lý dữ liệu tài chính
  • Phân tích thống kê cơ bản
  • Trực quan hóa dữ liệu
  • Phân tích danh mục đầu tư
  • Tối ưu hóa danh mục đầu tư

Để tiếp tục học hỏi, bạn có thể tham khảo thêm tài liệu chính thức của Pandas tại https://pandas.pydata.org/docs/ và các khóa học chuyên sâu về phân tích dữ liệu tài chính.


Tài liệu tham khảo:

  1. McKinney, W. (2022). Python for Data Analysis. O'Reilly Media.
  2. Pandas Documentation: https://pandas.pydata.org/docs/
  3. Yahoo Finance API: https://pypi.org/project/yfinance/
  4. Seaborn Documentation: https://seaborn.pydata.org/

← Xem tất cả bài viết · Trang chủ