From 587e987c5c247a8a79131020125cdbed4469a265 Mon Sep 17 00:00:00 2001 From: Justin Ko Date: Wed, 10 Jun 2026 11:06:56 +0900 Subject: [PATCH] =?UTF-8?q?feat(config):=20BAT-028=20M1=20=E2=80=94=20max?= =?UTF-8?q?=5Factive=5Fslots=20per-instance=20TOML=20(dcy-020/REQ-060)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 자산 중심 모드 게이트 + M 값. DaemonInstanceConfig/DaemonConfig 에 max_active_slots: Optional[int] 추가, from_toml 파싱(>0 검증), from_config 전파. 미설정(None) → legacy pool 모드. additive — 전체 375 passed, ruff clean. Co-Authored-By: Claude Opus 4.8 --- trex_core/runtime/config.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/trex_core/runtime/config.py b/trex_core/runtime/config.py index 03c84c2..3980771 100644 --- a/trex_core/runtime/config.py +++ b/trex_core/runtime/config.py @@ -143,6 +143,10 @@ class DaemonInstanceConfig: # Optional — absent keys fall back to KST / midnight defaults. trading_timezone: str = "Asia/Seoul" daily_preallocation_time: str = "00:00" + # dcy-020 / REQ-060 (BAT-028): max concurrent active (holding) slots, M. + # Presence is the asset-centric mode gate: set -> universe reconcile + FCFS/M + # admission; absent -> legacy pool model (preallocation + find_allocatable). + max_active_slots: Optional[int] = None @staticmethod def from_toml(path: str) -> "DaemonInstanceConfig": @@ -155,11 +159,18 @@ class DaemonInstanceConfig: raise RuntimeError( f"instance TOML missing required 'instance_key': {path}" ) + raw_max = data.get("max_active_slots") + max_active = int(raw_max) if raw_max is not None else None + if max_active is not None and max_active <= 0: + raise RuntimeError( + f"instance TOML 'max_active_slots' must be > 0, got {raw_max}: {path}" + ) return DaemonInstanceConfig( instance_key=str(instance_key), portfolio_hub_token=str(data.get("portfolio_hub_token") or ""), trading_timezone=str(data.get("trading_timezone") or "Asia/Seoul"), daily_preallocation_time=str(data.get("daily_preallocation_time") or "00:00"), + max_active_slots=max_active, ) @@ -172,6 +183,9 @@ class DaemonConfig: # BAT-013 / REQ-049: instance identity for multi-instance queue naming. # "default" keeps legacy literal queue names (backward-compat). instance_key: str = "default" + # dcy-020 / REQ-060 (BAT-028): M (max concurrent active slots) + asset-centric + # mode gate. None -> legacy pool model. + max_active_slots: Optional[int] = None kis: Optional[KISConfig] = None # REQ-011: paper broker tuning (only consulted when broker == 'paper'). paper: PaperBrokerConfig = PaperBrokerConfig() @@ -316,4 +330,5 @@ class DaemonConfig: portfolio_hub=pf, trading_timezone=inst.trading_timezone, daily_preallocation_time=inst.daily_preallocation_time, + max_active_slots=inst.max_active_slots, )