auto: 일일 백업 2026-09-12 02:00

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
hyowons
2026-09-12 02:00:06 +09:00
parent b4f510d1ad
commit 34498c554e
139 changed files with 1839 additions and 1574 deletions
@@ -1006,6 +1006,15 @@ def modify_open_order(ord_no: Optional[str] = None,
return {'ok': False, 'message': resolved['message'], 'code': resolved['code']}
row = resolved['row']
# 스톱지정가(trde_tp=28) 계열은 정정 대상에서 뺀다. 두 가지가 동시에 깨진다:
# ① 여기선 mdfy_cond_uv 를 안 넘겨 조건단가가 빈 값으로 나간다(조건 소실 위험).
# ② 정정 응답 ord_no 가 신규 번호라, trailing_stops.json 의 레그 ord_no 가 어긋나
# 그 레그의 자동 손절선 상향이 이후 전부 실패한다.
# 바꾸고 싶으면 취소 후 재등록이 맞다.
if row.get('stop_price'):
return {'ok': False, 'code': 'STOP_ORDER',
'message': f"⛔ 스톱지정가·트레일링 주문은 정정 불가 (ord_no={row['ord_no']}) — "
'취소 후 재등록하세요'}
if qty is None and price is None:
return {'ok': False,
'message': '⛔ 정정 항목 누락 — qty/price 중 최소 하나는 필요합니다'}
@@ -1020,6 +1029,27 @@ def modify_open_order(ord_no: Optional[str] = None,
return {'ok': False,
'message': '⛔ 시장가 미체결은 정정 불가 (가격 0). 취소 후 신규 발주하세요.'}
# 가격제한폭·예수금 — 신규 주문과 같은 가드를 태운다. 정정도 결국 새 가격으로 주문이 나가고,
# propose 만 막아두면 정정이 그 검증을 우회하는 뒷문이 된다.
# 매도 보유수량은 태우지 않는다 — 이미 접수된 주문의 수량을 그대로 두거나 줄이는 경로라
# (웹은 price 만 보낸다) 새로 필요한 보유분이 없다.
md = datasource.collect_market_data(row['account'], row['code'], row['side'], new_qty)
r = guards.validate_price_band(row['side'], new_price,
md['upper_limit'], md['lower_limit'])
if not r.ok:
return {'ok': False, 'code': r.code,
'message': f"⛔ 정정 거부 [{r.code}] · ord_no={row['ord_no']} · {r.message}"}
if row['side'] == 'BUY':
# ⚠️ md['balance_d2'] 는 미체결 매수로 묶인 돈을 **정정 대상 주문까지 포함해** 뺀 값이다.
# 그 주문은 지금 가격을 바꾸는 당사자라, 되돌려 더하지 않으면 제 주문에 제가 막힌다
# (149,000×2 로 묶인 상태에서 149,100 으로 올리는 것조차 '예수금 부족'이 된다).
# 되더하는 식은 datasource 의 locked 계산(order_price × unfilled_qty)과 같아야 정확히 상쇄된다.
avail = md['balance_d2'] + row['order_price'] * row['unfilled_qty']
r = guards.validate_balance_for_buy(new_qty, new_price, avail)
if not r.ok:
return {'ok': False, 'code': r.code,
'message': f"⛔ 정정 거부 [{r.code}] · ord_no={row['ord_no']} · {r.message}"}
side_word = '매수' if row['side'] == 'BUY' else ('매도' if row['side'] == 'SELL' else row['side'])
res = kiwoom_order.modify_order(
account_label=row['account'],