Lập trình mô hình phân tích kỹ thuật cơ bản bằng Python
Phân tích kỹ thuật là một phương pháp quan trọng trong giao dịch tài chính, giúp các nhà đầu tư đưa ra quyết định dựa trên các mẫu hình và chỉ báo kỹ thuật. Bài viết này sẽ hướng dẫn bạn cách xây dựng các mô hình phân tích kỹ thuật cơ bản bằng Python.
Tổng quan về NumPy và phân tích kỹ thuật
NumPy là thư viện nền tảng cho tính toán số học trong Python, đặc biệt mạnh mẽ khi xử lý dữ liệu tài chính dạng mảng (array). Các chỉ báo kỹ thuật như MA, RSI, MACD đều dựa trên các phép toán với mảng số liệu giá.
Mảng NumPy và phép toán cơ bản
Ví dụ, cộng một số vào toàn bộ mảng giá:
1. Cài đặt thư viện cần thiết
Đầu tiên, chúng ta cần cài đặt các thư viện cần thiết:
pip install pandas numpy matplotlib yfinance ta-lib
2. Lấy dữ liệu giá
Sử dụng thư viện yfinance để lấy dữ liệu giá cổ phiếu:
import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Lấy dữ liệu giá cổ phiếu
symbol = "AAPL" # Apple Inc.
start_date = "2023-01-01"
end_date = "2024-01-01"
df = yf.download(symbol, start=start_date, end=end_date)
3. Tính toán các chỉ báo kỹ thuật cơ bản
3.1. Moving Average (MA)
MA (Trung bình động) là chỉ báo làm mượt giá, giúp nhận diện xu hướng. Có nhiều loại MA, phổ biến nhất là SMA (Simple Moving Average).
def calculate_ma(data, window):
return data.rolling(window=window).mean()
# Tính toán MA 20 và MA 50
df['MA20'] = calculate_ma(df['Close'], 20)
df['MA50'] = calculate_ma(df['Close'], 50)
3.2. Relative Strength Index (RSI)
RSI đo sức mạnh tương đối của giá, dao động từ 0-100. RSI > 70: Quá mua, RSI < 30: Quá bán.
def calculate_rsi(data, window=14):
delta = data.diff()
gain = (delta.where(delta > 0, 0)).rolling(window=window).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=window).mean()
rs = gain / loss
return 100 - (100 / (1 + rs))
# Tính toán RSI
df['RSI'] = calculate_rsi(df['Close'])
3.3. MACD (Moving Average Convergence Divergence)
def calculate_macd(data, fast=12, slow=26, signal=9):
exp1 = data.ewm(span=fast, adjust=False).mean()
exp2 = data.ewm(span=slow, adjust=False).mean()
macd = exp1 - exp2
signal_line = macd.ewm(span=signal, adjust=False).mean()
return macd, signal_line
# Tính toán MACD
df['MACD'], df['Signal'] = calculate_macd(df['Close'])
4. Xây dựng chiến lược giao dịch đơn giản
4.1. Chiến lược giao cắt MA
def ma_crossover_strategy(df):
df['Signal'] = 0
df.loc[df['MA20'] > df['MA50'], 'Signal'] = 1 # Tín hiệu mua
df.loc[df['MA20'] < df['MA50'], 'Signal'] = -1 # Tín hiệu bán
return df
# Áp dụng chiến lược
df = ma_crossover_strategy(df)
4.2. Chiến lược RSI
def rsi_strategy(df, overbought=70, oversold=30):
df['RSI_Signal'] = 0
df.loc[df['RSI'] < oversold, 'RSI_Signal'] = 1 # Tín hiệu mua
df.loc[df['RSI'] > overbought, 'RSI_Signal'] = -1 # Tín hiệu bán
return df
# Áp dụng chiến lược
df = rsi_strategy(df)
5. Trực quan hóa kết quả
def plot_technical_analysis(df):
# Tạo subplot
fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(15, 12), gridspec_kw={'height_ratios': [3, 1, 1]})
# Plot giá và MA
ax1.plot(df.index, df['Close'], label='Giá đóng cửa')
ax1.plot(df.index, df['MA20'], label='MA20')
ax1.plot(df.index, df['MA50'], label='MA50')
ax1.set_title('Giá và Moving Average')
ax1.legend()
# Plot RSI
ax2.plot(df.index, df['RSI'], label='RSI')
ax2.axhline(y=70, color='r', linestyle='--')
ax2.axhline(y=30, color='g', linestyle='--')
ax2.set_title('RSI')
ax2.legend()
# Plot MACD
ax3.plot(df.index, df['MACD'], label='MACD')
ax3.plot(df.index, df['Signal'], label='Signal')
ax3.set_title('MACD')
ax3.legend()
plt.tight_layout()
plt.show()
6. Đánh giá hiệu suất
def calculate_returns(df):
# Tính toán lợi nhuận
df['Returns'] = df['Close'].pct_change()
# Tính toán lợi nhuận của chiến lược
df['Strategy_Returns'] = df['Returns'] * df['Signal'].shift(1)
# Tính toán lợi nhuận tích lũy
df['Cumulative_Returns'] = (1 + df['Returns']).cumprod()
df['Strategy_Cumulative_Returns'] = (1 + df['Strategy_Returns']).cumprod()
return df
# Tính toán và hiển thị kết quả
df = calculate_returns(df)
print(f"Lợi nhuận của chiến lược: {df['Strategy_Cumulative_Returns'].iloc[-1]:.2%}")
7. Tối ưu hóa tham số
def optimize_parameters(df):
best_sharpe = 0
best_params = None
# Thử nghiệm các tham số khác nhau
for ma_short in range(5, 30, 5):
for ma_long in range(30, 100, 10):
if ma_short >= ma_long:
continue
# Tính toán MA
df['MA_Short'] = calculate_ma(df['Close'], ma_short)
df['MA_Long'] = calculate_ma(df['Close'], ma_long)
# Tạo tín hiệu
df['Signal'] = 0
df.loc[df['MA_Short'] > df['MA_Long'], 'Signal'] = 1
df.loc[df['MA_Short'] < df['MA_Long'], 'Signal'] = -1
# Tính toán lợi nhuận
df['Strategy_Returns'] = df['Returns'] * df['Signal'].shift(1)
# Tính toán Sharpe Ratio
sharpe = np.sqrt(252) * df['Strategy_Returns'].mean() / df['Strategy_Returns'].std()
if sharpe > best_sharpe:
best_sharpe = sharpe
best_params = (ma_short, ma_long)
return best_params, best_sharpe
# Tối ưu hóa tham số
best_params, best_sharpe = optimize_parameters(df)
print(f"Tham số tối ưu: MA{best_params[0]}, MA{best_params[1]}")
print(f"Sharpe Ratio tối ưu: {best_sharpe:.2f}")
Kết luận
Trong bài viết này, chúng ta đã học cách:
- Lấy dữ liệu giá cổ phiếu sử dụng yfinance
- Tính toán các chỉ báo kỹ thuật cơ bản (MA, RSI, MACD)
- Xây dựng chiến lược giao dịch đơn giản
- Trực quan hóa kết quả phân tích
- Đánh giá hiệu suất chiến lược
- Tối ưu hóa tham số
Đây là nền tảng cơ bản để bạn có thể phát triển thêm các chiến lược giao dịch phức tạp hơn. Hãy nhớ rằng phân tích kỹ thuật chỉ là một công cụ hỗ trợ quyết định, và bạn nên kết hợp với các phương pháp phân tích khác để có cái nhìn toàn diện hơn.