Hi QC team,
First off thanks for the work you’ve done to maintain and improve QC. It has very impressive capabilities and having attempted to create my own simple equity backtester I can only imagine the difficulty of the work.
I am trying to create a dynamic universe for an equity backtest. The universe largely depends on trends of fundamentals, specifically EarningReports.BasicEPS, such that I want the reported values and dates they were released from the last 2 years. I cannot use EarningReports.BasicEPS.TwelveMonths, as I need data further back in time.
I have written some basic code to attempt to log the earnings reports and their filing date. I do my coarse filtering and then access the dataframe containing the fundamental data of the coarse symbols. In my code I commented this out and just hard coded AAPL so that I could verify the logs. I then log the date and the earningreports.BasicEPS.ThreeMonths to get the most recent reported earnings.
There are two problems:
1. The BasicEPS from the historical dataframe in universe selection is reported multiple days late
2. The format of the FileDate of the earnings report is confusing
For problem 1, know that external sources say that an earnings report was released on 2023-11-02 for AAPL. On a universe selection performed on 2023-11-03, the BasicEPS value is 1.27 and on a universe selection on 2023-11-04, the BasicEPS value is 1.47. The backtest should have access to the BasicEPS on 2023-11-03 since it was reported the day before. This likely won’t have a large affect on my filtering process but I’d like to know if this is a mistake or a feature.
For problem 2, I want to know how to access the earnings release dates so that I know when new earnings are reported. I need this to distinguish in the event that two successive earnings reports are the equal. On a universe selection performed on 2023-11-03, the BasicEPS value is 1.27 and the FileDate output is: 3M:8/4/2023 12:00:00 AM; 6M:5/5/2023 12:00:00 AM; 9M:8/4/2023 12:00:00 AM; 12M:10/28/2022 12:00:00 AM. The 3M value makes sense since the that is the day after the earnings report for the previous quarter was released. But why is the 9M also that date? Don’t these parameters refer to which previous quarter the BasicEPS is from, 3M being the most recent and 12M being the report for the same quarter a year ago? Then on a universe selection from 2023-11-04, the BasicEPS value is 1.47, and the FileDate output is: 3M:8/4/2023 12:00:00 AM;6M:5/5/2023 12:00:00 AM;9M:8/4/2023 12:00:00 AM;12M:11/3/2023 12:00:00 AM. Why isn’t the 3M updated to 11/3/2023 since it is now the most recent reported date and instead it was updated in the 12M value?
In the end I just want to, for each stock, run simple calculations on the last 8 quarters of earnings, if available, and updated whenever the new earnings report is released. If there is a more efficient way to do this in QC I would love to know! Thanks in advance. I have added my backtest for reference
Mia Alissi
Reviewing 'Josh's' Python code for bugs, here are the findings:
In the
main.pyfile:The
UniverseFilterfunction is intended to filter symbols based on fundamental data, but the implementation provided does not actually filter based on any fundamental criteria. It simply returns a hardcoded list of symbols for "AAPL". This does not align with the goal of dynamically selecting symbols based on trends of fundamentals likeEarningReports.BasicEPS.The use of
self.History(Fundamental, symbols, 1)is incorrect for fetching fundamental data. TheHistorymethod is primarily used for fetching historical price data. To access fundamental data, you should use the fine universe selection process where you can filter stocks based on their fundamental data during the universe selection phase.The
UniverseFilterfunction is missing the logic to access and log the earnings reports and their filing date as described in the problem statement. To achieve this, you would typically need to implement a fine universe selection function that filters symbols based on their fundamental data, such asEarningReports.BasicEPS.The
UniverseFilterfunction attempts to iterate overset_fundamental_dfwithfor index, row in set_fundamental_df.iterrows():, but there is no further use ofrowwithin the loop, and the loop does not perform any action that would affect the outcome of the universe selection.In the
research.ipynbfile:The code snippet provided seems to be a mix of intended operations without a clear goal related to the problem statement. It includes adding an equity ("SPY"), fetching its historical price data, and performing indicator analysis with Bollinger Bands, which are unrelated to fetching or analyzing fundamental data.
The use of
self.Historyis incorrect in the Jupyter notebook context (research.ipynb). In QuantConnect's research environment (QuantBook), you should useqb.Historyinstead ofself.History. Theselfkeyword is used within an algorithm class in the QuantConnect Algorithm Lab, not in the research environment.The attempt to fetch fundamental data using
self.History(Fundamental, ibm, timedelta(30))and similar lines is misplaced in a Jupyter notebook. In the research environment, you would useqb(QuantBook object) to interact with QuantConnect's API, including fetching historical data.The code snippet attempting to sort fundamentals by market cap (
highest_market_cap = sorted(fundamental, key=lambda x: x.MarketCap)[-5:]) is conceptually correct but is placed in a context wherefundamentalis not defined, leading to potential confusion about its purpose and usage.To address the issues related to fundamental data access and manipulation, 'Josh' should focus on correctly implementing fine universe selection in the algorithm environment and utilize QuantBook's capabilities for fundamental data analysis in the research environment, ensuring the correct use of
qbinstead ofselfin the latter.The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Josh Belandres
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!