diff options
| author | Somhairle H. Marisol <[email protected]> | 2026-09-17 14:32:37 +0800 |
|---|---|---|
| committer | Somhairle H. Marisol <[email protected]> | 2026-09-17 14:32:37 +0800 |
| commit | 5c0ba37eda80d39e6ceca59bb1d5f4942f858995 (patch) | |
| tree | 948723f9cedf7ccb0707fa6ee516bd30fe20fd10 /frontend/src/lib/coverage.ts | |
| download | strategy-lab-5c0ba37eda80d39e6ceca59bb1d5f4942f858995.tar.gz | |
chore: establish Strategy Lab source baseline (development, not release)
Diffstat (limited to 'frontend/src/lib/coverage.ts')
| -rw-r--r-- | frontend/src/lib/coverage.ts | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/frontend/src/lib/coverage.ts b/frontend/src/lib/coverage.ts new file mode 100644 index 0000000..c9a8447 --- /dev/null +++ b/frontend/src/lib/coverage.ts @@ -0,0 +1,52 @@ +export interface CoverageEntry { + instrument: string; + market?: string; + asset_type?: string; + requested_start?: string | null; + requested_end?: string | null; + actual_start?: string | null; + actual_end?: string | null; + row_count?: number; + warnings?: string[]; +} + +export interface CoverageSummary { + common: { start: string | null; end: string | null }; + warnings: string[]; +} + +export function summarizeCoverage(entries: CoverageEntry[]): CoverageSummary { + const warnings: string[] = []; + const withData = entries.filter((e) => (e.row_count ?? 0) > 0 && e.actual_start && e.actual_end); + for (const e of entries) { + if ((e.row_count ?? 0) === 0) { + warnings.push(`${e.instrument} 没有返回任何数据行`); + } else if (!e.actual_start || !e.actual_end) { + warnings.push(`${e.instrument} 数据区间不完整`); + } + } + let common: { start: string | null; end: string | null } = { start: null, end: null }; + if (withData.length > 0) { + const starts = withData.map((e) => e.actual_start as string).sort(); + const startsAsc = [...starts]; + const earliest = startsAsc[0]; + const lateStart = starts[starts.length - 1]; + if (lateStart > earliest) { + const owner = withData.find((e) => e.actual_start === lateStart); + if (owner) { + warnings.push(`${owner.instrument} 起始数据较其他标的更晚(${lateStart})`); + } + } + const ends = withData.map((e) => e.actual_end as string); + const commonEnd = ends.sort()[0]; + const earlyOwners = withData.filter((e) => e.actual_end === commonEnd); + const otherEnds = withData.filter((e) => (e.actual_end as string) > commonEnd); + if (otherEnds.length > 0) { + for (const e of earlyOwners) { + warnings.push(`${e.instrument} 较早结束(${commonEnd}),造成共有区间缺失`); + } + } + common = { start: lateStart, end: commonEnd }; + } + return { common, warnings }; +} |
