"""exchange reconcile 단위 테스트.""" from __future__ import annotations from datetime import datetime, timedelta from bithumb.operations.exchange_reconcile import ( _match_orders_to_signals, _trade_from_exchange_order, ) def test_match_orders_to_signals_by_side_and_time() -> None: """같은 side·시간 창 안에서 주문-신호 1:1 매칭.""" sig_dt = datetime(2026, 6, 14, 10, 48, 0) signals = [ {"datetime": sig_dt.strftime("%Y-%m-%d %H:%M:%S"), "side": "buy", "bar_index": 1}, ] order_dt = sig_dt + timedelta(minutes=30) orders = [ { "uuid": "order-1", "side": "bid", "created_at": order_dt.isoformat(), "executed_volume": "0.001", "executed_funds": "100000", }, ] matches = _match_orders_to_signals( orders, signals, match_window_min=720, known_uuids=set(), ) assert len(matches) == 1 assert matches[0][0]["side"] == "buy" assert matches[0][1]["uuid"] == "order-1" def test_match_skips_known_uuid() -> None: """이미 history에 있는 uuid는 재매칭하지 않는다.""" sig_dt = datetime(2026, 6, 14, 11, 0, 0) signals = [ {"datetime": sig_dt.strftime("%Y-%m-%d %H:%M:%S"), "side": "sell", "bar_index": 2}, ] orders = [ { "uuid": "already-used", "side": "ask", "created_at": (sig_dt + timedelta(minutes=5)).isoformat(), "executed_volume": "0.001", "executed_funds": "100000", }, ] matches = _match_orders_to_signals( orders, signals, match_window_min=720, known_uuids={"already-used"}, ) assert matches == [] def test_trade_from_exchange_order_buy() -> None: """매수 체결 → executed TradeResult.""" sig = {"datetime": "2026-06-14 10:48:00", "side": "buy", "price": 140_000_000.0} order = { "uuid": "x", "side": "bid", "executed_volume": "0.002", "executed_funds": "280000", } trade = _trade_from_exchange_order(sig, order) assert trade.executed is True assert trade.side == "buy" assert trade.order_coin == 0.002 assert trade.api_response == order