DXtrade sizing: volatility only (12h default hold); fees and every-day only for DXtrade

The symbol map's fixed notional per contract is gone: every DXtrade leg is
sized from the instrument's recent volatility for the firm's target hold
(blank = 12 h), and a candidate without a volatility isn't picked. Percent
commission and every-day trading are ignored on non-DXtrade firms, which keep
measured per-contract fees and the CME calendar.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Brandon Li
2026-09-26 17:29:32 -05:00
co-authored by Claude Opus 5.5
parent 28f465508d
commit d01f03b293
9 changed files with 87 additions and 100 deletions
+6 -4
View File
@@ -156,10 +156,9 @@ function sanitizeSymbolMap(raw: unknown): SymbolMap {
if (typeof c !== 'object' || c === null) return [];
const cand = c as Record<string, unknown>;
if (typeof cand.symbol !== 'string' || !cand.symbol || cand.symbol.includes('|')) return [];
const notional = nonNegative(cand.notionalPerContract);
const pct = typeof cand.commissionPct === 'number' && Number.isFinite(cand.commissionPct) && cand.commissionPct >= 0
? cand.commissionPct : undefined;
return [{ symbol: cand.symbol, notionalPerContract: notional, ...(pct !== undefined ? { commissionPct: pct } : {}) }];
return [{ symbol: cand.symbol, ...(pct !== undefined ? { commissionPct: pct } : {}) }];
});
if (candidates.length > 0) map[root.toUpperCase()] = candidates;
}
@@ -200,7 +199,10 @@ function validatePayload(raw: unknown): FirmCatalogPayload {
warnUnknownPlatform(firm.id, firm.name, platform);
return;
}
const tradesEveryDay = firm.tradesEveryDay === true;
// Percent commission and every-day trading are DXtrade settings;
// futures firms keep measured per-contract fees and the CME calendar.
const dx = platform === 'dxtrade';
const tradesEveryDay = dx && firm.tradesEveryDay === true;
if (!Array.isArray(firm.accountTypes)) throw new Error(`firm ${firm.name} is missing accountTypes`);
const accountTypes: CatalogAccountType[] = firm.accountTypes.map((t: unknown, j: number) => {
@@ -246,7 +248,7 @@ function validatePayload(raw: unknown): FirmCatalogPayload {
accountTypes,
serverUrl: typeof firm.serverUrl === 'string' ? firm.serverUrl : '',
loginDomain: typeof firm.loginDomain === 'string' ? firm.loginDomain : '',
commissionPct: nonNegative(firm.commissionPct),
commissionPct: dx ? nonNegative(firm.commissionPct) : 0,
tradesEveryDay,
symbolMap: sanitizeSymbolMap(firm.symbolMap),
targetHoldHours: nonNegative(firm.targetHoldHours),