Files
gavindiazandClaude Code 3a005ddcc6
Docs / Validate documentation (push) Canceled after 0s
Docs / Deploy GitHub Pages (push) Canceled after 0s
CI Final Summary (AI) / AI Final Summary (push) Canceled after 0s
CI Final Summary (AI) / Push/PR event feed (push) Canceled after 0s
CI / CI Integrity and Change Classification (push) Canceled after 0s
CI / Code Quality & Tests (push) Canceled after 0s
Dependency Lock & Migration Safety / Dependency drift (lock vs pyproject) (push) Canceled after 0s
Dependency Lock & Migration Safety / Migration safety (fail-loud + version postconditions) (push) Canceled after 0s
JS Tests / Frontend JS Unit Tests (push) Canceled after 0s
Security / CodeQL Analysis (push) Canceled after 0s
Security / Trivy Vulnerability Scan (push) Canceled after 0s
Tests (OS Matrix) / Py Tests (macos-latest) (push) Canceled after 0s
Tests (OS Matrix) / Py Tests (windows-latest) (push) Canceled after 0s
CI / Extended Validation (Tier 2) (push) Canceled after 0s
CI / Heavy CI (database-provider) (push) Canceled after 0s
CI / Heavy CI (e2e) (push) Canceled after 0s
CI / Heavy CI (integration) (push) Canceled after 0s
CI / Heavy CI (model-validation) (push) Canceled after 0s
CI / Heavy CI (research-backtest) (push) Canceled after 0s
CI / Aggregate CI Results (push) Canceled after 0s
chore(repo): initial import of Nexus Trading Forex Bot into self-hosted hosting
Full project import for the self-hosted code hosting
(https://code.aifunny.ltd/gavindiaz/my-NexusTradingForexBot.git).

Includes the live-freshness + scaler-hash fixes for the permanent
STALE dashboard (tick_pipeline now_utc stamps; infer_probabilities
computes model_input_hash on the actual scaled 70D tensor), the
data-fetch default-path fix, the g29 web-auth test fixes, and a
Chinese user manual (使用手册.md) for the web dashboard.

Scratch diagnostic scripts (check*.py, contain a live web-auth token)
and the .kilo/ agent-worktree directory are gitignored, not committed.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-23 23:24:54 +08:00

80 lines
2.7 KiB
Python

"""Task D reconciliation helper for PAPER accounting (tests/helpers).
Importable helper to assert equity==balance+unrealized and realized invariants.
"""
from __future__ import annotations
from typing import Any
def assert_accounting_invariants(adapter: Any, *, strict: bool = True) -> dict[str, Any]:
"""Assert equity == balance + floating PnL within 1 cent.
Also asserts each open position's stored profit matches current tick when
available. Returns the reconcile dict for logging. Raises AssertionError
on violation (strict=True, default), otherwise returns ok=False.
"""
# prefer adapter's own reconcile if present
if hasattr(adapter, "reconcile_accounting"):
try:
return adapter.reconcile_accounting() # type: ignore[operator]
except AssertionError:
raise
except Exception as e:
if strict:
raise AssertionError(f"reconcile_accounting failed: {e}") from e
# fallback manual check against adapter attributes
balance = float(getattr(adapter, "balance", 0.0))
equity = float(getattr(adapter, "equity", 0.0))
positions = list(
getattr(adapter, "_positions", []) or getattr(adapter, "get_positions", lambda **_: [])()
)
# try floating helper
floating = None
if hasattr(adapter, "_floating_pnl"):
try:
floating = float(adapter._floating_pnl()) # type: ignore[operator]
except Exception:
floating = None
if floating is None:
floating = sum(float(getattr(p, "profit", 0.0)) for p in positions)
expected = round(balance + floating, 2)
ok = abs(equity - expected) < 0.015
info: dict[str, Any] = {
"balance": balance,
"equity": equity,
"floating_pnl": floating,
"expected_equity": expected,
"ok": ok,
"positions": len(positions),
}
if strict:
assert ok, f"equity invariant broken: {info}"
return info
def assert_realized_pnl_formula(
*,
symbol: str,
order_type: str,
price_open: float,
price_close: float,
volume: float,
contract_size: float = 100.0,
expected: float,
) -> None:
"""Check BUY=(close-open)*vol*contract, SELL=(open-close)*vol*contract."""
if str(order_type).upper() == "BUY":
calc = round(
(float(price_close) - float(price_open)) * float(volume) * float(contract_size), 2
)
else:
calc = round(
(float(price_open) - float(price_close)) * float(volume) * float(contract_size), 2
)
assert abs(calc - float(expected)) < 0.015, (
f"realized PnL mismatch: calc {calc} vs expected {expected} ({symbol} {order_type} {price_open}->{price_close} x{volume}*c{contract_size})"
)