Bài viết gần đây
-
-
So sánh Flutter và React Native
Tháng mười một 17, 2025 -
So sánh Flutter và React Native
Tháng mười một 17, 2025 -
Chiến lược RSI 30–70 trong Bot Auto Trading Python
Tháng mười một 17, 2025 -
Chiến Lược Giao Dịch News Filter sử dụng API Python
Tháng mười một 17, 2025
| Phân tích kỹ thuật auto trading với Python: Hướng dẫn toàn diện cho người mới bắt đầu
Được viết bởi thanhdt vào ngày 16/11/2025 lúc 10:42 | 9 lượt xem
Phân tích kỹ thuật với Python
Phân tích kỹ thuật là phương pháp phân tích thị trường tài chính bằng cách sử dụng các mô hình giá cả lịch sử, khối lượng giao dịch và các chỉ báo kỹ thuật khác để dự đoán biến động giá trong tương lai. Python, với các thư viện phân tích dữ liệu mạnh mẽ như Pandas, NumPy, và Matplotlib, là công cụ lý tưởng để thực hiện phân tích kỹ thuật một cách chuyên nghiệp.
Phân tích kỹ thuật là gì?
Phân tích kỹ thuật là một phương pháp dự đoán hướng giá của tài sản tài chính dựa trên việc nghiên cứu các dữ liệu giao dịch trong quá khứ, đặc biệt là giá và khối lượng. Khác với phân tích cơ bản (fundamental analysis) tập trung vào các yếu tố kinh tế và tài chính của công ty, phân tích kỹ thuật dựa trên giả định rằng:
- Giá phản ánh tất cả thông tin
- Giá di chuyển theo xu hướng
- Lịch sử có xu hướng lặp lại
Tại sao sử dụng Python cho phân tích kỹ thuật?
Python là ngôn ngữ lập trình lý tưởng cho phân tích kỹ thuật vì:
- Thư viện phong phú: Pandas, NumPy, Matplotlib, yfinance, TA-Lib
- Xử lý dữ liệu mạnh mẽ: Dễ dàng đọc và xử lý dữ liệu giá từ nhiều nguồn
- Trực quan hóa tốt: Tạo biểu đồ nến, biểu đồ đường, và các chỉ báo kỹ thuật
- Tự động hóa: Xây dựng hệ thống phân tích và giao dịch tự động
- Cộng đồng lớn: Nhiều tài liệu và ví dụ có sẵn
Cài đặt các thư viện cần thiết
Trước khi bắt đầu, bạn cần cài đặt các thư viện Python sau:
# Cài đặt các thư viện cơ bản
pip install pandas numpy matplotlib
# Thư viện lấy dữ liệu tài chính
pip install yfinance
# Thư viện tính toán chỉ báo kỹ thuật
pip install ta-lib
# Thư viện vẽ biểu đồ nến
pip install mplfinance
Lấy dữ liệu giá từ thị trường
Sử dụng yfinance
yfinance là thư viện phổ biến để lấy dữ liệu giá từ Yahoo Finance:
import yfinance as yf
import pandas as pd
# Lấy dữ liệu giá cổ phiếu Apple (AAPL)
ticker = yf.Ticker("AAPL")
data = ticker.history(period="1y") # Lấy dữ liệu 1 năm
# Hiển thị 5 dòng đầu tiên
print(data.head())
# Lấy dữ liệu Bitcoin
btc = yf.download("BTC-USD", period="6mo", interval="1d")
print(btc.head())
Lấy dữ liệu từ Binance API
Nếu bạn muốn lấy dữ liệu từ Binance, có thể sử dụng API:
import requests
import pandas as pd
def get_binance_data(symbol, interval='1d', limit=500):
"""
Lấy dữ liệu giá từ Binance API
Parameters:
symbol: Cặp giao dịch (ví dụ: 'BTCUSDT')
interval: Khung thời gian ('1m', '5m', '1h', '1d', ...)
limit: Số lượng nến cần lấy
"""
url = f"https://api.binance.com/api/v3/klines"
params = {
'symbol': symbol,
'interval': interval,
'limit': limit
}
response = requests.get(url, params=params)
data = response.json()
# Chuyển đổi sang DataFrame
df = pd.DataFrame(data, columns=[
'timestamp', 'open', 'high', 'low', 'close', 'volume',
'close_time', 'quote_volume', 'trades', 'taker_buy_base',
'taker_buy_quote', 'ignore'
])
# Chuyển đổi kiểu dữ liệu
df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
for col in ['open', 'high', 'low', 'close', 'volume']:
df[col] = df[col].astype(float)
df.set_index('timestamp', inplace=True)
return df[['open', 'high', 'low', 'close', 'volume']]
# Lấy dữ liệu BTC/USDT
btc_data = get_binance_data('BTCUSDT', interval='1d', limit=365)
print(btc_data.head())
Vẽ biểu đồ giá
Biểu đồ đường đơn giản
import matplotlib.pyplot as plt
import pandas as pd
# Lấy dữ liệu
ticker = yf.Ticker("AAPL")
data = ticker.history(period="6mo")
# Vẽ biểu đồ giá đóng cửa
plt.figure(figsize=(12, 6))
plt.plot(data.index, data['Close'], linewidth=2)
plt.title('Giá cổ phiếu Apple (AAPL)', fontsize=16, fontweight='bold')
plt.xlabel('Ngày')
plt.ylabel('Giá (USD)')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
Biểu đồ nến (Candlestick Chart)
import mplfinance as mpf
# Vẽ biểu đồ nến
mpf.plot(data,
type='candle',
style='yahoo',
volume=True,
title='Biểu đồ nến AAPL',
figsize=(14, 8))
Các chỉ báo kỹ thuật phổ biến
Moving Average (Đường trung bình động)
Moving Average là một trong những chỉ báo kỹ thuật cơ bản nhất:
def calculate_ma(data, period=20):
"""
Tính đường trung bình động đơn giản (SMA)
"""
return data['Close'].rolling(window=period).mean()
# Tính SMA 20 và SMA 50
data['SMA_20'] = calculate_ma(data, 20)
data['SMA_50'] = calculate_ma(data, 50)
# Vẽ biểu đồ với SMA
plt.figure(figsize=(14, 8))
plt.plot(data.index, data['Close'], label='Giá đóng cửa', linewidth=2)
plt.plot(data.index, data['SMA_20'], label='SMA 20', linewidth=1.5)
plt.plot(data.index, data['SMA_50'], label='SMA 50', linewidth=1.5)
plt.title('Giá cổ phiếu với Moving Average', fontsize=16, fontweight='bold')
plt.xlabel('Ngày')
plt.ylabel('Giá (USD)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
Exponential Moving Average (EMA)
EMA cho trọng số cao hơn cho các giá trị gần đây:
def calculate_ema(data, period=20):
"""
Tính đường trung bình động hàm mũ (EMA)
"""
return data['Close'].ewm(span=period, adjust=False).mean()
# Tính EMA 12 và EMA 26
data['EMA_12'] = calculate_ema(data, 12)
data['EMA_26'] = calculate_ema(data, 26)
RSI (Relative Strength Index)
RSI đo lường sức mạnh của xu hướng giá:
def calculate_rsi(data, period=14):
"""
Tính chỉ báo RSI (Relative Strength Index)
"""
delta = data['Close'].diff()
gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
rs = gain / loss
rsi = 100 - (100 / (1 + rs))
return rsi
# Tính RSI
data['RSI'] = calculate_rsi(data, 14)
# Vẽ biểu đồ RSI
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10), sharex=True)
# Biểu đồ giá
ax1.plot(data.index, data['Close'], label='Giá đóng cửa', linewidth=2)
ax1.set_title('Giá cổ phiếu', fontsize=14, fontweight='bold')
ax1.set_ylabel('Giá (USD)')
ax1.legend()
ax1.grid(True, alpha=0.3)
# Biểu đồ RSI
ax2.plot(data.index, data['RSI'], label='RSI', linewidth=2, color='purple')
ax2.axhline(y=70, color='r', linestyle='--', label='Overbought (70)')
ax2.axhline(y=30, color='g', linestyle='--', label='Oversold (30)')
ax2.set_title('RSI Indicator', fontsize=14, fontweight='bold')
ax2.set_xlabel('Ngày')
ax2.set_ylabel('RSI')
ax2.set_ylim(0, 100)
ax2.legend()
ax2.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
MACD (Moving Average Convergence Divergence)
MACD là chỉ báo xu hướng mạnh mẽ:
def calculate_macd(data, fast=12, slow=26, signal=9):
"""
Tính chỉ báo MACD
"""
ema_fast = calculate_ema(data, fast)
ema_slow = calculate_ema(data, slow)
macd_line = ema_fast - ema_slow
signal_line = macd_line.ewm(span=signal, adjust=False).mean()
histogram = macd_line - signal_line
return macd_line, signal_line, histogram
# Tính MACD
data['MACD'], data['MACD_Signal'], data['MACD_Hist'] = calculate_macd(data)
# Vẽ biểu đồ MACD
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10), sharex=True)
# Biểu đồ giá
ax1.plot(data.index, data['Close'], label='Giá đóng cửa', linewidth=2)
ax1.set_title('Giá cổ phiếu', fontsize=14, fontweight='bold')
ax1.set_ylabel('Giá (USD)')
ax1.legend()
ax1.grid(True, alpha=0.3)
# Biểu đồ MACD
ax2.plot(data.index, data['MACD'], label='MACD', linewidth=2)
ax2.plot(data.index, data['MACD_Signal'], label='Signal', linewidth=2)
ax2.bar(data.index, data['MACD_Hist'], label='Histogram', alpha=0.3)
ax2.set_title('MACD Indicator', fontsize=14, fontweight='bold')
ax2.set_xlabel('Ngày')
ax2.set_ylabel('MACD')
ax2.legend()
ax2.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
Bollinger Bands
Bollinger Bands giúp xác định biến động giá:
def calculate_bollinger_bands(data, period=20, std_dev=2):
"""
Tính Bollinger Bands
"""
sma = calculate_ma(data, period)
std = data['Close'].rolling(window=period).std()
upper_band = sma + (std * std_dev)
lower_band = sma - (std * std_dev)
return upper_band, lower_band, sma
# Tính Bollinger Bands
data['BB_Upper'], data['BB_Lower'], data['BB_Middle'] = calculate_bollinger_bands(data)
# Vẽ biểu đồ Bollinger Bands
plt.figure(figsize=(14, 8))
plt.plot(data.index, data['Close'], label='Giá đóng cửa', linewidth=2)
plt.plot(data.index, data['BB_Upper'], label='Upper Band', linestyle='--', alpha=0.7)
plt.plot(data.index, data['BB_Lower'], label='Lower Band', linestyle='--', alpha=0.7)
plt.plot(data.index, data['BB_Middle'], label='Middle Band (SMA)', linestyle='--', alpha=0.7)
plt.fill_between(data.index, data['BB_Upper'], data['BB_Lower'], alpha=0.1)
plt.title('Bollinger Bands', fontsize=16, fontweight='bold')
plt.xlabel('Ngày')
plt.ylabel('Giá (USD)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
Xây dựng chiến lược giao dịch đơn giản
Chiến lược Moving Average Crossover
Chiến lược này mua khi SMA ngắn hạn cắt lên trên SMA dài hạn và bán khi ngược lại:
def ma_crossover_strategy(data, short_period=20, long_period=50):
"""
Chiến lược giao dịch dựa trên Moving Average Crossover
"""
# Tính SMA
data['SMA_Short'] = calculate_ma(data, short_period)
data['SMA_Long'] = calculate_ma(data, long_period)
# Tạo tín hiệu
data['Signal'] = 0
data['Signal'][short_period:] = np.where(
data['SMA_Short'][short_period:] > data['SMA_Long'][short_period:], 1, 0
)
# Tạo lệnh mua/bán
data['Position'] = data['Signal'].diff()
return data
# Áp dụng chiến lược
data = ma_crossover_strategy(data)
# Vẽ biểu đồ với tín hiệu
plt.figure(figsize=(14, 8))
plt.plot(data.index, data['Close'], label='Giá đóng cửa', linewidth=2)
plt.plot(data.index, data['SMA_20'], label='SMA 20', linewidth=1.5)
plt.plot(data.index, data['SMA_50'], label='SMA 50', linewidth=1.5)
# Đánh dấu điểm mua
buy_signals = data[data['Position'] == 1]
plt.scatter(buy_signals.index, buy_signals['Close'],
marker='^', color='green', s=100, label='Tín hiệu MUA', zorder=5)
# Đánh dấu điểm bán
sell_signals = data[data['Position'] == -1]
plt.scatter(sell_signals.index, sell_signals['Close'],
marker='v', color='red', s=100, label='Tín hiệu BÁN', zorder=5)
plt.title('Chiến lược Moving Average Crossover', fontsize=16, fontweight='bold')
plt.xlabel('Ngày')
plt.ylabel('Giá (USD)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
Backtesting chiến lược
Backtesting giúp đánh giá hiệu quả của chiến lược trên dữ liệu lịch sử:
def backtest_strategy(data, initial_capital=10000):
"""
Backtest chiến lược giao dịch
"""
capital = initial_capital
position = 0 # Số lượng cổ phiếu đang nắm giữ
trades = []
for i in range(len(data)):
if data['Position'].iloc[i] == 1: # Tín hiệu mua
if position == 0: # Chưa có vị thế
position = capital / data['Close'].iloc[i]
capital = 0
trades.append({
'date': data.index[i],
'action': 'BUY',
'price': data['Close'].iloc[i],
'shares': position
})
elif data['Position'].iloc[i] == -1: # Tín hiệu bán
if position > 0: # Đang có vị thế
capital = position * data['Close'].iloc[i]
trades.append({
'date': data.index[i],
'action': 'SELL',
'price': data['Close'].iloc[i],
'shares': position
})
position = 0
# Tính toán lợi nhuận cuối cùng
if position > 0:
final_capital = position * data['Close'].iloc[-1]
else:
final_capital = capital
total_return = ((final_capital - initial_capital) / initial_capital) * 100
return {
'initial_capital': initial_capital,
'final_capital': final_capital,
'total_return': total_return,
'trades': trades
}
# Chạy backtest
results = backtest_strategy(data)
print(f"Vốn ban đầu: ${results['initial_capital']:,.2f}")
print(f"Vốn cuối cùng: ${results['final_capital']:,.2f}")
print(f"Lợi nhuận: {results['total_return']:.2f}%")
print(f"Số lần giao dịch: {len(results['trades'])}")
Ví dụ hoàn chỉnh: Phân tích cổ phiếu với nhiều chỉ báo
Dưới đây là một ví dụ hoàn chỉnh kết hợp nhiều chỉ báo kỹ thuật:
import yfinance as yf
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
# Lấy dữ liệu
ticker = yf.Ticker("AAPL")
data = ticker.history(period="1y")
# Tính các chỉ báo
data['SMA_20'] = calculate_ma(data, 20)
data['SMA_50'] = calculate_ma(data, 50)
data['RSI'] = calculate_rsi(data, 14)
data['MACD'], data['MACD_Signal'], data['MACD_Hist'] = calculate_macd(data)
data['BB_Upper'], data['BB_Lower'], data['BB_Middle'] = calculate_bollinger_bands(data)
# Vẽ biểu đồ tổng hợp
fig = plt.figure(figsize=(16, 12))
# Biểu đồ giá với Moving Average và Bollinger Bands
ax1 = plt.subplot(3, 1, 1)
ax1.plot(data.index, data['Close'], label='Giá đóng cửa', linewidth=2)
ax1.plot(data.index, data['SMA_20'], label='SMA 20', linewidth=1.5)
ax1.plot(data.index, data['SMA_50'], label='SMA 50', linewidth=1.5)
ax1.fill_between(data.index, data['BB_Upper'], data['BB_Lower'], alpha=0.1)
ax1.set_title('Phân tích kỹ thuật AAPL', fontsize=16, fontweight='bold')
ax1.set_ylabel('Giá (USD)')
ax1.legend()
ax1.grid(True, alpha=0.3)
# Biểu đồ RSI
ax2 = plt.subplot(3, 1, 2)
ax2.plot(data.index, data['RSI'], label='RSI', linewidth=2, color='purple')
ax2.axhline(y=70, color='r', linestyle='--', label='Overbought (70)')
ax2.axhline(y=30, color='g', linestyle='--', label='Oversold (30)')
ax2.set_ylabel('RSI')
ax2.set_ylim(0, 100)
ax2.legend()
ax2.grid(True, alpha=0.3)
# Biểu đồ MACD
ax3 = plt.subplot(3, 1, 3)
ax3.plot(data.index, data['MACD'], label='MACD', linewidth=2)
ax3.plot(data.index, data['MACD_Signal'], label='Signal', linewidth=2)
ax3.bar(data.index, data['MACD_Hist'], label='Histogram', alpha=0.3)
ax3.set_xlabel('Ngày')
ax3.set_ylabel('MACD')
ax3.legend()
ax3.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
Kết luận
Phân tích kỹ thuật với Python là một công cụ mạnh mẽ để phân tích thị trường tài chính. Với các thư viện như Pandas, NumPy, Matplotlib, và yfinance, bạn có thể:
- Lấy và xử lý dữ liệu giá từ nhiều nguồn
- Tính toán các chỉ báo kỹ thuật phổ biến
- Vẽ biểu đồ trực quan và chuyên nghiệp
- Xây dựng và backtest các chiến lược giao dịch
- Tự động hóa quy trình phân tích
Để tìm hiểu thêm về các thư viện Python trong giao dịch, bạn có thể xem bài viết Giới thiệu về Pandas hoặc Làm Bot Giao Dịch Backtest với Pandas. Nếu bạn muốn xây dựng chiến lược giao dịch định lượng hoàn chỉnh, hãy tham khảo bài viết Làm thế nào để sử dụng Python xây dựng chiến lược giao dịch định lượng.