Back to Community
Fundamentals: how to query earnings_report data?

When I try running this query:

def before_trading_start(context):  
    fundamental_df = get_fundamentals(  
        query(  
              fundamentals.earnings_report.accession_number,  
              fundamentals.earnings_report.file_date,  
              fundamentals.earnings_report.basic_eps,  
              fundamentals.earnings_report.form_type,  
              fundamentals.earnings_report.normalized_basic_eps,  
              fundamentals.earnings_report.period_ending_date,  
              )  
        );  
    context.fundamental_df = fundamental_df  

I get the following error:
AttributeError: type object 'earnings_report' has no attribute 'accession_number'

If I comment out accession_number, I get an error with the next line of the query:
AttributeError: type object 'earnings_report' has no attribute 'file_date' leading me to believe this isn't working for another reason?

6 responses

OK Problem solved.

I used the built-in quantopian debugger and see that the names of these fields is actually different than that described in the docs:

fundamentals.earnings_report  
 fundamentals.earnings_report: type  
accession_number_earnings_reports: UserInstrumentedAttribute  
accession_number_earnings_reports_as_of: UserInstrumentedAttribute  
accession_number_earnings_reports_is_calculated: UserInstrumentedAttribute  
basic_accounting_change: UserInstrumentedAttribute  
basic_accounting_change_as_of: UserInstrumentedAttribute  
basic_accounting_change_is_calculated: UserInstrumentedAttribute  
basic_average_shares: UserInstrumentedAttribute  
basic_average_shares_as_of: UserInstrumentedAttribute  
basic_average_shares_is_calculated: UserInstrumentedAttribute  
basic_continuous_operations: UserInstrumentedAttribute  
basic_continuous_operations_as_of: UserInstrumentedAttribute  
basic_continuous_operations_is_calculated: UserInstrumentedAttribute  
basic_discontinuous_operations: UserInstrumentedAttribute  
basic_discontinuous_operations_as_of: UserInstrumentedAttribute  
basic_discontinuous_operations_is_calculated: UserInstrumentedAttribute  
basic_eps: UserInstrumentedAttribute  
basic_eps_as_of: UserInstrumentedAttribute  
basic_eps_is_calculated: UserInstrumentedAttribute  
basic_eps_other_gains_losses: UserInstrumentedAttribute  
basic_eps_other_gains_losses_as_of: UserInstrumentedAttribute  
basic_eps_other_gains_losses_is_calculated: UserInstrumentedAttribute  
basic_extraordinary: UserInstrumentedAttribute  
basic_extraordinary_as_of: UserInstrumentedAttribute  
basic_extraordinary_is_calculated: UserInstrumentedAttribute  
continuing_and_discontinued_basic_eps: UserInstrumentedAttribute  
continuing_and_discontinued_basic_eps_as_of: UserInstrumentedAttribute  
continuing_and_discontinued_basic_eps_is_calculated: UserInstrumentedAttribute  
continuing_and_discontinued_diluted_eps: UserInstrumentedAttribute  
continuing_and_discontinued_diluted_eps_as_of: UserInstrumentedAttribute  
continuing_and_discontinued_diluted_eps_is_calculated: UserInstrumentedAttribute  
diluted_accounting_change: UserInstrumentedAttribute  
diluted_accounting_change_as_of: UserInstrumentedAttribute  
diluted_accounting_change_is_calculated: UserInstrumentedAttribute  
diluted_average_shares: UserInstrumentedAttribute  
diluted_average_shares_as_of: UserInstrumentedAttribute  
diluted_average_shares_is_calculated: UserInstrumentedAttribute  
diluted_continuous_operations: UserInstrumentedAttribute  
diluted_continuous_operations_as_of: UserInstrumentedAttribute  
diluted_continuous_operations_is_calculated: UserInstrumentedAttribute  
diluted_discontinuous_operations: UserInstrumentedAttribute  
diluted_discontinuous_operations_as_of: UserInstrumentedAttribute  
diluted_discontinuous_operations_is_calculated: UserInstrumentedAttribute  
diluted_eps: UserInstrumentedAttribute  
diluted_eps_as_of: UserInstrumentedAttribute  
diluted_eps_is_calculated: UserInstrumentedAttribute  
diluted_eps_other_gains_losses: UserInstrumentedAttribute  
diluted_eps_other_gains_losses_as_of: UserInstrumentedAttribute  
diluted_eps_other_gains_losses_is_calculated: UserInstrumentedAttribute  
diluted_extraordinary: UserInstrumentedAttribute  
diluted_extraordinary_as_of: UserInstrumentedAttribute  
diluted_extraordinary_is_calculated: UserInstrumentedAttribute  
dividend_per_share: UserInstrumentedAttribute  
dividend_per_share_as_of: UserInstrumentedAttribute  
dividend_per_share_is_calculated: UserInstrumentedAttribute  
file_date_earnings_reports: UserInstrumentedAttribute  
file_date_earnings_reports_as_of: UserInstrumentedAttribute  
file_date_earnings_reports_is_calculated: UserInstrumentedAttribute  
form_type_earnings_reports: UserInstrumentedAttribute  
form_type_earnings_reports_as_of: UserInstrumentedAttribute  
form_type_earnings_reports_is_calculated: UserInstrumentedAttribute  
normalized_basic_eps: UserInstrumentedAttribute  
normalized_basic_eps_as_of: UserInstrumentedAttribute  
normalized_basic_eps_is_calculated: UserInstrumentedAttribute  
normalized_diluted_eps: UserInstrumentedAttribute  
normalized_diluted_eps_as_of: UserInstrumentedAttribute  
normalized_diluted_eps_is_calculated: UserInstrumentedAttribute  
period_ending_date_earnings_reports: UserInstrumentedAttribute  
period_ending_date_earnings_reports_as_of: UserInstrumentedAttribute  
period_ending_date_earnings_reports_is_calculated: UserInstrumentedAttribute  
sid: user_hybrid_propertyProxy  
tax_loss_carryforward_basic_eps: UserInstrumentedAttribute  
tax_loss_carryforward_basic_eps_as_of: UserInstrumentedAttribute  
tax_loss_carryforward_basic_eps_is_calculated: UserInstrumentedAttribute  
tax_loss_carryforward_diluted_eps: UserInstrumentedAttribute  
tax_loss_carryforward_diluted_eps_as_of: UserInstrumentedAttribute  
tax_loss_carryforward_diluted_eps_is_calculated: UserInstrumentedAttribute  

Debugging skills are one of the top three of those valued by professional technical analysts and programmers the world 'round.

The other two are:
1) Communication skills. If one cannot describe, nor transcribe one's context or situation then neither of the other two matter.
2) Humility. To theorize the source of contention and yet be proven wrong, and lo, to accept this failure and contradiction of assumption -- is to grow beyond one's initial boundary of assumption. A great skill indeed.

[Edit: A happy coincidence that you, Jason, interpreted my comment as a mild request... All benefit no? But no worries, the communication channels are wide and clear.]

@Market Tech: LOL, I can't tell if you are saying "thank you" or "please give better details" hah.

In case of the latter, here's my "working" query (using the renamed fields as I show above):

def before_trading_start(context=Shims.Context()):  
    fundamental_df = get_fundamentals(  
        query(  
              fundamentals.earnings_report.accession_number_earnings_reports,  
              fundamentals.earnings_report.file_date_earnings_reports,  
              fundamentals.earnings_report.basic_eps,  
              fundamentals.earnings_report.form_type_earnings_reports,  
              fundamentals.earnings_report.normalized_basic_eps,  
              fundamentals.earnings_report.period_ending_date_earnings_reports,  
              )  
        );  
    context.fundamental_df = fundamental_df  

It works, however a few days into my simulation run I am now getting a cryptic error:
Something went wrong on our end. Sorry for the inconvenience. Please email us so we can help. KeyError: 12681 There was a runtime error on line 1489. No stack trace, but my code was working before. I'll do more debugging and try to get it working. (and post more details then)

EDIT: and line 1489 is simply
context.framework._update(data) #hook into my update loop so the trace isn't helpful.

Four examples make for harder to read code like accession_number_earnings_reports instead of simply accession_number (since 'earnings_reports' is redundant) so hopefully Q can improve those, pretty cool that you figured that out.

ok figured out the error: it's a "key missing from dictionary" and the 12681 is actually a quantopian SID.

it's because the sid may not exist in the returned fundamentals dataframe (why I don't know):

if "accession_number_earnings_reports" in this.framework.context.fundamental_df[security.sid]:  

so the fix is:
if security.sid in this.framework.context.fundamental_df and "accession_number_earnings_reports" in this.framework.context.fundamental_df[security.sid]:

Jason, were you able to get value of "file_date_earnings_reports" field?
I get "None" value.