Harden scheduler and stale breakout reentry
This commit is contained in:
@@ -55,9 +55,17 @@ class KISClient:
|
||||
)
|
||||
self._load_token_from_file()
|
||||
|
||||
# rate limit: 모의투자 1건/초보다 보수적, 실거래 5건/초 이하
|
||||
self._rate_limit = 1 if self.is_mock else 5
|
||||
self._request_spacing = 1.2 if self.is_mock else 0.22
|
||||
# rate limit: KIS occasionally rejects even nominally safe bursts.
|
||||
# Keep defaults conservative and allow local override from .env.
|
||||
self._rate_limit = int(os.getenv(
|
||||
"KIS_MOCK_RATE_LIMIT" if self.is_mock else "KIS_REAL_RATE_LIMIT",
|
||||
"1" if self.is_mock else "3",
|
||||
))
|
||||
self._request_spacing = float(os.getenv(
|
||||
"KIS_MOCK_REQUEST_SPACING" if self.is_mock else "KIS_REAL_REQUEST_SPACING",
|
||||
"1.7" if self.is_mock else "0.35",
|
||||
))
|
||||
self._cooldown_until = 0.0
|
||||
self._semaphore = asyncio.Semaphore(1)
|
||||
self._req_times : list = []
|
||||
|
||||
@@ -175,6 +183,9 @@ class KISClient:
|
||||
|
||||
async with self._semaphore:
|
||||
now = time.monotonic()
|
||||
if now < self._cooldown_until:
|
||||
await asyncio.sleep(self._cooldown_until - now)
|
||||
now = time.monotonic()
|
||||
if self._req_times:
|
||||
wait = self._request_spacing - (now - self._req_times[-1])
|
||||
if wait > 0:
|
||||
@@ -204,6 +215,8 @@ class KISClient:
|
||||
rt_cd = data.get("rt_cd", "")
|
||||
if rt_cd != "0":
|
||||
msg = data.get("msg1", "알 수 없는 오류")
|
||||
if "초당" in msg or "거래건수" in msg or "rate" in msg.lower():
|
||||
self._cooldown_until = time.monotonic() + max(2.5, self._request_spacing * 2)
|
||||
logger.error(f"KIS API 오류 [{tr_id}]: {rt_cd} - {msg}")
|
||||
raise RuntimeError(f"KIS API 오류: {msg}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user