fix(tinvest): чистка отменённых операций, цена бумаги от брокера, логотипы эмитентов
Отменённые и незавершённые операции удаляются из event по raw_tinvest_operation, а не только из текущего окна синка. Бумага, которую MOEX не котирует (структурные ноты, внебиржевые облигации), получает цену из портфеля брокера. Логотип и цвет бренда копируются в instrument (миграция e8b21f6a90c3).
This commit is contained in:
@@ -107,3 +107,64 @@ async def test_re_reading_removes_a_cancelled_order_imported_before_this_filter(
|
||||
|
||||
await write(account, op("cancel-1", "OPERATION_STATE_CANCELED"))
|
||||
assert await dedupe_keys() == []
|
||||
|
||||
|
||||
async def _raw(state: object, op_id: str) -> None:
|
||||
from fintracker.models import RawTinvestOperation
|
||||
|
||||
async with get_sessionmaker()() as session:
|
||||
session.add(
|
||||
RawTinvestOperation(
|
||||
account_id="tinv-1",
|
||||
id=op_id,
|
||||
operation_type="OPERATION_TYPE_BUY",
|
||||
ts=datetime(2026, 4, 2, 10, 0, tzinfo=UTC),
|
||||
payload={"state": state},
|
||||
)
|
||||
)
|
||||
await session.commit()
|
||||
|
||||
|
||||
async def _event(account: int, op_id: str) -> None:
|
||||
async with get_sessionmaker()() as session:
|
||||
session.add(
|
||||
Event(
|
||||
account_id=account,
|
||||
kind=EventKind.buy,
|
||||
ts=datetime(2026, 4, 2, 10, 0, tzinfo=UTC),
|
||||
trade_date=datetime(2026, 4, 2, tzinfo=UTC).date(),
|
||||
quantity=D(2),
|
||||
amount=D("-22650.95"),
|
||||
currency="RUB",
|
||||
source="tinvest",
|
||||
source_id=op_id,
|
||||
dedupe_key=f"tinvest:tinv-1:{op_id}",
|
||||
)
|
||||
)
|
||||
await session.commit()
|
||||
|
||||
|
||||
async def test_a_cancelled_order_that_is_no_longer_re_read_is_still_removed(app):
|
||||
"""The sync re-reads only a recent window, so an old cancelled order never comes back in
|
||||
the batch. It is found through the raw table instead."""
|
||||
account = await broker_account()
|
||||
await _raw(2, "old-cancel") # the payload keeps the enum as its number
|
||||
await _raw("OPERATION_STATE_PROGRESS", "old-progress")
|
||||
await _raw(1, "old-exec")
|
||||
for op_id in ("old-cancel", "old-progress", "old-exec"):
|
||||
await _event(account, op_id)
|
||||
|
||||
await write(account, op("fresh-1", "OPERATION_STATE_EXECUTED", quantity="1"))
|
||||
|
||||
assert sorted(await dedupe_keys()) == ["tinvest:tinv-1:fresh-1", "tinvest:tinv-1:old-exec"]
|
||||
|
||||
|
||||
async def test_the_purge_is_a_no_op_on_a_clean_ledger(app):
|
||||
account = await broker_account()
|
||||
await _raw(1, "old-exec")
|
||||
await _event(account, "old-exec")
|
||||
|
||||
await write(account, op("fresh-1", "OPERATION_STATE_EXECUTED", quantity="1"))
|
||||
await write(account, op("fresh-1", "OPERATION_STATE_EXECUTED", quantity="1"))
|
||||
|
||||
assert sorted(await dedupe_keys()) == ["tinvest:tinv-1:fresh-1", "tinvest:tinv-1:old-exec"]
|
||||
|
||||
Reference in New Issue
Block a user