fix: restore_positions에서 locked 잔고 포함 + 기존 매도주문 취소
- balance + locked으로 보유 수량 판단 (지정가 매도 중이면 locked에 잡힘) - 복구 시 기존 미체결 매도 주문 취소 후 새로 제출 - 취소 후 실제 가용 수량 재조회 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -640,7 +640,7 @@ def restore_positions() -> None:
|
|||||||
balances = upbit_client.get_balances()
|
balances = upbit_client.get_balances()
|
||||||
for b in balances:
|
for b in balances:
|
||||||
currency = b.get('currency', '')
|
currency = b.get('currency', '')
|
||||||
bal = float(b.get('balance', 0))
|
bal = float(b.get('balance', 0)) + float(b.get('locked', 0))
|
||||||
avg = float(b.get('avg_buy_price', 0))
|
avg = float(b.get('avg_buy_price', 0))
|
||||||
if currency == 'KRW' or bal <= 0 or avg <= 0:
|
if currency == 'KRW' or bal <= 0 or avg <= 0:
|
||||||
continue
|
continue
|
||||||
@@ -649,23 +649,34 @@ def restore_positions() -> None:
|
|||||||
continue
|
continue
|
||||||
if ticker in positions:
|
if ticker in positions:
|
||||||
continue
|
continue
|
||||||
# cascade ① 지정가 매도 즉시 제출
|
# 기존 미체결 매도 주문 전부 취소 후 새로 제출
|
||||||
|
try:
|
||||||
|
old_orders = upbit_client.get_order(ticker, state='wait') or []
|
||||||
|
for o in (old_orders if isinstance(old_orders, list) else []):
|
||||||
|
if o.get('side') == 'ask':
|
||||||
|
cancel_order_safe(o.get('uuid'))
|
||||||
|
log.info(f"[복구] {ticker} 기존 매도 주문 취소: {o.get('uuid')}")
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
# 취소 후 실제 가용 수량 재조회
|
||||||
|
time.sleep(0.5)
|
||||||
|
actual_bal = upbit_client.get_balance(currency) or bal
|
||||||
_, _, lr, stag = CASCADE_STAGES[0]
|
_, _, lr, stag = CASCADE_STAGES[0]
|
||||||
target = avg * (1 + lr)
|
target = avg * (1 + lr)
|
||||||
sell_uuid = submit_limit_sell(ticker, bal, target)
|
sell_uuid = submit_limit_sell(ticker, actual_bal, target)
|
||||||
positions[ticker] = {
|
positions[ticker] = {
|
||||||
'entry_price': avg,
|
'entry_price': avg,
|
||||||
'entry_ts': datetime.now() - timedelta(seconds=LLM_MIN_ELAPSED), # LLM 즉시 활성
|
'entry_ts': datetime.now() - timedelta(seconds=LLM_MIN_ELAPSED), # LLM 즉시 활성
|
||||||
'running_peak': avg,
|
'running_peak': avg,
|
||||||
'qty': bal,
|
'qty': actual_bal,
|
||||||
'stage': 0,
|
'stage': 0,
|
||||||
'sell_uuid': sell_uuid,
|
'sell_uuid': sell_uuid,
|
||||||
'sell_price': target,
|
'sell_price': target,
|
||||||
'llm_last_ts': None,
|
'llm_last_ts': None,
|
||||||
'llm_active': False,
|
'llm_active': False,
|
||||||
}
|
}
|
||||||
log.info(f"[복구] {ticker} 수량:{bal:.6f} 매수평균:{avg:,.0f}원")
|
log.info(f"[복구] {ticker} 수량:{actual_bal:.6f} 매수평균:{avg:,.0f}원")
|
||||||
tg(f"♻️ <b>포지션 복구</b> {ticker}\n매수평균: {avg:,.0f}원 수량: {bal:.6f}")
|
tg(f"♻️ <b>포지션 복구</b> {ticker}\n매수평균: {avg:,.0f}원 수량: {actual_bal:.6f}")
|
||||||
if positions:
|
if positions:
|
||||||
log.info(f"[복구] 총 {len(positions)}개 포지션 복구됨")
|
log.info(f"[복구] 총 {len(positions)}개 포지션 복구됨")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
Reference in New Issue
Block a user