This commit is contained in:
2026-09-10 22:16:18 +08:00
parent 1255ab21ba
commit 4e693d773a
2 changed files with 44 additions and 37 deletions

View File

@@ -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()

View File

@@ -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