fix: persist sell prices to DB and add WF filter bootstrap

- price_db: add sell_prices table (ensure/upsert/load/delete)
- trader: restore _last_sell_prices from DB on startup so re-entry
  block survives restarts; persist each sell price immediately
- market: retry chunk requests up to 3 times with backoff on 429

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
joungmin
2026-03-01 05:19:22 +09:00
parent 0b264b304c
commit d2a5c3ae9e
3 changed files with 86 additions and 5 deletions

View File

@@ -15,6 +15,7 @@ from .notify import notify_buy, notify_sell, notify_error
from .price_db import (
delete_position, load_positions, upsert_position,
ensure_trade_results_table, record_trade, load_recent_wins,
ensure_sell_prices_table, upsert_sell_price, load_sell_prices,
)
load_dotenv()
@@ -97,12 +98,26 @@ def restore_positions() -> None:
DB에 저장된 실제 매수가를 복원하고, Upbit 잔고에 없으면 DB에서도 삭제한다.
"""
# trade_results 테이블 초기화
# trade_results / sell_prices 테이블 초기화
try:
ensure_trade_results_table()
except Exception as e:
logger.warning(f"trade_results 테이블 생성 실패 (무시): {e}")
try:
ensure_sell_prices_table()
except Exception as e:
logger.warning(f"sell_prices 테이블 생성 실패 (무시): {e}")
# 직전 매도가 복원 (재매수 차단 기준 유지)
try:
loaded = load_sell_prices()
_last_sell_prices.update(loaded)
if loaded:
logger.info(f"[복원] 직전 매도가 {len(loaded)}건 복원: {list(loaded.keys())}")
except Exception as e:
logger.warning(f"직전 매도가 복원 실패 (무시): {e}")
# DB에서 저장된 포지션 로드
try:
saved = {row["ticker"]: row for row in load_positions()}
@@ -291,6 +306,10 @@ def sell(ticker: str, reason: str = "") -> bool:
notify_sell(ticker, current, pnl, reason)
if current:
_last_sell_prices[ticker] = current # 재매수 기준가 기록
try:
upsert_sell_price(ticker, current) # DB 영구 저장
except Exception as e:
logger.error(f"직전 매도가 DB 저장 실패 {ticker}: {e}")
_update_history(ticker, pnl > 0, pnl) # walk-forward 이력 갱신
del _positions[ticker]
try: