Files
eth_hedge_sim/backend/app/sim/ledger.py
T
2026-07-24 17:03:46 +08:00

62 lines
2.0 KiB
Python

from __future__ import annotations
import time
from typing import Any
from ..models.db import Database, get_db
class Ledger:
def __init__(self, db: Database | None = None) -> None:
self.db = db or get_db()
def snapshot(self) -> dict[str, Any]:
row = self.db.fetchone("SELECT * FROM ledger_meta WHERE id=1")
assert row is not None
return {
"equity": float(row["equity"]),
"available": float(row["available"]),
"reserved": float(row["reserved"]),
"updated_at_ms": int(row["updated_at_ms"]),
}
def apply_cash(
self,
amount: float,
*,
kind: str,
group_id: str | None = None,
note: str = "",
) -> float:
"""amount>0 入账;amount<0 出账。返回余额。"""
now = int(time.time() * 1000)
with self.db._lock:
row = self.db._conn.execute("SELECT * FROM ledger_meta WHERE id=1").fetchone()
assert row is not None
equity = float(row["equity"]) + float(amount)
available = float(row["available"]) + float(amount)
if available < -1e-9:
raise RuntimeError("可用资金不足")
self.db._conn.execute(
"UPDATE ledger_meta SET equity=?, available=?, updated_at_ms=? WHERE id=1",
(equity, available, now),
)
self.db._conn.execute(
"INSERT INTO ledger_entries(group_id, kind, amount, balance_after, note, ts_ms) VALUES (?,?,?,?,?,?)",
(group_id, kind, float(amount), equity, note, now),
)
self.db._conn.commit()
return equity
def get_setting_float(self, key: str, default: float) -> float:
v = self.db.get_setting(key)
if v is None or v == "":
return default
try:
return float(v)
except ValueError:
return default
def get_setting_int(self, key: str, default: int) -> int:
return int(self.get_setting_float(key, float(default)))