일단 커밋
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -4,15 +4,17 @@ import json
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.core.auth import token_manager
|
||||
from app.core.config import settings
|
||||
from app.core.logger import setup_logger
|
||||
from app.models.stock import PriceHistory, Strategy, Trade
|
||||
from app.services.market_data import market_data_service
|
||||
from app.services.trading import trading_service
|
||||
from app.engine.strategies.base import BaseStrategy, Signal
|
||||
from app.engine.strategies.conditional import ConditionalStrategy
|
||||
from app.engine.strategies.technical import TechnicalStrategy
|
||||
from app.engine.strategies.periodic import PeriodicStrategy
|
||||
from app.engine.strategies.technical import TechnicalStrategy
|
||||
from app.models.stock import PriceHistory, Strategy, Trade
|
||||
from app.services.account import account_service
|
||||
from app.services.market_data import market_data_service
|
||||
from app.services.trading import trading_service
|
||||
|
||||
logger = setup_logger("strategy_engine")
|
||||
|
||||
@@ -40,9 +42,25 @@ class StrategyEngine:
|
||||
strategy_id=strategy_record.id,
|
||||
)
|
||||
|
||||
async def _get_real_holdings(self, db: Session) -> dict[str, int]:
|
||||
"""실제 계좌 잔고 기반 보유수량 맵. 실패 시 로컬 DB로 폴백."""
|
||||
if token_manager.is_authenticated:
|
||||
try:
|
||||
balance = await account_service.get_balance()
|
||||
holdings = {s["stock_code"]: s["qty"] for s in balance.get("stocks", [])}
|
||||
if holdings:
|
||||
return holdings
|
||||
except Exception as e:
|
||||
logger.warning("잔고 조회 실패 - 로컬 보유정보 사용: %s", e)
|
||||
|
||||
from app.models.stock import Holding
|
||||
|
||||
return {h.stock_code: h.qty for h in db.query(Holding).filter(Holding.qty > 0).all()}
|
||||
|
||||
async def evaluate_all(self, db: Session) -> list[Signal]:
|
||||
strategies = db.query(Strategy).filter(Strategy.is_active == True).all()
|
||||
strategies = db.query(Strategy).filter(Strategy.is_active).all()
|
||||
signals: list[Signal] = []
|
||||
real_holdings = await self._get_real_holdings(db)
|
||||
|
||||
for strat_record in strategies:
|
||||
try:
|
||||
@@ -55,7 +73,7 @@ class StrategyEngine:
|
||||
continue
|
||||
|
||||
price_history = self._get_price_history(db, strat_record.stock_code)
|
||||
holding = self._get_holding_qty(db, strat_record.stock_code)
|
||||
holding = real_holdings.get(strat_record.stock_code, 0)
|
||||
|
||||
signal = strategy.evaluate(current_price, price_history, holding)
|
||||
if signal.action != "hold":
|
||||
@@ -103,7 +121,7 @@ class StrategyEngine:
|
||||
qty=signal.qty,
|
||||
price=signal.price,
|
||||
order_type=settings.strategy.default_order_type,
|
||||
status="filled" if order_result.get("rt_cd") == "0" else "rejected",
|
||||
status="pending" if order_result.get("rt_cd") == "0" else "rejected",
|
||||
strategy_id=signal.strategy_id,
|
||||
)
|
||||
db.add(trade)
|
||||
@@ -136,11 +154,6 @@ class StrategyEngine:
|
||||
for r in reversed(records)
|
||||
]
|
||||
|
||||
def _get_holding_qty(self, db: Session, stock_code: str) -> int:
|
||||
from app.models.stock import Holding
|
||||
holding = db.query(Holding).filter(Holding.stock_code == stock_code).first()
|
||||
return holding.qty if holding else 0
|
||||
|
||||
def reset_daily_count(self) -> None:
|
||||
self._daily_trade_count = 0
|
||||
|
||||
|
||||
Reference in New Issue
Block a user