src/orders/orders.test.ts
v0.1.0 · 5.5 KB
import { describe, expect, it } from 'vitest';
import { decToString, parseDec } from '../numbers/index.js';
import { cancelTruth, createWriteMemory } from '../pending/index.js';
import { fixtureFill, fixtureOrder } from '../testing/fixtures.js';
import { clampIocPrice, fullCloseSize, iocFill, rejectScope } from './index.js';
describe('order witnesses and pending memory', () => {
it('uses sent quantity and cumulative remainder, not last execution quantity', () => {
const report = iocFill({
symbol: 'BTC-USD',
cloid: fixtureOrder().cloid!,
orderId: fixtureOrder().orderId,
sent: '0.38',
side: 'BUY',
events: [
fixtureOrder({ status: 'FILLED', qty: '0.14', remaining: '0.24' }),
fixtureOrder({ status: 'FILLED', qty: '0.24', remaining: '0' }),
],
fills: [],
});
expect(report.quantity).toBe('0.38');
});
it('deduplicates trade ids and uses the conservative witness', () => {
const fill = fixtureFill({ qty: '0.18' });
expect(
iocFill({
symbol: 'BTC-USD',
cloid: fixtureOrder().cloid!,
orderId: fixtureOrder().orderId,
sent: '0.38',
side: 'BUY',
events: [fixtureOrder({ status: 'FILLED', remaining: '0' })],
fills: [fill, fill],
}).quantity,
).toBe('0.18');
});
it('refuses fill evidence for a different symbol even with a matching client id', () => {
expect(
iocFill({
symbol: 'BTC-USD',
cloid: fixtureOrder().cloid!,
orderId: fixtureOrder().orderId,
sent: '0.38',
side: 'BUY',
events: [],
fills: [fixtureFill({ symbol: 'ETH-USD' })],
}),
).toMatchObject({ confirmed: false, quantity: '0' });
});
it('does not interpret IOC terminal remaining zero as a fill', () => {
expect(
iocFill({
symbol: 'BTC-USD',
cloid: fixtureOrder().cloid!,
orderId: fixtureOrder().orderId,
sent: '0.38',
side: 'BUY',
events: [fixtureOrder({ status: 'IOC_CANCELLED', remaining: '0' })],
fills: [],
}).confirmed,
).toBe(false);
});
it('ceil quantizes a full close and uses only fresh bands', () => {
expect(decToString(fullCloseSize(parseDec('-0.381')!, parseDec('0.02')!))).toBe('0.4');
expect(
decToString(clampIocPrice(parseDec('200')!, 'BUY', parseDec('0.25')!, { min: '80', max: '180', fresh: false })),
).toBe('200');
expect(
decToString(clampIocPrice(parseDec('200')!, 'BUY', parseDec('0.25')!, { min: '80', max: '180.1', fresh: true })),
).toBe('180');
});
it('distinguishes partial execution from successful cancellation', () => {
expect(cancelTruth(fixtureOrder({ status: 'CANCELLED', remaining: '0.2' }), { fillsSeen: false }).verdict).toBe(
'not_cancelled',
);
expect(cancelTruth(fixtureOrder({ status: 'FILLED', remaining: '0.2' }), { fillsSeen: false }).verdict).toBe(
'not_final',
);
expect(cancelTruth(fixtureOrder({ status: 'CANCELLED' }), { fillsSeen: false }).verdict).toBe('cancelled');
});
it('never unlocks unknown fill from a lagging empty read or absent history', async () => {
const memory = createWriteMemory({
echoTtlMs: 80,
readAfterWriteMs: 30,
unknownLockMs: 70,
unknownLockGtcMs: 100,
failedHistoryLockMs: 170,
canExpire: () => false,
});
memory.noteUnknown({
cloid: 'ef'.repeat(16),
symbol: 'BTC-USD',
side: 'BUY',
kind: 'ioc',
quantity: '0.38',
sentAt: 1,
});
expect(
await memory.resolveUnknowns(
{ openOrders: async () => ({ orders: [], complete: true }), historicByCloid: async () => null },
1000,
),
).toEqual([]);
expect(memory.iocLock('BTC-USD')).toBeDefined();
expect(
await memory.resolveUnknowns(
{
openOrders: async () => ({ orders: [], complete: true }),
historicByCloid: async () => {
throw new Error('Unavailable');
},
},
2000,
),
).toEqual([]);
});
it('injects early acknowledged rows and masks a cancelled stale row', () => {
const memory = createWriteMemory({
echoTtlMs: 80,
readAfterWriteMs: 30,
unknownLockMs: 70,
unknownLockGtcMs: 100,
failedHistoryLockMs: 170,
canExpire: () => false,
});
const row = fixtureOrder();
memory.notePlaced(row, 10);
expect(memory.applyEcho([], 20, 20)).toHaveLength(1);
memory.noteCancelled(row.orderId, 25);
expect(memory.applyEcho([row], 30, 30)).toHaveLength(0);
});
it('keeps margin rejection scope symbol-specific except account margin', () => {
expect(rejectScope('FAILED_MARGIN_CHECK')).toBe('account');
expect(rejectScope('REJECTED_OPEN_INTEREST_LIMIT')).toBe('symbol');
});
it('keeps an unknown intent locked on a contradictory side or order id', () => {
const memory = createWriteMemory({
echoTtlMs: 80,
readAfterWriteMs: 30,
unknownLockMs: 70,
unknownLockGtcMs: 100,
failedHistoryLockMs: 170,
canExpire: () => false,
});
const row = fixtureOrder();
memory.noteUnknown({
cloid: row.cloid!,
symbol: row.symbol,
side: 'BUY',
kind: 'gtc',
quantity: row.qty,
sentAt: 1,
orderId: row.orderId,
});
expect(memory.resolveUnknownByEvent({ ...row, side: 'SELL' })).toBeNull();
expect(memory.resolveUnknownByEvent({ ...row, orderId: '20000000-0000-4000-8000-000000000003' })).toBeNull();
expect(memory.unknownIntents()).toHaveLength(1);
});
});