|
|
|
|
@ -128,26 +128,37 @@ async def get_alpaca_intraday_multi(
|
|
|
|
|
start_dt = datetime.combine(_start, datetime.min.time()).replace(tzinfo=timezone.utc)
|
|
|
|
|
end_dt = datetime.combine(_end, datetime.max.time()).replace(tzinfo=timezone.utc)
|
|
|
|
|
|
|
|
|
|
async with _INTRADAY_SEMAPHORE:
|
|
|
|
|
try:
|
|
|
|
|
data = await svc.get_or_fetch_multi_bars(
|
|
|
|
|
symbols, start_dt, end_dt, interval, force_refresh, feed="sip"
|
|
|
|
|
)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
err = str(e)
|
|
|
|
|
detail = f"Alpaca API error: {err}"
|
|
|
|
|
if "502" in err or "Bad Gateway" in err:
|
|
|
|
|
detail = (
|
|
|
|
|
f"Alpaca 502 Bad Gateway — 요청당 심볼 수 초과 가능성. "
|
|
|
|
|
f"내부 배치 크기: 100개/요청. 원인: {err}"
|
|
|
|
|
async def _do_fetch():
|
|
|
|
|
async with _INTRADAY_SEMAPHORE:
|
|
|
|
|
try:
|
|
|
|
|
return await svc.get_or_fetch_multi_bars(
|
|
|
|
|
symbols, start_dt, end_dt, interval, force_refresh, feed="sip"
|
|
|
|
|
)
|
|
|
|
|
raise HTTPException(status_code=502, detail=detail)
|
|
|
|
|
finally:
|
|
|
|
|
await svc.client.close()
|
|
|
|
|
finally:
|
|
|
|
|
try:
|
|
|
|
|
await svc.client.close()
|
|
|
|
|
except Exception:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
data = await asyncio.wait_for(_do_fetch(), timeout=120)
|
|
|
|
|
except asyncio.TimeoutError:
|
|
|
|
|
raise HTTPException(
|
|
|
|
|
status_code=504,
|
|
|
|
|
detail="요청 시간 초과 (120초). 티커 수를 줄이거나 나중에 다시 시도하세요.",
|
|
|
|
|
)
|
|
|
|
|
except HTTPException:
|
|
|
|
|
raise
|
|
|
|
|
except Exception as e:
|
|
|
|
|
err = str(e)
|
|
|
|
|
detail = f"Alpaca API error: {err}"
|
|
|
|
|
if "502" in err or "Bad Gateway" in err:
|
|
|
|
|
detail = (
|
|
|
|
|
f"Alpaca 502 Bad Gateway — 요청당 심볼 수 초과 가능성. "
|
|
|
|
|
f"내부 배치 크기: 100개/요청. 원인: {err}"
|
|
|
|
|
)
|
|
|
|
|
raise HTTPException(status_code=502, detail=detail)
|
|
|
|
|
|
|
|
|
|
# Reclaim Alpaca HTTP buffers, intermediate bar dicts, and DB row objects
|
|
|
|
|
# before building the serialised response. Prevents Python heap from growing
|
|
|
|
|
# unboundedly across thousands of backfill requests in a long-running worker.
|
|
|
|
|
gc.collect()
|
|
|
|
|
|
|
|
|
|
bars = {
|
|
|
|
|
@ -207,22 +218,36 @@ async def get_alpaca_intraday_today(
|
|
|
|
|
start_dt = datetime.combine(today, datetime.min.time()).replace(tzinfo=timezone.utc)
|
|
|
|
|
end_dt = datetime.combine(today, datetime.max.time()).replace(tzinfo=timezone.utc)
|
|
|
|
|
|
|
|
|
|
async with _INTRADAY_SEMAPHORE:
|
|
|
|
|
try:
|
|
|
|
|
data = await svc.get_or_fetch_multi_bars(
|
|
|
|
|
symbols, start_dt, end_dt, interval, force_refresh=True, feed="iex"
|
|
|
|
|
)
|
|
|
|
|
except Exception as e:
|
|
|
|
|
err = str(e)
|
|
|
|
|
detail = f"Alpaca API error: {err}"
|
|
|
|
|
if "502" in err or "Bad Gateway" in err:
|
|
|
|
|
detail = (
|
|
|
|
|
f"Alpaca 502 Bad Gateway — 요청당 심볼 수 초과 가능성. "
|
|
|
|
|
f"내부 배치 크기: 100개/요청. 원인: {err}"
|
|
|
|
|
async def _do_fetch():
|
|
|
|
|
async with _INTRADAY_SEMAPHORE:
|
|
|
|
|
try:
|
|
|
|
|
return await svc.get_or_fetch_multi_bars(
|
|
|
|
|
symbols, start_dt, end_dt, interval, force_refresh=True, feed="iex"
|
|
|
|
|
)
|
|
|
|
|
raise HTTPException(status_code=502, detail=detail)
|
|
|
|
|
finally:
|
|
|
|
|
await svc.client.close()
|
|
|
|
|
finally:
|
|
|
|
|
try:
|
|
|
|
|
await svc.client.close()
|
|
|
|
|
except Exception:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
data = await asyncio.wait_for(_do_fetch(), timeout=120)
|
|
|
|
|
except asyncio.TimeoutError:
|
|
|
|
|
raise HTTPException(
|
|
|
|
|
status_code=504,
|
|
|
|
|
detail="요청 시간 초과 (120초). 티커 수를 줄이거나 나중에 다시 시도하세요.",
|
|
|
|
|
)
|
|
|
|
|
except HTTPException:
|
|
|
|
|
raise
|
|
|
|
|
except Exception as e:
|
|
|
|
|
err = str(e)
|
|
|
|
|
detail = f"Alpaca API error: {err}"
|
|
|
|
|
if "502" in err or "Bad Gateway" in err:
|
|
|
|
|
detail = (
|
|
|
|
|
f"Alpaca 502 Bad Gateway — 요청당 심볼 수 초과 가능성. "
|
|
|
|
|
f"내부 배치 크기: 100개/요청. 원인: {err}"
|
|
|
|
|
)
|
|
|
|
|
raise HTTPException(status_code=502, detail=detail)
|
|
|
|
|
|
|
|
|
|
gc.collect()
|
|
|
|
|
|
|
|
|
|
|