Skip to content
markpaper

src/account/account.test.ts

v0.1.0 · 2.3 KB

Download file
import { describe, expect, it } from 'vitest';
import { parseDec } from '../numbers/index.js';
import { fixtureOrder } from '../testing/fixtures.js';
import {
  decodeHistoricByCloid,
  decodePositions,
  decodeSubaccountEquity,
  judgeEquity,
  judgeOrderPages,
} from './index.js';

describe('account read completeness and uncertainty', () => {
  it('rejects empty positions with a positive position margin', () => {
    expect(() =>
      decodePositions(
        { positions: null, balance: { available_balance: '1300', order_margin: '0', position_margin: '12' } },
        new Map(),
      ),
    ).toThrow();
  });
  it('preserves the canonical account id from the endpoint', () => {
    const canonical = 'AB000000-0000-4000-8000-000000000001';
    expect(
      decodeSubaccountEquity(
        { accounts: [{ account_id: canonical, equity: '1400', is_master: false }] },
        canonical.toLowerCase(),
      ),
    ).toMatchObject({ found: true, accountId: canonical });
  });
  it('does not mark a full final page or repeated ids complete', () => {
    const row = fixtureOrder();
    expect(
      judgeOrderPages({ limit: 1, pages: [{ orders: [row], twaps: [], stopOrders: [], malformed: [] }] }),
    ).toMatchObject({ ok: true, complete: false });
    expect(
      judgeOrderPages({ limit: 2, pages: [{ orders: [row, row], twaps: [], stopOrders: [], malformed: [] }] }),
    ).toMatchObject({ ok: true, complete: false });
  });
  it('matches historical cloids byte for byte and snaps print noise', () => {
    const cloid = 'ab'.repeat(16);
    const payload = {
      data: [
        {
          client_order_id: cloid,
          symbol: 'BTC-USD',
          side: 'BUY',
          terminal_status: 'FILLED',
          filled_qty: '0.38000000000000006',
        },
      ],
    };
    expect(decodeHistoricByCloid(payload, cloid.toUpperCase(), () => '0.02')).toBeNull();
    expect(decodeHistoricByCloid(payload, cloid, () => '0.02')?.filledQty).toBe('0.38');
  });
  it('does not accept exact equity that overflows the reporting number type', () => {
    expect(
      judgeEquity(null, parseDec('1e400'), {
        source: 'endpoint',
        alertTolUsd: 0,
        alertTolPct: 0,
        bothTolUsd: 0,
        bothTolPct: 0,
      }),
    ).toMatchObject({ equityFresh: false, endpoint: null, accountValue: 0 });
  });
});
All files