From a004d498abaf34ebbc792e37753eeee62f85e6ea Mon Sep 17 00:00:00 2001 From: khwkim1111 Date: Sat, 9 May 2026 13:22:16 +0900 Subject: [PATCH] commit --- bot bond sell.py | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/bot bond sell.py b/bot bond sell.py index 94b8bfd..a036399 100644 --- a/bot bond sell.py +++ b/bot bond sell.py @@ -55,17 +55,17 @@ def main(): # XLF state machine # IDLE → BUYING_BASKET → CONVERTING → SELLING_XLF → IDLE (바스켓→XLF) # IDLE → BUYING_XLF → CONVERTING → SELLING_BASKET → IDLE (XLF→바스켓) - xlf_state = "IDLE" - xlf_pending = set() # 체결 대기 중인 주문 ID - xlf_direction = None # "BASKET_TO_XLF" or "XLF_TO_BASKET" + xlf_state = "IDLE" + xlf_pending = {} # {order_id: remaining_size} 부분 체결 추적 + xlf_direction = None # "BASKET_TO_XLF" or "XLF_TO_BASKET" - state = StateManager() - om = OrderManager() - market_open = False + state = StateManager() + om = OrderManager() + market_open = False active_orders = {} # BOND 전용 {order_id: {"dir": ..., "price": ...}} - last_refresh = time.time() - vale_last_print = time.time() + last_refresh = time.time() + vale_last_print = time.time() def next_id(): return om.next_order() @@ -156,11 +156,11 @@ def main(): xlf_direction = "BASKET_TO_XLF" xlf_pending.clear() - # 바스켓 구성 종목 매수 + # 바스켓 구성 종목 매수 (size 추적) for sym, qty in [("BOND", 3), ("GS", 2), ("MS", 3), ("WFC", 2)]: oid = next_id() exchange.send_add_message(oid, sym, Dir.BUY, state.ask_prices[sym], qty) - xlf_pending.add(oid) + xlf_pending[oid] = qty return # 케이스 2: XLF 매수 → 바스켓 변환 → 각 종목 매도 @@ -173,16 +173,19 @@ def main(): oid = next_id() exchange.send_add_message(oid, "XLF", Dir.BUY, xlf_ask, 10) - xlf_pending.add(oid) + xlf_pending[oid] = 10 def handle_xlf_fill(order_id: int, symbol: str, dir_: Dir, qty: int): - """XLF state machine 체결 처리""" + """XLF state machine 체결 처리 (부분 체결 추적)""" nonlocal xlf_state, xlf_pending if order_id not in xlf_pending: return - xlf_pending.discard(order_id) + # 부분 체결 차감 + xlf_pending[order_id] -= qty + if xlf_pending[order_id] <= 0: + del xlf_pending[order_id] if xlf_state == "BUYING_BASKET" and not xlf_pending: # 바스켓 전부 체결 → XLF로 변환 @@ -237,15 +240,14 @@ def main(): elif message["type"] == "reject": print(message) - # 거부된 주문은 active_orders에서 제거 oid = message.get("order_id") active_orders.pop(oid, None) - xlf_pending.discard(oid) # XLF 주문 reject 시 IDLE로 복귀 - if xlf_state != "IDLE" and oid in xlf_pending: + if oid in xlf_pending: print(f" XLF 주문 reject → IDLE 복귀") xlf_state = "IDLE" xlf_pending.clear() + xlf_direction = None elif message["type"] == "ack": # 변환 ack 처리 (convert는 fill이 아닌 ack로 완료됨) @@ -258,7 +260,7 @@ def main(): exchange.send_add_message( oid, "XLF", Dir.SELL, state.bid_prices["XLF"], 10 ) - xlf_pending.add(oid) + xlf_pending[oid] = 10 elif xlf_direction == "XLF_TO_BASKET": # 바스켓 각 종목 매도 xlf_state = "SELLING_BASKET" @@ -267,13 +269,14 @@ def main(): exchange.send_add_message( oid, sym, Dir.SELL, state.bid_prices[sym], qty ) - xlf_pending.add(oid) + xlf_pending[oid] = qty elif message["type"] == "fill": print(message) qty = message["size"] sym = message["symbol"] dir_ = message["dir"] + oid = message["order_id"] # 포지션 업데이트 if dir_ == Dir.BUY: @@ -283,17 +286,16 @@ def main(): print(f" 포지션 → {state.positions}") - # BOND 체결 시 재주문 - if sym == "BOND" and message["order_id"] in active_orders: - active_orders.pop(message["order_id"], None) + # BOND 체결 시 무조건 재주문 + if sym == "BOND" and oid in active_orders: + active_orders.pop(oid, None) place_bond_orders() # XLF state machine 체결 처리 - handle_xlf_fill(message["order_id"], sym, dir_, qty) + handle_xlf_fill(oid, sym, dir_, qty) # SELLING 단계에서 pending 소진 시 IDLE 복귀 if xlf_state in ("SELLING_XLF", "SELLING_BASKET"): - xlf_pending.discard(message["order_id"]) if not xlf_pending: print(" XLF 차익거래 완료 → IDLE 복귀") xlf_state = "IDLE"