Merge pull request 'fix: market_data에 unrealized_pnl_pct/holding_days 추가하여 SELL 시나리오 정상화 (#259)' (#263) from feature/issue-259-market-data-pnl-holding-days into main
Some checks failed
CI / test (push) Has been cancelled

Reviewed-on: #263
This commit was merged in pull request #263.
This commit is contained in:
2026-02-26 00:23:55 +09:00
2 changed files with 18 additions and 2 deletions

View File

@@ -254,7 +254,7 @@ def get_open_position(
"""Return open position if latest trade is BUY, else None."""
cursor = conn.execute(
"""
SELECT action, decision_id, price, quantity
SELECT action, decision_id, price, quantity, timestamp
FROM trades
WHERE stock_code = ?
AND market = ?
@@ -266,7 +266,7 @@ def get_open_position(
row = cursor.fetchone()
if not row or row[0] != "BUY":
return None
return {"decision_id": row[1], "price": row[2], "quantity": row[3]}
return {"decision_id": row[1], "price": row[2], "quantity": row[3], "timestamp": row[4]}
def get_recent_symbols(

View File

@@ -576,6 +576,22 @@ async def trading_cycle(
market_data["rsi"] = candidate.rsi
market_data["volume_ratio"] = candidate.volume_ratio
# Enrich market_data with holding info for SELL/HOLD scenario conditions
open_pos = get_open_position(db_conn, stock_code, market.code)
if open_pos and current_price > 0:
entry_price = safe_float(open_pos.get("price"), 0.0)
if entry_price > 0:
market_data["unrealized_pnl_pct"] = (
(current_price - entry_price) / entry_price * 100
)
entry_ts = open_pos.get("timestamp")
if entry_ts:
try:
entry_date = datetime.fromisoformat(entry_ts).date()
market_data["holding_days"] = (datetime.now(UTC).date() - entry_date).days
except (ValueError, TypeError):
pass
# 1.3. Record L7 real-time context (market-scoped keys)
timeframe = datetime.now(UTC).isoformat()
context_store.set_context(