Drain and extra-day legs always trade MNQ
They traded the micro of whatever the firm listed: MNQ with NQ, but MGC for a firm listing only GC and CL. Now every futures firm's tiny legs go on MNQ, the one micro the bot has always drained on. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
5696f2b036
commit
ed62788480
@@ -122,8 +122,7 @@ the batch firm's list, at random but weighted:
|
|||||||
the type's max contracts); an instrument whose expected hold for the
|
the type's max contracts); an instrument whose expected hold for the
|
||||||
batch's leg is 12 h or more is out of the draw (e.g. 6E at a $1,000 leg,
|
batch's leg is 12 h or more is out of the draw (e.g. 6E at a $1,000 leg,
|
||||||
about a week).
|
about a week).
|
||||||
- Micros stay out of the draw; drain and extra-day legs trade the micro of a
|
- Micros stay out of the draw; drain and extra-day legs always trade MNQ.
|
||||||
listed product (MNQ when NQ is listed).
|
|
||||||
|
|
||||||
Every draw logs its odds. `GET /api/instruments` shows each firm's list with
|
Every draw logs its odds. `GET /api/instruments` shows each firm's list with
|
||||||
spread, daily move, hold and chance (`?simulate=10000` runs the real draw
|
spread, daily move, hold and chance (`?simulate=10000` runs the real draw
|
||||||
|
|||||||
+2
-2
@@ -23,7 +23,7 @@ import {
|
|||||||
} from './trading-logic';
|
} from './trading-logic';
|
||||||
import { getSetting, setSetting } from './db';
|
import { getSetting, setSetting } from './db';
|
||||||
import type { LaneTick, TickReason } from './master-protocol';
|
import type { LaneTick, TickReason } from './master-protocol';
|
||||||
import { POINT_VALUES, housekeepingRoot, MAX_HOLD_HOURS } from './instrument-specs';
|
import { POINT_VALUES, housekeepingRoot, HOUSEKEEPING_ROOT, MAX_HOLD_HOURS } from './instrument-specs';
|
||||||
import { firmInstruments, drawFuturesInstrument, spreadBlock, type LegShape } from './instruments';
|
import { firmInstruments, drawFuturesInstrument, spreadBlock, type LegShape } from './instruments';
|
||||||
import { recordEntry } from './trade-mix';
|
import { recordEntry } from './trade-mix';
|
||||||
import { errorMessage, isClientReady, isOrderNotPlaced, type PlatformClient, type PlatformContract, type PickContext } from './platform-client';
|
import { errorMessage, isClientReady, isOrderNotPlaced, type PlatformClient, type PlatformContract, type PickContext } from './platform-client';
|
||||||
@@ -434,7 +434,7 @@ function releaseTradeMutex(lease: number, lane: string): void {
|
|||||||
* housekeepingRoot); a DXtrade firm its current pick. */
|
* housekeepingRoot); a DXtrade firm its current pick. */
|
||||||
function housekeepingFor(firm: { platform: string; instruments?: string[]; bannedSymbols?: string[]; symbolMap?: Record<string, { symbol: string }[]> }): string {
|
function housekeepingFor(firm: { platform: string; instruments?: string[]; bannedSymbols?: string[]; symbolMap?: Record<string, { symbol: string }[]> }): string {
|
||||||
if (firm.platform === 'dxtrade') return '*';
|
if (firm.platform === 'dxtrade') return '*';
|
||||||
return housekeepingRoot(firmInstruments(firm)) ?? 'MNQ';
|
return housekeepingRoot(firmInstruments(firm)) ?? HOUSEKEEPING_ROOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The instrument a leg actually trades: drain legs go on the firm's
|
/** The instrument a leg actually trades: drain legs go on the firm's
|
||||||
|
|||||||
+7
-12
@@ -227,21 +227,16 @@ export function pickByChance(chances: { symbol: string; chance: number }[], rand
|
|||||||
return chances.length > 0 ? chances[chances.length - 1].symbol : null;
|
return chances.length > 0 ? chances[chances.length - 1].symbol : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** What every futures firm's drain and extra-day legs trade. */
|
||||||
|
export const HOUSEKEEPING_ROOT = 'MNQ';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* What a firm's drain and extra-day legs trade — tiny, so a micro: MNQ when
|
* What a firm's drain and extra-day legs trade: always MNQ — tiny targets
|
||||||
* NQ or MNQ is listed (as always), else the micro of a listed full-size
|
* belong on a micro, whatever the firm lists for its full-size legs. null
|
||||||
* contract, else a listed micro, else the listed root with the smallest tick
|
* for an empty list: that firm trades nothing.
|
||||||
* value. null for an empty list.
|
|
||||||
*/
|
*/
|
||||||
export function housekeepingRoot(listed: readonly string[]): string | null {
|
export function housekeepingRoot(listed: readonly string[]): string | null {
|
||||||
const roots = listed.filter((r) => CME_SPECS[r]);
|
return listed.some((r) => CME_SPECS[r]) ? HOUSEKEEPING_ROOT : null;
|
||||||
if (roots.length === 0) return null;
|
|
||||||
if (roots.includes('NQ') || roots.includes('MNQ')) return 'MNQ';
|
|
||||||
const twin = roots.find((r) => MICRO_OF[r]);
|
|
||||||
if (twin) return MICRO_OF[twin];
|
|
||||||
const micro = roots.find((r) => CME_SPECS[r].micro);
|
|
||||||
if (micro) return micro;
|
|
||||||
return [...roots].sort((a, b) => tickValue(a) - tickValue(b))[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const DXTRADE_SYMBOL = /^[A-Za-z0-9./_:-]{1,32}$/;
|
const DXTRADE_SYMBOL = /^[A-Za-z0-9./_:-]{1,32}$/;
|
||||||
|
|||||||
@@ -140,12 +140,13 @@ test('10k seeded draws land on the chances', () => {
|
|||||||
assert.equal(pickByChance([], 0.5), null);
|
assert.equal(pickByChance([], 0.5), null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('drain and extra-day legs: a micro of what is listed', () => {
|
test('drain and extra-day legs: always MNQ', () => {
|
||||||
|
// Always MNQ, whatever the firm lists; nothing for a firm that lists nothing.
|
||||||
assert.equal(housekeepingRoot(['NQ', 'GC', 'CL', '6E']), 'MNQ');
|
assert.equal(housekeepingRoot(['NQ', 'GC', 'CL', '6E']), 'MNQ');
|
||||||
assert.equal(housekeepingRoot(['MNQ']), 'MNQ');
|
assert.equal(housekeepingRoot(['MNQ']), 'MNQ');
|
||||||
assert.equal(housekeepingRoot(['GC', 'CL']), 'MGC');
|
assert.equal(housekeepingRoot(['GC', 'CL']), 'MNQ');
|
||||||
assert.equal(housekeepingRoot(['6E', 'ZN']), '6E'); // no micro: the smallest tick value
|
assert.equal(housekeepingRoot(['6E', 'ZN']), 'MNQ');
|
||||||
assert.equal(housekeepingRoot(['MCL', 'ZB']), 'MCL');
|
assert.equal(housekeepingRoot(['MCL', 'ZB']), 'MNQ');
|
||||||
assert.equal(housekeepingRoot([]), null);
|
assert.equal(housekeepingRoot([]), null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user