Files
stockautomtion/app/engine/collector.py
2026-07-16 23:55:16 +09:00

94 lines
2.8 KiB
Python

from __future__ import annotations
from datetime import datetime, time
from sqlalchemy.orm import Session
from app.core.config import settings
from app.core.logger import setup_logger
from app.models.stock import PriceHistory
from app.services.market_data import market_data_service
logger = setup_logger("collector")
class PriceCollector:
def __init__(self) -> None:
self._running = False
def is_market_open(self) -> bool:
now = datetime.now()
if now.weekday() >= 5:
return False
market_open = time(settings.collector.market_open_hour, 0)
market_close = time(settings.collector.market_close_hour, settings.collector.market_close_minute)
return market_open <= now.time() <= market_close
async def collect_price(self, stock_code: str, db: Session) -> bool:
if not self.is_market_open():
return False
try:
price_data = await market_data_service.get_current_price(stock_code)
if not price_data:
return False
now = datetime.now()
record = PriceHistory(
stock_code=stock_code,
datetime=now,
open=price_data.get("open_price", 0),
high=price_data.get("high_price", 0),
low=price_data.get("low_price", 0),
close=price_data.get("current_price", 0),
volume=price_data.get("volume", 0),
)
db.add(record)
db.commit()
logger.debug(
"가격 수집: %s = %d원 (%+.2f%%)",
stock_code,
price_data.get("current_price", 0),
price_data.get("change_rate", 0),
)
return True
except Exception as e:
logger.error("가격 수집 오류 (%s): %s", stock_code, e)
db.rollback()
return False
async def collect_all(self, db: Session) -> int:
from app.models.stock import Stock
stocks = db.query(Stock).filter(Stock.is_active == True).all()
count = 0
for stock in stocks:
if await self.collect_price(stock.code, db):
count += 1
return count
def get_latest_price(self, stock_code: str, db: Session) -> dict | None:
record = (
db.query(PriceHistory)
.filter(PriceHistory.stock_code == stock_code)
.order_by(PriceHistory.datetime.desc())
.first()
)
if not record:
return None
return {
"stock_code": record.stock_code,
"current_price": record.close,
"open": record.open,
"high": record.high,
"low": record.low,
"volume": record.volume,
"datetime": record.datetime.isoformat(),
}
price_collector = PriceCollector()