Skip to content

Fix finance log double-counting of exchange balances#3462

Merged
TaprootFreak merged 2 commits intodevelopfrom
fix/finance-log-exchange-balance-double-counting
Mar 19, 2026
Merged

Fix finance log double-counting of exchange balances#3462
TaprootFreak merged 2 commits intodevelopfrom
fix/finance-log-exchange-balance-double-counting

Conversation

@TaprootFreak
Copy link
Collaborator

Summary

  • The finance log used Amount (total balance incl. locked funds) as the liquidity base and added pending exchange orders (exchangeOrder) on top
  • For exchanges like Scrypt where Amount includes funds locked for pending withdrawals, this caused double-counting (~30k CHF overstatement, daily swings of up to 18x between min/max)
  • Root cause: ExchangeAdapter.getForExchange() stored getTotalBalances() (which includes locked funds) in LiquidityBalance.amount, then log-job.service.ts added the same withdrawal amount again as pending exchangeOrder

Fix

  • Add availableAmount field to LiquidityBalance entity (stores balance excluding locked funds)
  • Add getAvailableBalances() to ScryptService (uses AvailableAmount) and ExchangeService (uses b.free)
  • ExchangeAdapter now fetches and stores both amount (total) and availableAmount
  • Finance log uses availableAmount as liquidity base — pending exchange orders then correctly compensate for the locked/in-transit portion
  • Rule verification (rule.verify()) continues to use amount (total) — no behavioral change for deficit/redundancy detection

Trade-off

During active trading orders (buy/sell, typically <1 min), availableAmount is slightly lower since sell/buy aren't tracked in getPendingTx(). This is acceptable because trading orders fill in seconds, the valid flag threshold (5,000 CHF) catches brief outliers, and it self-corrects on the next cron run.

Test plan

  • Build passes
  • Lint passes
  • Existing log-job.service.spec.ts tests pass (9/9)
  • Verify on staging: finance log totalBalanceChf should stabilize (no more 3-18x daily swings)
  • Verify rule verification still triggers correctly for actual deficits/redundancies

🤖 Generated with Claude Code

TaprootFreak and others added 2 commits March 19, 2026 10:02
…ithdrawals

The finance log used Amount (total balance incl. locked funds) as the
liquidity base and added pending exchange orders on top. For exchanges
like Scrypt where Amount includes funds locked for pending withdrawals,
this caused double-counting (~30k CHF overstatement).

Add availableAmount to LiquidityBalance and use it in the finance log.
The available balance excludes locked funds, so pending exchange orders
correctly compensate for the difference.
@TaprootFreak TaprootFreak marked this pull request as ready for review March 19, 2026 18:00
@TaprootFreak TaprootFreak merged commit e6a50df into develop Mar 19, 2026
8 checks passed
@TaprootFreak TaprootFreak deleted the fix/finance-log-exchange-balance-double-counting branch March 19, 2026 18:00
TaprootFreak added a commit that referenced this pull request Mar 19, 2026
…geOrder

PR #3462 switched to availableAmount globally, but this over-corrected
for exchanges like XT where locked funds are trading orders not tracked
as exchangeOrder. This caused ~40k CHF to silently drop from the balance.

Revert to amount as liquidity base. Instead, deduct the locked portion
(amount - availableAmount) from exchangeOrder to avoid the Scrypt
double-counting that #3462 originally fixed.
TaprootFreak added a commit that referenced this pull request Mar 19, 2026
…geOrder (#3471)

PR #3462 switched to availableAmount globally, but this over-corrected
for exchanges like XT where locked funds are trading orders not tracked
as exchangeOrder. This caused ~40k CHF to silently drop from the balance.

Revert to amount as liquidity base. Instead, deduct the locked portion
(amount - availableAmount) from exchangeOrder to avoid the Scrypt
double-counting that #3462 originally fixed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants