feat: Pair-Typ um Trump-Universum erweitert (LINK/AAVE/ONDO/ENA/SUI/SEI)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-12 07:44:17 +00:00
parent 896a29bd04
commit 713f4efc3c
6 changed files with 19 additions and 9 deletions

View File

@@ -118,7 +118,7 @@ export function runGridBacktest(candles15ByPair: Map<Pair, Candle[]>, cfg: GridC
const c4h = aggregateTf(c15, p.tfMs); const c4h = aggregateTf(c15, p.tfMs);
return { pair, c4h, atr: atr(c4h, p.atrPeriod), adx: adx(c4h, p.atrPeriod), next4h: 0 }; return { pair, c4h, atr: atr(c4h, p.atrPeriod), adx: adx(c4h, p.atrPeriod), next4h: 0 };
}); });
const byPair = new Map(contexts.map((c) => [c.pair, c])); const byPair = new Map<Pair, (typeof contexts)[number]>(contexts.map((c) => [c.pair, c]));
const timeline: { ts: number; pair: Pair; candle: Candle }[] = []; const timeline: { ts: number; pair: Pair; candle: Candle }[] = [];
for (const ctx of contexts) { for (const ctx of contexts) {
@@ -126,7 +126,7 @@ export function runGridBacktest(candles15ByPair: Map<Pair, Candle[]>, cfg: GridC
if (candle.ts < cfg.tradeTo) timeline.push({ ts: candle.ts, pair: ctx.pair, candle }); if (candle.ts < cfg.tradeTo) timeline.push({ ts: candle.ts, pair: ctx.pair, candle });
} }
} }
timeline.sort((a, b) => a.ts - b.ts || PAIRS.indexOf(a.pair) - PAIRS.indexOf(b.pair)); timeline.sort((a, b) => a.ts - b.ts || PAIRS.indexOf(a.pair as (typeof PAIRS)[number]) - PAIRS.indexOf(b.pair as (typeof PAIRS)[number]));
let lastEquityBucket = -1; let lastEquityBucket = -1;

View File

@@ -50,7 +50,7 @@ export function runBacktest(candles15ByPair: Map<Pair, Candle[]>, cfg: BacktestC
if (candle.ts < cfg.tradeTo) timeline.push({ ts: candle.ts, pair: ctx.pair, candle }); if (candle.ts < cfg.tradeTo) timeline.push({ ts: candle.ts, pair: ctx.pair, candle });
} }
} }
timeline.sort((a, b) => a.ts - b.ts || PAIRS.indexOf(a.pair) - PAIRS.indexOf(b.pair)); timeline.sort((a, b) => a.ts - b.ts || PAIRS.indexOf(a.pair as (typeof PAIRS)[number]) - PAIRS.indexOf(b.pair as (typeof PAIRS)[number]));
const byPair = new Map<Pair, PairContext>(contexts.map((c) => [c.pair, c])); const byPair = new Map<Pair, PairContext>(contexts.map((c) => [c.pair, c]));
let lastEquityBucket = -1; let lastEquityBucket = -1;

View File

@@ -98,7 +98,7 @@ export function processGridCycle(
if (candle.ts > state.cursorTs) timeline.push({ ts: candle.ts, pair: ctx.pair, candle }); if (candle.ts > state.cursorTs) timeline.push({ ts: candle.ts, pair: ctx.pair, candle });
} }
} }
timeline.sort((a, b) => a.ts - b.ts || PAIRS.indexOf(a.pair) - PAIRS.indexOf(b.pair)); timeline.sort((a, b) => a.ts - b.ts || PAIRS.indexOf(a.pair as (typeof PAIRS)[number]) - PAIRS.indexOf(b.pair as (typeof PAIRS)[number]));
const sell = (pair: Pair, ts: number, price: number, lot: GridLot, reason: ClosedTrade['exitReason']): void => { const sell = (pair: Pair, ts: number, price: number, lot: GridLot, reason: ClosedTrade['exitReason']): void => {
const fill = price * (1 - exec.slippage); const fill = price * (1 - exec.slippage);

View File

@@ -82,7 +82,7 @@ export function processCycle(
} }
return { pair, c4h, ind: computeIndicators(c4h, cfg.params), next4h }; return { pair, c4h, ind: computeIndicators(c4h, cfg.params), next4h };
}); });
const byPair = new Map(contexts.map((c) => [c.pair, c])); const byPair = new Map<Pair, (typeof contexts)[number]>(contexts.map((c) => [c.pair, c]));
const timeline: { ts: number; pair: Pair; candle: Candle }[] = []; const timeline: { ts: number; pair: Pair; candle: Candle }[] = [];
for (const ctx of contexts) { for (const ctx of contexts) {
@@ -90,7 +90,7 @@ export function processCycle(
if (candle.ts > state.cursorTs) timeline.push({ ts: candle.ts, pair: ctx.pair, candle }); if (candle.ts > state.cursorTs) timeline.push({ ts: candle.ts, pair: ctx.pair, candle });
} }
} }
timeline.sort((a, b) => a.ts - b.ts || PAIRS.indexOf(a.pair) - PAIRS.indexOf(b.pair)); timeline.sort((a, b) => a.ts - b.ts || PAIRS.indexOf(a.pair as (typeof PAIRS)[number]) - PAIRS.indexOf(b.pair as (typeof PAIRS)[number]));
let cursorTs = state.cursorTs; let cursorTs = state.cursorTs;
let lastEquityBucket = -1; let lastEquityBucket = -1;

View File

@@ -1,4 +1,4 @@
import { PAIRS } from '../types'; import { ALL_PAIRS } from '../types';
import { fetchCandles } from '../market/cryptocom'; import { fetchCandles } from '../market/cryptocom';
import { insertCandles, getCoverage } from '../market/candle-store'; import { insertCandles, getCoverage } from '../market/candle-store';
import { sql } from '../db/client'; import { sql } from '../db/client';
@@ -7,7 +7,7 @@ const M15 = 15 * 60 * 1000;
const TARGET_MONTHS = 36; const TARGET_MONTHS = 36;
const since = Date.now() - TARGET_MONTHS * 30 * 24 * 60 * 60 * 1000; const since = Date.now() - TARGET_MONTHS * 30 * 24 * 60 * 60 * 1000;
for (const pair of PAIRS) { for (const pair of ALL_PAIRS) {
let endTs: number | undefined = undefined; let endTs: number | undefined = undefined;
let total = 0; let total = 0;
let prevOldest: number | undefined = undefined; let prevOldest: number | undefined = undefined;

View File

@@ -8,4 +8,14 @@ export interface Candle {
} }
export const PAIRS = ['BTC_USDT', 'ETH_USDT', 'SOL_USDT', 'XRP_USDT'] as const; export const PAIRS = ['BTC_USDT', 'ETH_USDT', 'SOL_USDT', 'XRP_USDT'] as const;
export type Pair = (typeof PAIRS)[number];
/** Handels-Universum der Trump-Engine (Schnittmenge Mapping × Crypto.com-USDT-Paare). */
export const TRUMP_PAIRS = [
'BTC_USDT', 'ETH_USDT', 'SOL_USDT', 'XRP_USDT',
'LINK_USDT', 'AAVE_USDT', 'ONDO_USDT', 'ENA_USDT', 'SUI_USDT', 'SEI_USDT',
] as const;
export type Pair = (typeof PAIRS)[number] | (typeof TRUMP_PAIRS)[number];
/** Vereinigung beider Universen — für Candle-Backfill. */
export const ALL_PAIRS: readonly Pair[] = [...new Set<Pair>([...PAIRS, ...TRUMP_PAIRS])];