This commit is contained in:
2026-09-07 00:27:33 +08:00
parent fdcbdc7869
commit d37f9edefc
11 changed files with 839 additions and 384 deletions

View File

@@ -0,0 +1,78 @@
import sqlite3
import tempfile
import unittest
from contextlib import closing
from dataclasses import asdict
from pathlib import Path
from libs.orderbook import OrderBook
from sdk.models import DealItem
from sdk.portfolio import PortfolioMixin
class DealModelTests(unittest.TestCase):
def setUp(self):
self.raw = {
'm_strOrderSysID': 'sys-123',
'm_strInstrumentID': '600000',
'm_strExchangeID': 'SH',
'm_strInstrumentName': 'Test stock',
'm_nOffsetFlag': '24',
'm_nOrderStatus': '56',
'm_nVolumeTotal': '0',
'm_nVolumeTraded': '200',
'm_nOrderTime': '101530',
'm_strInsertDate': '20260907',
'm_strInsertTime': '10:15:30',
'm_strRemark': 'zt-t-sell-local1|zt',
'm_dPrice': '15.8',
'm_dTradePrice': '15.6',
'm_dTradeAmount': '3120',
}
def test_all_api_fields_are_parsed(self):
self.assertEqual(asdict(DealItem.from_trade_detail(self.raw)), {
'sys_order_id': 'sys-123', 'local_order_id': 'zt-t-sell-local1',
'code': '600000.SH', 'instrument_id': '600000', 'exchange_id': 'SH',
'name': 'Test stock', 'offset_flag': '24', 'side': 'SELL', 'status': '56',
'remaining_volume': 0, 'traded_volume': 200, 'order_time': 101530,
'insert_date': '20260907', 'insert_time': '10:15:30',
'remark': 'zt-t-sell-local1|zt', 'price': 15.8,
'trade_price': 15.6, 'trade_amount': 3120.0,
})
def test_api_deals_response_returns_deal_items(self):
client = PortfolioMixin()
for response in ({'deals': [self.raw]}, [self.raw]):
with self.subTest(response_type=type(response).__name__):
client._get_json = lambda path: response
deals = client.deals()
self.assertIsInstance(deals[0], DealItem)
self.assertEqual(deals[0].sys_order_id, 'sys-123')
self.assertEqual(deals[0].traded_volume, 200)
def test_model_matches_sql_columns_and_restart(self):
deal = DealItem.from_trade_detail(self.raw)
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / 'state.db'
book = OrderBook(path)
book.sync_deals([deal])
with closing(sqlite3.connect(path)) as db:
columns = {row[1] for row in db.execute('PRAGMA table_info(deals)')}
self.assertEqual(columns, {'id', *asdict(deal)})
loaded = OrderBook(path).deals['sys-123']
expected = asdict(deal)
expected['insert_date'] = '2026-09-07'
self.assertEqual({key: value for key, value in loaded.items() if key != 'id'}, expected)
def test_missing_amount_uses_execution_price_not_order_price(self):
deal = DealItem.from_trade_detail({**self.raw, 'm_dTradeAmount': '0'})
row = OrderBook.deal_record(deal)
self.assertEqual(row['trade_amount'], 3120)
deal.trade_price = 0
with self.assertRaises(ValueError):
OrderBook.deal_record(deal)
if __name__ == '__main__':
unittest.main()