Chuyên gia lập trình
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ả.
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à 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:
Để 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')
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'),
...
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()
# 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()
# 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)
# 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()
# 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()
# 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()
# 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()
# 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()
# 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)
# 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í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()
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:
Để 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: