Bài viết gần đây
-
Buổi 14 IB Bot — Engine Copy Trading dưới 100ms & Guard System
Tháng 7 17, 2026 -
Buổi 21 IB Bot — Autorebates & minh bạch backcom OPC
Tháng 7 17, 2026
Trang chủ → Bài Viết → Kiến trúc 4 lớp PyNhiQuaiBot — Quant Buổi 1: từ script sang hệ thống quant Python hedging
| Kiến trúc 4 lớp PyNhiQuaiBot — Quant Buổi 1: từ script sang hệ thống quant Python hedging
Được viết bởi thanhdt vào ngày 18/07/2026 lúc 15:04 | 4 lượt xem
Nguồn:
Day DataPass/.../Bot Nhi Quai Nang Cao/bot_nhi_quai_v6_pro.py· lộ trình 12 buổi PyNhiQuaiBot (QuantTrade)
Hầu hết lập trình viên bắt đầu bot trading bằng một file Python duy nhất: while True, đọc giá, nếu điều kiện thì order_send, rồi sleep. Cách này chạy được trên demo vài phút — nhưng khi reconnect API, khi có hàng chục vị thế Buy/Sell cùng lúc, hoặc khi equity giảm và bot vẫn cố mở lệnh mới, script đơn sẽ sụp đổ vì không có ranh giới trách nhiệm giữa dữ liệu, chiến thuật, kiểm soát rủi ro và thực thi.
Buổi 1 — Kiến trúc & chuẩn hóa bài toán trong khóa Lập trình Python nâng cao Hedging tự động hóa (dự án PyNhiQuaiBot, góc PR QuantTrade · Master Quantitative Trading) trả lời câu hỏi nền tảng: một bot hedging production cần được chia thành những lớp nào, và vòng lặp chính đi qua chúng theo thứ tự gì?
Bài viết bám trực tiếp mã nguồn bot_nhi_quai_v6_pro.py — bản Python port từ Bot Nhị Quái V6 Pro trên MQ5. Đây là tài liệu kỹ thuật và bài lab Buổi 1, không phải khuyến nghị đầu tư, không cam kết lợi nhuận. Grid, hedging và giao dịch tự động có thể gây drawdown lớn, margin call, trượt giá, phí và lỗi kết nối. Chỉ thực hành trên demo, đặt giới hạn rủi ro độc lập và tự chịu trách nhiệm triển khai.
1. Script một file vs hệ thống quant có trách nhiệm
| Tiêu chí | Script một file | Hệ thống PyNhiQuaiBot |
|---|---|---|
| Trạng thái | Biến global rời, mất khi restart | GVStore JSON — persist + namespace theo symbol/account/magic |
| Quyết định mở lệnh | if signal: buy() |
Grid Logic (process_cluster) tách khỏi Guard (handle_lockdown) |
| Side effect | Gọi API trực tiếp trong logic | order_send — adapter execution, chiến thuật không biết filling mode |
| Quan sát | print(bid) |
draw_dashboard — equity, bias, P0, trạng thái Full Hedge |
| Thất bại | Crash hoặc nhồi lệnh | Spread guard, lockdown freeze, FSM STEP_BUSY (Buổi 8) |
QuantTrade không bắt đầu bằng “tín hiệu thần kỳ”. Nó bắt đầu bằng cấu trúc có thể kiểm thử: mỗi lớp trả lời một câu hỏi riêng, và vòng lặp chính gọi chúng theo thứ tự cố định để tránh “sửa API làm hỏng chiến thuật” hoặc “sửa chiến thuật làm bỏ qua guard”.
2. Bốn phần kiến trúc — bản đồ cả khóa 12 buổi
Ảnh lộ trình: PyNhiQuaiBot_Lo_Trinh_4_Phan.png (Infrastructure → Grid Logic → Brain → UX).
| Phần | Buổi học (12 buổi chính) | Module trong bot_nhi_quai_v6_pro.py |
Câu hỏi lớp trả lời |
|---|---|---|---|
| 1 — Infrastructure | B1–B4 | Config, GVStore, rates, order_send, positions |
Dữ liệu đúng chưa? API giao tiếp thế nào? State lưu ở đâu? |
| 2 — Grid Logic | B5–B7 | process_cluster, Step/X, Surplus/Hedge, cache |
Giá hiện tại = Step mấy? Có được mở lệnh tại Step này không? |
| 3 — Brain | B8–B10 | get_fsm/set_fsm, handle_lockdown, check_basket_tp |
Hành động có được phép? Rủi ro vượt ngưỡng chưa? |
| 4 — UX | B11–B12 | draw_dashboard, log, VPS, backtest hook |
Người vận hành nhìn thấy gì? Metric quant nào cần đo? |
Buổi 1 không đi sâu Step/X hay FSM — mục tiêu là đọc được toàn cảnh trước khi zoom vào từng module ở các buổi sau. Nếu bạn đã đọc bài tổng quan PyNhiQuaiBot, bài này là lab Buổi 1: cùng chủ đề nhưng gắn trực tiếp vào file code và sơ đồ runtime.
graph TB
subgraph UX["PHẦN 4 — UX"]
DASH[draw_dashboard]
LOG[logging]
end
subgraph BRAIN["PHẦN 3 — Brain"]
LOCK[handle_lockdown]
FSM[get_fsm / set_fsm]
BASKET[check_basket_tp]
end
subgraph GRID["PHẦN 2 — Grid Logic"]
CLUSTER[process_cluster]
TP[tp_logic / check_x_profit]
end
subgraph INFRA["PHẦN 1 — Infrastructure"]
CFG[Config dataclass]
GV[GVStore JSON]
API[rates · order_send · positions]
end
RUN[run → on_tick loop] --> INFRA
INFRA --> BRAIN
BRAIN --> GRID
GRID --> UX
UX --> GV
3. Khung dự án: Config — map 1-1 với input MQ5
Lớp Infrastructure bắt đầu bằng cấu hình tách biệt logic. Trong Python, @dataclass Config gom toàn bộ tham số mà trên MQ5 là input:
@dataclass
class Config:
bot_name: str = "NHỊ QUÁI V6"
storage_prefix: str = "NHỊ QUÁI V6"
buy_magic: int = 6111
sell_magic: int = 6112
buy_step: float = 50.0
buy_x: float = 60.0
sell_step: float = 100.0
sell_x: float = 120.0
auto_lockdown: bool = True
max_allowed_bias: float = 0.3
tick_sleep: float = 0.25
symbol: str = "BTCUSD"
Deliverable Buổi 1: liệt kê được mỗi nhóm field thuộc phần kiến trúc nào:
| Nhóm Config | Ví dụ | Thuộc phần |
|---|---|---|
| Identity | bot_name, storage_prefix, buy_magic, sell_magic |
Infrastructure — namespace |
| Grid | buy_step, buy_x, sell_step, sell_x, buy_lot |
Grid Logic |
| Risk | auto_lockdown, buy_min_equi2, max_allowed_bias |
Brain |
| Runtime | tick_sleep, max_spread, symbol |
Infrastructure + UX |
Hàm parse_args() cho phép override từ CLI (--symbol BTCUSD, --buy-step 50) mà không sửa class — pattern quant engineer: config ngoài code, dễ chạy trên VPS với tham số khác nhau.
4. GVStore — Global State thay GlobalVariable MT5
Trên MQ5, EA dùng GlobalVariableSet/Get. Port sang Python dùng file JSON:
class GVStore:
def __init__(self, path: Path):
self.path = path
self.data: Dict[str, float] = {}
self._load()
def get(self, name: str, default: float = 0.0) -> float:
return float(self.data.get(name, default))
def set(self, name: str, value: float) -> None:
self.data[name] = float(value)
def save(self) -> None:
self.path.write_text(json.dumps(self.data, ensure_ascii=False, indent=2), encoding="utf-8")
Mỗi tick kết thúc bằng self.gv.save() — state không chỉ nằm trong RAM. Key được namespace:
def gv_prefix(self, magic: int) -> str:
return f"{self.cfg.storage_prefix}_{self.symbol}_{self._login}_{magic}"
Ví dụ key thực tế: NHỊ QUÁI V6_BTCUSD_12345678_6111_P0, ..._6111_LastStep, ..._6111_LOCKED.
Vì sao Buổi 1 dạy GVStore trước Grid? Vì mọi quyết định chiến thuật đều đọc/ghi state (P0, LastStep, MinStep, MaxStep, FSM keys). Không có store thống nhất, reconnect sẽ làm bot “quên” P0 và nhồi lệnh sai Step — pain mà bài Global State (Buổi 2) sẽ mở rộng thêm schema Pandas.
5. Class NhiQuaiV6 — composition thay vì God object một chiều
NhiQuaiV6 giữ:
self.cfg— cấu hình bất biến trong sessionself.gv— store bền vững- Cache runtime:
buy_cache,sell_cache(Buổi 7 — concurrency) - Throttle:
last_action_buy,last_action_sell(2 giây giữa hai lần xử lý cụm)
Đây chưa phải OOP “sạch” kiểu microservice — nhưng đã phân tách method theo trách nhiệm:
| Method | Trách nhiệm |
|---|---|
rates() |
Đọc Bid/Ask/spread — Infrastructure |
order_send() / close_ticket() |
Execution adapter MT5 |
handle_lockdown() |
Brain — full hedge khi equity thấp |
tp_logic() |
Grid — gặt X cục bộ |
process_cluster() |
Grid — core rải lệnh theo Step |
draw_dashboard() |
UX — quan sát bias, float, P0 |
Nguyên tắc Buổi 1: chiến thuật không gọi MT5 trực tiếp ngoài order_send/close_ticket. Mọi thay đổi filling mode, deviation, comment format chỉ sửa một chỗ.
6. Vòng đời: on_init → run → on_tick
6.1. Khởi tạo on_init
Trước vòng lặp, bot:
- Kiểm tra
buy_magic != sell_magic(hai cụm không được trùng) mt5.symbol_select(symbol)- Lấy
account login→ namespace GVStore - Nếu cụm chưa có position →
reset_cluster - Khởi tạo
P0vàStartTimecho từng magic nếu chưa có sync_traversed()— đồng bộ MinStep/MaxStep từ comment lệnh đang mở
def on_init(self) -> bool:
if self.cfg.buy_magic == self.cfg.sell_magic:
log.error("Buy/Sell magic trùng nhau!")
return False
ai = mt5.account_info()
self._login = int(ai.login) if ai else 0
for magic in (self.cfg.buy_magic, self.cfg.sell_magic):
k = f"{self.gv_prefix(magic)}_P0"
if not self.gv.check(k):
bid, _, _ = self.rates()
self.gv.set(k, bid)
self.sync_traversed()
self.gv.save()
return True
Test Buổi 1 — init: chạy bot lần đầu trên demo → file .gv.json xuất hiện với key _P0 cho magic 6111 và 6112.
6.2. Vòng lặp chính run
def run(self) -> None:
if not self.on_init():
return
try:
while True:
self.on_tick()
time.sleep(self.cfg.tick_sleep)
except KeyboardInterrupt:
self.gv.save()
tick_sleep mặc định 0.25 giây — Python bot polling, không phải hook OnTick native như MQ5. Quant engineer cần hiểu: polling interval ảnh hưởng race window (Buổi 7) và tải CPU trên VPS (Buổi 12).
6.3. Một chu kỳ on_tick — flow đầy đủ
Đây là trái tim Buổi 1 — thứ tự gọi cố định:
def on_tick(self) -> None:
bid, ask, spread = self.rates()
if bid <= 0 or spread > self.cfg.max_spread:
return
if self.cfg.buy_enable:
self.handle_lockdown(self.cfg.buy_magic)
if not self.is_full_hedge_frozen(self.cfg.buy_magic):
self.tp_logic(self.cfg.buy_magic)
self.process_cluster(self.cfg.buy_magic)
if self.cfg.sell_enable:
self.handle_lockdown(self.cfg.sell_magic)
if not self.is_full_hedge_frozen(self.cfg.sell_magic):
self.tp_logic(self.cfg.sell_magic)
self.process_cluster(self.cfg.sell_magic)
self.draw_dashboard()
self.gv.save()
sequenceDiagram
participant Loop as run() while True
participant Tick as on_tick()
participant Rates as rates()
participant Lock as handle_lockdown()
participant TP as tp_logic()
participant Grid as process_cluster()
participant Dash as draw_dashboard()
participant GV as GVStore.save()
Loop->>Tick: mỗi tick_sleep
Tick->>Rates: Bid, Ask, spread
alt spread OK
Tick->>Lock: magic 6111
alt not frozen
Tick->>TP: gặt X cụm BUY
Tick->>Grid: rải lệnh cụm BUY
end
Tick->>Lock: magic 6112
alt not frozen
Tick->>TP: gặt X cụm SELL
Tick->>Grid: rải lệnh cụm SELL
end
Tick->>Dash: in equity, bias, P0
Tick->>GV: persist JSON
else spread quá rộng
Tick-->>Loop: return sớm
end
Thứ tự có ý nghĩa:
- Spread guard trước — không trade khi thị trường mỏng
- Lockdown trước Grid — equity thấp → hedge ABS, đặt
_LOCKED, bỏ quaprocess_cluster - tp_logic trước process_cluster — chốt lệnh đã đủ X trước khi cân nhắc mở mới
- Cụm BUY trước SELL — quy ước code hiện tại (documented, không “đúng/sai” thị trường)
- Dashboard + save cuối — UX và durability
7. Execution layer — order_send tách khỏi chiến thuật
def order_send(self, magic: int, side: int, lot: float, comment: str) -> bool:
tick = mt5.symbol_info_tick(self.symbol)
order_type = mt5.ORDER_TYPE_BUY if side == POS_BUY else mt5.ORDER_TYPE_SELL
price = tick.ask if side == POS_BUY else tick.bid
req = {
"action": mt5.TRADE_ACTION_DEAL,
"symbol": self.symbol,
"volume": float(lot),
"type": order_type,
"price": price,
"deviation": int(self.cfg.slippage_allow),
"magic": int(magic),
"comment": comment[:31],
"type_filling": filling,
}
r = mt5.order_send(req)
return r is not None and r.retcode == mt5.TRADE_RETCODE_DONE
process_cluster chỉ gọi order_send — không biết Ask/Bid lấy từ đâu. Buổi 3 sẽ mở rộng thành adapter đa sàn (Binance, SSI, DNSE); Buổi 1 chỉ cần nhận ra interface execution đã tồn tại.
Comment format: NHỊ QUÁI V6_B_S12 (cụm BUY, Step 12) — Buổi 4 sẽ học Magic + Comment + lifecycle đầy đủ.
8. Hai cụm magic 6111 / 6112 — preview cho Buổi 4
Mỗi on_tick xử lý hai cluster độc lập:
| Magic | Tên cụm | Step mặc định | X mặc định |
|---|---|---|---|
| 6111 | Cụm BUY | 50.0 | 60.0 |
| 6112 | Cụm SELL | 100.0 | 120.0 |
Mỗi cụm có P0 riêng, basket TP riêng, lockdown riêng. Tên “BUY cluster” không có nghĩa chỉ chứa lệnh Buy — cụm vẫn có cả Buy và Sell tại các Step (hedging). Chi tiết: Kiến trúc hai cụm 6111/6112 (Buổi 4).
9. Dashboard — UX không phải phần trang trí
def draw_dashboard(self) -> None:
if self.tick_ms() - self.last_draw < 500:
return
lines = [
"=== ROBOT NHI QUAI V6 (Python) ===",
f"EQUITY: {equity:.2f} | FullHed: {hed}",
f"CUM BUY | Float: {b_float:.2f} | P0: {p0_b:.2f}",
f" > Buy: {b_bv:.2f} | Sell: {b_sv:.2f} | BIAS: {b_bv - b_sv:.2f}",
f"BIAS TONG SYMBOL: {tot_b - tot_s:.2f} Lot",
]
log.info("n".join(lines))
Quant engineer cần metric quan sát được trước khi tin bot chạy 24/7: equity, bias từng cụm, trạng thái Full Hedge. Buổi 11 sẽ nâng lên dashboard Pandas + backtest report (MDD, cost).
10. Ba kịch bản kiểm thử Buổi 1
Chạy trên tài khoản demo, symbol cố định (vd. BTCUSD), log level INFO.
Kịch bản A — Cold start (happy path)
- Xóa file
bot_nhi_quai_v6_pro.gv.json python bot_nhi_quai_v6_pro.py --symbol BTCUSD- Kỳ vọng: log
Init OK, dashboard in equity, file GV có key_P0cho 6111 và 6112 - Không kỳ vọng: lợi nhuận — chỉ xác nhận lifecycle
Kịch bản B — Restart giữa chừng
- Bot đang chạy, có ít nhất 1 position
- Ctrl+C → chạy lại cùng symbol/account
- Kỳ vọng:
sync_traversed()khôi phục MinStep/MaxStep; không reset P0 nếu còn lệnh - Red flag: P0 = 0 hoặc mở trùng S0
Kịch bản C — Spread guard
- Set
max_spreadrất thấp (vd.0.01) trong Config test - Kỳ vọng:
on_tickreturn sớm, không gọiprocess_cluster - Ý nghĩa: Infrastructure layer chặn trade khi điều kiện thị trường xấu
11. Checklist deliverable Buổi 1
Sinh viên hoàn thành Buổi 1 khi:
- [ ] Vẽ được sơ đồ 4 phần và chỉ ra method tương ứng trong code
- [ ] Giải thích thứ tự
handle_lockdown→tp_logic→process_clustertrongon_tick - [ ] Đọc được file
.gv.jsonvà giải thích ý nghĩa key_P0,_LastStep - [ ] Chạy demo cold start + restart, ghi log quan sát dashboard
- [ ] Phân biệt được Config (input) vs GVStore (state runtime) vs cache RAM (
buy_cache) - [ ] Nêu được vì sao bot là hệ thống quant, không phải script signal
12. FAQ Buổi 1
PyNhiQuaiBot khác gì bot BUY/SELL đơn giản?
Bot quản lý cụm vị thế theo Step, có state persist, guard equity và FSM — không chỉ một lệnh một tín hiệu.
Buổi 1 có cần hiểu hết process_cluster?
Không. Buổi 1 chỉ cần biết đó là Grid Logic, được gọi sau lockdown/TP. Buổi 5–6 sẽ đi sâu Step, Surplus/Hedge.
GVStore JSON có thay được SQLite?
Có — Buổi 2 mở rộng schema. JSON đủ cho lab và port từ GlobalVariable MQ5.
QuantTrade và PyNhiQuaiBot có phải hai khóa?
Không. Cùng một khóa: PyNhiQuaiBot = dự án code; QuantTrade = góc PR Master Quantitative Trading.
Còn bao nhiêu ngày đến khai giảng?
KG 01/08/2026 — 12 buổi chính + 8 bài tập + 5 phụ đạo. FAQ: Lộ trình 12 buổi.
Có cam kết lợi nhuận không?
Không. Mọi ví dụ là tài liệu kỹ thuật; rủi ro thị trường vẫn tồn tại dù code đúng.
13. Buổi tiếp theo và liên kết nội bộ
| Buổi | Chủ đề | Bài đọc thêm |
|---|---|---|
| Buổi 2 | Global State, Pandas, schema | Global State Pandas bot |
| Buổi 4 | Magic 6111/6112, Comment, ID | Kiến trúc hai cụm |
| Buổi 5 | Step & X-Level | Toán Step X-Level |
| Buổi 8 | FSM STEP_BUSY 5s | FSM chống nhồi lệnh |
Tóm tắt Buổi 1: PyNhiQuaiBot không phải một vòng while nhồi lệnh — nó là bốn lớp (Infrastructure · Grid · Brain · UX) orchestrated bởi on_tick, với Config tách input, GVStore persist state, và execution adapter tách khỏi chiến thuật. Master Quantitative Trading bắt đầu từ chỗ đó: đo và kiểm soát rủi ro bằng cấu trúc code, không bằng lời hứa lợi nhuận.
Khóa học: Lập trình Python nâng cao Hedging tự động hóa · PyNhiQuaiBot · QuantTrade · KG 01/08/2026 · Hotline 0934 145 100
Khóa PyNhiQuaiBot · QuantTrade · Master Quantitative Trading: Lập trình Python Nâng cao Hedging & Tự động hóa
Weekly Digest — Nhận Bản Tin Hàng Tuần
Nhận các bài viết phân tích kỹ thuật chuyên sâu, thuật toán giao dịch tự động (Trading Bot) và các giải pháp công nghệ mới nhất từ Hướng Nghiệp Dữ Liệu.
admin
Biên tập viên, Hướng Nghiệp Dữ LiệuBiên tập viên nội dung tại Hướng Nghiệp Dữ Liệu, phụ trách tổng hợp và biên soạn các bài viết về lập trình Python, dữ liệu và công nghệ.