Mục lục
Nội dung này phục vụ mục đích giáo dục, không phải lời khuyên đầu tư hoặc tín hiệu giao dịch. Mô hình P25 dùng risk unit giả lập, không phải gợi ý khối lượng hoặc tỷ lệ vốn.
Trả lời ngắn: Portfolio EA là lớp điều phối nhận intent từ nhiều chiến lược hoặc nhiều symbol, chuẩn hóa chúng về cùng đơn vị rủi ro, rồi cấp phát hoặc từ chối theo giới hạn chung của account. Nó không đơn giản là bật nhiều EA; điểm cốt lõi là một risk authority nhìn được toàn bộ exposure, margin và trạng thái.
Đọc xong, bạn sẽ hiểu:
- Portfolio EA khác nhiều robot chạy cạnh nhau ở đâu.
- Cách sleeve cap, cluster cap và account cap phối hợp.
- Vì sao sổ ownership nội bộ phải reconcile với position thật của broker.
1. Portfolio EA là gì, và không phải “nhiều EA cùng chạy”?
Mở ba chart rồi gắn ba EA chỉ tạo ra ba chương trình cùng dùng một account. Mỗi EA có thể thấy signal của mình, nhưng không chắc nó biết hai EA còn lại đang xin bao nhiêu margin, đang tạo exposure cùng chiều hay vừa bật kill switch.
Portfolio EA thêm một lớp điều phối chung. Mỗi strategy sleeve — một chiến lược có ID, logic và quota riêng — gửi đề nghị. Một risk authority duy nhất quyết định đề nghị nào được cấp bao nhiêu risk, đề nghị nào phải chờ và đề nghị nào bị từ chối.
Hãy hình dung dàn nhạc. Violin, trống và kèn đều có bản nhạc riêng. Nếu mỗi nhạc công tự tăng âm lượng vì “đoạn của tôi quan trọng”, cả bài thành ồn. Nhạc trưởng không chơi thay từng người; nhạc trưởng giữ tempo, tổng âm lượng và thời điểm vào.
Portfolio EA cũng không nhất thiết là một file khổng lồ. Nó có thể là một EA trung tâm, nhiều module trong một process, hoặc nhiều strategy adapter nói chuyện qua một risk service. Kiến trúc nào cũng được, miễn ownership rõ:
- Strategy sleeve sở hữu logic tạo signal và mô tả rủi ro dự kiến.
- Portfolio layer sở hữu allocation, xung đột và global gate.
- Execution layer sở hữu side effect giao dịch.
- Reconciliation layer chứng minh internal ledger khớp account.
Hình 1 — Strategy gửi intent; Portfolio EA mới có quyền cấp risk và route execution.
Nhiều EA ≠ portfolio. Nếu không có exposure map, account cap và global kill switch, ta chỉ có nhiều nguồn side effect hơn.
2. Bản đồ ba tầng: strategy sleeve, portfolio và account
a. Tầng strategy sleeve
Sleeve nhận market data và tạo intent. Intent là đề nghị, chưa phải order. Nó nên mang đủ:
strategy_id,intent_id, symbol và direction.- Thời điểm tạo, thời hạn hiệu lực.
- Entry logic, invalidation/stop logic.
- Requested risk theo đơn vị chuẩn.
- Lý do, model/config version.
Sleeve không được tự lấy “lot quen tay” rồi gửi order. Nó không nhìn đủ account để biết lot đó còn hợp lệ không.
b. Tầng portfolio
Portfolio đổi mỗi request sang risk unit U — đơn vị giả lập giúp so nhiều instrument. U không phải tiền, không phải phần trăm chuẩn và không phải lời khuyên sizing.
Sau đó nó tạo exposure map: ảnh chụp risk đã cấp và đang mở, nhóm theo sleeve, symbol, direction, currency/driver và account.
Một cluster là nhóm có thể cùng chịu một driver. Ví dụ trong P25, Trend EURUSD A và Breakout GBPUSD B cùng nằm trong USD_DIRECTIONAL. Không cần tuyên bố hệ số correlation cố định; contract chỉ nói hai sleeve chia sẻ exposure USD và phải dùng chung cluster cap.
Portfolio layer chịu trách nhiệm:
- Chuẩn hóa đơn vị.
- Loại intent stale/duplicate.
- Áp sleeve cap.
- Cập nhật cluster exposure.
- Áp cluster cap.
- Áp account cap và reserve.
- Kiểm margin/account state.
- Resolve conflict.
- Cấp allocation và reason code.
- Route request idempotent.
c. Tầng account
Account là sự thật bên ngoài: balance, equity, margin, free margin, margin level, position, order và deal. MQL5 cung cấp AccountInfoDouble() để đọc các thuộc tính cấp account như balance, equity, margin, free margin và margin level (MQL5 Reference — AccountInfoDouble).
Ba tầng không thay nhau. Sleeve không được tự quyết account risk. Portfolio ledger không được giả vờ là broker state. Account state cũng không tự nói position thuộc sleeve nào.
Hình 2 — Mỗi tầng sở hữu quyết định khác nhau; không sleeve nào tự sở hữu toàn account.
Giống ba phòng trong công ty: bộ phận bán hàng đề xuất đơn, tài chính cấp hạn mức, kho xác nhận hàng thực. Một bảng Excel đẹp ở phòng bán hàng không thay được kiểm kho.
3. Luồng hoạt động và ledger P25
Contract giả lập P25:ALLOC:V1 có tổng budget 1.00 U, nhưng account cap chỉ cho phép allocate tối đa 0.80 U. Phần reserve 0.20 U được cố tình để trống; strategy không được tự dùng.
Ba sleeve có quota:
- A — Trend EURUSD: sleeve cap
0.35 U. - B — Breakout GBPUSD: sleeve cap
0.25 U. - C — Mean-reversion XAUUSD: sleeve cap
0.20 U.
A và B thuộc cluster USD_DIRECTIONAL, cap 0.60 U. Một sleeve D — Index Momentum — có thể gửi intent, nhưng không có quota đảm bảo nếu account cap đã đầy.
Allocation order của P25:
MARKET SNAPSHOT → INTENTS → NORMALIZE U → EXPOSURE MAP → SLEEVE CAP → CLUSTER CAP → ACCOUNT CAP → ROUTE → RECONCILE
Đây là policy riêng của P25, không phải thứ tự duy nhất cho mọi hệ thống.
a. Request A
A xin 0.40 U. Sleeve cap là 0.35 U, nên portfolio clip xuống 0.35 U và trả:
ACCEPT · FINAL 0.35 U · REASON CLIP_SLEEVE
b. Request B
B xin 0.30 U, bị clip xuống 0.25 U. A+B lúc này là:
0.35 + 0.25 = 0.60 U
Cluster USD_DIRECTIONAL vừa chạm cap, không vượt. B được accept 0.25 U.
c. Request C
C xin 0.25 U, bị clip xuống 0.20 U. Tổng account allocation:
0.35 + 0.25 + 0.20 = 0.80 U
Account cap đã đầy. Reserve 0.20 U vẫn khóa, không biến thành “tiền dư cho strategy”.
d. Request D đến muộn
D xin 0.10 U. Mỗi request nhìn riêng có vẻ nhỏ, nhưng account remaining theo cap là:
0.80 - 0.80 = 0
D bị từ chối:
REJECT · FINAL 0 · REASON ACCOUNT_CAP
| Sleeve | Request | Sleeve cap | Final allocation | Reason |
|---|---|---|---|---|
| A Trend EURUSD | 0.40 U | 0.35 U | 0.35 U | CLIP_SLEEVE |
| B Breakout GBPUSD | 0.30 U | 0.25 U | 0.25 U | CLIP_SLEEVE |
| C MeanRev XAUUSD | 0.25 U | 0.20 U | 0.20 U | CLIP_SLEEVE |
| D Index Momentum | 0.10 U | 0.10 U | 0 | REJECT_ACCOUNT_CAP |
Hình 3 — P25 dùng hết account cap 0.80 U nên request D bị reject, reserve 0.20 U vẫn khóa.
P25 chắc chắn reject D dưới contract đã freeze. Nếu cluster phản ánh đúng shared exposure, cap có thể giảm concentration. Hai câu này không có nghĩa P25 tạo lợi nhuận hoặc 0.80 U phù hợp với account thật.
Luồng execution còn phải trả về server result. OnTradeTransaction() có thể nhận các trade transaction liên quan request và execution result; Portfolio EA cần nối chúng về intent_id/allocation_id để reconcile (MQL5 Reference — OnTradeTransaction).
4. Xung đột, netting, hedging và giới hạn
a. Xung đột cùng symbol
Giả sử sleeve A muốn BUY EURUSD còn sleeve E muốn SELL EURUSD. Có bốn policy:
- Net intent trước khi route.
- Chỉ cho strategy ưu tiên cao hơn.
- Cho cả hai nhưng giữ attribution riêng nếu account mode cho phép.
- Reject cả hai khi conflict chưa resolve.
Không policy nào tự động đúng. Contract phải nói rõ để kết quả có thể tái lập.
b. Exposure khác symbol nhưng cùng driver
EURUSD và GBPUSD khác symbol, song cả hai intent cùng chiều có thể tạo cùng exposure USD. Chỉ cap theo symbol sẽ bỏ sót cluster risk. Ngược lại, nhét mọi FX vào một cluster cũng quá thô.
Correlation là ước lượng từ sample và có thể đổi theo regime. Portfolio layer nên lưu nguồn, window và version của cluster map, thay vì gọi nó là chân lý vĩnh viễn.
c. Netting và hedging
Trong account netting, tại một thời điểm chỉ có một position cho mỗi symbol. Nhiều deal từ A/E có thể hợp thành position account duy nhất. Trong account hedging, nhiều position trên cùng symbol có thể cùng tồn tại. Tài liệu PositionGetSymbol() nêu rõ khác biệt này khi duyệt position (MQL5 Reference — PositionGetSymbol).
Broker position không phải strategy ownership. Dù account netting hay hedging, Portfolio EA cần attribution ledger riêng:
| Account state | Internal ownership |
|---|---|
| EURUSD net +0.30 | A +0.50, E -0.20 |
| One realized deal | Allocation IDs contributing |
| One commission row | Rule phân bổ về sleeves |
Nếu chỉ nhìn broker position +0.30 rồi gán hết cho A, P/L và risk của E sẽ biến mất khỏi sổ.
Hình 4 — Broker position và strategy ownership là hai sổ khác nhau cần reconcile.
d. Sai lầm thường gặp
- Cộng lot từ các backtest độc lập. Lot không phải đơn vị rủi ro chung.
- Cộng đường equity đẹp nhưng không đồng bộ timestamp, cost và account rule.
- Dùng exposure snapshot stale trong lúc request đồng thời.
- Mỗi EA có kill switch riêng nhưng không có global halt.
- Double-count position đang pending và position đã fill.
- Không reserve margin cho request đã gửi chưa có result.
- Retry request không idempotent, tạo duplicate order.
- Không reconcile sau restart/disconnect.
- Gắn nhãn “diversified” chỉ vì có ba symbol.
- Cho strategy tự đổi quota sau khi bị reject.
e. Giới hạn
- Multi-currency backtest không tự chứng minh dữ liệu mọi symbol đồng bộ và đủ chất lượng.
- Cluster map có thể sai hoặc cũ.
- Account margin model và symbol specification có thể khác môi trường test.
- Central coordinator là single point of control; nếu recovery kém, nó cũng là single point of failure.
- Diversification giảm một số concentration nhưng không loại bỏ mất vốn.
MetaTrader 5 Strategy Tester hỗ trợ multi-currency EA và tự xử lý dữ liệu symbol được gọi; tài liệu cũng yêu cầu chú ý việc enable/download dữ liệu cần thiết (MetaTrader 5 Help — Strategy Testing). “Tester chạy được” vẫn chưa chứng minh Portfolio EA reconcile đúng.
5. Checklist kiến trúc fail-closed
Identity và data
- Canonical
strategy_id,intent_id,allocation_id,request_id. - EA/config/model/cluster-map version.
- Cùng clock, timezone và stale threshold.
- Market snapshot version dùng cho decision.
Risk contract
- Một risk unit và conversion rule duy nhất.
- Sleeve cap, symbol cap, direction cap, cluster cap.
- Account cap, reserve và daily loss gate.
- Margin/free-margin precheck từ account state mới.
- Policy netting/conflict/priority được freeze.
Execution
- Intent không có quyền side effect.
- Allocation có expiry và quantity cuối.
- Request idempotent; retry dùng cùng key.
- Pending/in-flight exposure được reserve.
- Known result code map tới state/action.
- Unknown result mặc định halt.
Reconciliation và recovery
- Reconcile internal ledger với positions/orders/deals.
- Rebuild state sau restart trước khi nhận intent mới.
- Global kill switch chặn toàn bộ route.
- Audit log append-only cho decision/reason.
- Daily review cluster, cap breach và orphan state.
Hình 5 — Global controls đứng sau mọi sleeve và trước mọi side effect giao dịch.
Đứng ngoài nếu chưa chuẩn hóa risk, chưa biết account mode hoặc không thể map position về sleeve.
Dừng ngay khi exposure snapshot stale, account state lệch ledger, cap bị vượt, margin check không xác định, duplicate request hoặc unknown result xuất hiện. Fail-closed nghĩa là risk authority không chắc thì allocation bằng 0.
Nếu tôi cộng thẳng lot của ba EA độc lập, tôi đã double-count account capacity và bỏ qua cluster.
6. Bắt đầu từ đâu: Portfolio Allocation Sheet 15 phút
Dùng Google Sheets hoặc LibreOffice Calc miễn phí. Bài tập hoàn toàn offline, không kết nối broker và không dùng tiền thật.
Phút 0–4: dựng contract
Ghi:
- Total budget
1.00 U - Account cap
0.80 U - Reserve
0.20 U - Cluster
USD_DIRECTIONALcap0.60 U - Sleeve caps A
0.35, B0.25, C0.20, D0.10
Phút 4–9: nhập requests
Nhập A 0.40, B 0.30, C 0.25, D 0.10. Cột After sleeve cap:
=MIN(Request, SleeveCap)
A/B/C lần lượt thành 0.35, 0.25, 0.20. Trước D, account allocated đã là 0.80.
Mẫu đối chiếu đã điền
| Sleeve | Request | After sleeve cap | Final | Reason |
|---|---|---|---|---|
| A | 0.40 U | 0.35 U | 0.35 U | CLIP_SLEEVE |
| B | 0.30 U | 0.25 U | 0.25 U | CLIP_SLEEVE |
| C | 0.25 U | 0.20 U | 0.20 U | CLIP_SLEEVE |
| D | 0.10 U | 0.10 U | 0 | REJECT_ACCOUNT_CAP |
Phút 9–13: kiểm totals
- A+B cluster:
0.35 + 0.25 = 0.60 U— đúng cap. - Account:
0.35 + 0.25 + 0.20 = 0.80 U— đúng cap. - Reserve:
1.00 - 0.80 = 0.20 U— vẫn khóa. - Remaining tradable capacity:
0.
Phút 13–15: thử một lỗi
Đổi formula để D được 0.10. Account allocation thành 0.90 U, vượt cap. Sheet phải báo HALT. Sau đó undo. Mục tiêu là thấy global gate chặn được local request hợp lệ.
Không chuyển U thành lot thật. Bài tập chỉ kiểm logic allocation.
7. Tổng kết và lộ trình Phase 5
a. Năm ý chính
- Portfolio EA là risk authority, không phải danh sách nhiều robot.
- Strategy sleeve gửi intent; portfolio mới allocation và route.
- Sleeve, cluster, account cap giải quyết ba phạm vi khác nhau.
- Broker position và internal attribution là hai sổ phải reconcile.
- Global kill switch và account truth đứng trên mọi strategy.
b. Câu hỏi tự kiểm tra
- Vì sao ba EA chạy cạnh nhau chưa thành Portfolio EA?
- A+B trong P25 chạm cluster cap bao nhiêu?
- Vì sao D bị reject dù chỉ xin 0.10 U?
- Netting account cần attribution ledger để làm gì?
c. Gợi ý đáp án
Xem gợi ý câu 1
Vì chưa có một risk authority nhìn shared exposure, cap và account state. Xem mục 1.
Xem gợi ý câu 2
A 0.35 + B 0.25 = 0.60 U, đúng cluster cap. Xem mục 3.
Xem gợi ý câu 3
Account cap 0.80 U đã dùng hết; reserve 0.20 U không được tự cấp. Xem mục 3.
Xem gợi ý câu 4
Broker có thể chỉ có một position tổng; ledger giữ ownership/risk/P&L của từng sleeve. Xem mục 4.
d. Thuật ngữ cần nhớ
| Thuật ngữ | Giải thích ngắn |
|---|---|
| Portfolio EA | Lớp điều phối nhiều strategy dưới shared account gates. |
| Strategy sleeve | Strategy unit có ID, logic và quota riêng. |
| Risk authority | Thành phần có quyền cấp hoặc từ chối allocation. |
| Risk unit U | Đơn vị giả lập để chuẩn hóa request. |
| Exposure map | Snapshot risk theo symbol, direction và cluster. |
| Cluster | Nhóm cùng chịu một driver rủi ro. |
| Allocation | Risk được duyệt sau mọi cap. |
| Netting / Hedging | Một position tổng hoặc nhiều position cùng symbol. |
| Attribution | Gắn account state về đúng sleeve. |
| Reconciliation | So internal ledger với broker/account state. |
e. Nguồn tham khảo
- MetaTrader 5 Help — Strategy Testing
- MetaTrader 5 Help — Testing Features
- MQL5 Reference — AccountInfoDouble
- MQL5 Reference — Account Properties
- MQL5 Reference — PositionGetSymbol
- MQL5 Reference — OnTradeTransaction
Live Validation #24 kiểm một pipeline trên feed thời gian thực. Portfolio EA #25 mở rộng quyền kiểm soát lên nhiều sleeve và shared account. Bài tiếp theo, VPS Deployment cho EA #26, đưa control plane ấy sang môi trường chạy liên tục nhưng vẫn giữ fail-closed.
Nội dung này phục vụ mục đích giáo dục, không phải lời khuyên đầu tư hoặc tín hiệu giao dịch. Portfolio coordination không loại bỏ rủi ro mất vốn.
Bài tiếp theo