Phân tích định lượng phương pháp giao dịch theo đường MA

Đường MA là gì
- Đường MA (hay còn gọi là Moving Average) là đường trung bình động, thể hiện biến động, chỉ báo xu hướng của giá cổ phiếu trong một khoảng thời gian
- Đường trung bình động (MA) là một cách giúp lọc nhiễu và làm dịu những biến động giá phức tạp trở nên mượt hơn giúp bạn quan sát xu hướng thị trường tốt hơn, chỉ báo chậm theo xu hướng bởi vì nó dựa trên giá cả trong quá khứ
- Có 3 loại đường MA phổ biến là SMA (đường trung bình cộng giản đơn), WMA (đường trung bình trọng số tuyến tính), EMA (đường trung bình trọng số mũ). Đường MA ngắn hạn thì sử dụng MA10, MA14, MA20, đường MA trung hạn sử dụng MA50, MA dài hạn sử dụng MA100, MA200. MA thường được sử dụng để xác định xu hướng thị trường và xác định ngưỡng kháng cự/hỗ trợ động.
Phương pháp định lượng
Chúng tôi sẽ định lượng các phương pháp giao dịch sử dụng đường MA qua bài viết này. dữ liệu bao gồm toàn bộ các cổ phiếu ở sàn HOSE từ 2018 đến bây giờ. Chúng tôi sẽ tìm ra các điểm mua, bán trong bộ dữ liệu trên, qua đó nghiên cứu xác suất, lợi nhuận để kiểm tra các phương pháp giao dịch sử dụng đường MA có còn hiệu quả hay không
Phương pháp giao dịch sử dụng đường MA thường xem đường MA là các ngưỡng kháng cự, hỗ trợ
- Tín hiệu mua vào khi giá vượt đường MA và bán ra khi giá cắt đường MA từ trên xuống
- Tín hiệu mua và khi đường MA ngắn hạn cắt lên trên MA dài hạn và ngược lại
Chúng tôi sẽ định lượng 3 đường MA là SMA, WMA, EMA, trong các khoảng thời gian ngắn hạn 20 ngày, trung hạn 50 ngày, và dài hạn 200 ngày

Phân tích chi tiết
Chúng tôi sử dụng python trên môi trường google colab và các thư viện talib, numpy, pandas để làm thống kê. Để cài thư viện talib chúng tôi chạy các dòng lệnh sau, thư viện numpy, pandas, matplotlib đã có sẵn trên môi trường google colab
url = 'https://anaconda.org/conda-forge/libta-lib/0.4.0/download/linux-64/libta-lib-0.4.0-h166bdaf_1.tar.bz2'
!curl -L $url | tar xj -C /usr/lib/x86_64-linux-gnu/ lib --strip-components=1
url = 'https://anaconda.org/conda-forge/ta-lib/0.4.19/download/linux-64/ta-lib-0.4.19-py310hde88566_4.tar.bz2'
!curl -L $url | tar xj -C /usr/local/lib/python3.10/dist-packages/ lib/python3.10/site-packages/talib --strip-components=3
Sau đó import các thư viện cần thiết
import talib
import numpy as np
import pandas as pd
import os
Dữ liệu giá của tất cả các mã cổ phiếu ở sàn HOSE từ ngày đầu được chúng tôi thu thập và nén lại có thể được download tại đây. Chúng tôi dùng đoạn code sau để tải dữ liệu về, giải nén, và đọc dữ liệu
! wget -O data.zip https://github.com/tranphuminhbkhn/MTQuant/raw/refs/heads/main/data.zip
! unzip data.zip
data = {}
for fn in os.listdir('data'):
symbol = fn[:-4]
if len(symbol) != 3 and symbol != 'VNINDEX':
continue
data[symbol] = pd.read_csv('data/{}'.format(fn))
Sử dụng thư viện talib để tính toán các đường MA cho từng mã cổ phiếu như sau
SMA = {}; WMA = {}; EMA = {}; ncandle = 20
for symbol in data:
sma = talib.SMA(np.array(data[symbol]['Close']), ncandle)
wma = talib.WMA(np.array(data[symbol]['Close']), ncandle)
ema = talib.EMA(np.array(data[symbol]['Close']), ncandle)
SMA[symbol] = sma; WMA[symbol] = wma; EMA[symbol] = ema
Sau đó chúng tôi sẽ trích xuất các giá trị cần thiết để tính toán theo mã cổ phiếu và ngày, Chúng tôi giả sử sẽ mua / bán được giá ATC trong phiên mà xuất hiện tín hiệu
DATA = {}
for symbol in data:
DATA[symbol] = {}
for i in range(ncandle, len(SMA[symbol])):
dt = data[symbol]['Date'][i]
if dt < 180000:
continue
c = data[symbol]['Close'][i]
sma = SMA[symbol][i]; wma = WMA[symbol][i]; ema = EMA[symbol][i]
DATA[symbol][dt] = [c, sma, wma, ema]
1. Tín hiệu mua bán tại điểm MA giao với giá
Phương pháp này xem đường MA như là hỗ trợ, kháng cự, khi giá cắt và vượt lên trên đường MA là break kháng cự và sẽ có tín hiệu mua, ngược lại khi giá cắt xuống đường MA, nghĩa là gãy vùng hỗ trợ và cho tín hiệu bán
price = data_[dt][0]; sma = data_[dt][1]
if sma > price and not inOrder_flag:
bprice = price # Mua tại giá đóng cửa
bvniprice = vprice
n = 0; inOrder_flag = True; order = [dt]
if sma < price and inOrder_flag and n >= 2: # Phải sau 2 ngày mới có thể bán
sprice = price # Bán tại giá đóng cửa
svniprice = vprice
profit = sprice / bprice - 1
inOrder_flag = False; order.append(dt); order_data[symbol].append(order)
order_profit.append(profit)
vni_change.append(svniprice / bvniprice - 1)
nhold.append(n)
- Số lần vào lệnh: 38634
- Thời gian giữ trung bình mỗi lệnh: 8.87 ngày
- Lợi nhuận trung bình mỗi lệnh : 0.508%
- Biến động trung bình VNINDEX khi hold mỗi lệnh: 0.4069%
- Xác suất lệnh đạt hiệu quả hơn VNINDEX: 29.75%
Nhìn qua quả định lượng, lợi nhuận có thể đạt tầm 15% mỗi năm. Nhưng sau khi chúng tôi đảo ngược tín hiệu mua bán của hệ thống, mua khi đường giá cắt xuống dướng đường MA và bán khi Giá cắt lên trên, thì lợi nhuận đạt 0.7341% sau thời gian nắm giữ trung bình là 8.82 ngày, có thể thấy phương pháp giao dịch này không hiệu quả trên dữ liệu thị trường chứng khoán Việt Nam. Tiếp theo chúng tôi sẽ phân tích nếu không phụ thuộc vào thị trường thì kết quả định lượng sẽ thế nào

Chúng tôi giả sử có thể giao dịch cổ phiếu ở cả 2 chiều LONG và SHORT, Long khi giá cắt và vượt lên SMA20 và SHORT khi giá cắt xuống SMA20. Khi đó có thể đánh giá tổng quan sự hiệu quả của phương pháp mà không bị ảnh hưởng bởi thị trường
if price < sma: # SHORT
if inOrder_flag == 'LONG' and n >= 2:
# Đóng vị thế LONG
sprice = price # Mua tại giá đóng cửa
order_profit.append(sprice / bprice - 1)
order.append(dt); order_data[symbol].append(order)
inOrder_flag = 'None'; nhold.append(n)
if inOrder_flag == 'None':
# Mở vị thế SHORT
bprice = price; n = 0; inOrder_flag = 'SHORT'; order = [dt]
if price > sma: # LONG
if inOrder_flag == 'SHORT' and n >= 2:
# Đóng vị thế SHORT
sprice = price # Mua tại giá đóng cửa
order_profit.append(1 - sprice / bprice)
order.append(dt); order_data[symbol].append(order)
inOrder_flag = 'None'; nhold.append(n)
if inOrder_flag == 'None':
# Mở vị thế LONG
bprice = price; n = 0; inOrder_flag = 'LONG'; order = [dt]
Kết quả được thể hiện ở bảng sau
Ngắn hạn | Trung hạn | Dài hạn | |||||||
---|---|---|---|---|---|---|---|---|---|
SMA-20 | WMA-20 | EMA-20 | SMA-50 | WMA-50 | EMA-50 | SMA-200 | WMA-200 | EMA-200 | |
Số lần vào lệnh | 72333 | 89414 | 78066 | 45069 | 57672 | 50788 | 20520 | 27211 | 23326 |
Thời gian nắm giữ | 9.12 ngày | 7.38 ngày | 8.44 ngày | 14.43 ngày | 11.35 ngày | 12.79 ngày | 29.47 ngày | 22.82 ngày | 26.03 ngày |
Lợi nhuận trung bình | -0.0818% | -0.0998% | -0.1137% | -0.0668% | -0.098% | -0.146% | 0.492% | 0.2845% | 0.2679% |
Nhìn bảng kết quả trên chúng ta có thể thấy
- Chỉ các chỉ báo MA trên khung dài hạn còn hiệu quả, nhưng nếu trừ phí thuế giao dịch, thì hiệu quả cũng về không.
- Hiệu quả của đường MA đơn giản (SMA) thường tốt nhất trên các khung thời gian khác nhau
2. Tín hiệu mua bán tại các điểm MA giao nhau
Vì các đường MA là các chỉ báo vận động khá chậm so với giá, nên khi so sánh hai đường MA thì nó biến động rất chậm, trong nghiên cứu này, chúng tôi so sánh MA10 và MA20 để xác định xu hướng trung hạn, MA20 và MA50 cho xu hướng dài hạn. Kết quả như sau
Trung hạn | Dài hạn | |||||
---|---|---|---|---|---|---|
SMA10 & SMA20 | WMA10 & WMA20 | EMA10 & EMA20 | SMA20 & SMA50 | WMA20 & WMA50 | EMA20 & EMA50 | |
Số lần vào lệnh | 37351 | 41289 | 29221 | 15070 | 17924 | 12591 |
Thời gian nắm giữ | 17.59 ngày | 15.91 ngày | 22.25 ngày | 42.81 ngày | 36.17 ngày | 50.35 ngày |
Lợi nhuận trung bình | 0.6568% | 0.3114% | 0.4135% | 1.3573% | 1.276% | 1.9823% |
- Tín hiệu điểm cắt nhau giữa các đường MA10 và MA20 vẫn đem lại sự hiệu quả trong trường hợp không tính phí, thuế giao dịch
- Tín hiệu điểm cắt nhau giữa các đường MA20 và MA50 đạt hiệu quả tương đối tốt (mức sinh lợi tầm 6% khi đã trừ phí thuế giao dịch và không tính đến biến động thị trường)
3. Kết luận
Trong các phần trên chúng tôi đã làm thống kê định lượng các phương pháp giao dịch sử dụng đường MA bao gồm:
- Tín hiệu mua vào khi giá vượt đường MA và bán ra khi giá cắt đường MA từ trên xuống
- Tín hiệu mua và khi đường MA ngắn hạn cắt lên trên MA dài hạn và ngược lại
Trong từng phương pháp chúng tôi làm các thí nghiệm riêng rẻ với các loại đường MA khác nhau (SMA, WMA, EMA) và với các khung thời gian khác nhau. Phương pháp tín hiệu khi các đường MA cắt nhau là một phương pháp đơn giản và là một phương pháp hiếm hoi có thể đem lại hiệu quả trong thị trường chứng khoán Việt Nam. Các chỉ báo MA về dài hạn thể hiện xu hướng tương đối tốt, và rất khó để có thể bị "vẽ"
Mọi nghiên cứu phía trên chúng tôi thực hiện trên môi trường google colab, bấm vào để xem vào thực thi đoạn code