StackTrading Docs

MT5 Plugin — Business Logic Reference

FieldValue
Date Created2026-09-15
AuthorAntigravity (BA QC Agent)
Versionv1.5
ScopeSIM + LIVE — Forex MT5 only

Mục đích: Tổng hợp toàn bộ nghiệp vụ liên quan đến C++ MT5 Plugin (Sotatek-built) từ các UC đã viết. Đây là reference doc nội bộ — không phải SRS mới. Mọi rule ở đây đều có nguồn gốc từ SRS/BR đã được confirm; các link trỏ về file gốc để truy nguyên.


1. Định Danh Plugin

Thuộc tínhGiá trị
Tên chính thứcC++ MT5 Plugin (Sotatek-built)
Bên xây dựngSotatek
LoạiC++ plugin cài server-side trên MT5 White Label server tại Equinix NY4
Tên cũ (đã deprecated)YourBourse Contest Stop Out Plugin —không còn dùng
Nguồn xác nhậnQnA STAGE2-019 ★★★ (Adrian Stack, 2026-07-20) — overrides RFQ V7 §2.2
ScopeÁp dụng chotất cả Forex MT5 sub-accounts (SIM + LIVE)

⚠️ Phân biệt YourBourse Bridge và MT5 Plugin:

  • YourBourse FIX Bridge = order-routing engine (Abri Van Rooyen) — MT5/TE ↔ Liquidity Providers (Forex.com / IBKR). Vẫn còn dùng.
  • C++ MT5 Plugin (Sotatek) = stop-out / flatten mechanism. Thay thế Contest Stop Out Plugin.

Hai component này hoàn toàn tách biệt nhau. Không được nhầm lẫn.


2. Hai Cơ Chế MT5 — Phân Biệt Rõ

MT5 có hai cơ chế riêng biệt, không thể thay thế cho nhau:

Cơ chếAPI / ComponentTác dụng
Lock (Disable/Read-Only)MT5 Manager API'Disable/Read-Only'Chặn order mới.
FlattenC++ MT5 Plugin (Sotatek-built)Force-close toàn bộ open positions. Có configurable failsafes cho forceful liquidation.

Khi một UC cần cả Lock lẫn Flatten, phải gọi cả 2 — Lock trước, Flatten sau.


3. Risk Rule Contexts — Plugin Được Gọi Ở Đâu

3.1 Soft Breach — Daily Loss Limit (SIM & LIVE)

Source UC: UC_4.10.1 BR_4.10.1.4 · UC_4.15.1

Trigger: Net_P&L <= −Daily_Loss_Limit — gateway evaluate natively (không qua middleware).

Formula:

Absolute_Stop_Loss = Notional × SIM_stop_percent     (default 7.5%, Table C — configurable)
Daily_Loss_Limit   = Absolute_Stop_Loss × Daily_Loss_Ratio  (Daily_Loss_Ratio = 0.334, Table C)

Parameters:

ParameterValueSource
Notional$25,000 / $50,000 / $150,000 (Level 1 / 2 / 5)Table A (Forex) / Table B (Futures)
SIM_stop_percent7.5% (default, configurable via Table C)Table C — [CHR-49]
Daily_Loss_Ratio0.334Table C

Worked example — Level 1, $25,000:

Absolute_Stop_Loss = $25,000 × 7.5% = $1,875
Daily_Loss_Limit   = $1,875 × 0.334 = $626.25
→ Breach fires when Net_P&L <= −$626.25

MT5 action — Forex (SIM và LIVE):

  • Lock account (chặn order mới)

- Flatten toàn bộ open positions, cancel open orders

Khi nào unlock: Tự động tại reset_time cố định (Forex: 16:00 CT / 17:00 ET, Monday–Friday). Không cần gọi plugin thêm.

⚠️ Note — giờ mùa đông/mùa hè (DST): reset_time là một wall-clock anchor theo America/New_York (17:00 giờ địa phương New York), không phải một giờ UTC cố định. Backend dùng timezone-aware library (Intl/date-fns-tz/luxon) resolve theo zone America/New_York — zone này tự encode lịch chuyển EST ⇄ EDT, nên giờ UTC thực tế đổi 2 lần/năm: 21:00 UTC khi đang EDT (giờ mùa hè), 22:00 UTC khi đang EST (giờ mùa đông). Không hardcode offset UTC, không tự maintain bảng ngày chuyển DST ở đâu cả (Ref: BR_4.1.3.5).

Đặc điểm nghiệp vụ quan trọng:

  • Account Status không thay đổi — vẫn Active_SIM / Active_DMA.
  • POST /fail-challenge không được gọi.
  • Là soft pause — không terminate account.
  • Hard Breach supersedes Soft Breach nếu cả hai xảy ra đồng thời

3.2 Hard Breach — Level Stop / Kill Switch (SIM)

Source UC: UC_4.10.2 §5.1 Broker-Side Processing Flow

Trigger: Net_P&L <= −Absolute_Stop_Loss (broker-native detection) hoặc Stack Trading self-trigger (resignation / stagnation)

Formula (Max Drawdown / Absolute Stop Loss):

Absolute_Stop_Loss = Notional × SIM_stop_percent  (default 7.5%, Table C — configurable)

Parameters:

ParameterValueSource
Notional$25,000 / $50,000 / $150,000 (Level 1 / 2 / 5)Table A (Forex) / Table B (Futures)
SIM_stop_percent7.5% (default, configurable via Table C)Table C — [CHR-49]

Worked example — Level 1, $25,000:

Absolute_Stop_Loss = $25,000 × 7.5% = $1,875
→ Hard Breach fires when Net_P&L <= −$1,875

SIM_stop_percent dùng chung cho cả Hard Breach và Soft Breach (xem §3.1) — cùng 1 biến Table C. Net_P&L = Realized P&L + Unrealized P&L

3.2.1 Market Open — Hai Trigger Path, Cả Hai Đều Do Plugin Tự Care

Trigger PathĐiều gì xảy raPlugin phải làm gì
Entry point 1 — Hard Breach detect (Net_P&L <= −Absolute_Stop_Loss)Middleware liên tục monitorNet_P&L real-time từ execution-gateway stream (ACCOUNT_METRICS); khi breach, middleware detect trước (không phải MT5 tự phát hiện) rồi ra lệnh cho plugin xử lý phía trading account.Plugin nhận lệnh từ middleware → Flatten toàn bộ open positions → Cancel toàn bộ working orders → sau khi 2 bước này confirm xong, set account state (xem bên dưới).
Entry point 2/3 — Stack Trading self-trigger (POST /resign tự nguyện resign, hoặc Flow 19 phát hiện stagnation/hết time-limit)Không có breach thị trường nào xảy ra — chính middleware chủ động quyết định đóng account (do trader bấm resign, hoặc do hết thời hạn challenge). Middleware gọi plugin để thực thi.Plugin nhận lệnh từ middleware → Flatten toàn bộ open positions → Cancel toàn bộ working orders → sau khi 2 bước này confirm xong, set account state (xem bên dưới).

⚠️ Với Rithmic/TraderEvolution để đối chiếu (không phải nghiệp vụ MT5, chỉ để hiểu vì sao MT5 khác):

  • Rithmic (Entry 1): Broker's own native risk rule tự detect và tự handle Lock/Flatten/Cancel — Stack Trading không cần gọi API nào.
  • TraderEvolution (Entry 2/3): Middleware chỉ cần set MaxDrawDown Level = 999,999,999 — TE's risk engine tự đọc field này và tự flatten, Stack Trading không tự code phần flatten.
  • MT5 (cả Entry 1 và 2/3): Không có field kiểu MaxDrawDown nào để "set rồi broker tự lo". Toàn bộ Lock + Flatten + Cancel ở cả 2 path đều nằm trong code của C++ Plugin (Sotatek build) — nếu plugin có bug, đây là defect cần fix, không phải architectural gap (Ref: QnA STAGE2-019 ★★★).

Post-flatten — account phải ở trạng thái login-but-no-trade:

Về mặt business framing, thứ tự giống Soft Breach ở §3.1 — cùng là "Lock → Flatten → Cancel" (UC_4.10.1 nói rõ Soft Breach dùng "same account-first ordering as Hard Breach's Atomic Kill Switch"; UC_4.10.2 §5 Step 3 sub-step 4 cũng label chung là "Lock → Flatten → Cancel"). Không phải 2 cơ chế dùng 2 thứ tự khác nhau.

Riêng phần micro-timing của MT5 (chi tiết implementation, không phải khác thứ tự nghiệp vụ): theo UC_4.10.2 §5.1.1, account chỉ được xác nhận chính thức ở trạng thái login-but-no-trade sau khi plugin confirm Flatten + Cancel đã hoàn tất — đây là cách MT5 "hiện thực hóa" bước Lock (khác Rithmic/TE vốn có thể set Lock ngay tức thì qua API/native engine). Với MT5, trạng thái này là TRADE_DISABLED. Áp dụng cho cả 2 trigger path (Entry point 1 và Entry point 2/3).

Account stateLoginTradeKhi nào set
TRADE_DISABLEDĐượcKhông đượcNgay sau khi plugin Flatten + Cancel xong (cả Entry point 1 và Entry point 2/3)

3.2.2 Market Closed — Chỉ Xảy Ra Với Entry Point 2/3 (Self-Trigger)

Bối cảnh: Entry point 1 (Hard Breach detect qua Net_P&L <= −Absolute_Stop_Loss) không thể xảy ra khi market đóng — vì không có active price feed để tính P&L, nên không có gì để breach. Case market-closed chỉ có thể đến từ Entry point 2/3 (resignation hoặc stagnation/time-limit expiry), vì đây là quyết định của Stack Trading chứ không phụ thuộc giá thị trường.

Trình tự xử lý:

  1. Trigger broker-side stop giống hệt nhánh self/system-trigger ở §3.2.1 — middleware ra lệnh, plugin nhận và xử lý.
  2. Set TRADE_DISABLED ngay lập tức — bước này KHÔNG đợi market mở lại (khác với case market-open ở §3.2.1, nơi việc set state chờ Flatten+Cancel confirm xong). Trader vẫn login được nhưng không trade được ngay từ lúc này.
  3. Flatten bị defer đến khi market re-open — vì lúc market đóng không có ai khớp lệnh close được. Ngay khi market mở lại, phần Flatten (đóng hết open positions) mới thực thi.
  4. Đây là phần plugin cần tự handle edge case: plugin phải tự theo dõi market status và tự kích hoạt Flatten ngay khi market mở lại, không cần middleware gọi lại lần 2 — nếu chưa handle được case này, cần confirm với Sotatek.

(Source: UC_4.10.2 §5.1.1 — §5.1.2)


3.3 Hard Breach — Archive & Reset Flow (SIM)

Source UC: UC_4.10.2 §5.2 Archive Flow · UC_4.10.2 §5.3 Reset Flow

Archive Flow (§5.2) — Chỉ M2, không có M1

Với MT5, archive_date chỉ tính theo một mốc duy nhất — Discount Window Expiry:

archive_date (MT5) = failure_timestamp + users.post_failure_retention_days

(users.post_failure_retention_days — frozen per-user copy của Table C Post_Failure_Retention_Days, default 10 ngày.)

Khi archive_date đến mà trader chưa reset:

  • Pre-Archive Gate chạy trước: sync PostgreSQL write + async S3 Glacier write (WORM-lock).
  • MT5 Failsafe action: hard-delete locked sub-account.

Reset Flow (§5.3) — Case A: Reset Trước archive_date

BrokerProvisioning action
MT5Delete failed sub-account → Provision brand-new sub-account
RithmicUnassign → Provision new + handle Market Data (xem §5.3)
TraderEvolutionChange statusCLOSED → Provision new

MT5 không có Market Data handling (Rithmic-specific). MT5 sub-account đơn giản bị delete và provision mới hoàn toàn.

Reset Flow (§5.3) — Case B: Reset Sau archive_date (Failsafe already fired)

MT5 sub-account đã bị hard-delete bởi Failsafe. Reset chỉ cần:

  • Provision brand-new sub-account (old sub-account không còn tồn tại).

3.4 Overnight Margin Enforcement — Forex 25% Cap (LIVE)

Source UC: UC_6.1.2 BR_6.1.2.1 · UC_6.1.2 BR_6.1.2.5 · UC_6.1.2 §5 Step 1 · UC_6.1.2 §5 Step 7

T-3min — Pre-Close Lockout (order filter, chạy trước T-2min margin check)

Trigger: Tại đúng Official_Close_UTC − 3min cho asset class đang closing (Ref: BR_6.1.2.1).

Hành vi:

  • Order-routing layer (UC_6.1.2 gọi là "API gateway" — đối với Forex MT5, đây chính là MT5 Gateway API liệt kê ở Overview, không phải MT5 native order routing) kích hoạt state Pre_Close_Lockout cho các symbol thuộc asset class đó.
  • Chặn: mọi order mới mở position, hoặc order làm tăng net directional exposure của position đang mở.
  • Vẫn cho phép: order closing/reducing/flattening — giảm size, partial fill, hoặc đóng hoàn toàn position.
  • Filter này tự giải phóng tại Session_Open_UTC (BR_6.1.2.6).

⚠️ Không gọi C++ MT5 Plugin, không gọi MT5 Manager API Disable/Read-Only. Đây là filter theo loại order + symbol (chỉ chặn new/increasing trên symbol đang closing), khác hoàn toàn với 2 cơ chế MT5 ở §2:

  • Không phải "Lock toàn account" như Soft Breach (§3.1) — account vẫn trade được bình thường trên symbol khác/asset class khác.
  • Không phải "Flatten" — không force-close gì cả, position đang mở tiếp tục roll qua đêm nếu pass được margin check ở T-2min tiếp theo.

T-2min — Forex 25% Notional Cap check (sau khi Pre-Close Lockout đã active)

Trigger: Tại Official_Close_UTC − 2min, sau khi Universal Drawdown Safety Gate pass:

Allowed_Notional = Total_Account_Equity × Table_C_Cap_Percent (25%)

Nếu Current_Forex_Notional > Allowed_Notional:

⚠️ CHR-102 (client-confirmed 2026-09-15) — MT5 path đổi hoàn toàn, không còn dùng leverage reduction:

  • MT5 và TraderEvolution xử lý giống nhau, không phân biệt: middleware dispatch unconditionally đến UC_6.1.3 — TRIM_TO_COMPLIANCE với Target_Limit = Allowed_Notional.
  • Node.js middleware tự tính overage và dispatch market close orders trực tiếp qua MT5 Gateway API (route mới, không qua C++ Plugin) — cùng algorithmic TRIM_TO_COMPLIANCE loop (T-120s Primary Loop) dùng cho Futures/Rithmic.
  • Không còn native-capability check nào chạy trước trên bất kỳ platform nào — nhánh cũ "MT5: Plugin reduce leverage limit → native Stop Out engine tự clear" (invoke C++ MT5 Plugin) đã bị remove hoàn toàn, cùng với nhánh cũ của TraderEvolution ("check native group leverage reduction trước, chỉ dispatch nếu unavailable").

So sánh MT5 vs TraderEvolution (sau CHR-102):

BrokerXử lý Forex shortfall
MT5Dispatch unconditionally đến UC_6.1.3TRIM_TO_COMPLIANCE, qua MT5 Gateway API trực tiếp.
TraderEvolutionDispatch unconditionally đến UC_6.1.3TRIM_TO_COMPLIANCE, qua TraderEvolution Admin API trực tiếp.

⚠️ C++ MT5 Plugin (Sotatek) không bị remove khỏi architecture — chỉ bị demote khỏi vai trò primary enforcement path cho riêng cơ chế 25% overnight notional cap này. Plugin vẫn còn tồn tại/dùng cho các context khác trong doc này (§3.1, §3.2, §3.5) và có thể vẫn đóng vai trò configurable forceful-liquidation failsafe khác (STAGE2-019) — không liên quan đến overnight cap nữa.

T-30sec Active Failsafe: Universal (Rithmic/MT5/TE) — Node.js middleware xử lý qua UC_6.1.3. Không có native broker failsafe riêng cho MT5 (Ref: BR_6.1.2.7). Áp dụng đồng nhất cho cả 3 platform kể từ CHR-102, vì MT5 Forex giờ cũng thực sự đi tới UC_6.1.3 (trước đây thì không).

(Source: CHR-102, client-confirmed 2026-09-15 — supersedes the earlier "MT5 leverage-reduction, no dispatch" description; UC_6.1.2 BR_6.1.2.5)


3.5 SIM Profit Target — Level Up Trigger

Source UC: UC_5.1 BR_5.1.7 · UC_5.1 §2 Trigger

Trigger: Net_Equity >= Target_Equity_Trigger — middleware detect qua state-change webhook PROFIT_TARGET_HIT.

Formula:

Profit_Target_PnL     = Starting_Capital × SIM_target_percent
Target_Equity_Trigger = Starting_Capital + Profit_Target_PnL

Parameters:

ParameterValueSource
Starting_Capital$25,000 / $50,000 / $150,000 (Level 1 / 2 / 5)Table A (Forex) / Table B (Futures)
SIM_target_percent14% (default, configurable via Table C)Table C — client confirmed 2026-08-24

Worked example — Level 1, $25,000:

Profit_Target_PnL     = $25,000 × 14% = $3,500
Target_Equity_Trigger = $25,000 + $3,500 = $28,500
→ Pass fires when Net_Equity >= $28,500

Khi Profit Target đạt — MT5 sequence:

  1. Plugin server-side detect Net_Equity >= Target_Equity_Trigger và tự fire profit-lock:
    • Cancel tất cả pending limit/stop orders
    • Flatten toàn bộ open positions (forced market close)
    • Verify loop: poll Open_Positions mỗi 500ms (max 10s) cho đến khi Open_Positions == 0
    • Set account sang Read-Only (READONLY) — trader vẫn login được vào account, nhưng không đặt order/trade được nữa, cho đến khi Level-Up provisioning xong và sub-account mới được cấp.
  2. Middleware detect state change → emit PROFIT_TARGET_HIT webhook → initiate Level-Up / Flow 3A.

⚠️ Note: BR_5.1.7 vẫn đang label component này là "YourBourse Contest Stop Out server-side plugin" — label cũ chưa được update theo STAGE2-019. Cần sửa trong lần review tới.


3.6 Live Account — Graduation (SIM → LIVE Cleanup)

Source UC: UC_5.1 §4 Post-conditions

Khi trader hoàn thành KYC và chuyển sang LIVE (Flow 3H), SIM sub-account cần cleanup:

BrokerCleanup action
RithmicUnassign SIM sub-account khỏi trader's Rithmic User ID
MT5Backup data → AWS S3 Glacier →Hard-delete SIM sub-account từ NY4 server
TraderEvolutionBackup data → AWS S3 Glacier → Hard-delete

Lý do hard-delete MT5 SIM: prevent data bloat trên Equinix NY4 server.


4. MT5 Account State Reference

StateÝ nghĩaSet bởi
TRADE_DISABLEDLogin được,không trade được (login-but-no-trade)Kill Switch — Hard Breach
Disable/Read-Only (via Manager API)Login được, không trade được — tạm thời, tự unlock tạireset_time. Đây là tên API call theo nguồn UC_4.10.1/UC_4.15.1; chưa có UC nào confirm bằng văn bản tên state enum cụ thể, nhưng nhiều khả năng cũng chính là TRADE_DISABLED (cùng bản chất login-but-no-trade, cùng thứ tự Lock→Flatten như Hard Breach — xem §3.1)Soft Breach
READONLYLogin được, không trade được — tạm thời, đến khi provision xong sub-account mớiProfit Target Level-Up
(Sub-account deleted)Không còn tồn tại trên serverArchive Failsafe / Graduation

5. Priority & Conflict Rules

RuleSource
Hard Breach > Universal Drawdown Safety Gate > Daily Loss Limit Soft BreachBR_6.1.2.3
Nếu Hard Breach và Drawdown Gate xảy ra đồng thời — chỉ Hard Breach's FLATTEN_ALL fires, Drawdown Gate không fire duplicateBR_4.10.1.5
MT5 Overnight shortfall → dispatch unconditionally đến UC_6.1.3TRIM_TO_COMPLIANCE qua MT5 Gateway API (CHR-102 — không còn Plugin leverage reduction)BR_6.1.2.5
Không có native broker failsafe cho MT5 ở overnight — chỉ Node.js T-30s universal failsafe (UC_6.1.3)BR_6.1.2.7
Plugin failsafe failure = defect to fix, không phải architectural gapQnA STAGE2-019 ★★★

6. Summary — Plugin Call Map

ScenarioLockFlatten / Leverage actionSource
Soft Breach (SIM)MT5 Manager APIDisable/Read-OnlyC++ MT5 Plugin → flatten all positionsUC_4.10.1 BR_4.10.1.4
Soft Breach (LIVE)MT5 Manager APIDisable/Read-OnlyC++ MT5 Plugin → flatten all positionsUC_4.15.1
Hard Breach — market open (Entry 1 hoặc 2/3)SetTRADE_DISABLED (cùng thứ tự Lock→Flatten→Cancel như Soft Breach; xác nhận chính thức sau khi plugin confirm Flatten+Cancel xong)Plugin (Sotatek) → flatten toàn bộ open positions → cancel toàn bộ working ordersUC_4.10.2 §5.1.1
Hard Breach — self-trigger, market closed (Entry 2/3 only)SetTRADE_DISABLED NGAY LẬP TỨC (không đợi flatten)Flatten deferred đến khi market re-openUC_4.10.2 §5.1.2
Archive Failsafe (M2)—Hard-delete sub-accountUC_4.10.2 §5.2
Reset Case A (before archive_date)—Delete old sub-account → provision newUC_4.10.2 §5.3
Reset Case B (after archive_date)—Provision new (old already deleted by Failsafe)UC_4.10.2 §5.3
Overnight Margin 25% Cap (LIVE Forex)—Dispatch unconditionally đến UC_6.1.3TRIM_TO_COMPLIANCE, qua MT5 Gateway API (CHR-102)UC_6.1.2 BR_6.1.2.5
Profit Target — Level Up (SIM)—Plugin self-fires (profit-lock + flatten)UC_5.1 BR_5.1.7
Graduation (SIM → LIVE)—Hard-delete SIM sub-accountUC_5.1

Changelog

DateVersionNotes
2026-09-15v1Initial creation — tổng hợp từ UC_4.10.1, UC_4.10.2, UC_4.15.1, UC_5.1, UC_6.1.2, QnA STAGE2-019
2026-09-16v1 → v1.1§3.4, §5 (Priority Rules), §6 (Summary map) — cập nhật theo UC_6.1.2 mới nhất
2026-09-16v1.1 → v1.2§3.4 — thêm logic T-3min Pre-Close Lockout
2026-09-16v1.2 → v1.3Sửa theo feedback BA: §3.1 thêm note DST (America/New_York timezone-aware, không phải giờ UTC cố định); §3.2.1 viết lại rõ cả 2 entry point đều do plugin Sotatek tự care, giải thích chi tiết từng trigger point, nêu rõ post-flatten phải ở login-but-no-trade (TRADE_DISABLED); §3.2.2 viết đủ ngữ cảnh (chỉ áp dụng Entry point 2/3, lý do Entry 1 không thể xảy ra khi market đóng); §3.3 Archive Flow bỏ nhắc M1 (MT5 chỉ có 1 mốc duy nhất); §3.5 chú thích rõ READONLY = login được, không trade được; §4 cập nhật state reference đồng bộ
2026-09-16v1.3 → v1.4Fix lỗi thứ tự Lock/Flatten/Cancel ở §3.2.1: theo đúng nguồn UC_4.10.2 §5.1.1 (dòng "once the broker confirms flatten + cancel orders are complete..."), việc set account state (TRADE_DISABLED) diễn ra SAU KHI Flatten + Cancel đã confirm xong — áp dụng đồng nhất cho cả Entry point 1 và Entry point 2/3 khi market open. Bản v1.3 viết sai khi gán "Lock trước, Flatten sau" (thứ tự của Soft Breach §3.1) nhầm sang Entry point 1 của Hard Breach, tạo ra 2 thứ tự khác nhau không có cơ sở. Case market-closed (§3.2.2) vẫn giữ đúng đặc thù riêng: set TRADE_DISABLED ngay lập tức, Flatten mới defer — vì đây là exception được nguồn nói rõ, không phải do market-open dùng thứ tự khác. Đồng bộ sửa bảng Summary Call Map (§6).
2026-09-16v1.4 → v1.5Sửa lại theo feedback BA: v1.4 nói Soft Breach (§3.1) và Hard Breach (§3.2.1) dùng2 thứ tự khác nhau — đây là kết luận sai. Check lại nguồn: UC_4.10.1 §5 Step 2 dòng 76 nói rõ Soft Breach's "Lock happens before Flatten — same account-first ordering as Hard Breach's Atomic Kill Switch"; UC_4.15.1 lặp lại y hệt; và UC_4.10.2 §5 Step 3 sub-step 4 tự nó cũng label chung là "Lock → Flatten → Cancel" — tức 2 cơ chế dùng chung 1 business framing/thứ tự ("Lock → Flatten → Cancel"), không phải khác nhau. Đã sửa §3.1 (thêm note đối chiếu), §3.2.1 "Post-flatten" paragraph (đổi từ "khác Soft Breach" sang "giống Soft Breach", giữ lại phần micro-timing implementation của MT5 riêng như một chi tiết bổ sung, không phải khác thứ tự nghiệp vụ), §4 Account State Reference (thêm suy luận Disable/Read-Only khả năng cũng là TRADE_DISABLED, gắn nhãn rõ đây là suy luận — chưa có UC nào confirm bằng văn bản tên state enum cho Soft Breach).

On this page