import pytest from app.core.order_lifecycle import ( evaluate_limit_order, order_distance_pct, order_expires_at, order_rr, order_touched, order_too_far, ) def test_limit_order_touched_for_long_and_short(): assert order_touched({"side": "long", "target_price": 95}, 94.9) is True assert order_touched({"side": "long", "target_price": 95}, 96) is False assert order_touched({"side": "short", "target_price": 105}, 105.1) is True assert order_touched({"side": "short", "target_price": 105}, 104.9) is False assert order_touched({"side": "空", "target_price": 105}, 105.1) is True assert order_touched({"side": "做空", "target_price": 105}, 105.1) is True assert order_touched({"side": "sell", "target_price": 105}, 105.1) is True def test_limit_order_cancel_when_expired(): decision = evaluate_limit_order( order={"id": 1, "side": "long", "target_price": 95, "expires_at": "2026-05-16T10:00:00"}, current_price=100, event_time="2026-05-16T10:01:00", config={"order_cancel_far_from_entry_pct": 12}, ).as_dict() assert decision["action"] == "cancel" assert decision["reason"] == "expired" def test_limit_order_cancel_when_price_moves_too_far(): order = {"id": 1, "side": "long", "target_price": 95, "expires_at": "2026-05-17T10:00:00"} assert order_too_far(order, 107, threshold_pct=12) is True decision = evaluate_limit_order( order=order, current_price=107, event_time="2026-05-16T10:01:00", config={"order_cancel_far_from_entry_pct": 12}, ).as_dict() assert decision["action"] == "cancel" assert decision["reason"] == "too_far_from_entry" def test_order_rr_and_distance_are_side_aware(): assert order_rr("long", 95, 90, 105) == pytest.approx(2.0) assert order_rr("short", 105, 110, 95) == pytest.approx(2.0) assert order_distance_pct("long", 100, 95) == pytest.approx(5.2631578947) assert order_distance_pct("short", 100, 105) == pytest.approx(5.0) assert order_distance_pct("空", 100, 105) == pytest.approx(5.0) def test_order_expires_at_uses_minimum_quarter_hour(): assert order_expires_at("2026-05-16T10:00:00", expire_hours=0.1) == "2026-05-16T10:15:00"