fix: DB 타임스탬프 KST 통일 + KIS 토큰 캐시 영속화
시간대 혼재: 모델 기본값은 datetime.utcnow(UTC), 수동 매매 등 일부 경로는 _get_kst_now(KST)로 저장해 같은 테이블에 9시간 차가 섞였다(화면 매매시각 02:14 등). 조회 구간(utcnow - days)도 KST 저장분과 비교돼 어긋났고, 추가매수 쿨다운은 (UTC now - KST created_at)이 음수라 상시 발동했다. app.core.timeutil.now_kst() 도입 후 모델 기본값 27곳과 app/ 전역 utcnow() 호출을 모두 KST 기준으로 통일(잔존 0건, 테스트로 고정). KIS 토큰 캐시(~/.cache/auto-stock)가 컨테이너에만 있어 배포마다 사라지고 토큰을 새로 발급받다 KIS가 EGW00103(유효하지 않은 AppKey)로 거부 → 502·잔고 0 유발. 볼륨 마운트로 재배포 후에도 재사용. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,7 @@ from app.services.technical_indicators import (
|
||||
from app.services.signal_types import BUY_KEYWORDS, SELL_KEYWORDS, STRONG_BUY_KEYWORDS, BLOCK_KEYWORDS
|
||||
from app.services.correlation_filter import validate_correlation_filter
|
||||
from app.services.exchange_detector import is_us_stock, detect_exchange, get_market_info
|
||||
from app.core.timeutil import now_kst
|
||||
from app.services.trade_helpers import (
|
||||
check_opening_range_volatility, check_surge_prevention, check_trend_filter,
|
||||
calculate_cooldown_minutes, get_daily_cutoff_utc, get_leverage_check_keywords,
|
||||
@@ -725,7 +726,7 @@ async def _execute_buy(
|
||||
if available_cash > 0:
|
||||
_set_account_cache(available_cash, total_assets)
|
||||
|
||||
# [이슈1 수정] TradeHistory.created_at은 UTC 저장(datetime.utcnow)이므로
|
||||
# [2026-09-23] TradeHistory.created_at 은 KST 저장(now_kst)이므로
|
||||
# daily_cutoff도 UTC 기준으로 계산해야 9시간 오차가 없음.
|
||||
daily_cutoff = get_daily_cutoff_utc() # 오늘 00:00:00 UTC
|
||||
|
||||
@@ -770,9 +771,9 @@ async def _execute_buy(
|
||||
)
|
||||
recent_buys = cooldown_check.scalars().all()
|
||||
# 마지막 매수 이후 쿨다운 시간이 지나지 않았으면 HOLD
|
||||
# [이슈1 수정] created_at은 UTC이므로 현재 시각도 UTC로 비교
|
||||
from datetime import datetime as _dt_utc2
|
||||
if recent_buys and (_dt_utc2.utcnow() - recent_buys[0].created_at).total_seconds() < cooldown_min * 60:
|
||||
# created_at·현재시각 모두 KST naive 기준 (예전에는 UTC now 와 KST created_at 을
|
||||
# 비교해 차이가 음수가 되어 쿨다운이 항상 발동했다)
|
||||
if recent_buys and (now_kst() - recent_buys[0].created_at).total_seconds() < cooldown_min * 60:
|
||||
return {"action": "HOLD", "stock": stock_name, "reason": "cooldown"}
|
||||
|
||||
# ── 6.5. 상관관계 필터 (CLAUDE.md 섹션 5.4) ──────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user