|
@@ -128,6 +128,76 @@ def test_sell_final_pnl_uses_the_same_row() -> None:
|
|
|
assert sold.check_value == Decimal("70.00")
|
|
assert sold.check_value == Decimal("70.00")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+def test_note_distance_ratios_use_cleared_prices_and_round_half_up() -> None:
|
|
|
|
|
+ """风控距离比例用票据清算结果重算,按百分数保留两位。"""
|
|
|
|
|
+
|
|
|
|
|
+ note = {
|
|
|
|
|
+ "id": 31,
|
|
|
|
|
+ "note_no": "N1",
|
|
|
|
|
+ "latest_px": Decimal("200"),
|
|
|
|
|
+ "warn_price": Decimal("179.99"),
|
|
|
|
|
+ "danger_price": Decimal("159.98"),
|
|
|
|
|
+ "force_price": Decimal("139.97"),
|
|
|
|
|
+ "distance_warning": Decimal("10.01"),
|
|
|
|
|
+ "distance_danger": Decimal("20.01"),
|
|
|
|
|
+ "distance_force": Decimal("30.02"),
|
|
|
|
|
+ }
|
|
|
|
|
+ lines = check_order(_order(_sub(), notes=(note,)))
|
|
|
|
|
+ warning = _one(lines, "distance_warning")
|
|
|
|
|
+ assert warning.verdict == "correct"
|
|
|
|
|
+ assert warning.calc_value == Decimal("10.01")
|
|
|
|
|
+ assert warning.check_value == Decimal("10.01")
|
|
|
|
|
+ danger = _one(lines, "distance_danger")
|
|
|
|
|
+ assert danger.verdict == "correct"
|
|
|
|
|
+ assert danger.calc_value == Decimal("20.01")
|
|
|
|
|
+ force = _one(lines, "distance_force")
|
|
|
|
|
+ assert force.verdict == "correct"
|
|
|
|
|
+ assert force.calc_value == Decimal("30.02")
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def test_note_distance_ratio_mismatch_is_error_and_zero_latest_is_suspect() -> None:
|
|
|
|
|
+ note = {
|
|
|
|
|
+ "id": 31,
|
|
|
|
|
+ "note_no": "N1",
|
|
|
|
|
+ "latest_px": Decimal("100"),
|
|
|
|
|
+ "warn_price": Decimal("90"),
|
|
|
|
|
+ "danger_price": Decimal("80"),
|
|
|
|
|
+ "force_price": Decimal("70"),
|
|
|
|
|
+ "distance_warning": Decimal("9.99"),
|
|
|
|
|
+ "distance_danger": Decimal("20.00"),
|
|
|
|
|
+ "distance_force": Decimal("30.00"),
|
|
|
|
|
+ }
|
|
|
|
|
+ warning = _one(check_order(_order(_sub(), notes=(note,))), "distance_warning")
|
|
|
|
|
+ assert warning.verdict == "error"
|
|
|
|
|
+ assert warning.calc_value == Decimal("10.00")
|
|
|
|
|
+
|
|
|
|
|
+ note["latest_px"] = Decimal("0")
|
|
|
|
|
+ warning = _one(check_order(_order(_sub(), notes=(note,))), "distance_warning")
|
|
|
|
|
+ assert warning.verdict == "suspect"
|
|
|
|
|
+ assert warning.calc_value is None
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+def test_sell_order_checks_note_distance_ratios() -> None:
|
|
|
|
|
+ order = _sell_order()
|
|
|
|
|
+ note = order["note_sub_a"][0]
|
|
|
|
|
+ assert isinstance(note, dict)
|
|
|
|
|
+ note.update(
|
|
|
|
|
+ {
|
|
|
|
|
+ "latest_px": Decimal("100"),
|
|
|
|
|
+ "warn_price": Decimal("90"),
|
|
|
|
|
+ "danger_price": Decimal("80"),
|
|
|
|
|
+ "force_price": Decimal("70"),
|
|
|
|
|
+ "distance_warning": Decimal("10"),
|
|
|
|
|
+ "distance_danger": Decimal("20"),
|
|
|
|
|
+ "distance_force": Decimal("30"),
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+ lines = check_order(order)
|
|
|
|
|
+ assert _one(lines, "distance_warning").verdict == "correct"
|
|
|
|
|
+ assert _one(lines, "distance_danger").verdict == "correct"
|
|
|
|
|
+ assert _one(lines, "distance_force").verdict == "correct"
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
def test_sell_ratio_without_exec_notional_is_not_checked() -> None:
|
|
def test_sell_ratio_without_exec_notional_is_not_checked() -> None:
|
|
|
"""执行名义本金和当前名义本金都没有时,比例三列不核。"""
|
|
"""执行名义本金和当前名义本金都没有时,比例三列不核。"""
|
|
|
|
|
|