Bài viết này dành cho người mới bắt đầu hoàn toàn. Tôi sẽ hướng dẫn bạn từng bước cách xây dựng một chiến lược giao dịch định lượng với AI, tránh các thuật ngữ phức tạp, đi thẳng vào thực hành. Sau khi đọc xong, bạn sẽ có thể tự tạo được một mô hình dự đoán giá cổ phiếu cơ bản.

Mục lục

1. Giới thiệu: Tại sao nên dùng AI trong giao dịch định lượng?

Trước đây, tôi cũng là một nhà giao dịch thủ công, ngồi hàng giờ nghiên cứu biểu đồ nến, tìm kiếm các mô hình giá. Kết quả? Thua lỗ đều đặn nhưng không hiểu tại sao. Cho đến khi tôi phát hiện ra rằng: thị trường tài chính là một hệ thống phức tạp với quá nhiều biến số để não bộ con người xử lý.

Chiến lược giao dịch định lượng (quantitative trading) giúp bạn:

Khi kết hợp với AI (đặc biệt là các mô hình ngôn ngữ lớn như DeepSeek, GPT-4), bạn có thể:

2. Cài đặt môi trường và công cụ

Đây là bước đầu tiên và quan trọng nhất. Nếu bạn cài sai, code sẽ không chạy. Tôi đã từng mất 3 ngày debug vì quên cài một thư viện.

Yêu cầu hệ thống

Cài đặt Python và pip

# Trên Windows, tải Python từ https://python.org

Chọn "Add Python to PATH" khi cài đặt

Kiểm tra phiên bản Python sau khi cài

python --version

Kết quả mong đợi: Python 3.10.12 hoặc cao hơn

Kiểm tra pip

pip --version

Kết quả mong đợi: pip 23.x.x

Tạo môi trường ảo (Virtual Environment)

# Tạo thư mục dự án
mkdir quant-ai-strategy
cd quant-ai-strategy

Tạo môi trường ảo

python -m venv venv

Kích hoạt môi trường ảo

Trên Windows:

venv\Scripts\activate

Trên macOS/Linux:

source venv/bin/activate

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

pip install pandas numpy scikit-learn yfinance ta-lib-ffi ta-lib pip install openai python-dotenv tqdm matplotlib seaborn pip install jupyter notebook

Mở Jupyter Notebook để bắt đầu

jupyter notebook

💡 Mẹo: Nếu cài ta-lib bị lỗi trên Windows, hãy tải file .whl từ https://www.lfd.uci.edu/~gohlke/pythonlibs/#ta-lib và cài bằng pip install ten_file.whl

3. Thu thập dữ liệu thị trường

Dữ liệu là nhiên liệu cho mô hình AI của bạn. Không có dữ liệu chất lượng, mô hình của bạn sẽ "rác vào, rác ra" (GIGO - Garbage In, Garbage Out).

Các nguồn dữ liệu miễn phí phổ biến

Tải dữ liệu cổ phiếu với yFinance

import yfinance as yf
import pandas as pd
from datetime import datetime, timedelta

def tai_du_lieu_co_phieu(ma_cp, ngay_bat_dau, ngay_ket_thuc):
    """
    Tải dữ liệu giá cổ phiếu từ Yahoo Finance
    
    Args:
        ma_cp: Mã cổ phiếu (VD: 'AAPL', 'MSFT', 'VND')
        ngay_bat_dau: Ngày bắt đầu (YYYY-MM-DD)
        ngay_ket_thuc: Ngày kết thúc (YYYY-MM-DD)
    
    Returns:
        DataFrame chứa dữ liệu OHLCV
    """
    # Tải dữ liệu
    df = yf.download(ma_cp, start=ngay_bat_dau, end=ngay_ket_thuc)
    
    print(f"Đã tải {len(df)} ngày dữ liệu cho {ma_cp}")
    print(f"Khoảng thời gian: {df.index.min()} đến {df.index.max()}")
    
    return df

Ví dụ: Tải dữ liệu VND (Vietcombank) 2 năm gần nhất

ngay_ket_thuc = datetime.now() ngay_bat_dau = ngay_ket_thuc - timedelta(days=730) # 2 năm df_vnd = tai_du_lieu_co_phieu('VND', ngay_bat_dau.strftime('%Y-%m-%d'), ngay_ket_thuc.strftime('%Y-%m-%d'))

Xem 5 dòng đầu tiên

print(df_vnd.head())

Kết quả mẫu

Đã tải 504 ngày dữ liệu cho VND
Khoảng thời gian: 2022-01-03 00:00:00 đến 2023-12-29

                   Open    High     Low   Close    Volume
Date                                                       
2022-01-03  95.000000  96.200  94.100  95.500  12345678
2022-01-04  95.500000  96.000  94.800  95.200  9876543
2022-01-05  96.200000  97.500  96.000  97.100  11234567
2022-01-06  95.800000  96.500  95.000  95.500  8765432
2022-01-07  96.100000  96.800  95.500  96.000  10234567

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

Đây là bước mà 80% người mới bỏ qua, dẫn đến mô hình kém chính xác. Theo kinh nghiệm của tôi, việc xử lý dữ liệu chiếm 60-70% thời gian của cả dự án.

Các vấn đề thường gặp

import numpy as np
import pandas as pd
from ta import add_all_ta_features
from ta.utils import dropna

class XuLyDuLieu:
    """Lớp xử lý dữ liệu giao dịch định lượng"""
    
    def __init__(self, df):
        self.df = df.copy()
    
    def lam_sach_du_lieu(self):
        """Làm sạch dữ liệu cơ bản"""
        # Xử lý MultiIndex columns (nếu có)
        if isinstance(self.df.columns, pd.MultiIndex):
            self.df.columns = self.df.columns.get_level_values(0)
        
        # Xử lý missing values
        missing_before = self.df.isnull().sum().sum()
        self.df = self.df.ffill()  # Forward fill
        self.df = self.df.bfill()  # Backward fill
        missing_after = self.df.isnull().sum().sum()
        
        print(f"Đã xử lý {missing_before - missing_after} giá trị thiếu")
        
        # Loại bỏ outliers bằng IQR method
        for col in ['Close', 'Volume']:
            if col in self.df.columns:
                Q1 = self.df[col].quantile(0.25)
                Q3 = self.df[col].quantile(0.75)
                IQR = Q3 - Q1
                lower = Q1 - 1.5 * IQR
                upper = Q3 + 1.5 * IQR
                
                outliers = ((self.df[col] < lower) | (self.df[col] > upper)).sum()
                print(f"Cột {col}: {outliers} outliers được phát hiện")
        
        return self
    
    def them_chi_so_ky_thuat(self):
        """Thêm các chỉ báo kỹ thuật phổ biến"""
        # Thêm tất cả các chỉ báo kỹ thuật
        self.df = add_all_ta_features(
            self.df, 
            open="Open", 
            high="High", 
            low="Low", 
            close="Close", 
            volume="Volume",
            fillna=True
        )
        
        print(f"Đã thêm {len(self.df.columns)} cột đặc trưng")
        return self
    
    def tao_target(self, cot_gia='Close', so_ngay=5):
        """
        Tạo biến mục tiêu: Giá tương lai tăng hay giảm?
        
        Args:
            cot_gia: Cột giá sử dụng
            so_ngay: Số ngày dự đoán trước
        
        Returns:
            DataFrame với cột 'target' (1 = giá tăng, 0 = giá giảm)
        """
        self.df['future_close'] = self.df[cot_gia].shift(-so_ngay)
        self.df['target'] = (self.df['future_close'] > self.df[cot_gia]).astype(int)
        self.df = self.df.dropna()
        
        print(f"Đã tạo target với {self.df['target'].sum()} ngày giá tăng, "
              f"{len(self.df) - self.df['target'].sum()} ngày giá giảm")
        
        return self

Áp dụng xử lý

xu_ly = XuLyDuLieu(df_vnd) du_lieu_sach = (xu_ly .lam_sach_du_lieu() .them_chi_so_ky_thuat() .tao_target(cot_gia='Close', so_ngay=5)) df_final = du_lieu_sach.df print(f"\nKích thước dữ liệu cuối cùng: {df_final.shape}")

5. Lựa chọn đặc trưng (Feature Selection)

Đây là phần quan trọng nhất trong toàn bộ quy trình. Feature Selection quyết định 70% chất lượng mô hình của bạn. Tôi đã từng huấn luyện mô hình với 200 features và được kết quả tệ hơn khi chỉ dùng 10 features tốt nhất.

Tại sao Feature Selection quan trọng?

Phương pháp 1: Correlation Analysis (Phân tích tương quan)

import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.feature_selection import mutual_info_classif

class ChonDacTrung:
    """Lớp lựa chọn đặc trưng cho mô hình"""
    
    def __init__(self, df, cot_target='target'):
        self.df = df
        self.cot_target = cot_target
        self.features = [c for c in df.columns 
                        if c not in ['target', 'future_close', 'Open', 'High', 'Low', 'Close', 'Volume']]
    
    def phan_tich_tuong_quan(self, nghich_ngao=0.02):
        """
        Phân tích tương quan giữa các đặc trưng và target
        
        Args:
            nghich_ngao: Ngưỡng tương quan tối thiểu (tuyệt đối)
        """
        # Tính correlation với target
        correlations = self.df[self.features + [self.cot_target]].corr()[self.cot_target]
        correlations = correlations.drop(self.cot_target).sort_values(key=abs, ascending=False)
        
        # Lọc features có correlation đủ lớn
        good_features = correlations[abs(correlations) > nghich_ngao]
        
        print("Top 15 đặc trưng có tương quan cao nhất với target:")
        print(good_features.head(15))
        
        # Vẽ biểu đồ
        plt.figure(figsize=(12, 8))
        good_features.plot(kind='barh', color=['green' if x > 0 else 'red' 
                                               for x in good_features])
        plt.xlabel('Correlation với Target')
        plt.title('Feature Correlation Analysis')
        plt.tight_layout()
        plt.savefig('feature_correlation.png', dpi=150)
        plt.show()
        
        return good_features.index.tolist()
    
    def mutual_information(self, top_n=20):
        """
        Tính Mutual Information Score
        
        Mutual Information đo lường mức độ phụ thuộc lẫn nhau
        giữa features và target (tốt hơn correlation cho dữ liệu phi tuyến)
        """
        X = self.df[self.features]
        y = self.df[self.cot_target]
        
        # Tính MI scores
        mi_scores = mutual_info_classif(X, y, random_state=42)
        mi_df = pd.DataFrame({'feature': self.features, 'mi_score': mi_scores})
        mi_df = mi_df.sort_values('mi_score', ascending=False)
        
        print("Top 20 đặc trưng theo Mutual Information:")
        print(mi_df.head(20))
        
        # Vẽ biểu đồ
        plt.figure(figsize=(12, 8))
        plt.barh(mi_df['feature'].head(20)[::-1], mi_df['mi_score'].head(20)[::-1])
        plt.xlabel('Mutual Information Score')
        plt.title('Feature Importance (Mutual Information)')
        plt.tight_layout()
        plt.savefig('feature_mi.png', dpi=150)
        plt.show()
        
        return mi_df.head(top_n)['feature'].tolist()
    
    def chon_features_tot_nhat(self, tuong_quan_nguong=0.02, mi_top_n=15):
        """
        Kết hợp cả correlation và MI để chọn features tốt nhất
        """
        # Features từ correlation
        corr_features = set(self.phan_tich_tuong_quan(nghich_ngao=tuong_quan_nguong))
        
        # Features từ MI
        mi_features = set(self.mutual_information(top_n=mi_top_n))
        
        # Union của cả hai phương pháp
        final_features = corr_features.union(mi_features)
        
        print(f"\n✅ Đã chọn {len(final_features)} đặc trưng cuối cùng:")
        for f in final_features:
            print(f"  - {f}")
        
        return list(final_features)

Áp dụng feature selection

chon_feature = ChonDacTrung(df_final) features_duoc_chon = chon_feature.chon_features_tot_nhat()

Phương pháp 2: Dùng AI để phân tích (nâng cao)

Bạn có thể dùng HolySheep AI để nhờ AI phân tích và chọn features. Với chi phí chỉ $0.42/MTok cho DeepSeek V3.2, việc này cực kỳ tiết kiệm.

import openai
import os

Cấu hình HolySheep API

openai.api_base = "https://api.holysheep.ai/v1" openai.api_key = "YOUR_HOLYSHEEP_API_KEY" # Thay bằng API key của bạn def hoi_ai_ve_features(features_list, target_description): """ Sử dụng AI để phân tích và đề xuất features quan trọng nhất Args: features_list: Danh sách tên các features target_description: Mô tả biến mục tiêu """ prompt = f""" Tôi đang xây dựng mô hình dự đoán: {target_description} Dưới đây là danh sách các đặc trưng (features) tôi có: {', '.join(features_list)} Hãy phân tích và đề xuất: 1. 10 features quan trọng nhất nên dùng 2. Giải thích ngắn gọn tại sao mỗi feature hữu ích 3. Những features nào có thể gây data leakage (rò rỉ dữ liệu) cần tránh Trả lời bằng tiếng Việt, ngắn gọn và thực tế. """ response = openai.ChatCompletion.create( model="deepseek-chat", # Hoặc "gpt-4", "claude-3-sonnet" tùy nhu cầu messages=[ {"role": "system", "content": "Bạn là chuyên gia phân tích dữ liệu tài chính."}, {"role": "user", "content": prompt} ], temperature=0.3, # Độ sáng tạo thấp để câu trả lời nhất quán max_tokens=1000 ) return response.choices[0].message['content']

Ví dụ sử dụng

print("Đang hỏi AI phân tích features...") goi_y = hoi_ai_ve_features( features_list=features_duoc_chon, target_description="Giá cổ phiếu VND 5 ngày tới tăng hay giảm" ) print("\n" + goi_y)

6. Huấn luyện mô hình AI

Bây giờ bạn đã có dữ liệu sạch và features tốt, đến lúc huấn luyện mô hình. Tôi sẽ hướng dẫn bạn xây dựng một pipeline hoàn chỉnh.

Chia dữ liệu Train/Test/Validation

from sklearn.model_selection import train_test_split, TimeSeriesSplit
from sklearn.preprocessing import StandardScaler
import numpy as np

class HuanLuyenMôHình:
    """Pipeline huấn luyện mô hình dự đoán giá cổ phiếu"""
    
    def __init__(self, df, features, target='target'):
        self.df = df
        self.features = features
        self.target = target
        self.models = {}
        self.results = {}
    
    def chia_du_lieu(self, test_size=0.2, val_size=0.1):
        """
        Chia dữ liệu theo thứ tự thời gian (không shuffle!)
        Rất quan trọng: Không dùng train_test_split thông thường
        vì nó shuffle data, vi phạm nguyên tắc time series
        """
        X = self.df[self.features]
        y = self.df[self.target]
        
        # Chia theo thứ tự thời gian
        n = len(X)
        train_end = int(n * (1 - test_size - val_size))
        val_end = int(n * (1 - test_size))
        
        self.X_train = X.iloc[:train_end]
        self.X_val = X.iloc[train_end:val_end]
        self.X_test = X.iloc[val_end:]
        
        self.y_train = y.iloc[:train_end]
        self.y_val = y.iloc[train_end:val_end]
        self.y_test = y.iloc[val_end:]
        
        print(f"Train: {len(self.X_train)} mẫu ({train_end/n*100:.1f}%)")
        print(f"Validation: {len(self.X_val)} mẫu ({val_size*100:.1f}%)")
        print(f"Test: {len(self.X_test)} mẫu ({test_size*100:.1f}%)")
        
        # Scale dữ liệu
        self.scaler = StandardScaler()
        self.X_train_scaled = self.scaler.fit_transform(self.X_train)
        self.X_val_scaled = self.scaler.transform(self.X_val)
        self.X_test_scaled = self.scaler.transform(self.X_test)
        
        return self
    
    def huan_luyen_nhieu_model(self):
        """
        Huấn luyện nhiều mô hình và so sánh
        """
        from sklearn.linear_model import LogisticRegression
        from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
        from sklearn.svm import SVC
        from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
        
        models = {
            'Logistic Regression': LogisticRegression(max_iter=1000, random_state=42),
            'Random Forest': RandomForestClassifier(n_estimators=100, random_state=42, n_jobs=-1),
            'Gradient Boosting': GradientBoostingClassifier(n_estimators=100, random_state=42),
            'SVM': SVC(kernel='rbf', probability=True, random_state=42)
        }
        
        print("\n🔄 Đang huấn luyện các mô hình...\n")
        
        for name, model in models.items():
            print(f"  Huấn luyện {name}...")
            
            # Chọn dữ liệu scaled phù hợp
            if name in ['Logistic Regression', 'SVM']:
                X_tr, X_te = self.X_train_scaled, self.X_test_scaled
            else:
                X_tr, X_te = self.X_train, self.X_test
            
            # Huấn luyện
            model.fit(X_tr, self.y_train)
            
            # Dự đoán
            y_pred = model.predict(X_te)
            
            # Lưu kết quả
            self.models[name] = model
            self.results[name] = {
                'accuracy': accuracy_score(self.y_test, y_pred),
                'precision': precision_score(self.y_test, y_pred),
                'recall': recall_score(self.y_test, y_pred),
                'f1': f1_score(self.y_test, y_pred)
            }
            
            print(f"    ✅ Accuracy: {self.results[name]['accuracy']:.4f}")
        
        return self
    
    def hien_thi_ket_qua(self):
        """Hiển thị bảng so sánh các mô hình"""
        results_df = pd.DataFrame(self.results).T
        results_df = results_df.sort_values('f1', ascending=False)
        
        print("\n📊 Kết quả so sánh các mô hình:")
        print(results_df.to_string())
        
        # Highlight model tốt nhất
        best_model = results_df.index[0]
        print(f"\n🏆 Model tốt nhất: {best_model} (F1={results_df.loc[best_model, 'f1']:.4f})")
        
        return results_df

Áp dụng huấn luyện

huan_luyen = HuanLuyenMôHình(df_final, features_duoc_chon) huan_luyen.chia_du_lieu(test_size=0.2, val_size=0.1) huan_luyen.huan_luyen_nhieu_model() ket_qua = huan_luyen.hien_thi_ket_qua()

Kết quả mẫu

Train: 363 mẫu (72.0%)
Validation: 51 mẫu (10.0%)
Test: 91 mẫu (18.0%)

🔄 Đang huấn luyện các mô hình...

  Huấn luyện Logistic Regression...
    ✅ Accuracy: 0.5385
  Huấn luyện Random Forest...
    ✅ Accuracy: 0.5714
  Huấn luyện Gradient Boosting...
    ✅ Accuracy: 0.6044
  Huấn luyện SVM...
    ✅ Accuracy: 0.5604

📊 Kết quả so sánh các mô hình:
                    accuracy  precision    recall       f1
Gradient Boosting   0.6044    0.6154     0.5714     0.5926
Random Forest       0.5714    0.5556     0.6667     0.6061
SVM                 0.5604    0.5484     0.6296     0.5865
Logistic Regression 0.5385    0.5200     0.6842     0.5913

🏆 Model tốt nhất: Random Forest (