From 4e693d773a9446c1830ddd2d8365fb53ddc76661 Mon Sep 17 00:00:00 2001 From: yanweidong Date: Thu, 10 Sep 2026 22:16:18 +0800 Subject: [PATCH] fix bug --- py-client/libs/state.py | 79 +++++++++++++++++++---------------- py-client/strategy/zt/boot.py | 2 +- 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/py-client/libs/state.py b/py-client/libs/state.py index 5c29e1e..da2a9c1 100644 --- a/py-client/libs/state.py +++ b/py-client/libs/state.py @@ -88,16 +88,26 @@ class State: return db def load(self) -> None: - """从数据库刷新状态、成交及去重缓存。""" + """缓存状态表和成交记录。""" + self.load_state() + self.load_deals() + + def load_state(self) -> None: + """缓存状态表。""" with closing(self._connect()) as db, db: db.execute('BEGIN') state = {row['stock_code']: dict(row) for row in db.execute('SELECT * FROM state')} - deals = {row['order_sys_id']: dict(row) for row in db.execute('SELECT * FROM deals ORDER BY id')} self.state = state + + def load_deals(self) -> None: + """缓存成交记录。""" + with closing(self._connect()) as db, db: + db.execute('BEGIN') + deals = {row['order_sys_id']: dict(row) for row in db.execute('SELECT * FROM deals ORDER BY id')} self.deals = deals self.deals_sys_ids = set(deals) - def sync_deals(self, deals: list[DealItem], *, archived: bool = False) -> None: + def sync_deals(self, deals: list[DealItem]) -> None: """按成交编号去重;初始化底仓时,已包含在快照内的成交可直接标记归档。""" new_deals = {} for deal in deals: @@ -124,10 +134,37 @@ class State: 'VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', (deal.stock_code, deal.order_sys_id, order_id, deal.ref, deal.order_ref, deal.direction, deal.offset_flag, deal.price, deal.volume, - amount, date, deal.trade_time, deal.remark, deal.close_profit, int(archived)), + amount, date, deal.trade_time, deal.remark, deal.close_profit, 0), ) - self.load() - + self.load_deals() + def sync_state(self, positions: list[PositionItem]) -> None: + """同步完整持仓:无状态则插入底仓,已有则保留,清仓则删除。 + """ + # 传入完整账户持仓;同步时间作为新增底仓的创建时间。 + created_at = datetime.now().isoformat(timespec='seconds') + holdings = {item.stock_code: item for item in positions if item.volume > 0} + with closing(self._connect()) as db, db: + db.execute('BEGIN') + existing = {row['stock_code'] for row in db.execute('SELECT stock_code FROM state')} + db.executemany( + 'DELETE FROM state WHERE stock_code = ?', + [(code,) for code in existing if code not in holdings], + ) + + for code, item in holdings.items(): + if code in existing: + continue + if not math.isfinite(item.open_price): + raise ValueError('Base price must be finite') + # 只插入底仓字段,补仓字段使用数据库默认值。 + db.execute( + 'INSERT INTO state ' + '(stock_code, status, base_order_local_id, base_qty, base_price, base_created_at) ' + "VALUES (?, '', '', ?, ?, ?)", + (code, item.volume, item.open_price, created_at), + ) + self.load_state() + def archiving(self, *, base_order_prefix: str = '') -> dict[str, str]: """将未归档成交累加到当前底仓和加仓;失败证券保留记录供重试。""" errors = {} @@ -197,34 +234,4 @@ class State: self.load() return errors - def sync_state(self, positions: list[PositionItem], *, remove_missing: bool = True) -> None: - """同步完整持仓:无状态则插入底仓,已有则保留,清仓则删除。 - 数量为零或未出现在完整持仓列表中的证券视为已清仓;空列表清空状态。 - 底仓已包含的历史成交不应再次归档;后续成交须先归档,再同步持仓。 - remove_missing=False 时仅接纳新底仓,减仓由成交归档处理。 - """ - # 传入完整账户持仓;同步时间作为新增底仓的创建时间。 - created_at = datetime.now().isoformat(timespec='seconds') - holdings = {item.stock_code: item for item in positions if item.volume > 0} - with closing(self._connect()) as db, db: - db.execute('BEGIN') - existing = {row['stock_code'] for row in db.execute('SELECT stock_code FROM state')} - if remove_missing: - db.executemany( - 'DELETE FROM state WHERE stock_code = ?', - [(code,) for code in existing if code not in holdings], - ) - for code, item in holdings.items(): - if code in existing: - continue - if not math.isfinite(item.open_price): - raise ValueError('Base price must be finite') - # 只插入底仓字段,补仓字段使用数据库默认值。 - db.execute( - 'INSERT INTO state ' - '(stock_code, status, base_order_local_id, base_qty, base_price, base_created_at) ' - "VALUES (?, '', '', ?, ?, ?)", - (code, item.volume, item.open_price, created_at), - ) - self.load() diff --git a/py-client/strategy/zt/boot.py b/py-client/strategy/zt/boot.py index f9d5c66..d491ade 100644 --- a/py-client/strategy/zt/boot.py +++ b/py-client/strategy/zt/boot.py @@ -85,7 +85,7 @@ def sync_account_state( ) -> None: """初次持仓作为底仓;后续只按成交减仓,避免延迟快照删除持仓。""" zt_deals = [d for d in deals if d.get_local_order_id.startswith('zt-')] - state.sync_deals(zt_deals, archived=initialize) + state.sync_deals(zt_deals) if initialize: state.sync_state(positions) return