DXtrade: Hyperliquid prices when /marketdata is denied; closing stop/limit without quantity

Tradeify247's API user may not read DXtrade market data (code 34), which
skipped every batch at the instrument pick. Quotes and hourly candles then
come from Hyperliquid's public API (BTC, ETH on the main dex; XYZ100, SP500
and tokenized stocks on trade[XYZ]) — for the pick and sizing only; orders,
fills and exit prices stay DXtrade's.

Closing STOP/LIMIT orders close the whole position by positionCode and must
not carry a quantity (code 33) — the exit bracket was refused, and the
daily-loss guard flattened both accounts. A close's fill price also falls
back to its executions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Li
2026-09-26 17:35:23 -05:00
co-authored by Claude Opus 5.5
parent d01f03b293
commit 9fc1ed6908
3 changed files with 190 additions and 18 deletions
+22
View File
@@ -484,3 +484,25 @@ test('the selector drops what cannot trade right now', () => {
assert.match(candidateRejection({ ...ok, candles: 10 }), /candles/);
assert.match(candidateRejection({ ...ok, currency: 'EUR' }), /EUR/);
});
// ── Hyperliquid price fallback (lib/hyperliquid-feed.ts) ─────────────────────
import { hyperliquidCoinFor, parseL2Book } from '../lib/hyperliquid-feed.ts';
test('DXtrade symbols map to Hyperliquid coins', () => {
const coins = new Set(['BTC', 'ETH', 'xyz:XYZ100', 'xyz:SP500', 'xyz:AAPL']);
assert.equal(hyperliquidCoinFor('BTC/USD', coins), 'BTC');
assert.equal(hyperliquidCoinFor('ETH/USD', coins), 'ETH');
assert.equal(hyperliquidCoinFor('XYZ100', coins), 'xyz:XYZ100');
assert.equal(hyperliquidCoinFor('SP500', coins), 'xyz:SP500');
assert.equal(hyperliquidCoinFor('AAPL/USD', coins), 'xyz:AAPL');
assert.equal(hyperliquidCoinFor('DOGE/USD', coins), null);
});
test('l2Book best bid/ask', () => {
const q = parseL2Book({ levels: [[{ px: '84310.0' }, { px: '84309' }], [{ px: '84311.0' }]], time: 1790461870878 });
assert.deepEqual(q, { bid: 84310, ask: 84311, time: 1790461870878 });
const empty = parseL2Book({ levels: [[], []] });
assert.equal(empty.bid, undefined);
assert.equal(empty.ask, undefined);
});