|
| 1 | +Metadata-Version: 2.1 |
| 2 | +Name: FredBrain |
| 3 | +Version: 0.2.0 |
| 4 | +Summary: A Python API for retrieving Federal Reserve Economic Data at Scale and feeding it to OpenAI |
| 5 | +Home-page: https://github.com/AlexanderRicht/FredBrain |
| 6 | +Author: Alexander Richt |
| 7 | +Author-email: alexander.richt1@gmail.com |
| 8 | +License: MIT License |
| 9 | + |
| 10 | + Copyright (c) 2024 Alexander Richt |
| 11 | + |
| 12 | + Permission is hereby granted, free of charge, to any person obtaining a copy |
| 13 | + of this software and associated documentation files (the "Software"), to deal |
| 14 | + in the Software without restriction, including without limitation the rights |
| 15 | + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| 16 | + copies of the Software, and to permit persons to whom the Software is |
| 17 | + furnished to do so, subject to the following conditions: |
| 18 | + |
| 19 | + The above copyright notice and this permission notice shall be included in all |
| 20 | + copies or substantial portions of the Software. |
| 21 | + |
| 22 | + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 23 | + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 24 | + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
| 25 | + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 26 | + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
| 27 | + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| 28 | + SOFTWARE. |
| 29 | + |
| 30 | +Project-URL: Documentation, https://pypi.org/project/FredBrain/ |
| 31 | +Project-URL: Source, https://github.com/AlexanderRicht/FredBrain |
| 32 | +Classifier: Development Status :: 3 - Alpha |
| 33 | +Classifier: Intended Audience :: Developers |
| 34 | +Classifier: Intended Audience :: Science/Research |
| 35 | +Classifier: Programming Language :: Python |
| 36 | +Classifier: Topic :: Scientific/Engineering :: Information Analysis |
| 37 | +Classifier: Topic :: Utilities |
| 38 | +Requires-Python: >=3.10 |
| 39 | +Description-Content-Type: text/markdown |
| 40 | +License-File: LICENSE |
| 41 | +Requires-Dist: requests |
| 42 | +Requires-Dist: pandas |
| 43 | +Requires-Dist: datetime |
| 44 | +Requires-Dist: openai |
| 45 | + |
| 46 | + |
| 47 | + |
| 48 | +# FredBrain: A Python API for retrieving Federal Reserve Economic Data at Scale and feeding it to OpenAI |
| 49 | +FredBrain is a Python package that offers a practical approach for accessing economic data from the Federal Reserve ([FRED API Documentation](https://fred.stlouisfed.org/docs/api/fred/)). It is built to assist those involved in economic research, financial analysis, and model development by providing a straightforward means of data retrieval. Additionally, it takes an experimental approach to integrating the OpenAI GPT framework into the class with the ultimate aim of creating an Ad-Hoc GPT economist expert to assist you in your analysis. Hence, why we refer to the class as `FredBrain`. The class itself will hopefully act as the Brain to power OpenAI Chat Completions. |
| 50 | + |
| 51 | +Utilizing familiar libraries such as `pandas`, `datetime`, `requests`, and `openai` FredBrain facilitates the transformation of JSON responses into user-friendly `DataFrame` objects. This process is designed to be intuitive, allowing users to focus more on their analysis, less on data wrangling and to leverage OpenAI chat for analysis support and conclusions. |
| 52 | + |
| 53 | +As FredBrain continues to develop, it seeks to maintain a balance between expanding its functionality and ensuring reliability. It strives to be a helpful resource for users who need to integrate economic data into their work, without being overwhelming or overly complex. |
| 54 | + |
| 55 | +FredBrain invites you to streamline the way you interact with economic data, opening up possibilities for more focused research and insightful analyses. |
| 56 | +## Things it does well |
| 57 | +- Efficiently navigates through FRED's series data using single or multiple filters, enhancing the user's ability to pinpoint relevant datasets. |
| 58 | +- Streamlines the discovery and selection of economic variables by fetching extensive subsets of FRED categories and their associated series. |
| 59 | +- Equips users with tools to instantly convert series searches or category subsets into comprehensive datasets of original or revised time-series data. |
| 60 | +- Offers the flexibility to fetch time-series data for pre-determined sets of series or categories without additional search requirements. |
| 61 | +- Facilitates the extraction of metadata, preserving critical details about the time-series data for informed analysis. |
| 62 | +- Optimized for scalability, complying with the Federal Reserve's API request limits, enabling extensive data retrieval within the threshold of 1000 requests per minute |
| 63 | +- *Integrating OpenAI to create an economist GPT for providing additional insights on data extracted via the FredBrain |
| 64 | + |
| 65 | +*This is experimental and not guaranteed to perform well. The ambition of myself and contributors would be to design a system that feeds data to a GPT to create an Economist GPT |
| 66 | + |
| 67 | +## Installing FredBrain |
| 68 | +Install the package using |
| 69 | +```sh |
| 70 | +# or PyPI |
| 71 | +pip install FredBrain |
| 72 | +``` |
| 73 | +## Dependencies |
| 74 | +- [Pandas](https://pypi.org/project/pandas/) |
| 75 | +- [Datetime](https://docs.python.org/3/library/datetime.html) |
| 76 | +- [Requests](https://pypi.org/project/requests/) |
| 77 | +- [OpenAI](https://platform.openai.com/docs/libraries) |
| 78 | +## License |
| 79 | +[MIT License](https://github.com/AlexanderRicht/InvestmentResearch/blob/main/LICENSE.md) |
| 80 | +## Contributing |
| 81 | +All contributions and ideas are welcome |
| 82 | +# A walk-through - From Search to Time-Series Data |
| 83 | +## Step 1: Importing and getting our initial dataframe of FRED series IDs |
| 84 | +The first thing we can do is import and then begin with a preliminary search to identify a series we want to extract. To do this, we need to import the FredBrain package and our API_KEY |
| 85 | +```sh |
| 86 | +from FredBrain import FredBrain |
| 87 | +from config import FRED_API_KEY, OPENAI_API_KEY |
| 88 | +import pandas as pd |
| 89 | + |
| 90 | +fred = FredBrain(fred_api_key=FRED_API_KEY, openai_api_key=OPENAI_API_KEY) |
| 91 | +``` |
| 92 | +Once this is done we can search for a "series" we believe is relevant to the research or questions we have. To do this, you must input a search text and optionally, enter a search and value attribute |
| 93 | +1. Our search text "Labor" |
| 94 | +2. Our search attributes "Popularity" or "Frequency" or both |
| 95 | +4. Our search value is 75 (returning those series with popularity equal to or greater than 75) or "Monthly" (returning those series with a frequency of monthly) |
| 96 | +5. We repeat this for search text "Employment" and "Wages" as shown |
| 97 | +```sh |
| 98 | +search_attributes = ["popularity", "frequency"] |
| 99 | +search_values = [50, "Monthly"] |
| 100 | +search_output_labor = fred.search_brain("Labor", search_attributes, search_values) |
| 101 | +search_output_employment = fred.search_brain("Employment", search_attributes, search_values) |
| 102 | +search_output_wages = fred.search_brain("Wages", search_attributes, search_values) |
| 103 | +search_output_combined = pd.concat([search_output_labor, search_output_employment, search_output_wages], ignore_index=True) |
| 104 | +``` |
| 105 | +| id | notes | |
| 106 | +|:------------|:--------------------------------------------------------------------------| |
| 107 | +| UNRATE | The unemployment rate represents the number of... | |
| 108 | +| UNRATENSA | The unemployment rate represents the number of... | |
| 109 | +| CIVPART | The series comes from the 'Current Population... | |
| 110 | +| U6RATE | The series comes from the 'Current Population... | |
| 111 | +| LNS11300060 | The series comes from the 'Current Population... | |
| 112 | + |
| 113 | +Now we have gotten a `DataFrame` of different series ids and their related metadata |
| 114 | +## Step 2: Retrieve additional metadata related |
| 115 | +Now that we have a `DataFrame` of different series ids we will loop through them to extract additional metadata related to the series. To begin, we need to store the id column into a list and define the relevant metadata that we believe is interesting to retain [FRED Series Doc](https://fred.stlouisfed.org/docs/api/fred/series.html) |
| 116 | +```sh |
| 117 | +series_list = list(search_output_combined['id']) |
| 118 | +relevant_info = ['title', 'frequency', 'units', 'popularity', 'notes'] |
| 119 | +series_info_data = [] |
| 120 | +for item in series_list: |
| 121 | + series_info_data.append(fred.fetch_series_info(series_id=item, relevant_info=relevant_info)) |
| 122 | +series_information = pd.DataFrame(series_info_data) |
| 123 | +``` |
| 124 | +| title | notes | |
| 125 | +|----------------------------------------------------|--------------------------------------------------------------------------------------------| |
| 126 | +| Unemployment Rate | The unemployment rate represents the number of... | |
| 127 | +| Unemployment Rate | The unemployment rate represents the number of... | |
| 128 | +| Labor Force Participation Rate | The series comes from the 'Current Population... | |
| 129 | +| Total Unemployed, Plus All Persons Marginally ... | The series comes from the 'Current Population... | |
| 130 | +| Labor Force Participation Rate - 25-54 Yrs. | The series comes from the 'Current Population... | |
| 131 | +| ... | ... | |
| 132 | +| Average Hourly Earnings of All Employees, Tran... | The series comes from the 'Current Employment... | |
| 133 | +| Average Hourly Earnings of All Employees, Prof... | The series comes from the 'Current Employment... | |
| 134 | +| Average Hourly Earnings of All Employees, Reta... | The series comes from the 'Current Employment... | |
| 135 | +| Average Hourly Earnings of All Employees, Priv... | The series comes from the 'Current Employment... | |
| 136 | +| Federal Funds Effective Rate | Averages of daily figures. \n\nFor additional ... | |
| 137 | + |
| 138 | +## Step 3: Extract the unrevised releases of data related to the series |
| 139 | +Based on the series `DataFrame` we extracted before, we will loop through the given series ID, add the metadata extracted previously, and store the unrevised observation for each series in a `DataFrame`. Why unrevised? Well, if we intend to model or use the data for any predictive purposes, using revised data would incorporate look-ahead bias. Therefore, we want to retain the observations as they were reported based on the information that was known at that given time |
| 140 | +```sh |
| 141 | +all_data_observations = pd.DataFrame() |
| 142 | +for i, item in enumerate(series_list): |
| 143 | + data_observations = fred.retrieve_series_first_release(series_id=item) |
| 144 | + data_website_url = fred.get_website_url(series_id=item) |
| 145 | + data_json_url = fred.get_json_url(series_id=item) |
| 146 | + if data_observations is not None: |
| 147 | + title = series_information.loc[i, 'title'] |
| 148 | + frequency = series_information.loc[i, 'frequency'] |
| 149 | + unit = series_information.loc[i, 'units'] |
| 150 | + data_observations['Category'] = title |
| 151 | + data_observations['Frequency'] = frequency |
| 152 | + data_observations['Units'] = unit |
| 153 | + data_observations['Website URL'] = data_website_url |
| 154 | + data_observations['JSON URL'] = data_json_url |
| 155 | + if all_data_observations.empty: |
| 156 | + all_data_observations = data_observations |
| 157 | + else: |
| 158 | + all_data_observations = all_data_observations._append(data_observations, ignore_index=True) |
| 159 | + else: |
| 160 | + print(f"No data available for series {item}.") |
| 161 | +``` |
| 162 | +## Step 4: Input the DataFrame into OpenAI (GPT-4) for insights |
| 163 | +The `DataFrame` will be inputted into the chatgpt method and a prompt of your choosing can be tailored. This will result in an output given by chatgpt based on the prompt and data provided |
| 164 | +```sh |
| 165 | +# Assuming this method returns a DataFrame |
| 166 | +analysis = fred.analyze_with_chatgpt(all_data_observations, "Provide a summary of the key trends in this economic data.") |
| 167 | +print(analysis) |
| 168 | +``` |
| 169 | + |
| 170 | +Congratulations! You now have a LLM Powered Economist at your finger tips! Who knows what the world will have in store for you two! |
| 171 | + |
| 172 | + |
0 commit comments