fix(trend): reconcile state from actual fills

This commit is contained in:
2026-09-05 00:29:50 +08:00
parent 6c2eca8fdc
commit a53fc738cf
5 changed files with 76 additions and 37 deletions

View File

@@ -44,9 +44,9 @@ class FailedOrderClient:
class TrendTests(unittest.TestCase):
def test_trend_order_id_format(self):
self.assertRegex(OrderBook.new_order_id("base"), r"^trend-[0-9a-f]{8}$")
self.assertRegex(OrderBook.new_order_id(), r"^trend-[0-9a-f]{24}$")
def test_open_records_base_order_and_rounded_cost(self):
def test_open_records_only_pending_order(self):
with TemporaryDirectory() as directory:
state = State.for_strategy(directory, "trend", "A")
forgotten = []
@@ -60,9 +60,9 @@ class TrendTests(unittest.TestCase):
do_open(runtime, "000001.SZ", 100, "morning", 12.345)
item = state.get("000001.SZ")
self.assertRegex(item.base_order_id, r"^trend-[0-9a-f]{8}$")
self.assertEqual(item.base_qty, 100)
self.assertEqual(item.base_cost, 12.35)
self.assertRegex(item.base_order_id, r"^trend-[0-9a-f]{24}$")
self.assertEqual(item.base_qty, 0)
self.assertEqual(item.base_cost, 0)
self.assertEqual(item.base_status, "ING")
self.assertEqual(forgotten, ["000001.SZ"])
@@ -226,7 +226,10 @@ class TrendTests(unittest.TestCase):
state = State.for_strategy(directory, "trend", "A")
position = PositionItem(stock_code="A", volume=100, open_price=10)
state.set(StateItem("A", base_order_id="local-1", base_status="ING"))
completed = OrderItem("1", "A", "BUY", "", "56", None, 50, "local-1")
completed = OrderItem(
"1", "A", "BUY", "", "56", None, 50, "local-1",
traded_volume=50, trade_price=10.1,
)
processing = OrderItem("2", "A", "BUY", "", "50", None, 50, "local-1")
state.reconcile([position], [completed, processing])
@@ -234,9 +237,18 @@ class TrendTests(unittest.TestCase):
state.reconcile(
[position],
[completed, OrderItem("2", "A", "BUY", "", "56", None, 50, "local-1")],
[
completed,
OrderItem(
"2", "A", "BUY", "", "56", None, 50, "local-1",
traded_volume=50, trade_price=10.3,
),
],
)
self.assertEqual(state.get("A").base_status, STATUS_OK)
item = state.get("A")
self.assertEqual(item.base_status, STATUS_OK)
self.assertEqual(item.base_qty, 100)
self.assertEqual(item.base_cost, 10.2)
canceled = OrderItem("2", "A", "BUY", "", "54", None, 50, "local-1")
item = state.get("A")
@@ -245,6 +257,31 @@ class TrendTests(unittest.TestCase):
state.reconcile([position], [completed, canceled])
self.assertEqual(state.get("A").base_status, "")
def test_reconcile_records_filled_add_order(self):
with TemporaryDirectory() as directory:
state = State.for_strategy(directory, "trend", "A")
position = PositionItem(stock_code="A", volume=200, open_price=10)
state.set(StateItem(
"A",
base_qty=100,
base_cost=10,
base_status=STATUS_OK,
added_order_id="add-1",
added_status="ING",
))
completed = OrderItem(
"1", "A", "BUY", "", "56", None, 100, "add-1",
traded_volume=100, trade_amount=950,
)
state.reconcile([position], [completed])
item = state.get("A")
self.assertEqual(item.added_status, STATUS_OK)
self.assertEqual(item.added_num, 1)
self.assertEqual(item.added_qty, 100)
self.assertEqual(item.added_cost, 9.5)
def test_low_cash_still_runs_position_management(self):
client = SimpleNamespace(
portfolio=lambda: Portfolio(