Automate issuer overlay creation from ticker searches
This commit is contained in:
@@ -151,11 +151,28 @@ function latestMetrics(snapshots: FilingTaxonomySnapshotRecord[]) {
|
||||
}
|
||||
|
||||
function defaultDisplayModes(surfaceKind: FinancialSurfaceKind): FinancialDisplayMode[] {
|
||||
if (surfaceKind === 'equity_statement') {
|
||||
return ['faithful'];
|
||||
}
|
||||
|
||||
return isStatementSurface(surfaceKind)
|
||||
? ['standardized', 'faithful']
|
||||
: ['standardized'];
|
||||
}
|
||||
|
||||
function defaultDisplayMode(
|
||||
surfaceKind: FinancialSurfaceKind,
|
||||
displayModes = defaultDisplayModes(surfaceKind)
|
||||
): FinancialDisplayMode {
|
||||
if (surfaceKind === 'equity_statement') {
|
||||
return 'faithful';
|
||||
}
|
||||
|
||||
return displayModes.includes('standardized')
|
||||
? 'standardized'
|
||||
: displayModes[0] ?? 'standardized';
|
||||
}
|
||||
|
||||
function rekeyRowsByFilingId<T extends {
|
||||
values: Record<string, number | null>;
|
||||
resolvedSourceRowKeys?: Record<string, string | null>;
|
||||
@@ -311,6 +328,10 @@ function emptyNormalizationMetadata(): NormalizationMetadata {
|
||||
kpiRowCount: 0,
|
||||
unmappedRowCount: 0,
|
||||
materialUnmappedRowCount: 0,
|
||||
residualPrimaryCount: 0,
|
||||
residualDisclosureCount: 0,
|
||||
unsupportedConceptCount: 0,
|
||||
issuerOverlayMatchCount: 0,
|
||||
warnings: []
|
||||
};
|
||||
}
|
||||
@@ -348,6 +369,22 @@ function buildNormalizationMetadata(
|
||||
(sum, snapshot) => sum + (snapshot.normalization_summary?.materialUnmappedRowCount ?? 0),
|
||||
0
|
||||
),
|
||||
residualPrimaryCount: snapshots.reduce(
|
||||
(sum, snapshot) => sum + (snapshot.normalization_summary?.residualPrimaryCount ?? 0),
|
||||
0
|
||||
),
|
||||
residualDisclosureCount: snapshots.reduce(
|
||||
(sum, snapshot) => sum + (snapshot.normalization_summary?.residualDisclosureCount ?? 0),
|
||||
0
|
||||
),
|
||||
unsupportedConceptCount: snapshots.reduce(
|
||||
(sum, snapshot) => sum + (snapshot.normalization_summary?.unsupportedConceptCount ?? 0),
|
||||
0
|
||||
),
|
||||
issuerOverlayMatchCount: snapshots.reduce(
|
||||
(sum, snapshot) => sum + (snapshot.normalization_summary?.issuerOverlayMatchCount ?? 0),
|
||||
0
|
||||
),
|
||||
warnings: [...new Set(snapshots.flatMap((snapshot) => snapshot.normalization_summary?.warnings ?? []))]
|
||||
.sort((left, right) => left.localeCompare(right))
|
||||
};
|
||||
@@ -568,7 +605,7 @@ function buildLtmDetailRows(input: {
|
||||
detailRows: SurfaceDetailMap;
|
||||
quarterlyPeriods: FinancialStatementPeriod[];
|
||||
ltmPeriods: FinancialStatementPeriod[];
|
||||
statement: Extract<FinancialStatementKind, 'income' | 'balance' | 'cash_flow'>;
|
||||
statement: Extract<FinancialStatementKind, 'income' | 'balance' | 'cash_flow' | 'equity' | 'disclosure'>;
|
||||
}) {
|
||||
const sortedQuarterlyPeriods = [...input.quarterlyPeriods].sort(periodSorter);
|
||||
|
||||
@@ -586,7 +623,7 @@ function buildLtmDetailRows(input: {
|
||||
|
||||
const slice = sortedQuarterlyPeriods.slice(anchorIndex - 3, anchorIndex + 1);
|
||||
const sourceValues = slice.map((period) => row.values[period.id] ?? null);
|
||||
values[ltmPeriod.id] = input.statement === 'balance'
|
||||
values[ltmPeriod.id] = input.statement === 'balance' || input.statement === 'equity'
|
||||
? sourceValues[sourceValues.length - 1] ?? null
|
||||
: sourceValues.some((value) => value === null)
|
||||
? null
|
||||
@@ -606,7 +643,7 @@ function buildLtmDetailRows(input: {
|
||||
}
|
||||
|
||||
function buildQuarterlyStatementSurfaceRows(input: {
|
||||
statement: Extract<FinancialStatementKind, 'income' | 'balance' | 'cash_flow'>;
|
||||
statement: Extract<FinancialStatementKind, 'income' | 'balance' | 'cash_flow' | 'equity' | 'disclosure'>;
|
||||
sourcePeriods: FinancialStatementPeriod[];
|
||||
selectedPeriodIds: Set<string>;
|
||||
faithfulRows: TaxonomyStatementRow[];
|
||||
@@ -682,6 +719,8 @@ function buildEmptyResponse(input: {
|
||||
nextCursor: string | null;
|
||||
coverageFacts: number;
|
||||
}) {
|
||||
const displayModes = defaultDisplayModes(input.surfaceKind);
|
||||
|
||||
return {
|
||||
company: {
|
||||
ticker: input.ticker,
|
||||
@@ -690,8 +729,8 @@ function buildEmptyResponse(input: {
|
||||
},
|
||||
surfaceKind: input.surfaceKind,
|
||||
cadence: input.cadence,
|
||||
displayModes: defaultDisplayModes(input.surfaceKind),
|
||||
defaultDisplayMode: 'standardized',
|
||||
displayModes,
|
||||
defaultDisplayMode: defaultDisplayMode(input.surfaceKind, displayModes),
|
||||
periods: [],
|
||||
statementRows: isStatementSurface(input.surfaceKind)
|
||||
? { faithful: [], standardized: [] }
|
||||
@@ -728,7 +767,10 @@ function buildEmptyResponse(input: {
|
||||
}
|
||||
|
||||
async function buildStatementSurfaceBundle(input: {
|
||||
surfaceKind: Extract<FinancialSurfaceKind, 'income_statement' | 'balance_sheet' | 'cash_flow_statement'>;
|
||||
surfaceKind: Extract<
|
||||
FinancialSurfaceKind,
|
||||
'income_statement' | 'balance_sheet' | 'cash_flow_statement' | 'equity_statement' | 'disclosures'
|
||||
>;
|
||||
cadence: FinancialCadence;
|
||||
sourcePeriods: FinancialStatementPeriod[];
|
||||
targetPeriods: FinancialStatementPeriod[];
|
||||
@@ -752,7 +794,14 @@ async function buildStatementSurfaceBundle(input: {
|
||||
}
|
||||
|
||||
const statement = surfaceToStatementKind(input.surfaceKind);
|
||||
if (!statement || (statement !== 'income' && statement !== 'balance' && statement !== 'cash_flow')) {
|
||||
if (
|
||||
!statement ||
|
||||
(statement !== 'income' &&
|
||||
statement !== 'balance' &&
|
||||
statement !== 'cash_flow' &&
|
||||
statement !== 'equity' &&
|
||||
statement !== 'disclosure')
|
||||
) {
|
||||
return {
|
||||
rows: [],
|
||||
detailRows: {},
|
||||
@@ -810,6 +859,16 @@ async function buildStatementSurfaceBundle(input: {
|
||||
return payload;
|
||||
}
|
||||
|
||||
async function buildDisclosureSurfaceBundle(input: Omit<
|
||||
Parameters<typeof buildStatementSurfaceBundle>[0],
|
||||
'surfaceKind'
|
||||
>) {
|
||||
return await buildStatementSurfaceBundle({
|
||||
...input,
|
||||
surfaceKind: 'disclosures'
|
||||
});
|
||||
}
|
||||
|
||||
async function buildRatioSurfaceBundle(input: {
|
||||
ticker: string;
|
||||
cadence: FinancialCadence;
|
||||
@@ -1039,18 +1098,36 @@ export async function getCompanyFinancials(input: GetCompanyFinancialsInput): Pr
|
||||
|
||||
const factsForStatement = allFacts.facts.filter((fact) => fact.statement === statement);
|
||||
const factsForStandardization = allFacts.facts;
|
||||
const standardizedPayload = await buildStatementSurfaceBundle({
|
||||
surfaceKind: input.surfaceKind as Extract<FinancialSurfaceKind, 'income_statement' | 'balance_sheet' | 'cash_flow_statement'>,
|
||||
cadence: input.cadence,
|
||||
sourcePeriods: selection.periods,
|
||||
targetPeriods: periods,
|
||||
selectedPeriodIds: selection.selectedPeriodIds,
|
||||
faithfulRows: baseFaithfulRows,
|
||||
facts: factsForStandardization,
|
||||
snapshots: selection.snapshots
|
||||
});
|
||||
const standardizedPayload = input.surfaceKind === 'disclosures'
|
||||
? await buildDisclosureSurfaceBundle({
|
||||
cadence: input.cadence,
|
||||
sourcePeriods: selection.periods,
|
||||
targetPeriods: periods,
|
||||
selectedPeriodIds: selection.selectedPeriodIds,
|
||||
faithfulRows: baseFaithfulRows,
|
||||
facts: factsForStandardization,
|
||||
snapshots: selection.snapshots
|
||||
})
|
||||
: await buildStatementSurfaceBundle({
|
||||
surfaceKind: input.surfaceKind as Extract<
|
||||
FinancialSurfaceKind,
|
||||
'income_statement' | 'balance_sheet' | 'cash_flow_statement' | 'equity_statement'
|
||||
>,
|
||||
cadence: input.cadence,
|
||||
sourcePeriods: selection.periods,
|
||||
targetPeriods: periods,
|
||||
selectedPeriodIds: selection.selectedPeriodIds,
|
||||
faithfulRows: baseFaithfulRows,
|
||||
facts: factsForStandardization,
|
||||
snapshots: selection.snapshots
|
||||
});
|
||||
|
||||
const standardizedRows = standardizedPayload.rows;
|
||||
const statementDisplayModes: FinancialDisplayMode[] = input.surfaceKind === 'equity_statement'
|
||||
? (standardizedRows.length > 0
|
||||
? ['faithful', 'standardized']
|
||||
: ['faithful'])
|
||||
: defaultDisplayModes(input.surfaceKind);
|
||||
|
||||
const rawFacts = input.includeFacts
|
||||
? await listTaxonomyFactsByTicker({
|
||||
@@ -1075,8 +1152,8 @@ export async function getCompanyFinancials(input: GetCompanyFinancialsInput): Pr
|
||||
},
|
||||
surfaceKind: input.surfaceKind,
|
||||
cadence: input.cadence,
|
||||
displayModes: defaultDisplayModes(input.surfaceKind),
|
||||
defaultDisplayMode: 'standardized',
|
||||
displayModes: statementDisplayModes,
|
||||
defaultDisplayMode: defaultDisplayMode(input.surfaceKind, statementDisplayModes),
|
||||
periods,
|
||||
statementRows: {
|
||||
faithful: faithfulRows,
|
||||
@@ -1187,7 +1264,7 @@ export async function getCompanyFinancials(input: GetCompanyFinancialsInput): Pr
|
||||
surfaceKind: input.surfaceKind,
|
||||
cadence: input.cadence,
|
||||
displayModes: defaultDisplayModes(input.surfaceKind),
|
||||
defaultDisplayMode: 'standardized',
|
||||
defaultDisplayMode: defaultDisplayMode(input.surfaceKind),
|
||||
periods: basePeriods,
|
||||
statementRows: null,
|
||||
statementDetails: null,
|
||||
@@ -1253,7 +1330,7 @@ export async function getCompanyFinancials(input: GetCompanyFinancialsInput): Pr
|
||||
surfaceKind: input.surfaceKind,
|
||||
cadence: input.cadence,
|
||||
displayModes: defaultDisplayModes(input.surfaceKind),
|
||||
defaultDisplayMode: 'standardized',
|
||||
defaultDisplayMode: defaultDisplayMode(input.surfaceKind),
|
||||
periods: basePeriods,
|
||||
statementRows: null,
|
||||
statementDetails: null,
|
||||
@@ -1287,11 +1364,11 @@ export async function getCompanyFinancials(input: GetCompanyFinancialsInput): Pr
|
||||
};
|
||||
}
|
||||
|
||||
export async function getCompanyFinancialTaxonomy(input: GetCompanyFinancialsInput) {
|
||||
async function getCompanyFinancialTaxonomy(input: GetCompanyFinancialsInput) {
|
||||
return await getCompanyFinancials(input);
|
||||
}
|
||||
|
||||
export const __financialTaxonomyInternals = {
|
||||
const __financialTaxonomyInternals = {
|
||||
buildRows,
|
||||
buildDimensionBreakdown,
|
||||
buildNormalizationMetadata,
|
||||
|
||||
Reference in New Issue
Block a user