feat(vol_breakout): 15m 현물 롱 라이브·모니터·cron 운영 추가
vol_breakout 멀티종목 tick, vol_live HTML 모니터, 마감 봉만 저장하는 캔들 다운로드, 텔레그램 체결 알림, cron/watch 감시 스크립트 및 테스트를 포함한다. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
77
tests/test_exchange_reconcile.py
Normal file
77
tests/test_exchange_reconcile.py
Normal file
@@ -0,0 +1,77 @@
|
||||
"""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
|
||||
Reference in New Issue
Block a user