vol_breakout 멀티종목 tick, vol_live HTML 모니터, 마감 봉만 저장하는 캔들 다운로드, 텔레그램 체결 알림, cron/watch 감시 스크립트 및 테스트를 포함한다. Co-authored-by: Cursor <cursoragent@cursor.com>
78 lines
2.2 KiB
Python
78 lines
2.2 KiB
Python
"""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
|