fix bug
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user