2026-02-01 20:34:57 +00:00

114 lines
3.0 KiB
Python

# engine/ledger.py
from datetime import datetime, timezone
from indian_paper_trading_strategy.engine.db import insert_engine_event, run_with_retry, get_context
from indian_paper_trading_strategy.engine.time_utils import normalize_logical_time
def _event_exists_in_tx(cur, event, logical_time, user_id: str | None = None, run_id: str | None = None):
scope_user, scope_run = get_context(user_id, run_id)
logical_ts = normalize_logical_time(logical_time)
cur.execute(
"""
SELECT 1
FROM event_ledger
WHERE user_id = %s AND run_id = %s AND event = %s AND logical_time = %s
LIMIT 1
""",
(scope_user, scope_run, event, logical_ts),
)
return cur.fetchone() is not None
def event_exists(event, logical_time, *, cur=None, user_id: str | None = None, run_id: str | None = None):
if cur is not None:
return _event_exists_in_tx(cur, event, logical_time, user_id=user_id, run_id=run_id)
def _op(cur, _conn):
return _event_exists_in_tx(cur, event, logical_time, user_id=user_id, run_id=run_id)
return run_with_retry(_op)
def _log_event_in_tx(
cur,
event,
payload,
ts,
logical_time=None,
user_id: str | None = None,
run_id: str | None = None,
):
scope_user, scope_run = get_context(user_id, run_id)
logical_ts = normalize_logical_time(logical_time or ts)
cur.execute(
"""
INSERT INTO event_ledger (
user_id,
run_id,
timestamp,
logical_time,
event,
nifty_units,
gold_units,
nifty_price,
gold_price,
amount
)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
ON CONFLICT DO NOTHING
""",
(
scope_user,
scope_run,
ts,
logical_ts,
event,
payload.get("nifty_units"),
payload.get("gold_units"),
payload.get("nifty_price"),
payload.get("gold_price"),
payload.get("amount"),
),
)
if cur.rowcount:
insert_engine_event(cur, event, data=payload, ts=ts)
def log_event(
event,
payload,
*,
cur=None,
ts=None,
logical_time=None,
user_id: str | None = None,
run_id: str | None = None,
):
now = ts or logical_time or datetime.utcnow().replace(tzinfo=timezone.utc)
if cur is not None:
_log_event_in_tx(
cur,
event,
payload,
now,
logical_time=logical_time,
user_id=user_id,
run_id=run_id,
)
return
def _op(cur, _conn):
_log_event_in_tx(
cur,
event,
payload,
now,
logical_time=logical_time,
user_id=user_id,
run_id=run_id,
)
return run_with_retry(_op)