Merge pull request 'Fix overnight runner stability and token cooldown handling' (#139) from agentson/fix/137-run-overnight-python-tmux into main
Some checks failed
CI / test (push) Has been cancelled
Some checks failed
CI / test (push) Has been cancelled
Reviewed-on: #139
This commit was merged in pull request #139.
This commit is contained in:
@@ -315,6 +315,11 @@ class SmartVolatilityScanner:
|
||||
logger.info("Overseas scanner: no symbol universe for %s", market.name)
|
||||
return []
|
||||
|
||||
logger.info(
|
||||
"Overseas scanner: scanning %d fallback symbols for %s",
|
||||
len(symbols),
|
||||
market.name,
|
||||
)
|
||||
candidates: list[ScanCandidate] = []
|
||||
for stock_code in symbols:
|
||||
try:
|
||||
@@ -350,6 +355,11 @@ class SmartVolatilityScanner:
|
||||
logger.warning("Failed to analyze overseas %s: %s", stock_code, exc)
|
||||
except Exception as exc:
|
||||
logger.error("Unexpected error analyzing overseas %s: %s", stock_code, exc)
|
||||
logger.info(
|
||||
"Overseas symbol fallback scan found %d candidates for %s",
|
||||
len(candidates),
|
||||
market.name,
|
||||
)
|
||||
return candidates
|
||||
|
||||
def get_stock_codes(self, candidates: list[ScanCandidate]) -> list[str]:
|
||||
|
||||
@@ -104,12 +104,14 @@ class KISBroker:
|
||||
time_since_last_attempt = now - self._last_refresh_attempt
|
||||
if time_since_last_attempt < self._refresh_cooldown:
|
||||
remaining = self._refresh_cooldown - time_since_last_attempt
|
||||
error_msg = (
|
||||
f"Token refresh on cooldown. "
|
||||
f"Retry in {remaining:.1f}s (KIS allows 1/minute)"
|
||||
# Do not fail fast here. If token is unavailable, upstream calls
|
||||
# will all fail for up to a minute and scanning returns no trades.
|
||||
logger.warning(
|
||||
"Token refresh on cooldown. Waiting %.1fs before retry (KIS allows 1/minute)",
|
||||
remaining,
|
||||
)
|
||||
logger.warning(error_msg)
|
||||
raise ConnectionError(error_msg)
|
||||
await asyncio.sleep(remaining)
|
||||
now = asyncio.get_event_loop().time()
|
||||
|
||||
logger.info("Refreshing KIS access token")
|
||||
self._last_refresh_attempt = now
|
||||
|
||||
@@ -82,14 +82,19 @@ class OverseasBroker:
|
||||
session = self._broker._get_session()
|
||||
|
||||
if ranking_type == "volume":
|
||||
tr_id = self._broker._settings.OVERSEAS_RANKING_VOLUME_TR_ID
|
||||
path = self._broker._settings.OVERSEAS_RANKING_VOLUME_PATH
|
||||
configured_tr_id = self._broker._settings.OVERSEAS_RANKING_VOLUME_TR_ID
|
||||
configured_path = self._broker._settings.OVERSEAS_RANKING_VOLUME_PATH
|
||||
default_tr_id = "HHDFS76200200"
|
||||
default_path = "/uapi/overseas-price/v1/quotations/inquire-volume-rank"
|
||||
else:
|
||||
tr_id = self._broker._settings.OVERSEAS_RANKING_FLUCT_TR_ID
|
||||
path = self._broker._settings.OVERSEAS_RANKING_FLUCT_PATH
|
||||
configured_tr_id = self._broker._settings.OVERSEAS_RANKING_FLUCT_TR_ID
|
||||
configured_path = self._broker._settings.OVERSEAS_RANKING_FLUCT_PATH
|
||||
default_tr_id = "HHDFS76200100"
|
||||
default_path = "/uapi/overseas-price/v1/quotations/inquire-updown-rank"
|
||||
|
||||
headers = await self._broker._auth_headers(tr_id)
|
||||
url = f"{self._broker._base_url}{path}"
|
||||
endpoint_specs: list[tuple[str, str]] = [(configured_tr_id, configured_path)]
|
||||
if (configured_tr_id, configured_path) != (default_tr_id, default_path):
|
||||
endpoint_specs.append((default_tr_id, default_path))
|
||||
|
||||
# Try common param variants used by KIS overseas quotation APIs.
|
||||
param_variants = [
|
||||
@@ -100,12 +105,18 @@ class OverseasBroker:
|
||||
]
|
||||
|
||||
last_error: str | None = None
|
||||
saw_http_404 = False
|
||||
for tr_id, path in endpoint_specs:
|
||||
headers = await self._broker._auth_headers(tr_id)
|
||||
url = f"{self._broker._base_url}{path}"
|
||||
for params in param_variants:
|
||||
try:
|
||||
async with session.get(url, headers=headers, params=params) as resp:
|
||||
text = await resp.text()
|
||||
if resp.status != 200:
|
||||
last_error = f"HTTP {resp.status}: {text}"
|
||||
if resp.status == 404:
|
||||
saw_http_404 = True
|
||||
continue
|
||||
|
||||
data = await resp.json()
|
||||
@@ -119,6 +130,14 @@ class OverseasBroker:
|
||||
last_error = str(exc)
|
||||
continue
|
||||
|
||||
if saw_http_404:
|
||||
logger.warning(
|
||||
"Overseas ranking endpoint unavailable (404) for %s/%s; using symbol fallback scan",
|
||||
exchange_code,
|
||||
ranking_type,
|
||||
)
|
||||
return []
|
||||
|
||||
raise ConnectionError(
|
||||
f"fetch_overseas_rankings failed for {exchange_code}/{ranking_type}: {last_error}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user