Documentation1.0 (latest)
PagesDonnées fondamentales · 11 / 29

Données fondamentales

Travaux en cours : les données fondamentales ne sont pas encore pleinement fonctionnelles. L'utilisation de cette fonctionnalité dans l'IDE ou dans les backtests peut renvoyer des données fondamentales incohérentes (champs manquants, dates de rapport discordantes ou instantanés alignés sur les barres instables). Considérez les résultats comme expérimentaux jusqu'à ce qu'une prochaine version déclare les données fondamentales stables.

Les stratégies QuantCraft peuvent utiliser des données financières d'entreprise à côté des barres de prix OHLCV : bilans, tableaux de flux de trésorerie, comptes de résultat, et historique / estimations de résultats. Les données sont chargées une fois par symbole depuis le service de données fondamentales QuantCraft, organisées en tables indexées par date, et mises à la disposition de votre stratégie sous forme d'instantanés alignés sur les barres pendant un backtest. Le moment des callbacks suit le Cycle de vie de la stratégie ; configurez les symboles et les dates dans Test (Exécution du code).

Au-delà des trois états financiers, vous obtenez aussi des ratios (91 au total), des valeurs par action, des multiples et rendements de valorisation, et des scores de qualité (Piotroski F, Altman Z-prime, Beneish M) — tous point-in-time, tous optionnels. Ils sont déployés symbole par symbole ; protégez donc chaque accès : raw["metricsInputs"] is None signifie qu'un lot est antérieur à eux.

Cette page couvre :

  • Quelles données d'états financiers sont disponibles
  • Comment les tables indexées par date sont organisées
  • Comment les charges utiles alignées sur les barres parviennent à vos callbacks pendant un backtest

Voir aussi : les jeux de données globaux de rendements de facteurs Fama-French (non rattachés à un ticker) sont une fonctionnalité distincte — voir Facteurs Fama-French (fama_french.qc, sans argument de callback). Les rows de facteurs sont indexées par des chaînes YYYYMM, pas par des indices de liste.


Ce que vous obtenez

Chaque lot de données fondamentales est un unique objet JSON pour un ticker, contenant :

  • Bilan — rapports quarterly et yearly.
  • Flux de trésorerie — rapports quarterly et yearly.
  • Compte de résultat — rapports quarterly et yearly.
  • Résultats (earnings) :
    • History — BPA publié par rapport aux estimations et surprises, par date de rapport.
    • Trend — estimations futures, tendance du BPA et révisions des analystes.
    • Annual — epsActual par exercice.
  • Ratios — ratios financiers quarterly et yearly (marges, rendements, liquidité, endettement).
  • Financials extended — métriques étendues quarterly et yearly absentes des états de base (résultat, bilan, flux de trésorerie).
  • Par action — valeurs par action quarterly et yearly telles que déposées (nombre d'actions selon la base de fractionnement de cette période).
  • Valorisation — capitalisation boursière, valeur d'entreprise, multiples et rendements quarterly et yearly, plus un objet latest sans date.
  • Scores — Piotroski F, Altman Z-prime et Beneish M quarterly et yearly, plus notApplicableReason.
  • TTM — un unique objet sur douze mois glissants (non réparti par période).
  • Provenance des métriques — objets plats metricsInputs / metricsHealth. metricsInputs vaut None sur un lot antérieur à l'extension des métriques.
  • Historique des dépôts — métadonnées de dépôt quarterly et yearly (type de formulaire, date de dépôt, indexées par fin de période). Également incluses dans les instantanés alignés sur les barres current(...) lorsqu'elles sont présentes dans le lot ; les tables brutes restent disponibles via f.tables["filingHistory.quarterly"].
  • Informations sur la société — métadonnées plates de l'entité (nom, CIK, SIC, adresse, places de cotation, tickers). Non indexées par date et absentes des instantanés alignés sur les barres ; accès via f.raw["companyInfo"].

Chaque rapport est une ligne de métriques en camelCase — par exemple totalAssets, cash, freeCashFlow, totalRevenue, netIncome, epsActual, epsEstimate, surprisePercent. Les valeurs numériques peuvent arriver sous forme de chaînes dans le JSON sous-jacent, et tout champ manquant revient sous la forme None.

Un ticker donné peut ne pas exposer toutes les sections. Consultez l'Explorateur de couverture des données fondamentales pour voir quels champs sont disponibles pour un ticker.


Tables indexées par date

Pour chaque section ci-dessus, les données fondamentales sont organisées en une table indexée par date : les lignes sont indexées par date de rapport (YYYY-MM-DD), et les métriques sont exposées sous forme de listes parallèles que vous pouvez indexer comme un historique de prix.

Les chemins de tables standard sont :

CheminSignification
balanceSheet.quarterly / balanceSheet.yearlyInstantanés du bilan
cashFlow.quarterly / cashFlow.yearlyTableaux de flux de trésorerie
incomeStatement.quarterly / incomeStatement.yearlyComptes de résultat
earnings.HistoryBPA publié, estimations, surprise par rapport
earnings.TrendEstimations des analystes, tendance du BPA, révisions
earnings.AnnualepsActual annuel
ratios.quarterly / ratios.yearlyRatios financiers (marges, rendements, liquidité, endettement)
financialsExtended.quarterly / financialsExtended.yearlyMétriques financières étendues
perShare.quarterly / perShare.yearlyValeurs par action (telles que déposées)
valuation.quarterly / valuation.yearlyMultiples et rendements de valorisation
scores.quarterly / scores.yearlyPiotroski / Altman / Beneish
filingHistory.quarterly / filingHistory.yearlyMétadonnées de dépôt (type de formulaire, date de dépôt)

Ce ne sont pas des tables. valuation.latest, scores.notApplicableReason, ttm, metricsInputs, metricsHealth et companyInfo ne sont pas indexés par date ; ils sont donc absents de tables, de lists et de tout instantané à l'heure d'une barre — c'est voulu :

Pas une tablePourquoi
valuation.latestUn objet unique à côté des clés de date, pas une période
scores.notApplicableReasonUne chaîne à côté des clés de date
ttmUn objet unique ; les valeurs sont des scalaires et non des dicts de lignes
metricsInputs / metricsHealthObjets plats de provenance
companyInfoMétadonnées plates de l'entité

Tous ces éléments sont à la date du téléchargement plutôt que par période ; les garder hors de tables les garde aussi hors de tout instantané à l'heure d'une barre — un backtest ne peut donc pas lire par accident le prix d'aujourd'hui sur une barre de 2019. Accédez-y plutôt via f.raw. Un bloc vide ({"quarterly": {}, "yearly": {}}, ce à quoi ressemblent les scores d'un déclarant du secteur financier) n'enregistre aucune table.

Convention d'indexation : du plus récent au plus ancien

Dans l'une quelconque de ces tables, l'indice 0 est la période éligible la plus récente, l'indice 1 la précédente, et ainsi de suite. Cela correspond au fonctionnement des séries de prix dans le reste de QuantCraft.

Si vous voulez charger un lot directement (par exemple hors d'un backtest), la forme de base est :

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

Ce que vous pouvez lire sur un lot chargé :

AttributCe qu'il fournit
f.rawL'arbre JSON décodé complet.
f.symbolTicker résolu (p. ex. "AAPL").
f.tablesDict d'objets DateKeyedTable indexé par chemin pointé (p. ex. "balanceSheet.quarterly").
f.table(path)Accesseur pratique pour une seule DateKeyedTable.
f.listsTable plate indexée par "<tablePath>.<fieldName>", valeurs alignées du plus récent au plus ancien.

Une DateKeyedTable expose periods (les clés YYYY-MM-DD, du plus récent au plus ancien), columns (champ → valeurs) et prend en charge l'indexation table["fieldName"].

Découvrir les champs à l'exécution est facile : sorted(f.lists.keys()) affiche chaque série plate, et sorted(t.columns.keys()) affiche les colonnes d'une table — utile lorsqu'un serveur ajoute ou retire des champs.


Charges utiles alignées sur les barres en backtest

En backtest, vous ne lisez pas les données fondamentales sous forme de tables brutes — le moteur sélectionne le bon rapport pour la barre courante et le transmet à vos callbacks sous forme d'instantané. C'est ce qu'on appelle la charge utile alignée sur les barres.

Configurer les données fondamentales pour un backtest

Dans l'onglet Symbol & data de Run backtest :

  1. Cochez Uses fundamentals (select if your strategy requires fundamental data) (nécessite d'être connecté — QuantCraft envoie votre jeton de session pour charger les fichiers de données fondamentales B2). Les exécutions forward en masse et sur graphique l'appellent Use fundamentals (optional). La case s'affiche lorsque les fonctionnalités de données fondamentales sont disponibles dans votre version, mais elle est désactivée (avec une indication Premium) sauf si vous avez Premium ou si l'accès aux données gratuites est activé.
  2. Choisissez un ou plusieurs lots de données fondamentales dans la sélection multiple (chemins comme fundamentals/AAPL.json.gz).

Avec une source de symboles Screener (backtest) ou une cible Screener (exécutions en masse AutoTrading / QuantCloud), vous n'avez rien à choisir : activez les données fondamentales et chaque symbole retenu par le filtre reçoit son propre lot, de sorte que fundamentals.current(bar["t"], symbol=symbol) fonctionne pour chacun. Les lots proviennent du téléchargement du Screener lui-même (rien n'est récupéré deux fois), et un symbole que le Screener n'a pas encore téléchargé est récupéré une fois puis conservé. Dans une exécution en direct, les lots suivent chaque nouveau filtrage. Les sélections manuelles restent acceptées comme compléments (p. ex. un ticker de référence). Un symbole dont les données ne peuvent pas être chargées renvoie None au lieu de faire échouer l'exécution — le panneau Output indique combien ont été chargés.

Les symboles OHLCV et les symboles de données fondamentales sont indépendants. Vous pouvez faire un backtest de RNMBY via le flux du courtier tout en chargeant les données fondamentales de RHM.XETRA — transmettez le bon ticker à fundamentals.current(..., symbol="RHM.XETRA") (ou équivalent) dans le code.

Lorsque plusieurs lots sont sélectionnés, utilisez un symbol= explicite avec fundamentals.current / get_data_with_offset quand vous avez besoin d'un lot précis. Le lot principal utilisé pour les instantanés alignés sur les barres est par défaut le premier symbole OHLCV de votre liste de symboles, sauf si le moteur applique une autre règle.

Pour un accès de bas niveau aux tables hors des callbacks, utilisez qc_fundamentals depuis quantcraft.process.runtime lorsqu'il n'est pas None (p. ex. qc_fundamentals.raw["companyInfo"]). Il ne contient que le lot principal ; utilisez le handle fundamentals du callback avec symbol= pour tout autre ticker.

Si les données fondamentales ne sont pas configurées, le moteur transmet simplement fundamentals=None à vos callbacks, et vous le gérez par une garde.

Point-in-time (backtest) : le moteur de backtest et Debug Test construisent tous deux BacktestFundamentals(..., backtest_mode=True), de sorte que current / get_data_with_offset utilisent le filtrage par date de dépôt (use_filing_date=True) — une période est exclue si son filing_date est postérieure à l'heure de la barre. Lorsqu'une période n'a aucun filing_date exploitable, une échéance de dépôt supposée est utilisée à la place — 45 jours après la fin de période pour les tables trimestrielles, 90 jours pour les annuelles (default_filing_lag_days) — plutôt que de rendre le rapport visible le jour de la clôture de sa période. Les exécutions forward utilisent l'éligibilité à la fin de période (backtest_mode=False). Préférez le handle fundamentals du callback dans les backtests de l'IDE ; appeler directement qc_fundamentals.get_data_with_offset(...) sans use_filing_date=True peut anticiper par rapport aux dates de dépôt.

Exécutions forward : une exécution en direct recharge ses données fondamentales environ toutes les heures, et dans les 5 minutes environ qui suivent la mise à jour des données du Screener. Un rechargement en échec conserve les données précédentes. Comme le « maintenant » d'une exécution forward est réellement aujourd'hui, les blocs à la date du téléchargement (raw["ttm"], raw["valuation"]["latest"], …) y sont des données courantes, et non de l'anticipation.

Callbacks hérités : d'anciennes stratégies peuvent utiliser un argument qc_fundamentals distinct ou un dict brut au lieu de BacktestFundamentals. La signature moderne transmet fundamentals comme troisième argument de on_bar / on_tick. L'alias de niveau module fundamentals_as_of_bar correspond à la même forme de charge utile alignée sur les barres.

Le paramètre de callback fundamentals

Lorsque les données fondamentales sont chargées, le moteur transmet un handle BacktestFundamentals comme argument fundamentals à on_bar, on_tick et (lorsqu'il est utilisé sur les exécutions 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éthode / membreRôle
fundamentals.current(bar_time, symbol=None)Dict d'instantané à la date de la barre (filtré par date de dépôt en backtest). Le symbol optionnel sélectionne le lot chargé ; à omettre pour le lot principal. Inclut filingHistory lorsqu'il est présent dans le lot.
fundamentals.get_data_with_offset(bar_time, offset, *, symbol=None, print_on_shortfall=True)Période d'ordre N précédente par sous-table pour le lot choisi (même mode de date de dépôt que current).
fundamentals.symbolsTuple des clés en majuscules de chaque lot chargé.
fundamentals.primary_symbol()Clé principale utilisée lorsque symbol est omis.
fundamentals.reload_all()Retélécharge tous les lots. Les exécutions forward l'appellent pour vous ; vous en aurez rarement besoin.

À quoi ressemble l'instantané

Un instantané aligné sur les barres est un dict imbriqué contenant uniquement les périodes valides à la date de cette barre (filtrées par date de dépôt dans les backtests de l'IDE). Chaque section non nulle inclut un periodEnd ainsi que les métriques du rapport :

{ "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 peut valoir null lorsqu'aucune période ne qualifie à la date de la barre ou avant. Le priceToEarningsRatio: null à côté de earningsYield: -5.0 ci-dessus correspond à une société déficitaire, pas à une donnée manquante — voir Valorisation.

Jamais dans l'instantané : ttm, valuation.latest, scores.notApplicableReason, metricsInputs, metricsHealth, companyInfo. Ils sont à la date du téléchargement plutôt que par période ; les rattacher à une barre ferait fuiter de l'information future dans un backtest. Lisez-les depuis qc_fundamentals.raw[...].

Le même dict par barre apparaît sous le champ fundamentals de chaque ligne dans le résultat de backtest structuré ; ce que vous voyez dans votre stratégie correspond donc à ce qui apparaît dans les données du résultat.

Chercher des périodes plus anciennes (get_data_with_offset)

Parfois vous ne voulez pas le dernier rapport à la date d'une barre, mais un rapport précédent — le trimestre d'avant, l'exercice d'avant, la ligne de résultats précédente :

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

Comportement :

  • Chaque sous-table est indexée indépendamment. Avec offset=1, la section balanceSheet.quarterly recule d'un trimestre, tandis que balanceSheet.yearly recule d'un exercice, et ainsi de suite.
  • Si une sous-table n'a pas assez d'historique avant la barre courante, sa section vaut null dans le dict renvoyé (et une note d'une ligne peut être affichée).
  • La forme est la même que current(...), plus un "offset": <int> de niveau supérieur.
  • Sur l'API brute QcFundamentals, la signature préférée est f.get_data_with_offset(bar_time, offset, *, print_on_shortfall=True, use_filing_date=False). La fonction de niveau module get_data_with_offset(qc, bar_time, offset, *, print_on_shortfall=True) n'a pas de paramètre use_filing_date — elle utilise toujours l'éligibilité à la fin de période ; appelez donc la méthode avec use_filing_date=True (ou utilisez le handle du callback) pour des données point-in-time. La valeur par défaut use_filing_date=False signifie éligibilité à la fin de période uniquement (peut anticiper par rapport aux dates de dépôt). Avec use_filing_date=True, une période dont le filing_date est absent se rabat sur une échéance supposée de 45 jours (trimestriel) / 90 jours (annuel) après la fin de période. Préférez le handle fundamentals du callback dans les backtests de l'IDE, qui utilise automatiquement le filtrage par date de dépôt.

Données fondamentales multi-symboles

Lorsque vous chargez plusieurs lots (pour des stratégies transversales ou de comparaison), vous pouvez choisir celui à lire avec 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")
  • Omettre symbol utilise le lot principal : le seul chargé ; sinon fundamentals.primary s'il est défini, sinon le symbole tradé, sinon le ticker chargé premier par ordre alphabétique. Dans une exécution multi-symboles ou Screener, ce repli peut silencieusement désigner la mauvaise société — transmettez toujours symbol=symbol dans ce cas.
  • fundamentals.symbols liste chaque clé de ticker en majuscules actuellement chargée.
  • fundamentals.primary_symbol() renvoie la clé principale.
  • Le symbole tradé dans votre backtest peut être différent du ou des symboles de données fondamentales que vous chargez — par exemple, trader SPY tout en lisant les données fondamentales de AAPL et MSFT.

Heures de barre acceptées

current(...) et get_data_with_offset(...) acceptent plusieurs formats d'heure afin que vous puissiez transmettre bar["t"], bar.t[0] ou votre propre valeur :

  • datetime (un naïf est traité comme UTC),
  • date,
  • chaîne ISO (y compris un Z final),
  • secondes epoch UNIX (int / float).

Schémas pratiques

Quelques formes courantes :

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

Référence des champs de données fondamentales

La disponibilité des champs dépend du symbole — tous les émetteurs ne publient pas chaque ligne. Utilisez sorted(f.lists.keys()) ou sorted(t.columns.keys()) à l'exécution pour voir ce qu'un lot précis expose réellement. Les valeurs numériques peuvent arriver sous forme de chaînes ; convertissez avec float(...) pour calculer.

Bilan

Tables : balanceSheet.quarterly, balanceSheet.yearly

ChampChamp
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

Flux de trésorerie

Tables : cashFlow.quarterly, cashFlow.yearly

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

Compte de résultat

Tables : incomeStatement.quarterly, incomeStatement.yearly

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

Résultats — History

Table : earnings.History (BPA publié par rapport aux estimations, par date de rapport)

ChampDescription
beforeAfterMarketMoment de la publication du rapport par rapport aux heures de marché
currencyDevise de reporting
dateDate de fin de période
epsActualBPA publié
epsEstimateEstimation de consensus du BPA
epsDifferenceepsActual − epsEstimate
reportDateDate de publication des chiffres
surprisePercentSurprise du BPA en pourcentage

Résultats — Trend

Table : earnings.Trend (estimations futures et révisions)

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

Résultats — Annual

Table : earnings.Annual (BPA annuel publié)

ChampDescription
dateDate de fin d'exercice
epsActualBPA annuel publié

Ratios

Tables : ratios.quarterly, ratios.yearly

91 métriques depuis l'extension des métriques (94 clés en comptant date, currency_symbol et filing_date). L'ensemble d'origine est listé en premier ; tout ce qui suit à partir de Fonds de roulement est nouveau. Un symbole en cours de déploiement peut ne porter que l'ensemble d'origine ; découvrez donc la liste réelle avec sorted(f.table("ratios.quarterly").columns.keys()).

Ensemble d'origine

Les champs de marge et de rendement de ce groupe (grossMargin, operatingMargin, etc.) sont des fractions décimales — multipliez par 100 pour obtenir un pourcentage. debtToEquity a été renommé debtToEquityRatio.

ChampChamp
grossMargincurrentRatio
operatingMarginquickRatio
netProfitMargincashRatio
returnOnAssetsdebtToEquityRatio
returnOnEquitydebtToAssetsRatio
operatingCashFlowMargininterestCoverageRatio
freeCashFlowMarginassetTurnover
freeCashFlowToNetIncomeinventoryTurnover
receivablesTurnover

Fonds de roulement

ChampRemarques
daysSalesOutstandingJours, 2 déc.
daysInventoryOutstandingJours, 2 déc.
daysPayablesOutstandingJours, 2 déc.
cashConversionCycleJours, 2 déc. — signé ; une valeur négative (encaisser avant de payer) est souhaitable, pas une erreur
operatingCycleJours, 2 déc.
payablesTurnoverDécimal simple
workingCapitalTurnoverDécimal simple
fixedAssetTurnoverDécimal simple
netWorkingCapitalToAssetsDécimal simple
defensiveIntervalRatioDécimal simple

Endettement et couverture

Tous des décimaux simples (4 déc.).

ChampChamp
totalDebtToEquityRationetDebtToFreeCashFlowRatio
netDebtToEquityRatioequityMultiplier
longTermDebtToEquityRatioebitdaInterestCoverageRatio
longTermDebtToCapitalRatiocashFlowInterestCoverageRatio
capitalizationRatiocashFlowToDebtRatio
debtToEbitdaRatiodebtServiceCoverageRatio
netDebtToEbitdaRatio

Rendements

ChampRemarques
effectiveTaxRate%
returnOnInvestedCapital%
returnOnCapitalEmployed%
returnOnTangibleEquity%
cashReturnOnInvestedCapital%
operatingReturnOnAssets%
returnOnEquityDupontMargin%
returnOnEquityDupontTurnoverDécimal simple
returnOnEquityDupontLeverageDécimal simple
nopatChaîne monétaire, 2 déc. — l'intrus dans un bloc par ailleurs entièrement numérique
investedCapitalChaîne monétaire, 2 déc.
capitalEmployedChaîne monétaire, 2 déc.

Marges et intensité capitalistique

ChampRemarques
ebitMargin%
ebitdaMargin%
pretaxMargin%
researchAndDevelopmentToRevenue%
sellingGeneralAdministrativeToRevenue%
stockBasedCompensationToRevenue%
capexToRevenue%
capexToOperatingCashFlow%
accrualsRatio%
assetQualityRatio%
capexToDepreciationRatioDécimal simple (4 déc.)
cashConversionRatioDécimal simple (4 déc.)

Distribution

Tous des pourcentages (2 déc.) : dividendPayoutRatio, freeCashFlowPayoutRatio, shareholderPayoutToFreeCashFlow, retentionRatio, sustainableGrowthRate.

Croissance, en glissement annuel

Tous des pourcentages (2 déc.). La croissance du chiffre d'affaires / du résultat net / du BPA n'est pas dupliquée ici — elle se trouve dans earnings.Trend.

ChampChamp
grossProfitGrowthYoYtotalAssetsGrowthYoY
operatingIncomeGrowthYoYtotalStockholderEquityGrowthYoY
ebitdaGrowthYoYtotalDebtGrowthYoY
operatingCashFlowGrowthYoYdividendsPaidGrowthYoY
freeCashFlowGrowthYoYsharesDilutedGrowthYoY — négatif signifie rachats d'actions
capitalExpendituresGrowthYoYbookValuePerShareGrowthYoY

TCAC — yearly uniquement

Tous des pourcentages (2 déc.), et null sur chaque période quarterly — un filtre ou une règle qui en demande un sur une période trimestrielle fait échouer tous les symboles.

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

Financials extended

Tables : financialsExtended.quarterly, financialsExtended.yearly

Les champs varient selon le symbole et ne sont pas énumérés ici. Découvrez ce qu'un lot chargé expose à l'exécution :

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

Les champs courants incluent des métriques d'EBITDA étendues, des composantes du fonds de roulement et des données par action absentes du compte de résultat de base.

Champs retirés : ebitda, ebitdaMargin, enterpriseValue, priceToEarnings, priceToBook, priceToSales, evToEbitda et evToRevenue sont retirés de Financials extended au profit des versions de Valorisation et de Ratios, calculées sur douze mois glissants (les valeurs diffèrent donc).

Par action

Tables : perShare.quarterly, perShare.yearly

Un enregistrement tel que déposé : sharesOutstanding est sur la base de fractionnement déclarée pour cette période, donc non comparable de part et d'autre d'un fractionnement. Utilisez Valorisation pour toute comparaison. Les valeurs sont des chaînes à 4 décimales sauf indication contraire.

ChampRemarques
dateDate de fin de période
sharesOutstandingChaîne à 2 décimales
sharesBasis"dei" / "weightedAverageSharesDiluted" / "weightedAverageSharesBasic"
bookValuePerShare, tangibleBookValuePerShare
revenuePerShare, ebitdaPerShare
operatingCashFlowPerShare, freeCashFlowPerShare
cashPerShare, netCashPerShare
netDebtPerShare, totalDebtPerShare
workingCapitalPerShare, retainedEarningsPerShare
dividendsPaidPerShare
netCurrentAssetValuePerShareNCAV de Graham
grahamNumber

Valorisation

Tables : valuation.quarterly, valuation.yearly (plus le valuation.latest, qui n'est pas une table)

Trois règles :

  1. Les multiples sont marketCap / agrégat, et non price / perShare. Ne les recalculez pas à partir de perShare — des comparatifs retraités font diverger les deux pour les périodes plus anciennes.
  2. Un multiple None à côté d'un rendement signé est correct, pas un bug. Les multiples marqués null si dénominateur non positif ci-dessous passent à None lorsque leur dénominateur n'est pas positif, tandis que les rendements et bookToMarketRatio conservent leur signe. Une société déficitaire affiche priceToEarningsRatio: None et earningsYield: -5.0.
  3. Les multiples sont sur douze mois glissants, même pour les périodes trimestrielles — un PER trimestriel est un vrai PER glissant, pas un trimestre annualisé.

Métadonnées

ChampRemarques
dateDate de fin de période
sharePriceChaîne à 4 décimales
priceDateYYYY-MM-DD
priceLagDaysEntier
priceBasis"as-quoted" (le plus récent) / "split-adjusted" / "unreconciled" — méfiez-vous de "unreconciled"
approximatetrue sur les périodes historiques (ajustement rétroactif résiduel des dividendes)
sharesRebasedLe nombre d'actions a été ramené à la base de fractionnement actuelle
sharesOutstandingChaîne à 2 décimales, base de fractionnement actuelle — diffère de perShare.sharesOutstanding (tel que déposé) pour les périodes plus anciennes

Taille : marketCap, enterpriseValue — chaînes monétaires à 2 décimales.

Multiples (nombres à 4 décimales)

ChampNull si dénominateur non positif
priceToEarningsRatiooui
priceToBookRatiooui
priceToTangibleBookRatiooui
priceToSalesRatio
priceToFreeCashFlowRatiooui
priceToOperatingCashFlowRatiooui
pegRatioTrailingoui
enterpriseValueToEbitdaRatiooui
enterpriseValueToEbitRatiooui
enterpriseValueToSalesRatio
enterpriseValueToFreeCashFlowRatiooui
enterpriseValueToOperatingCashFlowRatio
enterpriseValueToInvestedCapitalRatio
bookToMarketRatioconserve son signe
netDebtToMarketCapRatio
marketCapToTotalAssets
altmanZScore

Rendements — pourcentages à 2 décimales, signés : earningsYield, ebitToEnterpriseValueYield, freeCashFlowYield, operatingCashFlowYield, dividendYield, buybackYield, shareholderYield.

valuation.latest — pas une période. Un objet unique portant chaque champ ci-dessus plus priceAsOf, priceAgeDays, priceSource, fundamentalsAsOf et ttmBasis. Il se trouve à côté des clés de date ; ce n'est donc pas une entrée de table et il n'apparaît jamais dans un instantané à l'heure d'une barre — le lire dans un backtest serait de l'anticipation. Accédez-y via qc_fundamentals.raw["valuation"]["latest"] ; il vaut None lorsqu'aucun prix n'est disponible.

Scores

Tables : scores.quarterly, scores.yearly

ChampRemarques
dateDate de fin de période
piotroskiFScoreEntier de 0 à 9
piotroskiComponentsObjet ou None — clés roaPositive, cfoPositive, roaImproved, accrualQuality, leverageImproved, currentRatioImproved, noShareIssuance, grossMarginImproved, assetTurnoverImproved, chacune valant 1, 0 ou None
altmanZScorePrivate4 déc. — Z-prime, valeur comptable des capitaux propres
beneishMScore4 déc.
beneishComponentsObjet ou None — clés dsri, gmi, aqi, sgi, depi, sgai, tata, lvgi (nombres à 4 déc.)

Deux absences attendues, dont aucune n'est une erreur :

  • La toute première période d'un déclarant n'a pas de scores — ils nécessitent une année précédente pour comparer.
  • Pour les SIC 6000–6799 (banques, courtiers, assureurs, REIT), les deux compartiments sont vides et scores.notApplicableReason vaut "financial-sector-sic". Traitez cela comme « non applicable », pas comme « pas de données ». Lisez-le depuis qc_fundamentals.raw["scores"]["notApplicableReason"].

TTM

ttm est un objet unique, pas une table — des agrégats sur douze mois glissants à la date du téléchargement, et non à la date d'une barre. Il n'apparaît jamais dans un instantané ; accédez-y via qc_fundamentals.raw["ttm"] (sans risque en exécution forward, anticipation en backtest).

  • Métadonnées : basis ("quarterly" / "annual"), asOf, periodsUsed (list[str]), complete (bool), synthetic (bool — le T4 de l'exercice a été reconstitué ; normal, généralement true), coverageDays (environ 365).
  • Flux — sommés sur 4 trimestres, chaînes à 2 décimales sauf epsBasic / epsDiluted (4 déc.) : 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.
  • Instantanés de stock — dernière période, jamais sommés, chaînes à 2 décimales : totalAssets, totalLiab, totalStockholderEquity, totalCurrentAssets, totalCurrentLiabilities, totalDebt, netDebt, cashAndShortTermInvestments, goodWill, intangibleAssets, netWorkingCapital, retainedEarnings, netReceivables, inventory, accountsPayable, propertyPlantAndEquipmentNet, preferredStockTotalEquity, commonStockSharesOutstanding, minorityInterest.

Provenance des métriques (metricsInputs / metricsHealth)

Objets plats décrivant l'origine des métriques :

"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" }

Vérifiez metricsHealth["prices"] != "absent" avant de vous appuyer sur des champs basés sur le prix ; "stale" reste utilisable — comparez avec priceAsOf. metricsInputs is None signifie un lot antérieur à l'extension des métriques. Les champs apparaissent symbole par symbole à mesure qu'il se retéléverse, donc la couverture est inégale pendant un temps : traitez chaque bloc ci-dessus comme optionnel.

Conventions de type pour les blocs de métriques

ClasseType JSONDécimalesExemple
Agrégats monétaireschaîne2"4519282704050.00"
Valeurs par action, sharePricechaîne4"309.3500"
Nombres d'actionschaîne2"14608963000.00"
Ratios / multiples / rotation / couverture / scoresnombre428.0462
Pourcentages (marges, rendements, distribution, croissance, TCAC, taux d'imposition)nombre242.35 signifie 42,35 %
Jours (DSO / DIO / DPO / CCC / cycle d'exploitation)nombre229.2
Comptes (piotroskiFScore, priceLagDays)nombreentier8
Dateschaîne—YYYY-MM-DD

Chaque métrique est indépendamment nullable. Un objet de période est omis entièrement lorsque toutes ses clés hors métadonnées sont nulles. Un bloc vaut {"quarterly": {}, "yearly": {}} lorsqu'il est vide — jamais null, jamais supprimé. NaN / Infinity n'apparaissent jamais.

Informations sur la société

companyInfo est un objet plat — il n'est pas indexé par date et n'apparaît pas dans les instantanés current(...) / get_data_with_offset(...). Accédez-y directement :

info = f.raw["companyInfo"]
ChampTypeRemarques
entityTypestring | nullp. ex. "operating"
entityNamestring | nullDénomination légale
cikstring | nullClé d'index centrale de la SEC
sicstring | nullCode d'industrie SIC
sicDescriptionstring | nullCatégorie SIC lisible
stateOfIncorporationstring | nullCode d'État à deux lettres
fiscalYearEndstring | nullFormat "MMDD", p. ex. "0926" = 26 sept.
categorystring | nullCatégorie de déclarant
phonestring | nullNuméro de téléphone de contact
exchangesstring[]Codes de places de cotation
tickersstring[]Symboles boursiers
businessAddressobject | nullstreet1, street2, city, stateOrCountry, zipCode

Remarques et pièges

  • Protégez toujours contre None. Si les données fondamentales ne sont pas configurées, fundamentals vaut None. Dans un instantané, certaines sections (p. ex. earnings.Trend, scores) peuvent aussi valoir null pour certaines barres, et les blocs de l'extension des métriques peuvent être entièrement absents sur d'anciens lots.
  • Transmettez toujours symbol= dans les exécutions multi-symboles et Screener — le repli sur le lot principal peut ne pas être le ticker sur lequel vous vous trouvez.
  • Les nombres peuvent être des chaînes. Le JSON sous-jacent livre souvent les métriques numériques sous forme de chaînes ; convertissez avec float(...) pour calculer.
  • L'indexation du plus récent au plus ancien s'applique aux tables indexées par date et aux recherches par décalage — l'indice 0 est la période éligible la plus récente à la date de la barre, 1 celle d'avant, etc.
  • L'horodatage de la barre fait foi pour déterminer quel rapport est « courant » — transmettez directement bar["t"] (ou bar.t[0]) ; vous n'avez pas besoin de l'analyser vous-même.
Données fondamentales — Documentation (1.0 (latest)) | QuantCraft