feat: 데이트레이딩 포지션 화면 표시 + 모든 매도 즉시 화면 반영

- portfolio_cache_bridge 신설: 매매 엔진 체결 시 Portfolio(db_worker 큐) + 인메모리 캐시 즉시 갱신.
  DT 매수는 strategy_type='daytrading'으로 태깅되어 보유 종목 패널의 '데이트레이딩' 그룹에 표시되고
  스윙 청산 로직(strategy_type='swing' 대상)에서 제외됨. (기존엔 KIS 동기화로 'swing'으로 유입돼
  DT 포지션이 안 보이고 스윙 엔진이 같이 관리하는 문제)
- DT 매도·스윙 자동 매도도 캐시에서 즉시 제거/차감 + 최근매도 기록(동기화 되살림 방지).
- 동기화 시 DT 엔진 보유 종목은 'daytrading'으로 태깅.
- 프론트: 수동 매도 성공 시 낙관적 갱신으로 서버 재조회 전 즉시 목록에서 제거.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-22 16:49:46 +09:00
parent 496529782b
commit a57c720559
7 changed files with 189 additions and 10 deletions

View File

@@ -603,6 +603,13 @@ async def sync_portfolio(db: AsyncSession = Depends(get_db), force: bool = True)
_realtime_price_map = {}
# ──────────────────────────────────────────────────────────────────
# 데이트레이딩 엔진이 보유 중인 종목 → strategy_type='daytrading' 태깅용
try:
from app.services.daytrading.position_manager import day_trading_state as _dts
_dt_codes = set(_dts.positions.keys())
except Exception:
_dt_codes = set()
for item in balance_data["output1"]:
stock_code = item.get("pdno")
@@ -739,6 +746,8 @@ async def sync_portfolio(db: AsyncSession = Depends(get_db), force: bool = True)
h.profit_loss = profit_loss
h.profit_loss_rate = profit_loss_rate
h.market = exchange_code
if stock_code in _dt_codes:
h.strategy_type = "daytrading"
new_holdings.append(h)
else:
new_holding = Portfolio(
@@ -750,6 +759,7 @@ async def sync_portfolio(db: AsyncSession = Depends(get_db), force: bool = True)
profit_loss=profit_loss,
profit_loss_rate=profit_loss_rate,
market=exchange_code,
strategy_type="daytrading" if stock_code in _dt_codes else "swing",
)
db.add(new_holding)
new_holdings.append(new_holding)