Skip to content

Commit 96f88e3

Browse files
committed
Remove LongBridge fractional order support
1 parent fa8a014 commit 96f88e3

3 files changed

Lines changed: 28 additions & 108 deletions

File tree

src/quant_platform_kit/longbridge/execution.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ def estimate_max_purchase_quantity(
1212
*,
1313
order_kind: str,
1414
ref_price: float,
15-
fractional_shares: bool = False,
1615
) -> float:
1716
from longport.openapi import OrderSide, OrderType
1817

@@ -22,7 +21,6 @@ def estimate_max_purchase_quantity(
2221
order_type=order_type,
2322
side=OrderSide.Buy,
2423
price=Decimal(str(ref_price)),
25-
fractional_shares=bool(fractional_shares),
2624
)
2725
cash_max_qty = getattr(response, "cash_max_qty", 0)
2826
return max(0.0, float(Decimal(str(cash_max_qty or "0"))))
@@ -42,15 +40,16 @@ def submit_order(
4240
order_type = OrderType.LO if order_kind == "limit" else OrderType.MO
4341
order_side = OrderSide.Buy if side == "buy" else OrderSide.Sell
4442
submitted_quantity = Decimal(str(quantity))
45-
if submitted_quantity < Decimal("1"):
43+
if submitted_quantity < Decimal("1") or submitted_quantity != submitted_quantity.to_integral_value():
4644
return ExecutionReport(
4745
symbol=symbol.split(".")[0],
4846
side=side,
4947
quantity=float(quantity),
5048
status="rejected",
5149
raw_payload={
5250
"detail": (
53-
"LongBridge submitted_quantity must be at least 1 share; "
51+
"LongBridge submitted_quantity must be a whole-share quantity "
52+
"of at least 1 share; "
5453
f"got {submitted_quantity}."
5554
),
5655
"order_kind": order_kind,

tests/test_longbridge_execution.py

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,28 +53,23 @@ def test_estimate_max_purchase_quantity(self) -> None:
5353
quantity = estimate_max_purchase_quantity(ctx, "SOXL.US", order_kind="limit", ref_price=100.5)
5454

5555
self.assertEqual(quantity, 12)
56-
self.assertIs(ctx.estimate_kwargs["fractional_shares"], False)
56+
self.assertNotIn("fractional_shares", ctx.estimate_kwargs)
5757

58-
def test_estimate_max_purchase_quantity_can_request_fractional_buying_power(self) -> None:
58+
def test_submit_order(self) -> None:
5959
longport_module = types.ModuleType("longport")
6060
openapi_module = types.ModuleType("longport.openapi")
61-
openapi_module.OrderSide = types.SimpleNamespace(Buy="Buy")
61+
openapi_module.OrderSide = types.SimpleNamespace(Buy="Buy", Sell="Sell")
6262
openapi_module.OrderType = types.SimpleNamespace(LO="LO", MO="MO")
63+
openapi_module.TimeInForceType = types.SimpleNamespace(Day="Day")
6364

6465
ctx = FakeTradeContext()
6566
with patch.dict(sys.modules, {"longport": longport_module, "longport.openapi": openapi_module}):
66-
quantity = estimate_max_purchase_quantity(
67-
ctx,
68-
"SOXX.US",
69-
order_kind="limit",
70-
ref_price=495.91,
71-
fractional_shares=True,
72-
)
67+
report = submit_order(ctx, "SOXL.US", order_kind="limit", side="buy", quantity=5, submitted_price=100.25)
7368

74-
self.assertEqual(quantity, 12)
75-
self.assertIs(ctx.estimate_kwargs["fractional_shares"], True)
69+
self.assertEqual(report.status, "submitted")
70+
self.assertEqual(report.broker_order_id, "OID-1")
7671

77-
def test_submit_order(self) -> None:
72+
def test_submit_order_allows_whole_decimal_quantity(self) -> None:
7873
longport_module = types.ModuleType("longport")
7974
openapi_module = types.ModuleType("longport.openapi")
8075
openapi_module.OrderSide = types.SimpleNamespace(Buy="Buy", Sell="Sell")
@@ -83,12 +78,12 @@ def test_submit_order(self) -> None:
8378

8479
ctx = FakeTradeContext()
8580
with patch.dict(sys.modules, {"longport": longport_module, "longport.openapi": openapi_module}):
86-
report = submit_order(ctx, "SOXL.US", order_kind="limit", side="buy", quantity=5, submitted_price=100.25)
81+
report = submit_order(ctx, "SOXL.US", order_kind="limit", side="buy", quantity=1.0, submitted_price=100.25)
8782

8883
self.assertEqual(report.status, "submitted")
89-
self.assertEqual(report.broker_order_id, "OID-1")
84+
self.assertEqual(str(ctx.submit_args[3]), "1.0")
9085

91-
def test_submit_order_allows_decimal_quantity_at_or_above_one_share(self) -> None:
86+
def test_submit_order_rejects_quantity_below_one_before_api_call(self) -> None:
9287
longport_module = types.ModuleType("longport")
9388
openapi_module = types.ModuleType("longport.openapi")
9489
openapi_module.OrderSide = types.SimpleNamespace(Buy="Buy", Sell="Sell")
@@ -97,12 +92,20 @@ def test_submit_order_allows_decimal_quantity_at_or_above_one_share(self) -> Non
9792

9893
ctx = FakeTradeContext()
9994
with patch.dict(sys.modules, {"longport": longport_module, "longport.openapi": openapi_module}):
100-
report = submit_order(ctx, "SOXL.US", order_kind="limit", side="buy", quantity=1.5, submitted_price=100.25)
95+
report = submit_order(
96+
ctx,
97+
"SOXX.US",
98+
order_kind="limit",
99+
side="buy",
100+
quantity=0.4326,
101+
submitted_price=495.91,
102+
)
101103

102-
self.assertEqual(report.status, "submitted")
103-
self.assertEqual(str(ctx.submit_args[3]), "1.5")
104+
self.assertEqual(report.status, "rejected")
105+
self.assertIn("whole-share quantity of at least 1 share", report.raw_payload["detail"])
106+
self.assertFalse(hasattr(ctx, "submit_args"))
104107

105-
def test_submit_order_rejects_quantity_below_one_before_api_call(self) -> None:
108+
def test_submit_order_rejects_fractional_quantity_before_api_call(self) -> None:
106109
longport_module = types.ModuleType("longport")
107110
openapi_module = types.ModuleType("longport.openapi")
108111
openapi_module.OrderSide = types.SimpleNamespace(Buy="Buy", Sell="Sell")
@@ -116,12 +119,12 @@ def test_submit_order_rejects_quantity_below_one_before_api_call(self) -> None:
116119
"SOXX.US",
117120
order_kind="limit",
118121
side="buy",
119-
quantity=0.4326,
122+
quantity=1.5,
120123
submitted_price=495.91,
121124
)
122125

123126
self.assertEqual(report.status, "rejected")
124-
self.assertIn("at least 1 share", report.raw_payload["detail"])
127+
self.assertIn("whole-share quantity of at least 1 share", report.raw_payload["detail"])
125128
self.assertFalse(hasattr(ctx, "submit_args"))
126129

127130
def test_fetch_order_status(self) -> None:

tests/test_longbridge_fractional_order_api_probe.py

Lines changed: 0 additions & 82 deletions
This file was deleted.

0 commit comments

Comments
 (0)