Bài viết gần đây
| Bài 5: Lập Trình Robot Thực Thi (Order Follower) Đặt Lệnh MetaTrader 5 Bất Đồng Bộ Qua Redis Pub/Sub
Được viết bởi thanhdt vào ngày 09/06/2026 lúc 09:31 | 35 lượt xem
Trong kiến trúc hệ thống giao dịch tự động phân rã (Decoupled Algo Trading System) mà chúng ta đã tìm hiểu ở các bài học trước, phân hệ phát tín hiệu Order Good (OG) và phân hệ thực thi Order Follower (OF) hoạt động hoàn toàn độc lập với nhau. Cầu nối trung chuyển thông tin giữa chúng chính là Message Queue Redis Pub/Sub với độ trễ truyền tin cực thấp (< 5ms).
Sau khi mô hình AI (như XGBoost ở Bài 3) được đóng gói và phát tín hiệu dự đoán xu hướng giá qua Redis (Bài 4), nhiệm vụ tiếp theo của chúng ta là xây dựng “cánh tay thực thi” – Robot Order Follower (OF). Con bot này sẽ liên tục lắng nghe kênh tín hiệu từ Redis và lập tức chuyển hóa chúng thành các lệnh mua/bán thực tế trên terminal MetaTrader 5 (MT5).
🎨 Sơ đồ luồng xử lý và đặt lệnh bất đồng bộ
Dưới đây là sơ đồ mô tả cách thức hoạt động của phân hệ Order Follower khi nhận tín hiệu từ hàng đợi Redis và chuyển tiếp đến MetaTrader 5:
1. Tại sao cần tách biệt lớp thực thi Order Follower?
Khi vận hành hệ thống Algo Trading ở quy mô lớn hoặc tần suất cao, việc gộp chung logic tính toán chiến lược và logic đặt lệnh vào một tiến trình duy nhất (Single Process) mang lại nhiều rủi ro:
* Tránh nghẽn luồng (Thread Blocking): Việc gửi yêu cầu đặt lệnh (Order Request) tới server của broker Forex thường mất từ 100ms – 500ms (hoặc lâu hơn do kết nối mạng). Nếu gộp chung, chiến lược của bạn sẽ bị “đơ” trong khoảng thời gian này và bỏ lỡ các nến tiếp theo.
* Tăng khả năng chịu lỗi (Fault Tolerance): Nếu terminal MT5 local bị mất kết nối hoặc bị treo, phân hệ phân tích (OG) vẫn chạy bình thường trên máy chủ đám mây để lưu trữ tín hiệu. Khi OF được khởi động lại, nó chỉ cần đăng ký lại với Redis để tiếp tục hoạt động mà không bị mất mát trạng thái hệ thống.
2. Lập trình Robot Order Follower bằng Python
Dưới đây là mã nguồn Python hoàn chỉnh của phân hệ Order Follower (OF). Robot thực hiện các nhiệm vụ:
1. Kết nối với Redis Server cục bộ hoặc đám mây và lắng nghe channel trading_signals.
2. Khởi tạo kết nối trực tiếp với ứng dụng MetaTrader 5 (MT5) đang mở trên Windows.
3. Khi nhận được tín hiệu (BUY/SELL), tự động tính toán khối lượng vị thế (Lot Size) dựa trên tỷ lệ rủi ro (Risk-based Position Sizing).
4. Gửi lệnh trực tiếp vào MT5 với thông số chốt lời (Take Profit) và dừng lỗ (Stop Loss) chuẩn xác.
import os
import json
import time
import MetaTrader5 as mt5
import redis
# Cấu hình thông số hệ thống
REDIS_HOST = 'localhost'
REDIS_PORT = 6379
REDIS_CHANNEL = 'trading_signals'
SYMBOL = "EURUSD"
RISK_PER_TRADE = 0.01 # Chấp nhận rủi ro 1% tài khoản cho mỗi lệnh
STOP_LOSS_PIPS = 150 # Điểm dừng lỗ (15 pips = 150 points)
TAKE_PROFIT_PIPS = 300 # Điểm chốt lời (30 pips = 300 points)
# 1. Kết nối với MetaTrader 5 Terminal
def init_mt5():
if not mt5.initialize():
print("❌ Khởi tạo kết nối MetaTrader 5 thất bại!")
return False
print("🟢 Kết nối MetaTrader 5 thành công!")
return True
# 2. Phân hệ quản trị rủi ro: Tính toán Lot Size động theo số dư tài khoản
def calculate_lot_size(symbol, stop_loss_points):
# Lấy thông tin tài khoản hiện tại
account_info = mt5.account_info()
if account_info is None:
return 0.01 # Trả về số lot tối thiểu nếu lỗi
balance = account_info.balance
# Số tiền chấp nhận mất cho lệnh này
risk_amount = balance * RISK_PER_TRADE
# Lấy thông tin thuộc tính của sản phẩm giao dịch
symbol_info = mt5.symbol_info(symbol)
if symbol_info is None:
return 0.01
# Tính toán giá trị của 1 point trên mỗi Lot tiêu chuẩn
point_value = symbol_info.trade_tick_value / symbol_info.trade_tick_size
# Công thức tính Lot Size: Lot = Risk Amount / (Stop Loss in Points * Point Value)
lot_size = risk_amount / (stop_loss_points * point_value)
# Giới hạn lot size theo quy định của sàn (Volume Min/Max/Step)
lot_size = max(symbol_info.volume_min, min(symbol_info.volume_max, lot_size))
# Làm tròn theo bước nhảy volume (volume_step, thường là 0.01)
step = symbol_info.volume_step
lot_size = round(lot_size / step) * step
print(f"💰 Số dư: {balance:.2f} USD | Số tiền rủi ro: {risk_amount:.2f} USD | Lot tính toán: {lot_size:.2f}")
return lot_size
# 3. Phân hệ thực thi: Gửi lệnh đặt lên MetaTrader 5
def send_mt5_order(action, symbol, num_lots):
symbol_info = mt5.symbol_info(symbol)
if not symbol_info:
print(f"❌ Không tìm thấy thông tin sản phẩm {symbol}")
return False
# Kích hoạt hiển thị symbol trên Market Watch
if not symbol_info.visible:
mt5.symbol_select(symbol, True)
# Lấy giá hiện tại (Bid/Ask)
tick = mt5.symbol_info_tick(symbol)
if not tick:
print(f"❌ Không lấy được giá Bid/Ask của {symbol}")
return False
# Xác định loại lệnh và mức giá dừng lỗ/chốt lời tương ứng
if action == "BUY":
order_type = mt5.ORDER_TYPE_BUY
price = tick.ask
sl = price - (STOP_LOSS_PIPS * symbol_info.point)
tp = price + (TAKE_PROFIT_PIPS * symbol_info.point)
elif action == "SELL":
order_type = mt5.ORDER_TYPE_SELL
price = tick.bid
sl = price + (STOP_LOSS_PIPS * symbol_info.point)
tp = price - (TAKE_PROFIT_PIPS * symbol_info.point)
else:
return False
# Cấu trúc yêu cầu đặt lệnh
request = {
"action": mt5.TRADE_ACTION_DEAL,
"symbol": symbol,
"volume": num_lots,
"type": order_type,
"price": price,
"sl": sl,
"tp": tp,
"deviation": 10, # Độ trượt giá tối đa cho phép (Slippage)
"magic": 150926, # Mã nhận diện của riêng con Bot này
"comment": "K15 AI Redis Follower",
"type_time": mt5.ORDER_TIME_GTC,
"type_filling": mt5.ORDER_FILLING_FOK,
}
# Gửi lệnh lên Terminal MT5
result = mt5.order_send(request)
if result.retcode != mt5.TRADE_RETCODE_DONE:
print(f"❌ Đặt lệnh thất bại! Mã lỗi từ sàn (Retcode): {result.retcode}")
return False
print(f"🟢 Đặt lệnh {action} {num_lots} lot {symbol} thành công! ID vị thế: {result.order}")
return True
# 4. Lắng nghe tín hiệu bất đồng bộ từ Redis Channel
def start_order_follower():
# Khởi tạo kết nối Redis
r = redis.Redis(host=REDIS_HOST, port=REDIS_PORT, db=0)
pubsub = r.pubsub()
pubsub.subscribe(REDIS_CHANNEL)
print(f"📡 Đang lắng nghe tín hiệu giao dịch bất đồng bộ trên kênh '{REDIS_CHANNEL}'...")
for message in pubsub.listen():
# Bỏ qua tin nhắn đăng ký ban đầu
if message['type'] == 'subscribe':
continue
try:
# Giải mã dữ liệu JSON nhận được từ kênh Redis
data = json.loads(message['data'].decode('utf-8'))
print(f"n⚡ Nhận được tín hiệu mới: {data}")
signal = data.get('signal') # "BUY" hoặc "SELL"
symbol = data.get('symbol', SYMBOL)
if signal in ["BUY", "SELL"]:
# Tính toán Lot Size an toàn trước khi vào lệnh
lots = calculate_lot_size(symbol, STOP_LOSS_PIPS)
# Thực hiện đặt lệnh trên MT5
send_mt5_order(signal, symbol, lots)
except Exception as e:
print(f"❌ Lỗi xử lý tin nhắn tín hiệu: {e}")
if __name__ == "__main__":
if init_mt5():
try:
start_order_follower()
except KeyboardInterrupt:
print("n🛑 Đang dừng Robot Order Follower...")
finally:
mt5.shutdown()
print("👋 Đã ngắt kết nối MetaTrader 5.")
3. Các lưu ý quan trọng về mã trả về (Retcodes) trên MT5
Một lỗi phổ biến khiến robot giao dịch bị treo là bỏ qua việc kiểm tra mã trả về (retcode) từ Broker. Khi bạn gọi hàm mt5.order_send(), terminal sẽ trả về mã trạng thái thực thi:
* TRADE_RETCODE_DONE (10009): Lệnh đã được khớp thành công hoàn toàn.
* TRADE_RETCODE_REQUOTE (10004): Bị báo giá lại (thường do thị trường biến động quá nhanh, giá hiện tại lệch quá deviation).
* TRADE_RETCODE_NO_MONEY (10019): Tài khoản không đủ tiền ký quỹ để mở lệnh với lot size yêu cầu.
* TRADE_RETCODE_PRICE_OFF (10012): Giá đặt lệnh không hợp lệ (sai bước giá hoặc trượt giá quá xa).
Lời khuyên thực chiến: Luôn kiểm tra kỹ các mã lỗi trên và lập lịch cơ chế thử lại (Retry) thông minh hoặc gửi cảnh báo khẩn cấp qua Telegram để can thiệp kịp thời.
🎓 Khóa học “Lập trình Bot Auto Trading thực chiến” cùng Hướng Nghiệp Dữ Liệu
Bạn muốn sở hữu những robot giao dịch tự động chạy ổn định và an toàn tuyệt đối? Bạn muốn tự tay thiết kế các hệ thống giao dịch có khả năng tự động xử lý các tình huống lỗi mạng, trượt giá, và quản trị rủi ro đa tầng như các quỹ đầu tư chuyên nghiệp?
Hãy tham gia khóa đào tạo chuyên sâu “Xây dựng Bot Auto Trading thực chiến” tại Hướng Nghiệp Dữ Liệu:
* Học trực tiếp 1-1: Giải quyết trực tiếp các bài toán lập trình và sửa lỗi code hệ thống của riêng bạn.
* Hạ tầng chuyên nghiệp: Tiếp cận kho thư viện mã nguồn đặt lệnh nâng cao, quản trị rủi ro đa tầng và kết nối cổng API an toàn.
* Đồng hành trọn đời: Được tham gia cộng đồng Quantitative Trader chất lượng cao, chia sẻ kinh nghiệm thực chiến và cập nhật các thuật toán mới liên tục.
👉 Đăng ký nhận lộ trình học tập chi tiết và ưu đãi học phí qua Zalo: