test: cover unmanaged position lifecycle flow
Co-authored-by: genichin <4282227+genichin@users.noreply.github.com>
This commit is contained in:
co-authored by
genichin
parent
fe51d211d9
commit
f2b825e720
@@ -12,8 +12,8 @@ from __future__ import annotations
|
||||
import logging
|
||||
import os
|
||||
import threading
|
||||
from datetime import date, datetime, time, timedelta, timezone
|
||||
from typing import Callable, Optional
|
||||
from collections.abc import Callable
|
||||
from datetime import UTC, date, datetime, time, timedelta, timezone
|
||||
|
||||
from trex_core.application.alarm_emitter import AlarmEmitter
|
||||
from trex_core.application.broker_port import BrokerPort
|
||||
@@ -23,10 +23,10 @@ from trex_core.application.portfolio import (
|
||||
PortfolioHubReadPort,
|
||||
PortfolioHubUnavailableError,
|
||||
ReconcileNotificationStore,
|
||||
UnmanagedPositionStore,
|
||||
ReconcileWarningStore,
|
||||
SnapshotStore,
|
||||
TradingContext,
|
||||
UnmanagedPositionStore,
|
||||
)
|
||||
from trex_core.application.reconciliation import reconcile_positions
|
||||
|
||||
@@ -45,32 +45,32 @@ class SnapshotScheduler:
|
||||
store: SnapshotStore,
|
||||
broker: BrokerPort,
|
||||
schedule_kst: time = time(hour=7, minute=30),
|
||||
clock: Optional[Callable[[], datetime]] = None,
|
||||
clock: Callable[[], datetime] | None = None,
|
||||
slot_repo=None,
|
||||
slot_service=None,
|
||||
instance_key: str = "default",
|
||||
alarm_emitter: Optional[AlarmEmitter] = None,
|
||||
warn_store: Optional[ReconcileWarningStore] = None,
|
||||
notification_store: Optional[ReconcileNotificationStore] = None,
|
||||
unmanaged_position_store: Optional[UnmanagedPositionStore] = None,
|
||||
alarm_emitter: AlarmEmitter | None = None,
|
||||
warn_store: ReconcileWarningStore | None = None,
|
||||
notification_store: ReconcileNotificationStore | None = None,
|
||||
unmanaged_position_store: UnmanagedPositionStore | None = None,
|
||||
credential_fetch_enabled: bool = False,
|
||||
kis_reinit_callback: Optional[Callable[[BrokerCredentialPayload], None]] = None,
|
||||
credential_refresh: Optional[Callable[[], object]] = None,
|
||||
kis_reinit_callback: Callable[[BrokerCredentialPayload], None] | None = None,
|
||||
credential_refresh: Callable[[], object] | None = None,
|
||||
) -> None:
|
||||
self._read = read_port
|
||||
self._store = store
|
||||
self._broker = broker
|
||||
self._schedule_kst = schedule_kst
|
||||
self._clock = clock or (lambda: datetime.now(tz=timezone.utc))
|
||||
self._daemon_id: Optional[str] = None
|
||||
self._last_fired_date: Optional[datetime] = None
|
||||
self._clock = clock or (lambda: datetime.now(tz=UTC))
|
||||
self._daemon_id: str | None = None
|
||||
self._last_fired_date: datetime | None = None
|
||||
# dcy-020 / REQ-058 (BAT-030): asset-centric slot reconcile after each
|
||||
# universe fetch — always on when slot_repo is wired (the reconcile is
|
||||
# what creates/retires the permanent asset slots).
|
||||
self._slot_repo = slot_repo
|
||||
self._slot_service = slot_service
|
||||
self._instance_key = instance_key
|
||||
self._last_universe_size: Optional[int] = None
|
||||
self._last_universe_size: int | None = None
|
||||
# dcy-033 / REQ-100: best-effort alarm emitter.
|
||||
self._alarm_emitter = alarm_emitter
|
||||
# BAT-050 / REQ-103: durable reconcile-warning store (Optional).
|
||||
@@ -84,7 +84,9 @@ class SnapshotScheduler:
|
||||
# dcy-036 / REQ-113 AC-2 / REQ-115 AC-1: optional callback to reinitialize
|
||||
# KISBroker with the fetched day-start credential. None = no reinit (paper
|
||||
# broker or credential_fetch_enabled=False). Set by daemon.py assembly.
|
||||
self._kis_reinit_callback: Optional[Callable[[BrokerCredentialPayload], None]] = kis_reinit_callback
|
||||
self._kis_reinit_callback: Callable[[BrokerCredentialPayload], None] | None = (
|
||||
kis_reinit_callback
|
||||
)
|
||||
# REQ-119: provider-owned refresh supersedes the legacy raw fetch hook.
|
||||
self._credential_refresh = credential_refresh
|
||||
# REQ-113: detect break-glass at init time (env var set by operator).
|
||||
@@ -93,8 +95,8 @@ class SnapshotScheduler:
|
||||
in ("1", "true", "yes")
|
||||
)
|
||||
# REQ-115: day-scoped credential cache. None until first successful fetch.
|
||||
self._cached_credential: Optional[BrokerCredentialPayload] = None
|
||||
self._credential_date: Optional[date] = None
|
||||
self._cached_credential: BrokerCredentialPayload | None = None
|
||||
self._credential_date: date | None = None
|
||||
# REQ-114: entry gate. True = new entries allowed (default).
|
||||
# credential_fetch_enabled=False keeps this always True (no gate).
|
||||
self._entry_allowed: bool = True
|
||||
@@ -266,7 +268,7 @@ class SnapshotScheduler:
|
||||
try:
|
||||
self._credential_refresh()
|
||||
self._entry_allowed = True
|
||||
except Exception as exc: # provider exposes only sanitized failure
|
||||
except Exception as exc: # noqa: BLE001 - provider exposes only sanitized failure
|
||||
_log.error("DAY_START_LOAD_FAILED: broker credential refresh failed: %s (instance=%s)",
|
||||
exc.__class__.__name__, self._instance_key)
|
||||
self._entry_allowed = False
|
||||
|
||||
Reference in New Issue
Block a user