Documentación1.0 (latest)
PáginasDatos fundamentales · 11 / 29

Datos fundamentales

Trabajo en curso: los datos fundamentales aún no son totalmente funcionales. Usar esta función en el IDE o en los backtests puede devolver datos fundamentales inconsistentes (campos ausentes, fechas de informe que no coinciden o instantáneas alineadas con las barras inestables). Trata los resultados como experimentales hasta que una versión futura marque los datos fundamentales como estables.

Las estrategias de QuantCraft pueden usar datos financieros de empresas junto con las barras de precio OHLCV: balances, estados de flujo de caja, cuentas de resultados e historial / estimaciones de resultados. Los datos se cargan una vez por símbolo desde el servicio de datos fundamentales de QuantCraft, se organizan en tablas indexadas por fecha y se ponen a disposición de tu estrategia como instantáneas alineadas con las barras durante un backtest. El momento de los callbacks sigue el Ciclo de vida de la estrategia; configura símbolos y fechas en Test (Ejecutar código).

Además de los tres estados financieros, obtienes ratios (91 en total), valores por acción, múltiplos y rendimientos de valoración y puntuaciones de calidad (Piotroski F, Altman Z-prime, Beneish M), todo point-in-time y todo opcional. Se van desplegando símbolo a símbolo, así que protege cada acceso: raw["metricsInputs"] is None significa que un paquete es anterior a ellos.

Esta página cubre:

  • Qué datos de estados financieros hay disponibles
  • Cómo se organizan las tablas indexadas por fecha
  • Cómo llegan las cargas alineadas con las barras a tus callbacks durante un backtest

Relacionado: los conjuntos de datos globales de rendimientos de factores Fama-French (no por ticker) son una función aparte; consulta Factores Fama-French (fama_french.qc, sin argumento de callback). Las rows de factores están indexadas por cadenas YYYYMM, no por índices de lista.


Qué obtienes

Cada paquete de datos fundamentales es un único objeto JSON de un ticker, que contiene:

  • Balance: informes quarterly y yearly.
  • Flujo de caja: informes quarterly y yearly.
  • Cuenta de resultados: informes quarterly y yearly.
  • Resultados (earnings):
    • History: BPA publicado frente a estimaciones y sorpresas por fecha de informe.
    • Trend: estimaciones futuras, tendencia del BPA y revisiones de analistas.
    • Annual: epsActual por ejercicio fiscal.
  • Ratios: ratios financieros quarterly y yearly (márgenes, rentabilidades, liquidez, apalancamiento).
  • Financials extended: métricas extendidas quarterly y yearly que no están en los estados básicos de resultados, balance o flujo de caja.
  • Por acción: valores por acción quarterly y yearly tal como se presentaron (número de acciones sobre la base de split de ese periodo).
  • Valoración: capitalización bursátil, valor empresarial, múltiplos y rendimientos quarterly y yearly, más un objeto latest sin fecha.
  • Puntuaciones: Piotroski F, Altman Z-prime y Beneish M quarterly y yearly, más notApplicableReason.
  • TTM: un único objeto de los últimos doce meses (no agrupado por periodo).
  • Procedencia de las métricas: objetos planos metricsInputs / metricsHealth. metricsInputs es None en un paquete anterior a la ampliación de métricas.
  • Historial de presentaciones: metadatos de presentación quarterly y yearly (tipo de formulario, fecha de presentación, indexados por fin de periodo). También se incluye en las instantáneas alineadas con las barras current(...) cuando está presente en el paquete; las tablas brutas siguen disponibles mediante f.tables["filingHistory.quarterly"].
  • Información de la empresa: metadatos planos de la entidad (nombre, CIK, SIC, dirección, bolsas, tickers). No indexados por fecha y ausentes de las instantáneas alineadas con las barras; se accede mediante f.raw["companyInfo"].

Cada informe es una fila de métricas en camelCase; por ejemplo totalAssets, cash, freeCashFlow, totalRevenue, netIncome, epsActual, epsEstimate, surprisePercent. Los valores numéricos pueden llegar como cadenas en el JSON subyacente, y cualquier campo ausente se devuelve como None.

Un ticker concreto puede no exponer todas las secciones. Consulta el Explorador de cobertura de datos fundamentales para ver qué campos hay disponibles para un ticker.


Tablas indexadas por fecha

Para cada sección anterior, los datos fundamentales se organizan como una tabla indexada por fecha: las filas se indexan por fecha de informe (YYYY-MM-DD) y las métricas se exponen como listas paralelas que puedes indexar como un historial de precios.

Las rutas de tabla estándar son:

RutaSignificado
balanceSheet.quarterly / balanceSheet.yearlyInstantáneas del balance
cashFlow.quarterly / cashFlow.yearlyEstados de flujo de caja
incomeStatement.quarterly / incomeStatement.yearlyCuentas de resultados
earnings.HistoryBPA publicado, estimaciones, sorpresa por informe
earnings.TrendEstimaciones de analistas, tendencia del BPA, revisiones
earnings.AnnualepsActual anual
ratios.quarterly / ratios.yearlyRatios financieros (márgenes, rentabilidades, liquidez, apalancamiento)
financialsExtended.quarterly / financialsExtended.yearlyMétricas financieras extendidas
perShare.quarterly / perShare.yearlyValores por acción (tal como se presentaron)
valuation.quarterly / valuation.yearlyMúltiplos y rendimientos de valoración
scores.quarterly / scores.yearlyPiotroski / Altman / Beneish
filingHistory.quarterly / filingHistory.yearlyMetadatos de presentación (tipo de formulario, fecha de presentación)

No son tablas. valuation.latest, scores.notApplicableReason, ttm, metricsInputs, metricsHealth y companyInfo no están indexados por fecha, así que no aparecen en tables, lists ni en ninguna instantánea a la hora de una barra; es intencionado:

No es una tablaPor qué
valuation.latestUn único objeto junto a las claves de fecha, no un periodo
scores.notApplicableReasonUna cadena junto a las claves de fecha
ttmUn único objeto; los valores son escalares y no dicts de filas
metricsInputs / metricsHealthObjetos planos de procedencia
companyInfoMetadatos planos de la entidad

Todos son a fecha de la subida y no por periodo, así que mantenerlos fuera de tables también los mantiene fuera de toda instantánea a la hora de una barra: un backtest no puede leer por accidente el precio de hoy en una barra de 2019. Accede a ellos mediante f.raw. Un bloque vacío ({"quarterly": {}, "yearly": {}}, que es el aspecto de los scores de un declarante del sector financiero) no registra ninguna tabla.

Convención de índices: primero lo más reciente

Dentro de cualquiera de estas tablas, el índice 0 es el periodo elegible más reciente, el índice 1 es el anterior, y así sucesivamente. Coincide con el funcionamiento de las series de precios en el resto de QuantCraft.

Si quieres cargar un paquete directamente (por ejemplo, fuera de un backtest), la forma básica es:

from quantcraft.fundamentals import QcFundamentals f = QcFundamentals(token, "fundamentals/AAPL.json.gz") latest_total_assets = f.tables["balanceSheet.quarterly"]["totalAssets"][0] prior_total_assets = f.tables["balanceSheet.quarterly"]["totalAssets"][1] same = f.lists["balanceSheet.quarterly.totalAssets"][0] whole = f.raw

Lo que puedes leer de un paquete cargado:

AtributoQué te da
f.rawEl árbol JSON decodificado completo.
f.symbolTicker resuelto (p. ej. "AAPL").
f.tablesDict de objetos DateKeyedTable indexado por ruta con puntos (p. ej. "balanceSheet.quarterly").
f.table(path)Acceso cómodo a una sola DateKeyedTable.
f.listsMapa plano indexado por "<tablePath>.<fieldName>", con valores alineados de más reciente a más antiguo.

Una DateKeyedTable expone periods (las claves YYYY-MM-DD, de más reciente a más antigua), columns (campo → valores) y admite la indexación table["fieldName"].

Descubrir campos en tiempo de ejecución es fácil: sorted(f.lists.keys()) muestra cada serie plana y sorted(t.columns.keys()) muestra las columnas de una tabla; es útil cuando un servidor añade o elimina campos.


Cargas alineadas con las barras en backtests

En un backtest no lees los datos fundamentales como tablas brutas: el motor selecciona el informe adecuado para la barra actual y se lo entrega a tus callbacks como una instantánea. Eso se llama la carga alineada con las barras.

Configurar los datos fundamentales para un backtest

En la pestaña Symbol & data de Run backtest:

  1. Marca Uses fundamentals (select if your strategy requires fundamental data) (requiere haber iniciado sesión; QuantCraft envía tu token de sesión para cargar los archivos de datos fundamentales B2). Las ejecuciones forward masivas y sobre el gráfico lo llaman Use fundamentals (optional). La casilla se muestra cuando las funciones de datos fundamentales están disponibles en tu versión, pero está desactivada (con una pista de Premium) salvo que tengas Premium o esté habilitado el acceso a datos gratuitos.
  2. Elige uno o más paquetes de datos fundamentales en la selección múltiple (rutas como fundamentals/AAPL.json.gz).

Con una fuente de símbolos Screener (backtest) o un objetivo Screener (ejecuciones masivas de AutoTrading / QuantCloud) no necesitas elegir nada: activa los datos fundamentales y cada símbolo que seleccione el filtro recibe su propio paquete, de modo que fundamentals.current(bar["t"], symbol=symbol) funciona para cada uno. Los paquetes proceden de la propia descarga del Screener (nada se obtiene dos veces) y un símbolo que el Screener aún no ha descargado se obtiene una vez y se conserva. En una ejecución en vivo, los paquetes siguen cada nuevo filtrado. Las selecciones manuales se siguen aceptando como extras (p. ej. un ticker de referencia). Un símbolo cuyos datos no se pueden cargar devuelve None en lugar de hacer fallar la ejecución; el panel Output indica cuántos se cargaron.

Los símbolos OHLCV y los símbolos de datos fundamentales son independientes. Puedes hacer backtest de RNMBY mediante el feed del bróker mientras cargas los datos fundamentales de RHM.XETRA: pasa el ticker correcto a fundamentals.current(..., symbol="RHM.XETRA") (o equivalente) en el código.

Cuando hay varios paquetes seleccionados, usa un symbol= explícito en fundamentals.current / get_data_with_offset cuando necesites un paquete concreto. El paquete principal usado para las instantáneas alineadas con las barras es por defecto el primer símbolo OHLCV de tu lista de símbolos, salvo que el motor aplique otra regla.

Para el acceso de bajo nivel a las tablas fuera de los callbacks, usa qc_fundamentals de quantcraft.process.runtime cuando no sea None (p. ej. qc_fundamentals.raw["companyInfo"]). Contiene solo el paquete principal; usa el manejador fundamentals del callback con symbol= para cualquier otro ticker.

Si los datos fundamentales no están configurados, el motor simplemente pasa fundamentals=None a tus callbacks y tú lo proteges con una comprobación.

Point-in-time (backtest): tanto el motor de backtest como Debug Test construyen BacktestFundamentals(..., backtest_mode=True), así que current / get_data_with_offset usan el filtrado por fecha de presentación (use_filing_date=True): un periodo se excluye si su filing_date es posterior a la hora de la barra. Cuando un periodo no tiene un filing_date utilizable, se usa en su lugar una fecha límite de presentación supuesta: 45 días después del fin de periodo en las tablas trimestrales y 90 días en las anuales (default_filing_lag_days), en lugar de hacer visible el informe el día en que cierra su periodo. Las ejecuciones forward usan la elegibilidad por fin de periodo (backtest_mode=False). Prefiere el manejador fundamentals del callback en los backtests del IDE; llamar directamente a qc_fundamentals.get_data_with_offset(...) sin use_filing_date=True puede anticiparse respecto a las fechas de presentación.

Ejecuciones forward: una ejecución en vivo recarga sus datos fundamentales aproximadamente cada hora, y en unos 5 minutos después de que se actualicen los datos del Screener. Una recarga fallida conserva los datos anteriores. Como el "ahora" de una ejecución forward es realmente hoy, los bloques a fecha de la subida (raw["ttm"], raw["valuation"]["latest"], …) son allí datos actuales, no anticipación.

Callbacks heredados: las estrategias antiguas pueden usar un argumento qc_fundamentals aparte o un dict bruto en lugar de BacktestFundamentals. La firma moderna pasa fundamentals como tercer argumento de on_bar / on_tick. El alias a nivel de módulo fundamentals_as_of_bar corresponde a la misma forma de carga alineada con las barras.

El parámetro de callback fundamentals

Cuando se cargan los datos fundamentales, el motor pasa un manejador BacktestFundamentals como argumento fundamentals a on_bar, on_tick y (cuando se usa en ejecuciones forward) on_timer:

def on_bar(bar_index, bar, fundamentals=None, symbol=None): if fundamentals is None: return snap = fundamentals.current(bar["t"]) bs_q = (snap.get("balanceSheet") or {}).get("quarterly") or {} total_assets = bs_q.get("totalAssets")
Método / miembroPropósito
fundamentals.current(bar_time, symbol=None)Dict de instantánea a la hora de esa barra (filtrado por fecha de presentación en backtest). El symbol opcional selecciona qué paquete cargado; omítelo para el principal. Incluye filingHistory cuando está presente en el paquete.
fundamentals.get_data_with_offset(bar_time, offset, *, symbol=None, print_on_shortfall=True)Periodo N anterior por subtabla para el paquete elegido (mismo modo de fecha de presentación que current).
fundamentals.symbolsTupla de claves en mayúsculas de cada paquete cargado.
fundamentals.primary_symbol()Clave principal usada cuando se omite symbol.
fundamentals.reload_all()Vuelve a descargar todos los paquetes. Las ejecuciones forward lo llaman por ti; rara vez lo necesitarás.

Qué aspecto tiene la instantánea

Una instantánea alineada con las barras es un dict anidado con solo los periodos válidos a la hora de esa barra (filtrados por fecha de presentación en los backtests del IDE). Cada sección no nula incluye un periodEnd más las métricas del informe:

{ "barTime": "2026-06-01T00:00:00+00:00", "symbol": "AAPL", "balanceSheet": { "quarterly": { "periodEnd": "2026-03-31", "totalAssets": 352000000.0, "cash": 51000000.0 }, "yearly": { "periodEnd": "2025-09-30", "totalAssets": 344000000.0 } }, "cashFlow": { "quarterly": { "periodEnd": "2026-03-31", "freeCashFlow": 24500000.0 } }, "incomeStatement": { "quarterly": { "periodEnd": "2026-03-31", "totalRevenue": 95000000.0, "netIncome": 23000000.0 } }, "earnings": { "History": { "periodEnd": "2026-03-31", "reportDate": "2026-05-02", "epsActual": 1.53 }, "Trend": null, "Annual": { "periodEnd": "2025-09-30", "epsActual": 6.13 } }, "ratios": { "quarterly": { "periodEnd": "2026-03-31", "grossMargin": 0.47, "operatingMargin": 0.31, "currentRatio": 1.04 }, "yearly": { "periodEnd": "2025-09-30", "grossMargin": 0.46, "currentRatio": 0.87 } }, "financialsExtended": { "quarterly": { "periodEnd": "2026-03-31", "ebitda": 38000000000.0, "ebitdaMargin": 0.40 }, "yearly": { "periodEnd": "2025-09-30", "ebitda": 134000000000.0 } }, "perShare": { "quarterly": { "periodEnd": "2026-03-31", "bookValuePerShare": 4.3, "grahamNumber": null }, "yearly": null }, "valuation": { "quarterly": { "periodEnd": "2026-03-31", "marketCap": 3812000000.0, "priceToEarningsRatio": null, "earningsYield": -5.0, "priceBasis": "split-adjusted", "approximate": true }, "yearly": null }, "scores": { "quarterly": { "periodEnd": "2026-03-31", "piotroskiFScore": 3, "beneishMScore": -1.94 }, "yearly": null }, "filingHistory": { "quarterly": { "periodEnd": "2026-03-31", "formType": "10-Q", "filedAt": "2026-05-02" }, "yearly": { "periodEnd": "2025-09-30", "formType": "10-K", "filedAt": "2025-10-31" } } }

Trend puede ser null cuando ningún periodo cumple en la hora de la barra o antes. El priceToEarningsRatio: null junto a earningsYield: -5.0 de arriba corresponde a una empresa con pérdidas, no a datos ausentes; consulta Valoración.

Nunca en la instantánea: ttm, valuation.latest, scores.notApplicableReason, metricsInputs, metricsHealth, companyInfo. Son a fecha de la subida y no por periodo; adjuntarlos a una barra filtraría información futura a un backtest. Léelos de qc_fundamentals.raw[...].

El mismo dict por barra aparece en el campo fundamentals de cada fila del resultado de backtest estructurado, así que lo que ves en tu estrategia coincide con lo que aparece en los datos del resultado.

Consultar periodos anteriores (get_data_with_offset)

A veces no quieres el último informe a la hora de una barra, sino uno anterior: el trimestre previo, el ejercicio previo, la línea de resultados anterior:

prior = fundamentals.get_data_with_offset(bar["t"], 1) prev_bs_q = (prior or {}).get("balanceSheet", {}).get("quarterly")

Comportamiento:

  • Cada subtabla se indexa de forma independiente. Con offset=1, la sección balanceSheet.quarterly retrocede un trimestre, mientras que balanceSheet.yearly retrocede un ejercicio, y así sucesivamente.
  • Si una subtabla no tiene suficiente historial antes de la barra actual, su sección es null en el dict devuelto (y puede imprimirse una nota de una línea).
  • La forma es la misma que current(...), más un "offset": <int> de nivel superior.
  • En la API bruta QcFundamentals, la firma preferida es f.get_data_with_offset(bar_time, offset, *, print_on_shortfall=True, use_filing_date=False). La función a nivel de módulo get_data_with_offset(qc, bar_time, offset, *, print_on_shortfall=True) no tiene el parámetro use_filing_date: siempre usa la elegibilidad por fin de periodo, así que llama al método con use_filing_date=True (o usa el manejador del callback) para datos point-in-time. El valor por defecto use_filing_date=False significa solo elegibilidad por fin de periodo (puede anticiparse respecto a las fechas de presentación). Con use_filing_date=True, un periodo cuyo filing_date falta recurre a una fecha límite supuesta de 45 días (trimestral) / 90 días (anual) tras el fin de periodo. Prefiere el manejador fundamentals del callback en los backtests del IDE, que usa el filtrado por fecha de presentación automáticamente.

Datos fundamentales con varios símbolos

Cuando cargas varios paquetes (para estrategias transversales o de comparación), puedes elegir de cuál leer con symbol="TICKER":

def on_bar(bar_index, bar, fundamentals=None, symbol=None): if fundamentals is None: return primary_snap = fundamentals.current(bar["t"]) msft_snap = fundamentals.current(bar["t"], symbol="MSFT") aapl_prior = fundamentals.get_data_with_offset(bar["t"], 1, symbol="AAPL")
  • Omitir symbol usa el paquete principal: el único cargado; si no, fundamentals.primary si está definido, si no el símbolo operado, si no el ticker cargado primero por orden alfabético. En una ejecución con varios símbolos o Screener, ese respaldo puede ser en silencio la empresa equivocada: pasa siempre symbol=symbol allí.
  • fundamentals.symbols lista cada clave de ticker en mayúsculas actualmente cargada.
  • fundamentals.primary_symbol() devuelve la clave principal.
  • El símbolo que operas en el backtest puede ser distinto del o de los símbolos de datos fundamentales que cargas; por ejemplo, operar SPY mientras lees los datos fundamentales de AAPL y MSFT.

Horas de barra aceptadas

Tanto current(...) como get_data_with_offset(...) aceptan varios formatos de hora para que puedas pasar bar["t"], bar.t[0] o tu propio valor:

  • datetime (el ingenuo se trata como UTC),
  • date,
  • cadena ISO (incluida una Z final),
  • segundos epoch UNIX (int / float).

Patrones prácticos

Algunas formas habituales:

def on_bar(bar_index, bar, fundamentals=None, symbol=None): if fundamentals is None: return snap = fundamentals.current(bar["t"]) if not snap: return bs_q = (snap.get("balanceSheet") or {}).get("quarterly") or {} is_q = (snap.get("incomeStatement") or {}).get("quarterly") or {} if (bs_q.get("totalAssets") or 0) > 0 and (is_q.get("netIncome") or 0) > 0: ...
def on_bar(bar_index, bar, fundamentals=None, symbol=None): if fundamentals is None: return snap = fundamentals.current(bar["t"]) or {} prior = fundamentals.get_data_with_offset(bar["t"], 1) or {} cur = ((snap.get("incomeStatement") or {}).get("quarterly") or {}).get("totalRevenue") prev = ((prior.get("incomeStatement") or {}).get("quarterly") or {}).get("totalRevenue") if cur and prev: revenue_growth = (cur - prev) / prev

Referencia de campos de datos fundamentales

La disponibilidad de los campos depende del símbolo: no todos los emisores informan cada línea. Usa sorted(f.lists.keys()) o sorted(t.columns.keys()) en tiempo de ejecución para ver qué expone realmente un paquete concreto. Los valores numéricos pueden llegar como cadenas; conviértelos con float(...) para operar.

Balance

Tablas: balanceSheet.quarterly, balanceSheet.yearly

CampoCampo
accountsPayablelongTermInvestments
accumulatedAmortizationnegativeGoodwill
accumulatedDepreciationnetDebt
accumulatedOtherComprehensiveIncomenetInvestedCapital
additionalPaidInCapitalnetReceivables
capitalLeaseObligationsnetTangibleAssets
capitalStocknetWorkingCapital
capitalSurplusenoncontrollingInterestInConsolidatedEntity
cashnonCurrrentAssetsOther
cashAndEquivalentsnonCurrentAssetsTotal
cashAndShortTermInvestmentsnonCurrentLiabilitiesOther
commonStocknonCurrentLiabilitiesTotal
commonStockSharesOutstandingotherAssets
commonStockTotalEquityotherCurrentAssets
currency_symbolotherCurrentLiab
currentDeferredRevenueotherLiab
dateotherStockholderEquity
deferredLongTermAssetChargespreferredStockRedeemable
deferredLongTermLiabpreferredStockTotalEquity
earningAssetspropertyPlantAndEquipmentGross
filing_datepropertyPlantAndEquipmentNet
goodWillpropertyPlantEquipment
intangibleAssetsretainedEarnings
inventoryretainedEarningsTotalEquity
liabilitiesAndStockholdersEquityshortLongTermDebt
longTermDebtshortLongTermDebtTotal
longTermDebtTotalshortTermDebt
shortTermInvestmentstemporaryEquityRedeemableNoncontrollingInterests
totalAssetstotalCurrentAssets
totalCurrentLiabilitiestotalLiab
totalPermanentEquitytotalStockholderEquity
treasuryStockwarrants

Flujo de caja

Tablas: cashFlow.quarterly, cashFlow.yearly

CampoCampo
beginPeriodCashFlowendPeriodCashFlow
capitalExpendituresexchangeRateChanges
cashAndCashEquivalentsChangesfiling_date
cashFlowsOtherOperatingfreeCashFlow
changeInCashinvestments
changeInWorkingCapitalissuanceOfCapitalStock
changeReceivablesnetBorrowings
changeToAccountReceivablesnetIncome
changeToInventoryotherCashflowsFromFinancingActivities
changeToLiabilitiesotherCashflowsFromInvestingActivities
changeToNetincomeotherNonCashItems
changeToOperatingActivitiessalePurchaseOfStock
currency_symbolstockBasedCompensation
datetotalCashflowsFromInvestingActivities
depreciationtotalCashFromFinancingActivities
dividendsPaidtotalCashFromOperatingActivities

Cuenta de resultados

Tablas: incomeStatement.quarterly, incomeStatement.yearly

CampoCampo
costOfRevenuenetIncomeFromContinuingOps
currency_symbolnetInterestIncome
datenonOperatingIncomeNetOther
depreciationAndAmortizationnonRecurring
discontinuedOperationsoperatingIncome
effectOfAccountingChargesotherItems
ebitotherOperatingExpenses
ebitdapreferredStockAndOtherAdjustments
extraordinaryItemsreconciledDepreciation
filing_dateresearchDevelopment
grossProfitsellingAndMarketingExpenses
incomeBeforeTaxsellingGeneralAdministrative
incomeTaxExpensetaxProvision
interestExpensetotalOperatingExpenses
interestIncometotalOtherIncomeExpenseNet
minorityInteresttotalRevenue
netIncome
netIncomeApplicableToCommonShares

Resultados — History

Tabla: earnings.History (BPA publicado frente a estimaciones por fecha de informe)

CampoDescripción
beforeAfterMarketCuándo se publicó el informe en relación con el horario de mercado
currencyDivisa del informe
dateFecha de fin de periodo
epsActualBPA publicado
epsEstimateEstimación de consenso del BPA
epsDifferenceepsActual − epsEstimate
reportDateFecha en que se publicaron las cifras
surprisePercentSorpresa del BPA como porcentaje

Resultados — Trend

Tabla: earnings.Trend (estimaciones futuras y revisiones)

CampoCampo
dateepsTrendCurrent
periodepsTrend7daysAgo
growthepsTrend30daysAgo
earningsEstimateAvgepsTrend60daysAgo
earningsEstimateLowepsTrend90daysAgo
earningsEstimateHighepsRevisionsUpLast7days
earningsEstimateYearAgoEpsepsRevisionsUpLast30days
earningsEstimateNumberOfAnalystsepsRevisionsDownLast7days
earningsEstimateGrowthepsRevisionsDownLast30days
revenueEstimateAvg
revenueEstimateLow
revenueEstimateHigh
revenueEstimateYearAgoEps
revenueEstimateNumberOfAnalysts
revenueEstimateGrowth

Resultados — Annual

Tabla: earnings.Annual (BPA anual publicado)

CampoDescripción
dateFecha de fin del ejercicio fiscal
epsActualBPA anual publicado

Ratios

Tablas: ratios.quarterly, ratios.yearly

91 métricas desde la ampliación de métricas (94 claves contando date, currency_symbol y filing_date). Primero se lista el conjunto original; todo lo que va desde Capital de trabajo hacia abajo es nuevo. Un símbolo a mitad de despliegue puede llevar solo el conjunto original, así que descubre la lista real con sorted(f.table("ratios.quarterly").columns.keys()).

Conjunto original

Los campos de margen y rentabilidad de este grupo (grossMargin, operatingMargin, etc.) son fracciones decimales: multiplica por 100 para obtener un porcentaje. debtToEquity se renombró a debtToEquityRatio.

CampoCampo
grossMargincurrentRatio
operatingMarginquickRatio
netProfitMargincashRatio
returnOnAssetsdebtToEquityRatio
returnOnEquitydebtToAssetsRatio
operatingCashFlowMargininterestCoverageRatio
freeCashFlowMarginassetTurnover
freeCashFlowToNetIncomeinventoryTurnover
receivablesTurnover

Capital de trabajo

CampoNotas
daysSalesOutstandingDías, 2 dec.
daysInventoryOutstandingDías, 2 dec.
daysPayablesOutstandingDías, 2 dec.
cashConversionCycleDías, 2 dec. — con signo; un valor negativo (cobrar antes de pagar) es deseable, no un error
operatingCycleDías, 2 dec.
payablesTurnoverDecimal simple
workingCapitalTurnoverDecimal simple
fixedAssetTurnoverDecimal simple
netWorkingCapitalToAssetsDecimal simple
defensiveIntervalRatioDecimal simple

Apalancamiento y cobertura

Todos son decimales simples (4 dec.).

CampoCampo
totalDebtToEquityRationetDebtToFreeCashFlowRatio
netDebtToEquityRatioequityMultiplier
longTermDebtToEquityRatioebitdaInterestCoverageRatio
longTermDebtToCapitalRatiocashFlowInterestCoverageRatio
capitalizationRatiocashFlowToDebtRatio
debtToEbitdaRatiodebtServiceCoverageRatio
netDebtToEbitdaRatio

Rentabilidades

CampoNotas
effectiveTaxRate%
returnOnInvestedCapital%
returnOnCapitalEmployed%
returnOnTangibleEquity%
cashReturnOnInvestedCapital%
operatingReturnOnAssets%
returnOnEquityDupontMargin%
returnOnEquityDupontTurnoverDecimal simple
returnOnEquityDupontLeverageDecimal simple
nopatCadena monetaria, 2 dec. — la excepción en un bloque por lo demás totalmente numérico
investedCapitalCadena monetaria, 2 dec.
capitalEmployedCadena monetaria, 2 dec.

Márgenes e intensidad de capital

CampoNotas
ebitMargin%
ebitdaMargin%
pretaxMargin%
researchAndDevelopmentToRevenue%
sellingGeneralAdministrativeToRevenue%
stockBasedCompensationToRevenue%
capexToRevenue%
capexToOperatingCashFlow%
accrualsRatio%
assetQualityRatio%
capexToDepreciationRatioDecimal simple (4 dec.)
cashConversionRatioDecimal simple (4 dec.)

Reparto

Todos son porcentajes (2 dec.): dividendPayoutRatio, freeCashFlowPayoutRatio, shareholderPayoutToFreeCashFlow, retentionRatio, sustainableGrowthRate.

Crecimiento interanual

Todos son porcentajes (2 dec.). El crecimiento de ingresos / beneficio neto / BPA no se duplica aquí: está en earnings.Trend.

CampoCampo
grossProfitGrowthYoYtotalAssetsGrowthYoY
operatingIncomeGrowthYoYtotalStockholderEquityGrowthYoY
ebitdaGrowthYoYtotalDebtGrowthYoY
operatingCashFlowGrowthYoYdividendsPaidGrowthYoY
freeCashFlowGrowthYoYsharesDilutedGrowthYoY — negativo significa recompras
capitalExpendituresGrowthYoYbookValuePerShareGrowthYoY

TCAC — solo yearly

Todos son porcentajes (2 dec.) y null en cada periodo quarterly: un filtro o una regla que pida uno en un periodo trimestral hace fallar a todos los símbolos.

revenueCagr3y / revenueCagr5y, netIncomeCagr3y / netIncomeCagr5y, epsCagr3y / epsCagr5y, freeCashFlowCagr3y / freeCashFlowCagr5y, dividendCagr3y / dividendCagr5y.

Financials extended

Tablas: financialsExtended.quarterly, financialsExtended.yearly

Los campos varían según el símbolo y no se enumeran aquí. Descubre lo que expone un paquete cargado en tiempo de ejecución:

t = f.table("financialsExtended.quarterly") if t: print(sorted(t.columns.keys()))

Los campos habituales incluyen métricas de EBITDA extendidas, componentes del capital de trabajo y datos por acción que no están en la cuenta de resultados básica.

Campos retirados: ebitda, ebitdaMargin, enterpriseValue, priceToEarnings, priceToBook, priceToSales, evToEbitda y evToRevenue se están retirando de Financials extended en favor de las versiones de Valoración y de Ratios, que se calculan sobre los últimos doce meses (por lo que los valores difieren).

Por acción

Tablas: perShare.quarterly, perShare.yearly

Un registro tal como se presentó: sharesOutstanding está sobre la base de split que se informó para ese periodo, así que no es comparable a ambos lados de un split. Usa Valoración para cualquier comparación. Los valores son cadenas de 4 decimales salvo que se indique lo contrario.

CampoNotas
dateFecha de fin de periodo
sharesOutstandingCadena de 2 decimales
sharesBasis"dei" / "weightedAverageSharesDiluted" / "weightedAverageSharesBasic"
bookValuePerShare, tangibleBookValuePerShare
revenuePerShare, ebitdaPerShare
operatingCashFlowPerShare, freeCashFlowPerShare
cashPerShare, netCashPerShare
netDebtPerShare, totalDebtPerShare
workingCapitalPerShare, retainedEarningsPerShare
dividendsPaidPerShare
netCurrentAssetValuePerShareNCAV de Graham
grahamNumber

Valoración

Tablas: valuation.quarterly, valuation.yearly (más el valuation.latest, que no es una tabla)

Tres reglas:

  1. Los múltiplos son marketCap / agregado, no price / perShare. No los recalcules a partir de perShare: los comparativos reexpresados hacen que ambos discrepen en los periodos más antiguos.
  2. Un múltiplo None junto a un rendimiento con signo es correcto, no un error. Los múltiplos marcados como null con denominador no positivo más abajo pasan a None cuando su denominador no es positivo, mientras que los rendimientos y bookToMarketRatio conservan su signo. Una empresa con pérdidas muestra priceToEarningsRatio: None y earningsYield: -5.0.
  3. Los múltiplos son de los últimos doce meses, incluso en periodos trimestrales: un PER trimestral es un auténtico PER de los últimos doce meses, no un trimestre anualizado.

Metadatos

CampoNotas
dateFecha de fin de periodo
sharePriceCadena de 4 decimales
priceDateYYYY-MM-DD
priceLagDaysEntero
priceBasis"as-quoted" (último) / "split-adjusted" / "unreconciled" — desconfía de "unreconciled"
approximatetrue en periodos históricos (ajuste retroactivo residual de dividendos)
sharesRebasedEl número de acciones se pasó a la base de split actual
sharesOutstandingCadena de 2 decimales, base de split actual — difiere de perShare.sharesOutstanding (tal como se presentó) en periodos más antiguos

Tamaño: marketCap, enterpriseValue — cadenas monetarias de 2 decimales.

Múltiplos (números de 4 decimales)

CampoNull con denominador no positivo
priceToEarningsRatiosí
priceToBookRatiosí
priceToTangibleBookRatiosí
priceToSalesRatio
priceToFreeCashFlowRatiosí
priceToOperatingCashFlowRatiosí
pegRatioTrailingsí
enterpriseValueToEbitdaRatiosí
enterpriseValueToEbitRatiosí
enterpriseValueToSalesRatio
enterpriseValueToFreeCashFlowRatiosí
enterpriseValueToOperatingCashFlowRatio
enterpriseValueToInvestedCapitalRatio
bookToMarketRatioconserva su signo
netDebtToMarketCapRatio
marketCapToTotalAssets
altmanZScore

Rendimientos — porcentajes de 2 decimales, con signo: earningsYield, ebitToEnterpriseValueYield, freeCashFlowYield, operatingCashFlowYield, dividendYield, buybackYield, shareholderYield.

valuation.latest — no es un periodo. Un único objeto que lleva todos los campos anteriores más priceAsOf, priceAgeDays, priceSource, fundamentalsAsOf y ttmBasis. Está junto a las claves de fecha, así que no es una entrada de tabla y nunca aparece en una instantánea a la hora de una barra: leerlo en un backtest sería anticipación. Accede a él mediante qc_fundamentals.raw["valuation"]["latest"]; es None cuando no hay precio disponible.

Puntuaciones

Tablas: scores.quarterly, scores.yearly

CampoNotas
dateFecha de fin de periodo
piotroskiFScoreEntero de 0 a 9
piotroskiComponentsObjeto o None — claves roaPositive, cfoPositive, roaImproved, accrualQuality, leverageImproved, currentRatioImproved, noShareIssuance, grossMarginImproved, assetTurnoverImproved, cada una 1, 0 o None
altmanZScorePrivate4 dec. — Z-prime, patrimonio contable
beneishMScore4 dec.
beneishComponentsObjeto o None — claves dsri, gmi, aqi, sgi, depi, sgai, tata, lvgi (números de 4 dec.)

Dos ausencias esperadas, ninguna de las cuales es un error:

  • El primer periodo de un declarante no lleva puntuaciones: necesitan un año previo con el que comparar.
  • Para los SIC 6000–6799 (bancos, corredurías, aseguradoras, REIT) ambos grupos están vacíos y scores.notApplicableReason es "financial-sector-sic". Trátalo como "no aplicable", no como "sin datos". Léelo de qc_fundamentals.raw["scores"]["notApplicableReason"].

TTM

ttm es un único objeto, no una tabla: agregados de los últimos doce meses a fecha de la subida, no a fecha de ninguna barra. Nunca aparece en una instantánea; accede a él mediante qc_fundamentals.raw["ttm"] (seguro en ejecuciones forward, anticipación en un backtest).

  • Metadatos: basis ("quarterly" / "annual"), asOf, periodsUsed (list[str]), complete (bool), synthetic (bool — se reconstruyó el 4T fiscal; normal, normalmente true), coverageDays (unos 365).
  • Flujos — sumados sobre 4 trimestres, cadenas de 2 decimales salvo epsBasic / epsDiluted (4 dec.): totalRevenue, grossProfit, operatingIncome, ebit, ebitda, netIncome, epsBasic, epsDiluted, depreciationAndAmortization, interestExpense, incomeBeforeTax, incomeTaxExpense, costOfRevenue, sellingGeneralAdministrative, researchDevelopment, taxProvision, totalCashFromOperatingActivities, totalCashflowsFromInvestingActivities, capitalExpenditures, freeCashFlow, dividendsPaid, stockBasedCompensation, paymentsForRepurchaseOfCommonStock, proceedsFromIssuanceOfCommonStock, repaymentsOfLongTermDebt.
  • Saldos puntuales — último periodo, nunca sumados, cadenas de 2 decimales: totalAssets, totalLiab, totalStockholderEquity, totalCurrentAssets, totalCurrentLiabilities, totalDebt, netDebt, cashAndShortTermInvestments, goodWill, intangibleAssets, netWorkingCapital, retainedEarnings, netReceivables, inventory, accountsPayable, propertyPlantAndEquipmentNet, preferredStockTotalEquity, commonStockSharesOutstanding, minorityInterest.

Procedencia de las métricas (metricsInputs / metricsHealth)

Objetos planos que describen de dónde proceden las métricas:

"metricsInputs": { "metricsVersion": 1, "priceAsOf": "2026-08-21", "priceSource": "…" | null, // source of valuation.latest "historicalPriceSource": "stooq" | null, // source of valuation.quarterly/yearly "sharesSource": "dei" | "weightedAverageSharesDiluted" | "weightedAverageSharesBasic" | null, "dividendSource": "nasdaq" | "edgar-xbrl" | "cash-flow" | null, "ttmBasis": "quarterly" | "annual" | null, "historicalValuation": true } "metricsHealth": { "prices": "ok" | "stale" | "absent", // current price for valuation.latest "historicalPrices": "ok" | "absent", "splits": "ok" | "absent", "calendar": "ok" | "absent" }

Comprueba metricsHealth["prices"] != "absent" antes de apoyarte en campos basados en precios; "stale" sigue siendo utilizable: compara con priceAsOf. metricsInputs is None significa un paquete anterior a la ampliación de métricas. Los campos aparecen símbolo a símbolo a medida que se vuelve a subir, así que la cobertura es irregular durante un tiempo: trata cada bloque anterior como opcional.

Convenciones de tipos de los bloques de métricas

ClaseTipo JSONDecimalesEjemplo
Agregados monetarioscadena2"4519282704050.00"
Valores por acción, sharePricecadena4"309.3500"
Número de accionescadena2"14608963000.00"
Ratios / múltiplos / rotación / cobertura / puntuacionesnúmero428.0462
Porcentajes (márgenes, rentabilidades, rendimientos, reparto, crecimiento, TCAC, tasa impositiva)número242.35 significa 42,35 %
Días (DSO / DIO / DPO / CCC / ciclo operativo)número229.2
Recuentos (piotroskiFScore, priceLagDays)númeroentero8
Fechascadena—YYYY-MM-DD

Cada métrica es anulable de forma independiente. Un objeto de periodo se omite por completo cuando todas sus claves que no son metadatos son nulas. Un bloque es {"quarterly": {}, "yearly": {}} cuando está vacío: nunca null, nunca eliminado. NaN / Infinity no aparecen jamás.

Información de la empresa

companyInfo es un objeto plano: no está indexado por fecha y no aparece en las instantáneas current(...) / get_data_with_offset(...). Accede a él directamente:

info = f.raw["companyInfo"]
CampoTipoNotas
entityTypestring | nullp. ej. "operating"
entityNamestring | nullDenominación legal de la entidad
cikstring | nullClave de índice central de la SEC
sicstring | nullCódigo de industria SIC
sicDescriptionstring | nullCategoría SIC legible
stateOfIncorporationstring | nullCódigo de estado de dos letras
fiscalYearEndstring | nullFormato "MMDD", p. ej. "0926" = 26 sept.
categorystring | nullCategoría del declarante
phonestring | nullTeléfono de contacto
exchangesstring[]Códigos de bolsa
tickersstring[]Símbolos bursátiles
businessAddressobject | nullstreet1, street2, city, stateOrCountry, zipCode

Notas y trampas

  • Protege siempre contra None. Si los datos fundamentales no están configurados, fundamentals es None. Dentro de una instantánea, secciones individuales (p. ej. earnings.Trend, scores) también pueden ser null en algunas barras, y los bloques de la ampliación de métricas pueden faltar por completo en paquetes antiguos.
  • Pasa siempre symbol= en ejecuciones con varios símbolos y Screener: el respaldo del paquete principal puede no ser el ticker en el que estás.
  • Los números pueden ser cadenas. El JSON subyacente suele enviar las métricas numéricas como cadenas; conviértelas con float(...) al operar.
  • La indexación de más reciente a más antiguo se aplica a las tablas indexadas por fecha y a las consultas por desplazamiento: el índice 0 es el periodo elegible más reciente a la hora de la barra, 1 el anterior, etc.
  • La marca de tiempo de la barra es la fuente de verdad para saber qué informe es el "actual": pasa bar["t"] (o bar.t[0]) directamente; no necesitas analizarla tú.
29 min de lecturaSugerir una edición ↗
Datos fundamentales — Documentación (1.0 (latest)) | QuantCraft