CatPtain commited on
Commit
e5b541f
·
verified ·
1 Parent(s): c01b5bd

Upload 468 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +2 -0
  2. openbb_platform/providers/federal_reserve/README.md +13 -0
  3. openbb_platform/providers/federal_reserve/__init__.py +1 -0
  4. openbb_platform/providers/federal_reserve/openbb_federal_reserve/__init__.py +48 -0
  5. openbb_platform/providers/federal_reserve/openbb_federal_reserve/assets/__init__.py +1 -0
  6. openbb_platform/providers/federal_reserve/openbb_federal_reserve/assets/historical_releases.json +0 -0
  7. openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/central_bank_holdings.py +368 -0
  8. openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/federal_funds_rate.py +141 -0
  9. openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/fomc_documents.py +219 -0
  10. openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/money_measures.py +112 -0
  11. openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/overnight_bank_funding_rate.py +122 -0
  12. openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/primary_dealer_fails.py +186 -0
  13. openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/primary_dealer_positioning.py +152 -0
  14. openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/sofr.py +108 -0
  15. openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/treasury_rates.py +120 -0
  16. openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/yield_curve.py +117 -0
  17. openbb_platform/providers/federal_reserve/openbb_federal_reserve/utils/__init__.py +0 -0
  18. openbb_platform/providers/federal_reserve/openbb_federal_reserve/utils/fomc_documents.py +195 -0
  19. openbb_platform/providers/federal_reserve/openbb_federal_reserve/utils/ny_fed_api.py +641 -0
  20. openbb_platform/providers/federal_reserve/openbb_federal_reserve/utils/primary_dealer_statistics.py +179 -0
  21. openbb_platform/providers/federal_reserve/poetry.lock +0 -0
  22. openbb_platform/providers/federal_reserve/pyproject.toml +20 -0
  23. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_central_bank_holdings_fetcher_urllib3_v1.yaml +209 -0
  24. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_central_bank_holdings_fetcher_urllib3_v2.yaml +206 -0
  25. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_federal_funds_rate_fetcher_urllib3_v1.yaml +92 -0
  26. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_federal_funds_rate_fetcher_urllib3_v2.yaml +89 -0
  27. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_fomc_documents_fetcher_urllib3_v1.yaml +311 -0
  28. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_fomc_documents_fetcher_urllib3_v2.yaml +0 -0
  29. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_money_measures_fetcher_urllib3_v1.yaml +0 -0
  30. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_money_measures_fetcher_urllib3_v2.yaml +0 -0
  31. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_overnight_bank_funding_rate_fetcher_urllib3_v1.yaml +63 -0
  32. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_overnight_bank_funding_rate_fetcher_urllib3_v2.yaml +60 -0
  33. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_primary_dealer_fails_fetcher_urllib3_v1.yaml +0 -0
  34. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_primary_dealer_fails_fetcher_urllib3_v2.yaml +0 -0
  35. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_primary_dealer_positioning_fetcher_urllib3_v1.yaml +332 -0
  36. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_primary_dealer_positioning_fetcher_urllib3_v2.yaml +326 -0
  37. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_sofr_fetcher_urllib3_v1.yaml +64 -0
  38. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_sofr_fetcher_urllib3_v2.yaml +61 -0
  39. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_treasury_rates_fetcher_urllib3_v1.yaml +0 -0
  40. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_treasury_rates_fetcher_urllib3_v2.yaml +0 -0
  41. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_yield_curve_fetcher_urllib3_v1.yaml +0 -0
  42. openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_yield_curve_fetcher_urllib3_v2.yaml +0 -0
  43. openbb_platform/providers/federal_reserve/tests/test_federal_reserve_fetchers.py +157 -0
  44. openbb_platform/providers/finra/README.md +13 -0
  45. openbb_platform/providers/finra/__init__.py +1 -0
  46. openbb_platform/providers/finra/openbb_finra/__init__.py +18 -0
  47. openbb_platform/providers/finra/openbb_finra/models/equity_short_interest.py +88 -0
  48. openbb_platform/providers/finra/openbb_finra/models/otc_aggregate.py +64 -0
  49. openbb_platform/providers/finra/openbb_finra/utils/data_storage.py +84 -0
  50. openbb_platform/providers/finra/openbb_finra/utils/helpers.py +186 -0
.gitattributes CHANGED
@@ -14,3 +14,5 @@ openbb_platform/providers/bls/openbb_bls/assets/ppi_series.xz filter=lfs diff=lf
14
  openbb_platform/providers/bls/openbb_bls/assets/sla_series.xz filter=lfs diff=lfs merge=lfs -text
15
  openbb_platform/providers/bls/openbb_bls/assets/tu_series.xz filter=lfs diff=lfs merge=lfs -text
16
  openbb_platform/providers/bls/openbb_bls/assets/wages_series.xz filter=lfs diff=lfs merge=lfs -text
 
 
 
14
  openbb_platform/providers/bls/openbb_bls/assets/sla_series.xz filter=lfs diff=lfs merge=lfs -text
15
  openbb_platform/providers/bls/openbb_bls/assets/tu_series.xz filter=lfs diff=lfs merge=lfs -text
16
  openbb_platform/providers/bls/openbb_bls/assets/wages_series.xz filter=lfs diff=lfs merge=lfs -text
17
+ openbb_platform/providers/finra/tests/record/http/test_finra_fetchers/test_finra_short_interest_fetcher_urllib3_v1.yaml filter=lfs diff=lfs merge=lfs -text
18
+ openbb_platform/providers/finra/tests/record/http/test_finra_fetchers/test_finra_short_interest_fetcher_urllib3_v2.yaml filter=lfs diff=lfs merge=lfs -text
openbb_platform/providers/federal_reserve/README.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # OpenBB Federal Reserve Provider
2
+
3
+ This extension integrates the [Federal Reserve](https://www.federalreserve.gov/data.htm) data provider into the OpenBB Platform.
4
+
5
+ ## Installation
6
+
7
+ To install the extension:
8
+
9
+ ```bash
10
+ pip install openbb-federal-reserve
11
+ ```
12
+
13
+ Documentation available [here](https://docs.openbb.co/platform/developer_guide/contributing).
openbb_platform/providers/federal_reserve/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ """Federal Reserve provider for OpenBB Platform."""
openbb_platform/providers/federal_reserve/openbb_federal_reserve/__init__.py ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Federal Reserve provider module."""
2
+
3
+ from openbb_core.provider.abstract.provider import Provider
4
+ from openbb_federal_reserve.models.central_bank_holdings import (
5
+ FederalReserveCentralBankHoldingsFetcher,
6
+ )
7
+ from openbb_federal_reserve.models.federal_funds_rate import (
8
+ FederalReserveFederalFundsRateFetcher,
9
+ )
10
+ from openbb_federal_reserve.models.fomc_documents import (
11
+ FederalReserveFomcDocumentsFetcher,
12
+ )
13
+ from openbb_federal_reserve.models.money_measures import (
14
+ FederalReserveMoneyMeasuresFetcher,
15
+ )
16
+ from openbb_federal_reserve.models.overnight_bank_funding_rate import (
17
+ FederalReserveOvernightBankFundingRateFetcher,
18
+ )
19
+ from openbb_federal_reserve.models.primary_dealer_fails import (
20
+ FederalReservePrimaryDealerFailsFetcher,
21
+ )
22
+ from openbb_federal_reserve.models.primary_dealer_positioning import (
23
+ FederalReservePrimaryDealerPositioningFetcher,
24
+ )
25
+ from openbb_federal_reserve.models.sofr import FederalReserveSOFRFetcher
26
+ from openbb_federal_reserve.models.treasury_rates import (
27
+ FederalReserveTreasuryRatesFetcher,
28
+ )
29
+ from openbb_federal_reserve.models.yield_curve import FederalReserveYieldCurveFetcher
30
+
31
+ federal_reserve_provider = Provider(
32
+ name="federal_reserve",
33
+ website="https://www.federalreserve.gov/data.htm", # Not a typo, it's really .htm
34
+ description="""Access data provided by the Federal Reserve System, the Central Bank of the United States.""",
35
+ fetcher_dict={
36
+ "CentralBankHoldings": FederalReserveCentralBankHoldingsFetcher,
37
+ "FederalFundsRate": FederalReserveFederalFundsRateFetcher,
38
+ "FomcDocuments": FederalReserveFomcDocumentsFetcher,
39
+ "MoneyMeasures": FederalReserveMoneyMeasuresFetcher,
40
+ "OvernightBankFundingRate": FederalReserveOvernightBankFundingRateFetcher,
41
+ "PrimaryDealerFails": FederalReservePrimaryDealerFailsFetcher,
42
+ "PrimaryDealerPositioning": FederalReservePrimaryDealerPositioningFetcher,
43
+ "SOFR": FederalReserveSOFRFetcher,
44
+ "TreasuryRates": FederalReserveTreasuryRatesFetcher,
45
+ "YieldCurve": FederalReserveYieldCurveFetcher,
46
+ },
47
+ repr_name="Federal Reserve (FED)",
48
+ )
openbb_platform/providers/federal_reserve/openbb_federal_reserve/assets/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ """OpenBB Federal Reserve Provider Assets."""
openbb_platform/providers/federal_reserve/openbb_federal_reserve/assets/historical_releases.json ADDED
The diff for this file is too large to render. See raw diff
 
openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/central_bank_holdings.py ADDED
@@ -0,0 +1,368 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Federal Reserve Central Bank Holdings Model."""
2
+
3
+ # pylint: disable=unused-argument,too-many-branches,too-many-statements,too-many-return-statements
4
+
5
+ from datetime import date as dateType
6
+ from typing import Any, Dict, List, Literal, Optional
7
+
8
+ from openbb_core.provider.abstract.fetcher import Fetcher
9
+ from openbb_core.provider.standard_models.central_bank_holdings import (
10
+ CentralBankHoldingsData,
11
+ CentralBankHoldingsQueryParams,
12
+ )
13
+ from openbb_core.provider.utils.descriptions import (
14
+ DATA_DESCRIPTIONS,
15
+ QUERY_DESCRIPTIONS,
16
+ )
17
+ from pydantic import Field, field_validator, model_validator
18
+
19
+ HoldingTypes = Literal[
20
+ "all_agency",
21
+ "agency_debts",
22
+ "mbs",
23
+ "cmbs",
24
+ "all_treasury",
25
+ "bills",
26
+ "notesbonds",
27
+ "frn",
28
+ "tips",
29
+ ]
30
+ HOLDING_TYPE_CHOICES = [
31
+ "all_agency",
32
+ "agency_debts",
33
+ "mbs",
34
+ "cmbs",
35
+ "all_treasury",
36
+ "bills",
37
+ "notesbonds",
38
+ "frn",
39
+ "tips",
40
+ ]
41
+ AGENCY_HOLDING_TYPES = {
42
+ "all": "all",
43
+ "agency_debts": "agency%20debts",
44
+ "mbs": "mbs",
45
+ "cmbs": "cmbs",
46
+ }
47
+ TREASURY_HOLDING_TYPES = ["all", "bills", "notesbonds", "frn", "tips"]
48
+
49
+
50
+ class FederalReserveCentralBankHoldingsQueryParams(CentralBankHoldingsQueryParams):
51
+ """Federal Reserve Central Bank Holdings Query.
52
+
53
+ The SOMA database contains data on the Federal Reserve's
54
+ domestic securities holdings from 2003 to the present.
55
+ SOMA holdings data is as of the close of business each Wednesday
56
+ and is published every Thursday by close of business.
57
+
58
+ Source: https://www.newyorkfed.org/markets/soma-holdings
59
+ """
60
+
61
+ __json_schema_extra__ = {
62
+ "cusip": {"multiple_items_allowed": True},
63
+ }
64
+
65
+ holding_type: HoldingTypes = Field(
66
+ default="all_treasury",
67
+ description="Type of holdings to return.",
68
+ json_schema_extra={"choices": HOLDING_TYPE_CHOICES},
69
+ )
70
+ summary: bool = Field(
71
+ default=False,
72
+ description="If True, returns historical weekly summary by holding type."
73
+ + " This parameter takes priority over other parameters.",
74
+ )
75
+ cusip: Optional[str] = Field(
76
+ default=None,
77
+ description=QUERY_DESCRIPTIONS.get("cusip", ""),
78
+ )
79
+ wam: bool = Field(
80
+ default=False,
81
+ description="If True, returns weighted average maturity aggregated by agency or treasury securities."
82
+ + " This parameter takes priority over `holding_type`, `cusip`, and `monthly`.",
83
+ )
84
+ monthly: bool = Field(
85
+ default=False,
86
+ description="If True, returns historical data for all Treasury securities at a monthly interval."
87
+ + " This parameter takes priority over other parameters, except `wam`."
88
+ + " Only valid when `holding_type` is set to: 'all_treasury', 'bills', 'notesbonds', 'frn', 'tips'.",
89
+ )
90
+
91
+
92
+ class FederalReserveCentralBankHoldingsData(CentralBankHoldingsData):
93
+ """Federal Reserve Central Bank Holdings Data."""
94
+
95
+ __alias_dict__ = {
96
+ "date": "asOfDate",
97
+ "notes_and_bonds": "notesbonds",
98
+ "description": "securityDescription",
99
+ "face_value": "currentFaceValue",
100
+ "is_aggregated": "isAggregated",
101
+ "security_type": "securityTypes",
102
+ "tips_inflation_compensation": "tipsInflationCompensation",
103
+ "change_prior_week": "changeFromPriorWeek",
104
+ "change_prior_year": "changeFromPriorYear",
105
+ }
106
+
107
+ security_type: Optional[str] = Field(
108
+ default=None,
109
+ description="Type of security - i.e. TIPs, FRNs, etc.",
110
+ )
111
+ description: Optional[str] = Field(
112
+ default=None,
113
+ description="Description of the security. Only returned for Agency securities.",
114
+ )
115
+ is_aggreated: Optional[Literal["Y"]] = Field(
116
+ default=None,
117
+ description="Whether the security is aggregated. Only returned for Agency securities.",
118
+ )
119
+ cusip: Optional[str] = Field(
120
+ default=None,
121
+ description=DATA_DESCRIPTIONS.get("cusip", ""),
122
+ )
123
+ issuer: Optional[str] = Field(
124
+ default=None,
125
+ description="Issuer of the security.",
126
+ )
127
+ maturity_date: Optional[dateType] = Field(
128
+ default=None,
129
+ description="Maturity date of the security.",
130
+ )
131
+ term: Optional[str] = Field(
132
+ default=None,
133
+ description="Term of the security. Only returned for Agency securities.",
134
+ )
135
+ face_value: Optional[float] = Field(
136
+ default=None,
137
+ description="Current face value of the security (Thousands of $USD)."
138
+ + " Current face value of the securities, which is the remaining principal balance of the securities.",
139
+ json_schema_extra={
140
+ "x-unit_measurement": "currency",
141
+ "x-frontend_multiply": 1000,
142
+ },
143
+ )
144
+ par_value: Optional[float] = Field(
145
+ default=None,
146
+ description="Par value of the security (Thousands of $USD)."
147
+ + " Changes in par may reflect primary and secondary market transactions and/or custodial account activity.",
148
+ json_schema_extra={
149
+ "x-unit_measurement": "currency",
150
+ "x-frontend_multiply": 1000,
151
+ },
152
+ )
153
+ coupon: Optional[float] = Field(
154
+ default=None,
155
+ description="Coupon rate of the security.",
156
+ json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
157
+ )
158
+ spread: Optional[float] = Field(
159
+ default=None,
160
+ description="Spread to the current reference rate, as determined at each security's initial auction.",
161
+ json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
162
+ )
163
+ percent_outstanding: Optional[float] = Field(
164
+ default=None,
165
+ description="Total percent of the outstanding CUSIP issuance.",
166
+ json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100},
167
+ )
168
+ bills: Optional[float] = Field(
169
+ default=None,
170
+ description="Treasury bills amount (Thousands of $USD)."
171
+ + " Only returned when 'summary' is True.",
172
+ json_schema_extra={
173
+ "x-unit_measurement": "currency",
174
+ "x-frontend_multiply": 1000,
175
+ },
176
+ )
177
+ frn: Optional[float] = Field(
178
+ default=None,
179
+ description="Floating rate Treasury notes amount (Thousands of $USD)."
180
+ + " Only returned when 'summary' is True.",
181
+ json_schema_extra={
182
+ "x-unit_measurement": "currency",
183
+ "x-frontend_multiply": 1000,
184
+ },
185
+ )
186
+ notes_and_bonds: Optional[float] = Field(
187
+ default=None,
188
+ description="Treasuy Notes and bonds amount (Thousands of $USD)."
189
+ + " Only returned when 'summary' is True.",
190
+ json_schema_extra={
191
+ "x-unit_measurement": "currency",
192
+ "x-frontend_multiply": 1000,
193
+ },
194
+ )
195
+ tips: Optional[float] = Field(
196
+ default=None,
197
+ description="Treasury inflation-protected securities amount (Thousands of $USD)."
198
+ + " Only returned when 'summary' is True.",
199
+ json_schema_extra={
200
+ "x-unit_measurement": "currency",
201
+ "x-frontend_multiply": 1000,
202
+ },
203
+ )
204
+ mbs: Optional[float] = Field(
205
+ default=None,
206
+ description="Mortgage-backed securities amount (Thousands of $USD)."
207
+ + " Only returned when 'summary' is True.",
208
+ json_schema_extra={
209
+ "x-unit_measurement": "currency",
210
+ "x-frontend_multiply": 1000,
211
+ },
212
+ )
213
+ cmbs: Optional[float] = Field(
214
+ default=None,
215
+ description="Commercial mortgage-backed securities amount (Thousands of $USD)."
216
+ + " Only returned when 'summary' is True.",
217
+ json_schema_extra={
218
+ "x-unit_measurement": "currency",
219
+ "x-frontend_multiply": 1000,
220
+ },
221
+ )
222
+ agencies: Optional[float] = Field(
223
+ default=None,
224
+ description="Agency securities amount (Thousands of $USD)."
225
+ + " Only returned when 'summary' is True.",
226
+ json_schema_extra={
227
+ "x-unit_measurement": "currency",
228
+ "x-frontend_multiply": 1000,
229
+ },
230
+ )
231
+ total: Optional[float] = Field(
232
+ default=None,
233
+ description="Total SOMA holdings amount (Thousands of $USD)."
234
+ + " Only returned when 'summary' is True.",
235
+ json_schema_extra={
236
+ "x-unit_measurement": "currency",
237
+ "x-frontend_multiply": 1000,
238
+ },
239
+ )
240
+ tips_inflation_compensation: Optional[float] = Field(
241
+ default=None,
242
+ description="Treasury inflation-protected securities inflation compensation amount (Thousands of $USD)."
243
+ + " Only returned when 'summary' is True.",
244
+ json_schema_extra={
245
+ "x-unit_measurement": "currency",
246
+ "x-frontend_multiply": 1000,
247
+ },
248
+ alias="inflationCompensation",
249
+ )
250
+ change_prior_week: Optional[float] = Field(
251
+ default=None,
252
+ description="Change in SOMA holdings from the prior week (Thousands of $USD).",
253
+ json_schema_extra={
254
+ "x-unit_measurement": "currency",
255
+ "x-frontend_multiply": 1000,
256
+ },
257
+ )
258
+ change_prior_year: Optional[float] = Field(
259
+ default=None,
260
+ description="Change in SOMA holdings from the prior year (Thousands of $USD).",
261
+ json_schema_extra={
262
+ "x-unit_measurement": "currency",
263
+ "x-frontend_multiply": 1000,
264
+ },
265
+ )
266
+
267
+ @field_validator("security_type", mode="before", check_fields=False)
268
+ @classmethod
269
+ def validate_security_type(cls, v):
270
+ """Validate the security type."""
271
+ if not v:
272
+ return None
273
+ if isinstance(v, list):
274
+ return ",".join(v)
275
+ return v
276
+
277
+ @field_validator("coupon", "spread", mode="before", check_fields=False)
278
+ @classmethod
279
+ def normalize_percent(cls, v):
280
+ """Normalize the percent value."""
281
+ return float(v) / 100 if v and v != "''" else None
282
+
283
+ @model_validator(mode="before")
284
+ @classmethod
285
+ def empty_strings(cls, values):
286
+ """Clear empty strings and replace with None."""
287
+ return (
288
+ {k: None if v in ("''", "", "0") else v for k, v in values.items()}
289
+ if isinstance(values, dict)
290
+ else values
291
+ )
292
+
293
+
294
+ class FederalReserveCentralBankHoldingsFetcher(
295
+ Fetcher[
296
+ FederalReserveCentralBankHoldingsQueryParams,
297
+ List[FederalReserveCentralBankHoldingsData],
298
+ ]
299
+ ):
300
+ """Federal Reserve Central Bank Holdings Fetcher."""
301
+
302
+ @staticmethod
303
+ def transform_query(
304
+ params: Dict[str, Any]
305
+ ) -> FederalReserveCentralBankHoldingsQueryParams:
306
+ """Transform the query params."""
307
+ return FederalReserveCentralBankHoldingsQueryParams(**params)
308
+
309
+ @staticmethod
310
+ async def aextract_data(
311
+ query: FederalReserveCentralBankHoldingsQueryParams,
312
+ credentials: Optional[Dict[str, str]],
313
+ **kwargs: Any,
314
+ ) -> List[Dict]:
315
+ """Return the raw data from the FederalReserve endpoint."""
316
+ # pylint: disable=import-outside-toplevel
317
+ from openbb_federal_reserve.utils.ny_fed_api import SomaHoldings
318
+
319
+ hold_type = "all" if "all" in query.holding_type else query.holding_type
320
+ security_type = query.holding_type
321
+ date = query.date.strftime("%Y-%m-%d") if query.date else None
322
+ if (
323
+ query.holding_type == "all_agency"
324
+ or query.holding_type in AGENCY_HOLDING_TYPES
325
+ ):
326
+ security_type = "agency" # type: ignore
327
+ if (
328
+ query.holding_type == "all_treasury"
329
+ or query.holding_type in TREASURY_HOLDING_TYPES
330
+ ):
331
+ security_type = "treasury" # type: ignore
332
+ if query.cusip is not None:
333
+ cusips = (
334
+ query.cusip if isinstance(query.cusip, str) else ",".join(query.cusip)
335
+ )
336
+ return (
337
+ await SomaHoldings().get_agency_holdings(cusip=cusips, as_of=date)
338
+ if security_type == "agency"
339
+ else await SomaHoldings().get_treasury_holdings(
340
+ cusip=cusips, as_of=date
341
+ )
342
+ )
343
+ if query.summary is True:
344
+ return await SomaHoldings().get_summary()
345
+ if query.monthly is True:
346
+ return await SomaHoldings().get_treasury_holdings(
347
+ monthly=True, holding_type=hold_type
348
+ )
349
+ if security_type == "treasury" and query.wam is True:
350
+ return await SomaHoldings().get_treasury_holdings(wam=True, as_of=date)
351
+ if security_type == "agency" and query.wam is True:
352
+ return await SomaHoldings().get_agency_holdings(wam=True, as_of=date)
353
+ return (
354
+ await SomaHoldings().get_agency_holdings(as_of=date, holding_type=hold_type)
355
+ if security_type == "agency"
356
+ else await SomaHoldings().get_treasury_holdings(
357
+ as_of=date, holding_type=hold_type
358
+ )
359
+ )
360
+
361
+ @staticmethod
362
+ def transform_data(
363
+ query: FederalReserveCentralBankHoldingsQueryParams,
364
+ data: List[Dict],
365
+ **kwargs: Any,
366
+ ) -> List[FederalReserveCentralBankHoldingsData]:
367
+ """Transform data."""
368
+ return [FederalReserveCentralBankHoldingsData.model_validate(d) for d in data]
openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/federal_funds_rate.py ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Federal Reserve Federal Funds Rate Model."""
2
+
3
+ # pylint: disable=unused-argument
4
+
5
+ from datetime import datetime
6
+ from typing import Any, Dict, List, Optional
7
+
8
+ from openbb_core.provider.abstract.fetcher import Fetcher
9
+ from openbb_core.provider.standard_models.federal_funds_rate import (
10
+ FederalFundsRateData,
11
+ FederalFundsRateQueryParams,
12
+ )
13
+ from openbb_core.provider.utils.errors import EmptyDataError
14
+ from pydantic import Field, field_validator
15
+
16
+
17
+ class FederalReserveFederalFundsRateQueryParams(FederalFundsRateQueryParams):
18
+ """FederalReserve FED Query."""
19
+
20
+
21
+ class FederalReserveFederalFundsRateData(FederalFundsRateData):
22
+ """FederalReserve FED Data."""
23
+
24
+ __alias_dict__ = {
25
+ "date": "effectiveDate",
26
+ "rate": "percentRate",
27
+ "target_range_upper": "targetRateTo",
28
+ "target_range_lower": "targetRateFrom",
29
+ "percentile_1": "percentPercentile1",
30
+ "percentile_25": "percentPercentile25",
31
+ "percentile_75": "percentPercentile75",
32
+ "percentile_99": "percentPercentile99",
33
+ "volume": "volumeInBillions",
34
+ "intraday_low": "intraDayLow",
35
+ "intraday_high": "intraDayHigh",
36
+ "standard_deviation": "stdDeviation",
37
+ "revision_indicator": "revisionIndicator",
38
+ }
39
+
40
+ intraday_low: Optional[float] = Field(
41
+ default=None,
42
+ description="Intraday low. This field is only present for data before 2016.",
43
+ )
44
+ intraday_high: Optional[float] = Field(
45
+ default=None,
46
+ description="Intraday high. This field is only present for data before 2016.",
47
+ )
48
+ standard_deviation: Optional[float] = Field(
49
+ default=None,
50
+ description="Standard deviation. This field is only present for data before 2016.",
51
+ )
52
+ revision_indicator: Optional[str] = Field(
53
+ default=None,
54
+ description="Indicates a revision of the data for that date.",
55
+ )
56
+
57
+ @field_validator("revision_indicator", mode="before", check_fields=False)
58
+ @classmethod
59
+ def validate_revision_indicator(cls, v):
60
+ """Validate revision indicator."""
61
+ return None if v in ("", "''") else v
62
+
63
+ @field_validator(
64
+ "rate",
65
+ "target_range_upper",
66
+ "target_range_lower",
67
+ "percentile_1",
68
+ "percentile_25",
69
+ "percentile_75",
70
+ "percentile_99",
71
+ "intraday_high",
72
+ "intraday_low",
73
+ mode="before",
74
+ check_fields=False,
75
+ )
76
+ @classmethod
77
+ def normalize_percent(cls, v):
78
+ """Normalize percent."""
79
+ if v is not None:
80
+ return v / 100 if v != 0 else 0
81
+ return None
82
+
83
+
84
+ class FederalReserveFederalFundsRateFetcher(
85
+ Fetcher[
86
+ FederalReserveFederalFundsRateQueryParams,
87
+ List[FederalReserveFederalFundsRateData],
88
+ ]
89
+ ):
90
+ """Federal Reserve Federal Funds Fetcher."""
91
+
92
+ @staticmethod
93
+ def transform_query(
94
+ params: Dict[str, Any]
95
+ ) -> FederalReserveFederalFundsRateQueryParams:
96
+ """Transform query."""
97
+ transformed_params = params.copy()
98
+ now = datetime.now().date()
99
+ if params.get("start_date") is None:
100
+ transformed_params["start_date"] = datetime(2016, 3, 1).date()
101
+ if params.get("end_date") is None:
102
+ transformed_params["end_date"] = now
103
+
104
+ return FederalReserveFederalFundsRateQueryParams(**transformed_params)
105
+
106
+ @staticmethod
107
+ async def aextract_data(
108
+ query: FederalReserveFederalFundsRateQueryParams,
109
+ credentials: Optional[Dict[str, str]],
110
+ **kwargs: Any,
111
+ ) -> List[Dict]:
112
+ """Extract the raw data."""
113
+ # pylint: disable=import-outside-toplevel
114
+ from openbb_core.provider.utils.helpers import amake_request
115
+
116
+ url = (
117
+ "https://markets.newyorkfed.org/api/rates/unsecured/effr/search.json?"
118
+ + f"startDate={query.start_date}&endDate={query.end_date}"
119
+ )
120
+ results: List[Dict] = []
121
+ response = await amake_request(url, **kwargs) # type: ignore
122
+ if response.get("refRates"): # type: ignore
123
+ results = response["refRates"] # type: ignore
124
+ if not results:
125
+ raise EmptyDataError()
126
+ return results
127
+
128
+ @staticmethod
129
+ def transform_data(
130
+ query: FederalReserveFederalFundsRateQueryParams,
131
+ data: List[Dict],
132
+ **kwargs: Any,
133
+ ) -> List[FederalReserveFederalFundsRateData]:
134
+ """Transform data."""
135
+ results: List[FederalReserveFederalFundsRateData] = []
136
+ for d in data.copy():
137
+ _ = d.pop("type", None)
138
+ _ = d.pop("footnoteId", None)
139
+ results.append(FederalReserveFederalFundsRateData.model_validate(d))
140
+
141
+ return results
openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/fomc_documents.py ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Federal Reserve FOMC documents model."""
2
+
3
+ # pylint: disable=unused-argument
4
+
5
+ from datetime import datetime
6
+ from typing import Any, Optional
7
+
8
+ from openbb_core.provider.abstract.data import Data
9
+ from openbb_core.provider.abstract.fetcher import Fetcher
10
+ from openbb_core.provider.abstract.query_params import QueryParams
11
+ from openbb_core.provider.utils.errors import EmptyDataError
12
+ from openbb_federal_reserve.utils.fomc_documents import FomcDocumentType
13
+ from pydantic import Field, field_validator
14
+
15
+ choice_types = list(FomcDocumentType.__args__)
16
+ choices = [
17
+ {
18
+ "label": (
19
+ "All Documents" if choice == "all" else choice.replace("_", " ").title()
20
+ ),
21
+ "value": choice if choice != "all" else None,
22
+ }
23
+ for choice in choice_types
24
+ ]
25
+
26
+
27
+ class FederalReserveFomcDocumentsQueryParams(QueryParams):
28
+ """Federal Reserve FOMC Documents Query."""
29
+
30
+ __json_schema_extra__ = {
31
+ "year": {
32
+ "x-widget_config": {
33
+ "type": "number",
34
+ "value": None,
35
+ "options": [
36
+ {"label": "All Years", "value": None},
37
+ *[
38
+ {"label": str(year), "value": year}
39
+ for year in sorted(
40
+ range(1959, datetime.now().year + 1), reverse=True
41
+ )
42
+ ],
43
+ ],
44
+ }
45
+ },
46
+ "document_type": {
47
+ "x-widget_config": {
48
+ "type": "text",
49
+ "value": None,
50
+ "options": choices,
51
+ }
52
+ },
53
+ "pdf_only": {
54
+ "x-widget_config": {"value": True, "type": "boolean", "show": False}
55
+ },
56
+ "as_choices": {
57
+ "x-widget_config": {"value": True, "type": "boolean", "show": False}
58
+ },
59
+ "url": {
60
+ "x-widget_config": {
61
+ "type": "endpoint",
62
+ "paramName": "url",
63
+ "optionsEndpoint": "api/v1/economy/fomc_documents",
64
+ "optionsParams": {
65
+ "document_type": "$document_type",
66
+ "year": "$year",
67
+ "pdf_only": True,
68
+ "as_choices": True,
69
+ "provider": "federal_reserve",
70
+ },
71
+ "show": False,
72
+ "roles": ["fileSelector"],
73
+ }
74
+ },
75
+ }
76
+
77
+ year: Optional[int] = Field(
78
+ default=None,
79
+ description="The year of FOMC documents to retrieve. If None, all years since 1959 are returned.",
80
+ )
81
+ document_type: Optional[str] = Field(
82
+ default=None,
83
+ description=f"Filter by document type. Default is all. Choose from: {', '.join(choice_types)}",
84
+ )
85
+ pdf_only: bool = Field(
86
+ default=False,
87
+ description="Whether to return as a list with only the PDF documents. Default is False.",
88
+ )
89
+ as_choices: bool = Field(
90
+ default=False,
91
+ description="Whether to return cast as a list of valid Workspace parameter choices."
92
+ + " Leave as False for typical use.",
93
+ )
94
+ url: Optional[str] = Field(
95
+ default=None,
96
+ description="Download a document from the supplied URL."
97
+ + " When provided, all other parameters are ignored."
98
+ + " Content is returned as a base64 encoded string.",
99
+ )
100
+
101
+ @field_validator("document_type", mode="before", check_fields=False)
102
+ @classmethod
103
+ def _validate_doc_type(cls, v):
104
+ """Validate document type."""
105
+ if v and v not in choice_types:
106
+ raise ValueError(
107
+ f"Invalid document type. Must be one of: {', '.join(choice_types)}"
108
+ )
109
+ return v
110
+
111
+ @field_validator("url", mode="before", check_fields=False)
112
+ @classmethod
113
+ def _validate_url(cls, v):
114
+ """Validate URL."""
115
+ if v and "federalreserve.gov" not in v:
116
+ raise ValueError("Invalid URL. Must be a Federal Reserve URL.")
117
+ return v if v else None
118
+
119
+
120
+ class FederalReserveFomcDocumentsData(Data):
121
+ """Federal Reserve FOMC Documents Data."""
122
+
123
+ content: Any = Field(
124
+ default=None,
125
+ description="The content of request results."
126
+ + " If `url` was provided, the content is a dictionary with keys `filename` and `content`."
127
+ + " Otherwise, it is a list of dictionaries with a mapping of FOMC documents to URLs."
128
+ + " The endpoint response will not be an OBBject.results object, but the content directly.",
129
+ )
130
+
131
+
132
+ class FederalReserveFomcDocumentsFetcher(
133
+ Fetcher[
134
+ FederalReserveFomcDocumentsQueryParams,
135
+ FederalReserveFomcDocumentsData,
136
+ ]
137
+ ):
138
+ """Federal Reserve FOMC Documents Fetcher."""
139
+
140
+ @staticmethod
141
+ def transform_query(
142
+ params: dict[str, Any],
143
+ ) -> FederalReserveFomcDocumentsQueryParams:
144
+ """Transform query."""
145
+ return FederalReserveFomcDocumentsQueryParams(**params)
146
+
147
+ @staticmethod
148
+ def extract_data(
149
+ query: FederalReserveFomcDocumentsQueryParams,
150
+ credentials: Optional[dict[str, str]],
151
+ **kwargs: Any,
152
+ ) -> dict:
153
+ """Extract the raw data."""
154
+ # pylint: disable=import-outside-toplevel
155
+ from openbb_core.provider.utils.helpers import make_request
156
+ from openbb_federal_reserve.utils.fomc_documents import (
157
+ get_fomc_documents_by_year,
158
+ )
159
+ from openbb_platform_api.response_models import PdfResponseModel
160
+
161
+ if query.url:
162
+ response = make_request(query.url)
163
+ response.raise_for_status()
164
+ pdf = response.content
165
+ if query.url.endswith(".pdf"):
166
+ content = PdfResponseModel(
167
+ filename=query.url.split("/")[-1], content=pdf
168
+ )
169
+ output = {
170
+ "content": content.model_dump(exclude_unset=True, exclude_none=True)
171
+ }
172
+ return output
173
+
174
+ output = {
175
+ "content": {
176
+ "filename": query.url.split("/")[-1],
177
+ "content": pdf,
178
+ "data_format": "markdown",
179
+ }
180
+ }
181
+
182
+ return output
183
+
184
+ docs = get_fomc_documents_by_year(
185
+ query.year, query.document_type, query.pdf_only
186
+ )
187
+
188
+ if query.as_choices is True:
189
+ choices_list: list = []
190
+ for doc in docs:
191
+ if query.pdf_only is True and doc.get("doc_format", "") != "pdf":
192
+ continue
193
+ title = (
194
+ doc.get("doc_type", "").replace("_", " ").title()
195
+ + " - "
196
+ + doc.get("date", "")
197
+ )
198
+ value = doc.get("url", "")
199
+ if title and value:
200
+ choices_list.append({"label": title, "value": value})
201
+
202
+ output = {"content": choices_list}
203
+
204
+ return output
205
+
206
+ output = {"content": docs}
207
+
208
+ return output
209
+
210
+ @staticmethod
211
+ def transform_data(
212
+ query: FederalReserveFomcDocumentsQueryParams,
213
+ data: dict,
214
+ **kwargs: Any,
215
+ ) -> FederalReserveFomcDocumentsData:
216
+ """Transform data."""
217
+ if not data:
218
+ raise EmptyDataError("No FOMC documents found.")
219
+ return FederalReserveFomcDocumentsData(content=data.get("content"))
openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/money_measures.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FederalReserve Money Measures Model."""
2
+
3
+ # pylint: disable=unused-argument
4
+
5
+ from datetime import datetime
6
+ from typing import Any, Dict, List, Optional
7
+
8
+ from openbb_core.provider.abstract.fetcher import Fetcher
9
+ from openbb_core.provider.standard_models.money_measures import (
10
+ MoneyMeasuresData,
11
+ MoneyMeasuresQueryParams,
12
+ )
13
+
14
+ titles = {
15
+ "M1": "M1",
16
+ "M2": "M2",
17
+ "MCU": "currency",
18
+ "MDD": "demand_deposits",
19
+ "MMFGB": "retail_money_market_funds",
20
+ "MDL": "other_liquid_deposits",
21
+ "MDTS": "small_denomination_time_deposits",
22
+ }
23
+
24
+
25
+ class FederalReserveMoneyMeasuresQueryParams(MoneyMeasuresQueryParams):
26
+ """FederalReserve Money Measures Query."""
27
+
28
+
29
+ class FederalReserveMoneyMeasuresData(MoneyMeasuresData):
30
+ """FederalReserve Money Measures Data."""
31
+
32
+
33
+ class FederalReserveMoneyMeasuresFetcher(
34
+ Fetcher[
35
+ FederalReserveMoneyMeasuresQueryParams,
36
+ List[FederalReserveMoneyMeasuresData],
37
+ ]
38
+ ):
39
+ """Transform the query, extract and transform the data from the FederalReserve endpoints."""
40
+
41
+ @staticmethod
42
+ def transform_query(
43
+ params: Dict[str, Any]
44
+ ) -> FederalReserveMoneyMeasuresQueryParams:
45
+ """Transform the query params. Start and end dates are set to a 90 day interval."""
46
+ # pylint: disable=import-outside-toplevel
47
+ from datetime import timedelta
48
+
49
+ transformed_params = params
50
+
51
+ now = datetime.now().date()
52
+ if params.get("start_date") is None:
53
+ transformed_params["start_date"] = now - timedelta(days=10 * 365)
54
+
55
+ if params.get("end_date") is None:
56
+ transformed_params["end_date"] = now
57
+
58
+ return FederalReserveMoneyMeasuresQueryParams(**transformed_params)
59
+
60
+ @staticmethod
61
+ def extract_data(
62
+ query: FederalReserveMoneyMeasuresQueryParams,
63
+ credentials: Optional[Dict[str, str]],
64
+ **kwargs: Any,
65
+ ) -> List[Dict]:
66
+ """Return the raw data from the FederalReserve endpoint."""
67
+ # pylint: disable=import-outside-toplevel
68
+ from io import BytesIO # noqa
69
+ from openbb_core.provider.utils.helpers import make_request # noqa
70
+ from pandas import read_csv, to_datetime # noqa
71
+
72
+ url = (
73
+ "https://www.federalreserve.gov/datadownload/Output.aspx?rel=H6&series=798e2796917702a5f8423426ba7e6b42"
74
+ "&lastobs=&from=&to=&filetype=csv&label=include&layout=seriescolumn&type=package"
75
+ )
76
+
77
+ r = make_request(url, **kwargs)
78
+ df = read_csv(BytesIO(r.content), header=5, index_col=None, parse_dates=True)
79
+
80
+ columns_to_get = ["Time Period"] + [
81
+ col + f'{"_N" if query.adjusted else ""}.M' for col in titles
82
+ ]
83
+ df = df[columns_to_get]
84
+ df.columns = ["month"] + list(titles.values())
85
+ df = df.replace("ND", None)
86
+ df["month"] = to_datetime(df["month"])
87
+ df = df[
88
+ (to_datetime(df.month) >= to_datetime(query.start_date))
89
+ & (to_datetime(df.month) <= to_datetime(query.end_date))
90
+ ].set_index("month")
91
+ # Needs the date to not be in the columns
92
+ df = df.applymap(lambda x: float(x) if x != "-" and x is not None else x)
93
+ df = df.reset_index(drop=False)
94
+
95
+ return df.to_dict(orient="records")
96
+
97
+ @staticmethod
98
+ def transform_data(
99
+ query: FederalReserveMoneyMeasuresQueryParams, data: List[Dict], **kwargs: Any
100
+ ) -> List[FederalReserveMoneyMeasuresData]:
101
+ """Return the transformed data."""
102
+ # pylint: disable=import-outside-toplevel
103
+ from pandas import isna
104
+
105
+ fed_data = []
106
+ for d in data:
107
+ for k, v in d.items():
108
+ if isna(v) and not isinstance(v, str):
109
+ d[k] = None
110
+ fed_data.append(FederalReserveMoneyMeasuresData.model_validate(d))
111
+
112
+ return fed_data
openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/overnight_bank_funding_rate.py ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Federal Reserve Federal Funds Rate Model."""
2
+
3
+ # pylint: disable=unused-argument
4
+
5
+ from datetime import datetime
6
+ from typing import Any, Dict, List, Optional
7
+
8
+ from openbb_core.provider.abstract.fetcher import Fetcher
9
+ from openbb_core.provider.standard_models.overnight_bank_funding_rate import (
10
+ OvernightBankFundingRateData,
11
+ OvernightBankFundingRateQueryParams,
12
+ )
13
+ from openbb_core.provider.utils.errors import EmptyDataError
14
+ from pydantic import Field, field_validator
15
+
16
+
17
+ class FederalReserveOvernightBankFundingRateQueryParams(
18
+ OvernightBankFundingRateQueryParams
19
+ ):
20
+ """FederalReserve Overnight Bank Funding Rate Query."""
21
+
22
+
23
+ class FederalReserveOvernightBankFundingRateData(OvernightBankFundingRateData):
24
+ """FederalReserve Overnight Bank Funding Rate Data."""
25
+
26
+ __alias_dict__ = {
27
+ "date": "effectiveDate",
28
+ "rate": "percentRate",
29
+ "percentile_1": "percentPercentile1",
30
+ "percentile_25": "percentPercentile25",
31
+ "percentile_75": "percentPercentile75",
32
+ "percentile_99": "percentPercentile99",
33
+ "volume": "volumeInBillions",
34
+ }
35
+
36
+ revision_indicator: Optional[str] = Field(
37
+ default=None,
38
+ description="Indicates a revision of the data for that date.",
39
+ )
40
+
41
+ @field_validator("revision_indicator", mode="before", check_fields=False)
42
+ @classmethod
43
+ def validate_revision_indicator(cls, v):
44
+ """Validate revision indicator."""
45
+ return None if v in ("", "''") else v
46
+
47
+ @field_validator(
48
+ "rate",
49
+ "percentile_1",
50
+ "percentile_25",
51
+ "percentile_75",
52
+ "percentile_99",
53
+ mode="before",
54
+ check_fields=False,
55
+ )
56
+ @classmethod
57
+ def normalize_percent(cls, v):
58
+ """Normalize percent."""
59
+ if v is not None:
60
+ return v / 100 if v != 0 else 0
61
+ return None
62
+
63
+
64
+ class FederalReserveOvernightBankFundingRateFetcher(
65
+ Fetcher[
66
+ FederalReserveOvernightBankFundingRateQueryParams,
67
+ List[FederalReserveOvernightBankFundingRateData],
68
+ ]
69
+ ):
70
+ """Federal Reserve Federal Funds Fetcher."""
71
+
72
+ @staticmethod
73
+ def transform_query(
74
+ params: Dict[str, Any]
75
+ ) -> FederalReserveOvernightBankFundingRateQueryParams:
76
+ """Transform query."""
77
+ transformed_params = params.copy()
78
+ now = datetime.now().date()
79
+ if params.get("start_date") is None:
80
+ transformed_params["start_date"] = datetime(2016, 3, 1).date()
81
+ if params.get("end_date") is None:
82
+ transformed_params["end_date"] = now
83
+
84
+ return FederalReserveOvernightBankFundingRateQueryParams(**transformed_params)
85
+
86
+ @staticmethod
87
+ async def aextract_data(
88
+ query: FederalReserveOvernightBankFundingRateQueryParams,
89
+ credentials: Optional[Dict[str, str]],
90
+ **kwargs: Any,
91
+ ) -> List[Dict]:
92
+ """Extract the raw data."""
93
+ # pylint: disable=import-outside-toplevel
94
+ from openbb_core.provider.utils.helpers import amake_request
95
+
96
+ url = (
97
+ "https://markets.newyorkfed.org/api/rates/unsecured/obfr/search.json?"
98
+ + f"startDate={query.start_date}&endDate={query.end_date}"
99
+ )
100
+ results: List[Dict] = []
101
+ response = await amake_request(url, **kwargs)
102
+ if response.get("refRates", []): # type: ignore
103
+ results = response["refRates"] # type: ignore
104
+ if not results:
105
+ raise EmptyDataError()
106
+ return results
107
+
108
+ @staticmethod
109
+ def transform_data(
110
+ query: FederalReserveOvernightBankFundingRateQueryParams,
111
+ data: List[Dict],
112
+ **kwargs: Any,
113
+ ) -> List[FederalReserveOvernightBankFundingRateData]:
114
+ """Transform data."""
115
+ results: List[FederalReserveOvernightBankFundingRateData] = []
116
+ for d in data.copy():
117
+ _ = d.pop("type", None)
118
+ _ = d.pop("revisionIndicator", None)
119
+ _ = d.pop("footnoteId", None)
120
+ results.append(FederalReserveOvernightBankFundingRateData.model_validate(d))
121
+
122
+ return results
openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/primary_dealer_fails.py ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Federal Reserve Primary Dealer Fails Model."""
2
+
3
+ # pylint: disable=unused-argument
4
+
5
+ from typing import Any, Dict, List, Literal, Optional, Union
6
+
7
+ from openbb_core.app.model.abstract.error import OpenBBError
8
+ from openbb_core.provider.abstract.fetcher import Fetcher
9
+ from openbb_core.provider.standard_models.primary_dealer_fails import (
10
+ PrimaryDealerFailsData,
11
+ PrimaryDealerFailsQueryParams,
12
+ )
13
+ from openbb_core.provider.utils.errors import EmptyDataError
14
+ from openbb_federal_reserve.utils.primary_dealer_statistics import FAILS_SERIES_TO_TITLE
15
+ from pydantic import Field
16
+
17
+
18
+ class FederalReservePrimaryDealerFailsQueryParams(PrimaryDealerFailsQueryParams):
19
+ """Federal Reserve Primary Dealer Fails Query Params."""
20
+
21
+ __json_schema_extra__ = {
22
+ "asset_class": {
23
+ "multiple_items_allowed": False,
24
+ "choices": ["all", "treasuries", "tips", "agency", "mbs", "corporate"],
25
+ },
26
+ "unit": {
27
+ "multiple_items_allowed": False,
28
+ "choices": ["value", "percent"],
29
+ },
30
+ }
31
+
32
+ asset_class: Literal["all", "treasuries", "tips", "agency", "mbs", "corporate"] = (
33
+ Field(
34
+ default="all",
35
+ description="Asset class to return, default is 'all'.",
36
+ )
37
+ )
38
+ unit: Literal["value", "percent"] = Field(
39
+ default="value",
40
+ description="Unit of the data returned to the 'value' field."
41
+ + " Default is 'value', which represents millions of USD."
42
+ + " 'percent' returns data as the percentage of the total"
43
+ + " fails-to-receive and fails-to-deliver, by asset class.",
44
+ )
45
+
46
+
47
+ class FederalReservePrimaryDealerFailsData(PrimaryDealerFailsData):
48
+ """Federal Reserve Primary Dealer Fails Data."""
49
+
50
+ title: str = Field(description="Title of the series' symbol.")
51
+ value: Union[int, float] = Field(
52
+ description="Value of the data returned, in millions of USD if the `unit`"
53
+ + " parameter is 'value' else a normalized percent."
54
+ )
55
+
56
+
57
+ class FederalReservePrimaryDealerFailsFetcher(
58
+ Fetcher[
59
+ FederalReservePrimaryDealerFailsQueryParams,
60
+ List[FederalReservePrimaryDealerFailsData],
61
+ ]
62
+ ):
63
+ """Federal Reserve Primary Dealer Fails Fetcher."""
64
+
65
+ @staticmethod
66
+ def transform_query(
67
+ params: Dict[str, Any]
68
+ ) -> FederalReservePrimaryDealerFailsQueryParams:
69
+ """Transform the query parameters."""
70
+ return FederalReservePrimaryDealerFailsQueryParams(**params)
71
+
72
+ @staticmethod
73
+ async def aextract_data(
74
+ query: FederalReservePrimaryDealerFailsQueryParams,
75
+ credentials: Optional[Dict[str, str]],
76
+ **kwargs: Any,
77
+ ) -> List[Dict]:
78
+ """Return the raw data from the Federal Reserve endpoint."""
79
+ # pylint: disable=import-outside-toplevel
80
+ from datetime import datetime # noqa
81
+ from openbb_core.provider.utils.helpers import amake_request
82
+
83
+ url = (
84
+ "https://markets.newyorkfed.org/api/pd/get/"
85
+ + "PDFTD-CS_PDFTR-CS_PDFTD-FGEM_PDFTR-FGEM_PDFTD-FGM_PDFTR-FGM_PDFTD-OM_"
86
+ + "PDFTR-OM_PDFTD-UST_PDFTR-UST_PDFTD-USTET_PDFTR-USTET.json"
87
+ )
88
+ try:
89
+
90
+ response = await amake_request(url, **kwargs)
91
+ data = response.get("pd", {}).get("timeseries", []) # type: ignore
92
+ if query.start_date and query.start_date < datetime(2013, 4, 1).date():
93
+ # The data is broken into different series and the structure of the data is different over time.
94
+ if query.start_date < datetime(2001, 7, 1).date():
95
+ url2 = (
96
+ "https://markets.newyorkfed.org/api/pd/get/SBP2001/timeseries/PDFASUFDA_PDFASUFRA"
97
+ + "_PDFASFAFDA_PDFASFAFRA_PDFASMBFDA_PDFASMBFRA.json"
98
+ )
99
+ response = await amake_request(url2, **kwargs)
100
+ data += response.get("pd", {}).get("timeseries", []) # type: ignore
101
+ url = (
102
+ "https://markets.newyorkfed.org/api/pd/get/SBP2013/timeseries/"
103
+ + "PDFASCFRA_PDFASCFDA_PDFASFAFRA_PDFASFAFDA_PDFASMBFRA_PDFASMBFDA_PDFASUFRA_PDFASUFDA.json"
104
+ )
105
+ response = await amake_request(url, **kwargs)
106
+ data += response.get("pd", {}).get("timeseries", []) # type: ignore
107
+ return data
108
+ except Exception as e: # pylint: disable=broad-except
109
+ raise OpenBBError(
110
+ "Failed to fetch data from the Federal Reserve API."
111
+ ) from e
112
+
113
+ @staticmethod
114
+ def transform_data(
115
+ query: FederalReservePrimaryDealerFailsQueryParams,
116
+ data: List[Dict],
117
+ **kwargs: Any,
118
+ ) -> List[FederalReservePrimaryDealerFailsData]:
119
+ """Transform the raw data into the standard format."""
120
+ # pylint: disable=import-outside-toplevel
121
+ from pandas import NA, DataFrame, concat, to_datetime
122
+
123
+ if not data:
124
+ raise EmptyDataError("No data returned from the Federal Reserve API.")
125
+
126
+ df = DataFrame(data)
127
+ df.loc[:, "title"] = df.keyid.map(FAILS_SERIES_TO_TITLE)
128
+ df.value = df.value.astype(int)
129
+ new_df = df.pivot(index="asofdate", columns="title", values="value").copy()
130
+ new_data = new_df.copy()
131
+ combined_df = DataFrame()
132
+
133
+ for target in ["FTD", "FTR"]:
134
+ total_col = target + " Total"
135
+ new_data = new_df[[d for d in new_df.columns if target in d]].copy()
136
+ new_data.loc[:, total_col] = new_data.sum(axis=1)
137
+
138
+ if query.unit == "percent":
139
+ new_data = new_data.div(new_data[total_col], axis=0)
140
+
141
+ combined_df = (
142
+ new_data.copy()
143
+ if combined_df.empty
144
+ else concat([combined_df, new_data], axis=1)
145
+ )
146
+ new_data = combined_df
147
+
148
+ if query.asset_class == "agency":
149
+ new_data = new_data[[d for d in new_data.columns if "Ex-MBS" in d]]
150
+ if query.asset_class == "mbs":
151
+ new_data = new_data[
152
+ [d for d in new_data.columns if "MBS" in d and "Ex-MBS" not in d]
153
+ ]
154
+ if query.asset_class == "treasuries":
155
+ new_data = new_data[
156
+ [d for d in new_data.columns if "Treasury Securities (Ex-TIPS)" in d]
157
+ ]
158
+ if query.asset_class == "tips":
159
+ new_data = new_data[
160
+ [d for d in new_data.columns if "TIPS" in d and "Ex-TIPS" not in d]
161
+ ]
162
+ if query.asset_class == "corporate":
163
+ new_data = new_data[[d for d in new_data.columns if "Corporate" in d]]
164
+
165
+ new_data = new_data.T.unstack().reset_index()
166
+ new_data.columns = ["date", "title", "value"]
167
+ new_data.loc[:, "symbol"] = new_data.title.map(
168
+ {v: k for k, v in FAILS_SERIES_TO_TITLE.items()}
169
+ ).replace({NA: "--"})
170
+ new_data = new_data.dropna()
171
+
172
+ if query.unit == "value":
173
+ new_data.value = new_data.value.astype(int)
174
+
175
+ new_data.date = to_datetime(new_data.date).dt.date
176
+
177
+ if query.start_date:
178
+ new_data = new_data[new_data.date >= query.start_date]
179
+
180
+ if query.end_date:
181
+ new_data = new_data[new_data.date <= query.end_date]
182
+
183
+ return [
184
+ FederalReservePrimaryDealerFailsData.model_validate(r)
185
+ for r in new_data.dropna().to_dict(orient="records")
186
+ ]
openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/primary_dealer_positioning.py ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Federal Reserve Primary Dealer Positioning Model."""
2
+
3
+ # pylint: disable=unused-argument
4
+
5
+ from typing import Any, Dict, List, Literal, Optional
6
+
7
+ from openbb_core.provider.abstract.fetcher import Fetcher
8
+ from openbb_core.provider.standard_models.primary_dealer_positioning import (
9
+ PrimaryDealerPositioningData,
10
+ PrimaryDealerPositioningQueryParams,
11
+ )
12
+ from openbb_core.provider.utils.errors import EmptyDataError
13
+ from pydantic import Field
14
+
15
+ PdsCategories = Literal[
16
+ "treasuries",
17
+ "bills",
18
+ "coupons",
19
+ "notes",
20
+ "tips",
21
+ "mbs",
22
+ "cmbs",
23
+ "municipal",
24
+ "corporate",
25
+ "commercial_paper",
26
+ "corporate_ig",
27
+ "corporate_junk",
28
+ "abs",
29
+ ]
30
+
31
+ PDS_CATEGORY_CHOICES = [
32
+ "treasuries",
33
+ "bills",
34
+ "coupons",
35
+ "notes",
36
+ "tips",
37
+ "mbs",
38
+ "cmbs",
39
+ "municipal",
40
+ "corporate",
41
+ "commercial_paper",
42
+ "corporate_ig",
43
+ "corporate_junk",
44
+ "abs",
45
+ ]
46
+
47
+
48
+ class FederalReservePrimaryDealerPositioningQueryParams(
49
+ PrimaryDealerPositioningQueryParams
50
+ ):
51
+ """Federal Reserve Primary Dealer Positioning Query Params."""
52
+
53
+ category: PdsCategories = Field(
54
+ default="treasuries",
55
+ description="The category of asset to return, defaults to 'treasuries'.",
56
+ json_schema_extra={"choices": PDS_CATEGORY_CHOICES}, # type: ignore
57
+ )
58
+
59
+
60
+ class FederalReservePrimaryDealerPositioningData(PrimaryDealerPositioningData):
61
+ """Federal Reserve Primary Dealer Positioning Data."""
62
+
63
+ value: int = Field(
64
+ description="The reported value of the net position (long - short), in millions of $USD.",
65
+ json_schema_extra={
66
+ "x-unit_measurement": "currency",
67
+ "x-frontend_multiply": 1e6,
68
+ },
69
+ )
70
+ name: str = Field(
71
+ description="Short name for the series.",
72
+ )
73
+ title: str = Field(
74
+ description="Title of the series.",
75
+ )
76
+
77
+
78
+ class FederalReservePrimaryDealerPositioningFetcher(
79
+ Fetcher[
80
+ FederalReservePrimaryDealerPositioningQueryParams,
81
+ List[FederalReservePrimaryDealerPositioningData],
82
+ ]
83
+ ):
84
+ """Federal Reserve Primary Dealer Positioning Fetcher."""
85
+
86
+ @staticmethod
87
+ def transform_query(
88
+ params: Dict[str, Any]
89
+ ) -> FederalReservePrimaryDealerPositioningQueryParams:
90
+ """Transform the query params."""
91
+ return FederalReservePrimaryDealerPositioningQueryParams(**params)
92
+
93
+ @staticmethod
94
+ async def aextract_data(
95
+ query: FederalReservePrimaryDealerPositioningQueryParams,
96
+ credentials: Optional[Dict[str, str]],
97
+ **kwargs: Any,
98
+ ) -> List[Dict]:
99
+ """Return the raw data from the FederalReserve endpoint."""
100
+ # pylint: disable=import-outside-toplevel
101
+ import asyncio # noqa
102
+ from openbb_core.provider.utils.helpers import amake_request
103
+ from openbb_federal_reserve.utils.primary_dealer_statistics import (
104
+ POSITION_GROUPS_TO_SERIES,
105
+ )
106
+
107
+ symbols = POSITION_GROUPS_TO_SERIES.get(query.category, [])
108
+ results: List[Dict] = []
109
+
110
+ base_url = "https://markets.newyorkfed.org/api/pd/get/"
111
+ urls = [base_url + symbol + ".json" for symbol in symbols]
112
+
113
+ async def get_one(url):
114
+ """Get data for a single URL."""
115
+ result = await amake_request(url)
116
+ if isinstance(result, dict):
117
+ data = result.get("pd", {}).get("timeseries")
118
+ if data:
119
+ results.extend(data)
120
+
121
+ await asyncio.gather(*[get_one(url) for url in urls])
122
+
123
+ if not results:
124
+ raise EmptyDataError("The request was returned empty.")
125
+
126
+ return results
127
+
128
+ @staticmethod
129
+ def transform_data(
130
+ query: FederalReservePrimaryDealerPositioningQueryParams,
131
+ data: List[Dict],
132
+ **kwargs: Any,
133
+ ) -> List[FederalReservePrimaryDealerPositioningData]:
134
+ """Transform the data."""
135
+ # pylint: disable=import-outside-toplevel
136
+ from openbb_federal_reserve.utils.primary_dealer_statistics import (
137
+ POSITION_SERIES_TO_FIELD,
138
+ POSITION_SERIES_TO_TITLE,
139
+ )
140
+ from pandas import DataFrame
141
+
142
+ df = DataFrame(data)
143
+ df = df.rename(columns={"keyid": "symbol", "asofdate": "date"})
144
+ df["name"] = df.symbol.map(
145
+ lambda x: POSITION_SERIES_TO_FIELD["dealer_position"].get(x)
146
+ )
147
+ df["title"] = df.symbol.map(lambda x: POSITION_SERIES_TO_TITLE.get(x))
148
+
149
+ return [
150
+ FederalReservePrimaryDealerPositioningData.model_validate(d)
151
+ for d in df.to_dict(orient="records")
152
+ ]
openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/sofr.py ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Federal Reserve SOFR Model."""
2
+
3
+ # pylint: disable=unused-argument
4
+
5
+ from datetime import datetime
6
+ from typing import Any, Dict, List, Optional
7
+
8
+ from openbb_core.provider.abstract.fetcher import Fetcher
9
+ from openbb_core.provider.standard_models.sofr import (
10
+ SOFRData,
11
+ SOFRQueryParams,
12
+ )
13
+ from openbb_core.provider.utils.errors import EmptyDataError
14
+ from pydantic import field_validator
15
+
16
+
17
+ class FederalReserveSOFRQueryParams(SOFRQueryParams):
18
+ """FederalReserve FED Query."""
19
+
20
+
21
+ class FederalReserveSOFRData(SOFRData):
22
+ """FederalReserve FED Data."""
23
+
24
+ __alias_dict__ = {
25
+ "date": "effectiveDate",
26
+ "rate": "percentRate",
27
+ "percentile_1": "percentPercentile1",
28
+ "percentile_25": "percentPercentile25",
29
+ "percentile_75": "percentPercentile75",
30
+ "percentile_99": "percentPercentile99",
31
+ "volume": "volumeInBillions",
32
+ }
33
+
34
+ @field_validator(
35
+ "rate",
36
+ "target_range_upper",
37
+ "target_range_lower",
38
+ "percentile_1",
39
+ "percentile_25",
40
+ "percentile_75",
41
+ "percentile_99",
42
+ mode="before",
43
+ check_fields=False,
44
+ )
45
+ @classmethod
46
+ def normalize_percent(cls, v):
47
+ """Normalize percent."""
48
+ if v not in (None, "", "''", "NA"):
49
+ return float(v) / 100 if v != 0 else 0
50
+ return None
51
+
52
+
53
+ class FederalReserveSOFRFetcher(
54
+ Fetcher[
55
+ FederalReserveSOFRQueryParams,
56
+ List[FederalReserveSOFRData],
57
+ ]
58
+ ):
59
+ """Federal Reserve Federal Funds Fetcher."""
60
+
61
+ @staticmethod
62
+ def transform_query(params: Dict[str, Any]) -> FederalReserveSOFRQueryParams:
63
+ """Transform query."""
64
+ transformed_params = params.copy()
65
+ now = datetime.now().date()
66
+ if params.get("start_date") is None:
67
+ transformed_params["start_date"] = datetime(2018, 4, 2).date()
68
+ if params.get("end_date") is None:
69
+ transformed_params["end_date"] = now
70
+
71
+ return FederalReserveSOFRQueryParams(**transformed_params)
72
+
73
+ @staticmethod
74
+ async def aextract_data(
75
+ query: FederalReserveSOFRQueryParams,
76
+ credentials: Optional[Dict[str, str]],
77
+ **kwargs: Any,
78
+ ) -> List[Dict]:
79
+ """Extract the raw data."""
80
+ # pylint: disable=import-outside-toplevel
81
+ from openbb_core.provider.utils.helpers import amake_request
82
+
83
+ url = (
84
+ "https://markets.newyorkfed.org/api/rates/secured/sofr/search.json?"
85
+ + f"startDate={query.start_date}&endDate={query.end_date}"
86
+ )
87
+ results: List[Dict] = []
88
+ response = await amake_request(url, **kwargs)
89
+ results = response.get("refRates") # type: ignore
90
+ if not results:
91
+ raise EmptyDataError()
92
+ return results
93
+
94
+ @staticmethod
95
+ def transform_data(
96
+ query: FederalReserveSOFRQueryParams,
97
+ data: List[Dict],
98
+ **kwargs: Any,
99
+ ) -> List[FederalReserveSOFRData]:
100
+ """Transform data."""
101
+ results: List[FederalReserveSOFRData] = []
102
+ for d in data.copy():
103
+ _ = d.pop("type", None)
104
+ _ = d.pop("footnoteId", None)
105
+ _ = d.pop("revisionIndicator", None)
106
+ results.append(FederalReserveSOFRData.model_validate(d))
107
+
108
+ return results
openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/treasury_rates.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FederalReserve Treasury Rates Model."""
2
+
3
+ # pylint: disable=unused-argument
4
+
5
+ from datetime import datetime
6
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional
7
+
8
+ from openbb_core.provider.abstract.fetcher import Fetcher
9
+ from openbb_core.provider.standard_models.treasury_rates import (
10
+ TreasuryRatesData,
11
+ TreasuryRatesQueryParams,
12
+ )
13
+ from pydantic import field_validator
14
+
15
+ if TYPE_CHECKING:
16
+ from pandas import DataFrame # pylint: disable=import-outside-toplevel
17
+
18
+ maturities = [
19
+ "month_1",
20
+ "month_3",
21
+ "month_6",
22
+ "year_1",
23
+ "year_2",
24
+ "year_3",
25
+ "year_5",
26
+ "year_7",
27
+ "year_10",
28
+ "year_20",
29
+ "year_30",
30
+ ]
31
+
32
+
33
+ class FederalReserveTreasuryRatesQueryParams(TreasuryRatesQueryParams):
34
+ """FederalReserve Treasury Rates Query."""
35
+
36
+
37
+ class FederalReserveTreasuryRatesData(TreasuryRatesData):
38
+ """FederalReserve Treasury Rates Data."""
39
+
40
+ @field_validator("date", mode="before", check_fields=False)
41
+ @classmethod
42
+ def date_validate(cls, v): # pylint: disable=E0213
43
+ """Return the date as a datetime object."""
44
+ return datetime.strptime(v, "%Y-%m-%d")
45
+
46
+
47
+ class FederalReserveTreasuryRatesFetcher(
48
+ Fetcher[
49
+ FederalReserveTreasuryRatesQueryParams,
50
+ List[FederalReserveTreasuryRatesData],
51
+ ]
52
+ ):
53
+ """Transform the query, extract and transform the data from the FederalReserve endpoints."""
54
+
55
+ @staticmethod
56
+ def transform_query(
57
+ params: Dict[str, Any]
58
+ ) -> FederalReserveTreasuryRatesQueryParams:
59
+ """Transform the query params. Start and end dates are set to a 90 day interval."""
60
+ # pylint: disable=import-outside-toplevel
61
+ from datetime import timedelta
62
+
63
+ transformed_params = params
64
+
65
+ now = datetime.now().date()
66
+ if params.get("start_date") is None:
67
+ transformed_params["start_date"] = now - timedelta(days=365)
68
+
69
+ if params.get("end_date") is None:
70
+ transformed_params["end_date"] = now
71
+
72
+ return FederalReserveTreasuryRatesQueryParams(**transformed_params)
73
+
74
+ @staticmethod
75
+ def extract_data(
76
+ query: FederalReserveTreasuryRatesQueryParams,
77
+ credentials: Optional[Dict[str, str]],
78
+ **kwargs: Any,
79
+ ) -> "DataFrame":
80
+ """Return the raw data from the FederalReserve endpoint."""
81
+ # pylint: disable=import-outside-toplevel
82
+ from io import BytesIO # noqa
83
+ from openbb_core.provider.utils.helpers import make_request # noqa
84
+ from numpy import nan # noqa
85
+ from pandas import DataFrame, read_csv # noqa
86
+
87
+ url = (
88
+ "https://www.federalreserve.gov/datadownload/Output.aspx?"
89
+ + "rel=H15&series=bf17364827e38702b42a58cf8eaa3f78&lastobs=&"
90
+ + "from=&to=&filetype=csv&label=include&layout=seriescolumn&type=package"
91
+ )
92
+
93
+ r = make_request(url, **kwargs)
94
+
95
+ df = read_csv(BytesIO(r.content), header=5, index_col=None, parse_dates=True)
96
+ df.columns = ["date"] + maturities
97
+ df = df.set_index("date").replace("ND", nan)
98
+
99
+ return df.dropna(axis=0, how="all").reset_index()
100
+
101
+ @staticmethod
102
+ def transform_data(
103
+ query: FederalReserveTreasuryRatesQueryParams, data: "DataFrame", **kwargs: Any
104
+ ) -> List[FederalReserveTreasuryRatesData]:
105
+ """Return the transformed data."""
106
+ # pylint: disable=import-outside-toplevel
107
+ from pandas import to_datetime
108
+
109
+ df = data.copy()
110
+ df = df[
111
+ (to_datetime(df.date) >= to_datetime(query.start_date)) # type: ignore
112
+ & (to_datetime(df.date) <= to_datetime(query.end_date)) # type: ignore
113
+ ]
114
+ for col in maturities:
115
+ df[col] = df[col].astype(float) / 100
116
+ df = df.fillna("N/A").replace("N/A", None)
117
+ return [
118
+ FederalReserveTreasuryRatesData.model_validate(d)
119
+ for d in df.to_dict("records")
120
+ ]
openbb_platform/providers/federal_reserve/openbb_federal_reserve/models/yield_curve.py ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FederalReserve Yield Curve Model."""
2
+
3
+ # pylint: disable=unused-argument
4
+
5
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional
6
+
7
+ from openbb_core.provider.abstract.fetcher import Fetcher
8
+ from openbb_core.provider.standard_models.yield_curve import (
9
+ YieldCurveData,
10
+ YieldCurveQueryParams,
11
+ )
12
+
13
+ if TYPE_CHECKING:
14
+ from pandas import DataFrame # pylint: disable=import-outside-toplevel
15
+
16
+ maturities = [
17
+ "month_1",
18
+ "month_3",
19
+ "month_6",
20
+ "year_1",
21
+ "year_2",
22
+ "year_3",
23
+ "year_5",
24
+ "year_7",
25
+ "year_10",
26
+ "year_20",
27
+ "year_30",
28
+ ]
29
+
30
+
31
+ class FederalReserveYieldCurveQueryParams(YieldCurveQueryParams):
32
+ """FederalReserve Yield Curve Query."""
33
+
34
+ __json_schema_extra__ = {"date": {"multiple_items_allowed": True}}
35
+
36
+
37
+ class FederalReserveYieldCurveData(YieldCurveData):
38
+ """FederalReserve Yield Curve Data."""
39
+
40
+
41
+ class FederalReserveYieldCurveFetcher(
42
+ Fetcher[
43
+ FederalReserveYieldCurveQueryParams,
44
+ List[FederalReserveYieldCurveData],
45
+ ]
46
+ ):
47
+ """FederalReserve Yield Curve Fetcher."""
48
+
49
+ @staticmethod
50
+ def transform_query(params: Dict[str, Any]) -> FederalReserveYieldCurveQueryParams:
51
+ """Transform the query params."""
52
+ return FederalReserveYieldCurveQueryParams(**params)
53
+
54
+ @staticmethod
55
+ def extract_data(
56
+ query: FederalReserveYieldCurveQueryParams,
57
+ credentials: Optional[Dict[str, str]],
58
+ **kwargs: Any,
59
+ ) -> "DataFrame":
60
+ """Extract the raw data."""
61
+ # pylint: disable=import-outside-toplevel
62
+ from io import BytesIO # noqa
63
+ from numpy import nan # noqa
64
+ from openbb_core.provider.utils.helpers import make_request # noqa
65
+ from pandas import read_csv # noqa
66
+
67
+ url = (
68
+ "https://www.federalreserve.gov/datadownload/Output.aspx?"
69
+ + "rel=H15&series=bf17364827e38702b42a58cf8eaa3f78&lastobs=&"
70
+ + "from=&to=&filetype=csv&label=include&layout=seriescolumn&type=package"
71
+ )
72
+ r = make_request(url, **kwargs)
73
+ df = read_csv(BytesIO(r.content), header=5, index_col=None, parse_dates=True)
74
+ df.columns = ["date"] + maturities
75
+ df = df.set_index("date").replace("ND", nan)
76
+
77
+ return df.dropna(axis=0, how="all").reset_index()
78
+
79
+ @staticmethod
80
+ def transform_data(
81
+ query: FederalReserveYieldCurveQueryParams, data: "DataFrame", **kwargs: Any
82
+ ) -> List[FederalReserveYieldCurveData]:
83
+ """Return the transformed data."""
84
+ # pylint: disable=import-outside-toplevel
85
+ from pandas import Categorical, DatetimeIndex
86
+
87
+ df = data.copy()
88
+ df.set_index("date", inplace=True)
89
+ dates = query.date.split(",") if query.date else [df.index.max()]
90
+ df.index = DatetimeIndex(df.index)
91
+ dates_list = DatetimeIndex(dates)
92
+ df.columns.name = "maturity"
93
+
94
+ # Find the nearest date in the DataFrame to each date in dates_list
95
+ nearest_dates = [df.index.asof(date) for date in dates_list]
96
+
97
+ # Filter for only the nearest dates
98
+ df = df[df.index.isin(nearest_dates)]
99
+
100
+ df = df.fillna("N/A").replace("N/A", None)
101
+
102
+ # Flatten the DataFrame
103
+ flattened_data = df.reset_index().melt(
104
+ id_vars="date", var_name="maturity", value_name="rate"
105
+ )
106
+ flattened_data = flattened_data.sort_values("date")
107
+ flattened_data["maturity"] = Categorical(
108
+ flattened_data["maturity"], categories=maturities, ordered=True
109
+ )
110
+ flattened_data["rate"] = flattened_data["rate"].astype(float) / 100
111
+ flattened_data = flattened_data.sort_values(
112
+ by=["date", "maturity"]
113
+ ).reset_index(drop=True)
114
+ flattened_data.loc[:, "date"] = flattened_data["date"].dt.strftime("%Y-%m-%d")
115
+ records = flattened_data.to_dict(orient="records")
116
+
117
+ return [FederalReserveYieldCurveData.model_validate(d) for d in records]
openbb_platform/providers/federal_reserve/openbb_federal_reserve/utils/__init__.py ADDED
File without changes
openbb_platform/providers/federal_reserve/openbb_federal_reserve/utils/fomc_documents.py ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FOMC document and release utilities."""
2
+
3
+ from functools import lru_cache
4
+ from typing import Literal, Optional
5
+
6
+ FomcDocumentType = Literal[
7
+ "all",
8
+ "monetary_policy",
9
+ "minutes",
10
+ "projections",
11
+ "materials",
12
+ "press_release",
13
+ "press_conference",
14
+ "conference_call",
15
+ "agenda",
16
+ "transcript",
17
+ "speaker_key",
18
+ "beige_book",
19
+ "teal_book",
20
+ "green_book",
21
+ "blue_book",
22
+ "red_book",
23
+ ]
24
+
25
+
26
+ @lru_cache(maxsize=1)
27
+ def load_historical_fomc_documents() -> list:
28
+ """Load historical FOMC documents map from the static assets."""
29
+ # pylint: disable=import-outside-toplevel
30
+ import json
31
+
32
+ historical_docs: list = []
33
+ historical_docs_path = __file__.replace(
34
+ "utils/fomc_documents.py", "assets/historical_releases.json"
35
+ )
36
+ with open(historical_docs_path, encoding="utf-8") as file:
37
+ historical_docs = json.load(file)
38
+
39
+ return historical_docs
40
+
41
+
42
+ @lru_cache(maxsize=1)
43
+ def get_current_fomc_documents() -> list:
44
+ """
45
+ Get the current FOMC documents from https://www.federalreserve.gov/monetarypolicy/fomccalendars.htm.
46
+
47
+ Returns
48
+ -------
49
+ list
50
+ A list of dictionaries containing the FOMC documents.
51
+ Each dictionary contains the following:
52
+ - date: str
53
+ The date of the document, formatted as YYYY-MM-DD.
54
+ - doc_type: str
55
+ The type of the document.
56
+ - doc_format: str
57
+ The format of the document.
58
+ - url: str
59
+ The URL of the document
60
+ """
61
+ # pylint: disable=import-outside-toplevel
62
+ import re # noqa
63
+ from bs4 import BeautifulSoup
64
+ from openbb_core.provider.utils.helpers import make_request
65
+
66
+ url = "https://www.federalreserve.gov/monetarypolicy/fomccalendars.htm"
67
+ response = make_request(url, method="GET")
68
+ soup = BeautifulSoup(response.content, "html.parser")
69
+ data_releases: list = []
70
+
71
+ for link in soup.find_all("a"):
72
+ url = link.get("href", "")
73
+
74
+ if "/newsevents/pressreleases" in url:
75
+ continue
76
+
77
+ file_url = f"https://www.federalreserve.gov{url}"
78
+ date = file_url.rsplit("/", 1)[-1].split(".")[0]
79
+ date_match = re.search(r"(\d{4})(\d{2})(\d{2})", date)
80
+ if date_match:
81
+ new_date = (
82
+ f"{date_match.group(1)}-{date_match.group(2)}-{date_match.group(3)}"
83
+ )
84
+ file_type = ""
85
+ if "files" in url and "monetary" in date:
86
+ file_type = "monetary_policy"
87
+ if "fomcproj" in date:
88
+ file_type = "projections"
89
+ if "fomcminutes" in date:
90
+ file_type = "minutes"
91
+ if "fomcpresconf" in date:
92
+ file_type = "press_conference"
93
+
94
+ file_format = file_url.rsplit(".", maxsplit=1)[-1]
95
+ data_releases.append(
96
+ {
97
+ "date": new_date,
98
+ "doc_type": file_type,
99
+ "doc_format": file_format,
100
+ "url": file_url,
101
+ }
102
+ )
103
+ data_releases = sorted(data_releases, key=lambda x: x["date"], reverse=True)
104
+
105
+ return data_releases
106
+
107
+
108
+ @lru_cache(maxsize=32)
109
+ def get_fomc_documents_by_year(
110
+ year: Optional[int] = None,
111
+ document_type: Optional[FomcDocumentType] = None,
112
+ pdf_only: bool = False,
113
+ ) -> list[dict]:
114
+ """
115
+ Get a list of FOMC documents by year and document type.
116
+
117
+ Parameters
118
+ ----------
119
+ year : Optional[int]
120
+ The year of the FOMC documents to retrieve. If None, all years since 1959 are returned.
121
+ document_type : Optional[FomcDocumentType]
122
+ The type of FOMC document to retrieve. If None, all document types are returned.
123
+ Valid document types are:
124
+ - all
125
+ - monetary_policy
126
+ - minutes
127
+ - projections
128
+ - materials
129
+ - press_release
130
+ - press_conference
131
+ - conference_call
132
+ - agenda
133
+ - transcript
134
+ - speaker_key
135
+ - beige_book
136
+ - teal_book
137
+ - green_book
138
+ - blue_book
139
+ - red_book
140
+ pdf_only : bool
141
+ Whether to return with only the PDF documents. Default is False.
142
+
143
+ Returns
144
+ -------
145
+ list[dict]
146
+ A list of dictionaries mapping FOMC documents to URLs.
147
+ Each dictionary contains the following:
148
+ - date: str
149
+ The date of the document, formatted as YYYY-MM-DD.
150
+ - doc_type: str
151
+ The type of the document.
152
+ - doc_format: str
153
+ The format of the document.
154
+ - url: str
155
+ The URL of the document
156
+ """
157
+ filtered_docs: list[dict] = []
158
+ choice_types = list(getattr(FomcDocumentType, "__args__", ()))
159
+
160
+ if year and year < 1959:
161
+ raise ValueError("Year must be from 1959.")
162
+
163
+ if year and isinstance(year, str):
164
+ year = int(year) if year.isdigit() else 0
165
+ if year == 0:
166
+ raise ValueError("Year must be an integer.")
167
+
168
+ if not document_type:
169
+ document_type = "all"
170
+
171
+ if document_type not in choice_types:
172
+ raise ValueError(
173
+ f"Invalid document type. Must be one of: {', '.join(choice_types)}"
174
+ )
175
+
176
+ if year:
177
+ docs = (
178
+ get_current_fomc_documents()
179
+ if year > 2019
180
+ else load_historical_fomc_documents()
181
+ )
182
+ else:
183
+ current_docs = get_current_fomc_documents()
184
+ historical_docs = load_historical_fomc_documents()
185
+ docs = current_docs + historical_docs
186
+
187
+ for doc in docs:
188
+ doc_year = int(doc["date"].split("-")[0])
189
+ if year and doc_year != year:
190
+ continue
191
+ if pdf_only is True and doc["doc_format"] != "pdf":
192
+ continue
193
+ if document_type in ("all", doc["doc_type"]):
194
+ filtered_docs.append(doc)
195
+ return filtered_docs
openbb_platform/providers/federal_reserve/openbb_federal_reserve/utils/ny_fed_api.py ADDED
@@ -0,0 +1,641 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """NY Federal Reserve API Utilities."""
2
+
3
+ # pylint: disable=too-many-arguments,too-many-locals,unused-argument
4
+
5
+ from typing import Dict, List, Literal, Optional, Union
6
+
7
+ from openbb_core.app.model.abstract.error import OpenBBError
8
+ from openbb_core.provider.utils.errors import EmptyDataError
9
+ from openbb_core.provider.utils.helpers import amake_request
10
+ from pandas import DataFrame, DatetimeIndex, to_datetime
11
+
12
+ BASE_URL = "https://markets.newyorkfed.org/api"
13
+ OPERATION_STATUS = ["announcements", "results"]
14
+ DETAILS = ["summary", "details"]
15
+ GUIDE_SHEET_TYPES = ["si", "wi", "fs"]
16
+ AMBS_OPERATION_TYPES = ["all", "purchases", "sales", "roll", "swap"]
17
+ AMBS_SECURITIES = {
18
+ None: "",
19
+ "basket": "Basket",
20
+ "coupon_swap": "Coupon%20Swap",
21
+ "dollar_roll": "Dollar%20Roll",
22
+ "specified_pool": "Specified%20Pool",
23
+ "tba": "TBA",
24
+ }
25
+ FXS_OPERATION_TYPES = ["all", "usdollar", "nonusdollar"]
26
+ FXS_DATE_TYPES = ["all", "trade", "maturity"]
27
+ REFERENCE_RATE_TYPES = ["rate", "volume"]
28
+ SECURED_RATE_TYPES = ["tgcr", "bgcr", "sofr", "sofrai"]
29
+ UNSECURED_RATE_TYPES = ["effr", "obfr"]
30
+ REPO_OPERATION_TYPES = ["all", "repo", "reverserepo"]
31
+ REPO_OPERATION_METHODS = ["all", "fixed", "single", "multiple"]
32
+ REPO_SECURITY_TYPES = ["mbs", "agency", "tsy", "srf"]
33
+ REPO_TERM_TYPES = ["overnight", "term"]
34
+ LENDING_OPERATION_TYPES = ["all", "seclending", "extensions"]
35
+ AGENCY_HOLDING_TYPES = {
36
+ "all": "all",
37
+ "agency_debts": "agency%20debts",
38
+ "mbs": "mbs",
39
+ "cmbs": "cmbs",
40
+ }
41
+ TREASURY_HOLDING_TYPES = ["all", "bills", "notesbonds", "frn", "tips"]
42
+ TREASURY_OPERATION_TYPES = ["all", "purchases", "sales"]
43
+ TREASURY_STATUS_TYPES = ["announcements", "results", "operations"]
44
+ TREASURY_SECURITY_TYPE = ["agency", "treasury"]
45
+ CategoryChoices = Literal[
46
+ "agency_mbs_operations",
47
+ "central_bank_liquidity_swaps_operations",
48
+ "guide_sheets",
49
+ "primary_dealer_statistics",
50
+ "primary_dealer_market_share",
51
+ "reference_rates",
52
+ "repo_and_reverse_repo_operations",
53
+ "securities_lending_operations",
54
+ "soma_holdings",
55
+ "treasury_securities_operations",
56
+ ]
57
+ HoldingTypes = Literal[
58
+ "all_agency",
59
+ "agency_debts",
60
+ "mbs",
61
+ "cmbs",
62
+ "all_treasury",
63
+ "bills",
64
+ "notesbonds",
65
+ "frn",
66
+ "tips",
67
+ ]
68
+ HOLDING_TYPE_CHOICES = [
69
+ "all_agency",
70
+ "agency_debts",
71
+ "mbs",
72
+ "cmbs",
73
+ "all_treasury",
74
+ "bills",
75
+ "notesbonds",
76
+ "frn",
77
+ "tips",
78
+ ]
79
+
80
+
81
+ def _get_endpoints(
82
+ category: Union[CategoryChoices, None] = None,
83
+ start_date: Optional[str] = "",
84
+ end_date: Optional[str] = "",
85
+ date: Optional[str] = "2022-02-22",
86
+ details: Optional[str] = "details",
87
+ n_operations: Optional[int] = 90,
88
+ operation_status: Optional[str] = "results",
89
+ ambs_operation: Optional[str] = "all",
90
+ ambs_security: Optional[str] = "",
91
+ fxs_operation_type: Optional[str] = "all",
92
+ fxs_date_type: Optional[str] = "",
93
+ fxs_counterparties: Optional[str] = "",
94
+ guide_sheet_types: Optional[str] = "si",
95
+ is_previous: Optional[bool] = False,
96
+ pd_seriesbreak: Optional[str] = "SBN2022",
97
+ pd_timeseries: Optional[str] = "PDSOOS-ABSTOT",
98
+ pd_asof_date: Optional[str] = "2023-03-01",
99
+ rate_type: Optional[str] = "",
100
+ secured_type: Optional[str] = "sofr",
101
+ unsecured_type: Optional[str] = "effr",
102
+ repo_security_type: Optional[str] = "all",
103
+ repo_operation_type: Optional[str] = "all",
104
+ repo_operation_method: Optional[str] = "all",
105
+ repo_term: Optional[str] = "",
106
+ lending_operation: Optional[str] = "all",
107
+ cusips: Optional[str] = "",
108
+ description: Optional[str] = "",
109
+ agency_holding_type: Optional[str] = "all",
110
+ treasury_holding_type: Optional[str] = "all",
111
+ treasury_operation: Optional[str] = "all",
112
+ treasury_status: Optional[str] = "results",
113
+ treasury_security_type: Optional[str] = "",
114
+ ) -> Dict:
115
+ """Generate URLs to the all, or a category of, endpoints.
116
+
117
+ This function is not intended to be used directly.
118
+ """
119
+ is_latest: str = "latest"
120
+ if ambs_security:
121
+ ambs_security = AMBS_SECURITIES[ambs_security]
122
+
123
+ if is_previous:
124
+ is_latest = "previous" if is_previous else "latest"
125
+
126
+ end_points = {
127
+ "agency_mbs_operations": {
128
+ "latest": BASE_URL + "/ambs/"
129
+ f"{ambs_operation}"
130
+ "/"
131
+ f"{operation_status}"
132
+ "/"
133
+ f"{details}"
134
+ "/latest.json",
135
+ "previous": BASE_URL + "/ambs/"
136
+ f"{ambs_operation}"
137
+ "/"
138
+ f"{operation_status}"
139
+ "/"
140
+ f"{details}"
141
+ "/previous.json",
142
+ "last_two_weeks": BASE_URL + "/ambs/"
143
+ f"{ambs_operation}"
144
+ "/"
145
+ f"{operation_status}"
146
+ "/"
147
+ f"{details}"
148
+ "/lastTwoWeeks.json",
149
+ "last": BASE_URL + "/ambs/"
150
+ f"{ambs_operation}"
151
+ "/"
152
+ f"{operation_status}"
153
+ "/"
154
+ f"{details}"
155
+ "/last/"
156
+ f"{n_operations}"
157
+ ".json",
158
+ "search": BASE_URL + "/ambs/"
159
+ f"{ambs_operation}"
160
+ "/"
161
+ f"{operation_status}"
162
+ "/"
163
+ f"{details}"
164
+ "/search.json?"
165
+ "securities="
166
+ f"{ambs_security}"
167
+ "&desc="
168
+ f"{description}"
169
+ "&cusip="
170
+ f"{cusips}"
171
+ "&startDate="
172
+ f"{start_date}"
173
+ "&endDate="
174
+ f"{end_date}",
175
+ },
176
+ "central_bank_liquidty_swaps_operations": {
177
+ "latest": BASE_URL + "/fxs/" f"{fxs_operation_type}" "/latest.json",
178
+ "last": BASE_URL + "/fxs/"
179
+ f"{fxs_operation_type}"
180
+ "/last/"
181
+ f"{n_operations}"
182
+ ".json",
183
+ "search": BASE_URL + "/fxs/"
184
+ f"{fxs_operation_type}"
185
+ "/search.json"
186
+ "?startDate="
187
+ f"{start_date}"
188
+ "&endDate="
189
+ f"{end_date}"
190
+ "&dateType="
191
+ f"{fxs_date_type}"
192
+ "&counterparties="
193
+ f"{fxs_counterparties}",
194
+ "counterparties": BASE_URL + "/fxs/list/counterparties.json",
195
+ },
196
+ "guide_sheets": BASE_URL + "/guidesheets/"
197
+ f"{guide_sheet_types}"
198
+ "/"
199
+ f"{is_latest}"
200
+ ".json",
201
+ "primary_dealer_statistics": {
202
+ "latest": BASE_URL + "/pd/latest/" f"{pd_seriesbreak}" ".json",
203
+ "all_timeseries": BASE_URL + "/pd/get/all/timeseries.csv",
204
+ "list_descriptions": BASE_URL + "/pd/list/timeseries.json",
205
+ "list_asof": BASE_URL + "/pd/list/asof.json",
206
+ "list_seriesbreaks": BASE_URL + "/pd/list/seriesbreaks.json",
207
+ "get_asof": BASE_URL + "/pd/get/asof/" f"{pd_asof_date}" ".json",
208
+ "get_timeseries": BASE_URL + "/pd/get/" f"{pd_timeseries}" ".json",
209
+ "get_timeseries_seriesbreak": BASE_URL + "/pd/get/"
210
+ f"{pd_seriesbreak}"
211
+ "/timeseries/"
212
+ f"{pd_timeseries}"
213
+ ".json",
214
+ },
215
+ "primary_dealer_market_share": {
216
+ "quarterly": BASE_URL + "/marketshare/qtrly/latest.xlsx",
217
+ "ytd": BASE_URL + "/marketshare/ytd/latest.xlsx",
218
+ },
219
+ "reference_rates": {
220
+ "latest": BASE_URL + "/rates/all/latest.json",
221
+ "search": BASE_URL + "/rates/all/search.json?"
222
+ "startDate="
223
+ f"{start_date}"
224
+ "&endDate="
225
+ f"{end_date}"
226
+ "&type="
227
+ f"{rate_type}",
228
+ "latest_secured": BASE_URL + "/rates/secured/all/latest.json",
229
+ "latest_unsecured": BASE_URL + "/rates/unsecured/all/latest.json",
230
+ "last_secured": BASE_URL + "/rates/secured/"
231
+ f"{secured_type}"
232
+ "/last/"
233
+ f"{n_operations}"
234
+ ".json",
235
+ "last_unsecured": BASE_URL + "/rates/unsecured/"
236
+ f"{unsecured_type}"
237
+ "/last/"
238
+ f"{n_operations}"
239
+ ".json",
240
+ },
241
+ "repo_and_reverse_repo_operations": {
242
+ "latest": BASE_URL + "/rp/"
243
+ f"{repo_operation_type}"
244
+ "/"
245
+ f"{repo_operation_method}"
246
+ "/"
247
+ f"{operation_status}"
248
+ "/latest.json",
249
+ "last_two_weeks": BASE_URL + "/rp/"
250
+ f"{repo_operation_type}"
251
+ "/"
252
+ f"{repo_operation_method}"
253
+ "/"
254
+ f"{operation_status}"
255
+ "/lastTwoWeeks.json",
256
+ "last": BASE_URL + "/rp/"
257
+ f"{repo_operation_type}"
258
+ "/"
259
+ f"{repo_operation_method}"
260
+ "/"
261
+ f"{operation_status}"
262
+ "/last/"
263
+ f"{n_operations}"
264
+ ".json",
265
+ "search": BASE_URL + "/rp/results/search.json?"
266
+ "startDate="
267
+ f"{start_date}"
268
+ "&endDate="
269
+ f"{end_date}"
270
+ "&operationTypes="
271
+ f"{repo_operation_type}"
272
+ "&method="
273
+ f"{repo_operation_method}"
274
+ "&securityType="
275
+ f"{repo_security_type}"
276
+ "&term="
277
+ f"{repo_term}",
278
+ "propositions": BASE_URL + "/rp/reverserepo/propositions/search.json?"
279
+ "startDate="
280
+ f"{start_date}"
281
+ "&endDate="
282
+ f"{end_date}",
283
+ },
284
+ "securities_lending_operations": {
285
+ "latest": BASE_URL + "/seclending/"
286
+ f"{lending_operation}"
287
+ "/results/"
288
+ f"{details}"
289
+ "/latest.json",
290
+ "last_two_weeks": BASE_URL + "/seclending/"
291
+ f"{lending_operation}"
292
+ "/results/"
293
+ f"{details}"
294
+ "/lastTwoWeeks.json",
295
+ "last": BASE_URL + "/seclending/"
296
+ f"{lending_operation}"
297
+ "/results/"
298
+ f"{details}"
299
+ "/last/"
300
+ f"{n_operations}"
301
+ ".json",
302
+ "search": BASE_URL + "/seclending/"
303
+ f"{lending_operation}"
304
+ "/results/"
305
+ f"{details}"
306
+ "/search.json"
307
+ "?startDate="
308
+ f"{start_date}"
309
+ "&endDate="
310
+ f"{end_date}"
311
+ "&cusips="
312
+ f"{cusips}"
313
+ "&descriptions="
314
+ f"{description}",
315
+ },
316
+ "soma_holdings": {
317
+ "summary": BASE_URL + "/soma/summary.json",
318
+ "release_log": BASE_URL + "/soma/agency/get/release_log.json",
319
+ "list_as_of": BASE_URL + "/soma/asofdates/list.json",
320
+ "get_as_of": BASE_URL + "/soma/agency/get/asof/" f"{date}" ".json",
321
+ "get_cusip": BASE_URL + "/soma/agency/get/cusip/" f"{cusips}" ".json",
322
+ "get_holding_type": BASE_URL + "/soma/agency/get/"
323
+ f"{agency_holding_type}"
324
+ "/asof/"
325
+ f"{date}"
326
+ ".json",
327
+ "agency_debts": BASE_URL + "/soma/agency/wam/agency%20debts/asof/"
328
+ f"{date}"
329
+ ".json",
330
+ "list_release_dates": BASE_URL + "/soma/tsy/get/release_log.json",
331
+ "get_treasury_as_of": BASE_URL + "/soma/tsy/get/asof/" f"{date}" ".json",
332
+ "get_treasury_cusip": BASE_URL + "/soma/tsy/get/cusip/" f"{cusips}" ".json",
333
+ "get_treasury_holding_type": BASE_URL + "/soma/tsy/get/"
334
+ f"{treasury_holding_type}"
335
+ "/asof/"
336
+ f"{date}"
337
+ ".json",
338
+ "get_treasury_debts": BASE_URL + "/soma/tsy/wam/"
339
+ f"{treasury_holding_type}"
340
+ "/asof/"
341
+ f"{date}"
342
+ ".json",
343
+ "get_treasury_monthly": BASE_URL + "/soma/tsy/get/monthly.json",
344
+ },
345
+ "treasury_securities_operations": {
346
+ "current": BASE_URL + "/tsy/"
347
+ f"{treasury_operation}"
348
+ "/"
349
+ f"{treasury_status}"
350
+ "/"
351
+ f"{details}"
352
+ "/latest.json",
353
+ "last_two_weeks": BASE_URL + "/tsy/"
354
+ f"{treasury_operation}"
355
+ "/results/"
356
+ f"{details}"
357
+ "/lastTwoWeeks.json",
358
+ "last": BASE_URL + "/tsy/"
359
+ f"{treasury_operation}"
360
+ "/results/"
361
+ f"{details}"
362
+ "/last/"
363
+ f"{n_operations}"
364
+ ".json",
365
+ "search": BASE_URL + "/tsy/"
366
+ f"{treasury_operation}"
367
+ "/results/"
368
+ f"{details}"
369
+ "/search.json?"
370
+ "startDate="
371
+ f"{start_date}"
372
+ "&endDate="
373
+ f"{end_date}"
374
+ "&securityType="
375
+ f"{treasury_security_type}"
376
+ "&cusip="
377
+ f"{cusips}"
378
+ "&desc="
379
+ f"{description}",
380
+ },
381
+ }
382
+ return end_points if category is None else end_points[category] # type: ignore
383
+
384
+
385
+ async def fetch_data(url: str) -> Dict:
386
+ """Fetch the JSON response from the API."""
387
+ try:
388
+ response = await amake_request(url)
389
+ except Exception as e: # pylint: disable=broad-except
390
+ raise e from e
391
+ return response # type: ignore
392
+
393
+
394
+ def get_nearest_date(dates: List[str], target_date: str) -> str:
395
+ """Get the nearest date in the list of dates to the target date."""
396
+ df = DataFrame(dates, columns=["dates"])
397
+ df["dates"] = DatetimeIndex(df["dates"])
398
+ target_date = to_datetime(target_date)
399
+ differences = (df.dates - target_date).abs()
400
+ nearest_date_index = differences.argmin()
401
+ nearest_date = df.index[nearest_date_index]
402
+ return df.iloc[nearest_date]["dates"].strftime("%Y-%m-%d")
403
+
404
+
405
+ class SomaHoldings:
406
+ """Wrapper for NY Fed's System Open Market Account endpoints.
407
+
408
+ All get methods are asynchronous.
409
+
410
+ Methods
411
+ -------
412
+ get_as_of_dates: Function for getting all valid as-of dates for SOMA data.
413
+ Returns: List
414
+ get_release_log: Function for getting the last three months of Agency release and as-of dates.
415
+ Returns: List[Dict]
416
+ get_summary: Function for getting historical weekly summaries by holding type.
417
+ Returns: List[Dict]
418
+ get_agency_holdings: Function for getting the latest agency holdings, or as of a single date.
419
+ Returns: List[Dict]
420
+ get_treasury_holdings: Function for getting the latest Treasury holdings, or as-of a single date.
421
+ Returns: List[Dict]
422
+
423
+ Examples
424
+ --------
425
+ >>> soma = SomaHoldings()
426
+
427
+ >>> logs = await soma.get_release_log()
428
+
429
+ >>> mbs = await soma.get_agency_holdings(holding_type = "mbs")
430
+
431
+ >>> monthly_holdings = await soma.get_treasury_holdings(monthly = True)
432
+ """
433
+
434
+ def __init__(self) -> None:
435
+ """Initialize the SomaHoldings class."""
436
+
437
+ def __repr__(self) -> str:
438
+ """Replace original repr with docstring."""
439
+ return str(self.__doc__)
440
+
441
+ async def get_as_of_dates(self) -> List:
442
+ """Get all valid as-of dates for SOMA operations."""
443
+ dates_url = _get_endpoints()["soma_holdings"]["list_as_of"]
444
+ dates_response = await fetch_data(dates_url)
445
+ dates = dates_response.get("soma", {}).get("asOfDates", [])
446
+ if not dates:
447
+ raise OpenBBError("Error requesting dates. Please try again later.")
448
+ return dates
449
+
450
+ async def get_release_log(
451
+ self,
452
+ treasury: bool = False,
453
+ ) -> List[Dict]:
454
+ """Return the last three months Agency Release and as-of dates.
455
+
456
+ Parameters
457
+ ----------
458
+ treasury: bool
459
+ If True, returns the last three months of Treasury release and as-of dates.
460
+
461
+ Returns
462
+ -------
463
+ List[Dict]: Dictionary of the release date and as-of dates.
464
+
465
+ Example
466
+ -------
467
+ >>> release_log = await SomaHoldings().get_release_log(treasury = True)
468
+ """
469
+ url = (
470
+ _get_endpoints()["soma_holdings"]["list_release_dates"]
471
+ if treasury is True
472
+ else _get_endpoints()["soma_holdings"]["release_log"]
473
+ )
474
+ response = await fetch_data(url)
475
+ release_log = response.get("soma", {}).get("dates", [])
476
+ if not release_log:
477
+ raise OpenBBError("No data found. Try again later.")
478
+
479
+ return release_log
480
+
481
+ async def get_summary(self) -> List[Dict]:
482
+ """Return historical weekly summary by holding type.
483
+
484
+ Returns
485
+ -------
486
+ List[Dict]: Historical weekly summary by holding type.
487
+
488
+ Example
489
+ -------
490
+ summary = await SomaHoldings().get_summary()
491
+ """
492
+ url = _get_endpoints()["soma_holdings"]["summary"]
493
+ response = await fetch_data(url)
494
+ summary = response.get("soma", {}).get("summary", [])
495
+ if not summary:
496
+ raise EmptyDataError(
497
+ "There was an error with the request and was returned empty."
498
+ )
499
+
500
+ return summary
501
+
502
+ async def get_agency_holdings(
503
+ self,
504
+ as_of: Optional[str] = None,
505
+ cusip: Optional[str] = None,
506
+ holding_type: Optional[str] = None,
507
+ wam: bool = False,
508
+ ) -> List[Dict]:
509
+ """Get the latest agency holdings, or as of a single date. Data is updated weekly.
510
+
511
+ Parameters
512
+ ----------
513
+ as_of: Optional[str]
514
+ The as-of date to get data for. Defaults to the latest.
515
+ cusip: Optional[str]
516
+ The CUSIP of the security to search for. This parameter takes priority over `holding_type`.
517
+ holding_type: Optional[str]
518
+ The holding type for which to retrieve. Choices are: ['all', 'agency debts', 'mbs', 'cmbs']
519
+ wam: Optional[bool]
520
+ Whether to return a single date weighted average maturity for Agency debt. Defaults to False.
521
+ This parameter takes priority over `holding_type` and `cusip`.
522
+
523
+ Returns
524
+ -------
525
+ List[Dict]: List of dictionaries with results.
526
+
527
+ Examples
528
+ --------
529
+ >>> holdings = await SomaHoldings().get_agency_holdings(holding_type = "cmbs")
530
+
531
+ >>> df = await SomaHoldings().get_agency_holdings(cusip = "3138LMCK7")
532
+
533
+ >>> wam = await SomaHoldings().get_agency_holdings(wam = True)
534
+ """
535
+ response: Dict = {}
536
+ url: str = ""
537
+ dates = await self.get_as_of_dates()
538
+ if as_of is not None:
539
+ as_of = get_nearest_date(dates, as_of)
540
+ if as_of is None:
541
+ as_of = dates[0]
542
+ if wam is True:
543
+ url = _get_endpoints(
544
+ date=as_of,
545
+ )[
546
+ "soma_holdings"
547
+ ]["agency_debts"]
548
+ response = await fetch_data(url)
549
+ return [response.get("soma", {})]
550
+ url = _get_endpoints(date=as_of)["soma_holdings"]["get_as_of"]
551
+ if holding_type is not None:
552
+ if holding_type not in AGENCY_HOLDING_TYPES:
553
+ raise OpenBBError(
554
+ "Invalid choice. Choose from: ['all', 'agency debts', 'mbs', 'cmbs']"
555
+ )
556
+ url = _get_endpoints(
557
+ agency_holding_type=AGENCY_HOLDING_TYPES[holding_type], date=as_of
558
+ )["soma_holdings"]["get_holding_type"]
559
+ if cusip is not None:
560
+ url = _get_endpoints(cusips=cusip)["soma_holdings"]["get_cusip"]
561
+ response = await fetch_data(url)
562
+ holdings = response.get("soma", {}).get("holdings", [])
563
+ if not holdings:
564
+ raise EmptyDataError()
565
+
566
+ return holdings
567
+
568
+ async def get_treasury_holdings(
569
+ self,
570
+ as_of: Optional[str] = None,
571
+ cusip: Optional[str] = None,
572
+ holding_type: Optional[str] = None,
573
+ wam: Optional[bool] = False,
574
+ monthly: Optional[bool] = False,
575
+ ) -> List[Dict]:
576
+ """Get the latest Treasury holdings, or as of a single date.
577
+
578
+ Parameters
579
+ ----------
580
+ as_of: Optional[str]
581
+ The as-of date to get data for. Defaults to the latest.
582
+ cusip: Optional[str]
583
+ The CUSIP of the security to search for. This parameter takes priority over `monthly` and `holding_type`.
584
+ holding_type: Optional[str]
585
+ The holding type for which to retrieve. Choices are: ['all', 'bills', 'notesbonds', 'frn', 'tips']
586
+ wam: Optional[bool]
587
+ Whether to return a single date weighted average maturity for Agency debt. Defaults to False.
588
+ This parameter takes priority over `holding_type`, `cusip`, and `monthly`.
589
+ monthly: Optional[bool]
590
+ If true, returns historical data for all securities at a monthly interval.
591
+ This parameter takes priority over other parameters except `wam`.
592
+
593
+ Returns
594
+ -------
595
+ List[Dict]: List of dictionaries with results.
596
+
597
+ Examples
598
+ --------
599
+ >>> holdings = await SomaHoldings().get_treasury_holdings(holding_type = "tips")
600
+
601
+ >>> df = await SomaHoldings().get_treasury_holdings(cusip = "912810FH6")
602
+
603
+ >>> wam = await SomaHoldings().get_treasury_holdings(wam = True)
604
+
605
+ >>> monthly = await SomaHoldings().get_treasury_holdings(monthly = True, holding_type = "bills")
606
+ """
607
+ response: Dict = {}
608
+ url: str = ""
609
+ dates = await self.get_as_of_dates()
610
+ if as_of is not None:
611
+ as_of = get_nearest_date(dates, as_of)
612
+ if as_of is None:
613
+ as_of = dates[0]
614
+ if wam is True:
615
+ url = _get_endpoints(
616
+ date=as_of,
617
+ )[
618
+ "soma_holdings"
619
+ ]["get_treasury_debts"]
620
+ response = await fetch_data(url)
621
+ return [response.get("soma", {})]
622
+
623
+ if holding_type is not None:
624
+ if holding_type not in TREASURY_HOLDING_TYPES:
625
+ raise OpenBBError(
626
+ f"Invalid choice. Choose from: {', '.join(TREASURY_HOLDING_TYPES)}"
627
+ )
628
+ url = _get_endpoints(treasury_holding_type=holding_type, date=as_of)[
629
+ "soma_holdings"
630
+ ]["get_treasury_holding_type"]
631
+ if monthly:
632
+ url = _get_endpoints()["soma_holdings"]["get_treasury_monthly"]
633
+ if cusip is not None:
634
+ url = _get_endpoints(cusips=cusip)["soma_holdings"]["get_treasury_cusip"]
635
+
636
+ response = await fetch_data(url)
637
+ holdings = response.get("soma", {}).get("holdings", [])
638
+ if not holdings:
639
+ raise EmptyDataError()
640
+
641
+ return holdings
openbb_platform/providers/federal_reserve/openbb_federal_reserve/utils/primary_dealer_statistics.py ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Primary Dealer Positioning Series IDs."""
2
+
3
+ # pylint: disable=line-too-long
4
+ # flake8: noqa
5
+
6
+ FAILS_SERIES_TO_TITLE = {
7
+ "PDFTD-CS": "FTD Corporate Securities",
8
+ "PDFTR-CS": "FTR Corporate Securities",
9
+ "PDFASCFDA": "FTD Corporate Securities",
10
+ "PDFASCFRA": "FTR Corporate Securities",
11
+ "PDFTD-FGEM": "FTD Agency and GSE Securities (Ex-MBS)",
12
+ "PDFTR-FGEM": "FTR Agency and GSE Securities (Ex-MBS)",
13
+ "PDFASFAFDA": "FTD Agency and GSE Securities (Ex-MBS)",
14
+ "PDFASFAFRA": "FTR Agency and GSE Securities (Ex-MBS)",
15
+ "PDFTD-FGM": "FTD Agency and GSE MBS",
16
+ "PDFTR-FGM": "FTR Agency and GSE MBS",
17
+ "PDFTD-OM": "FTD Other MBS",
18
+ "PDFTR-OM": "FTR Other MBS",
19
+ "PDFASMBFDA": "FTD MBS",
20
+ "PDFASMBFRA": "FTR MBS",
21
+ "PDFTD-UST": "FTD TIPS",
22
+ "PDFTR-UST": "FTR TIPS",
23
+ "PDFTD-USTET": "FTD Treasury Securities (Ex-TIPS)",
24
+ "PDFTR-USTET": "FTR Treasury Securities (Ex-TIPS)",
25
+ "PDFASUFRA": "FTR Treasury Securities",
26
+ "PDFASUFDA": "FTD Treasury Securities",
27
+ }
28
+
29
+
30
+ POSITION_SERIES_TO_TITLE = {
31
+ "PDPOSGS-B": "BILLS (EX. TIPS): DEALER POSITION - LONG. - BILLS (EX. TIPS): DEALER POSITION - SHORT",
32
+ "PDPOSGSC-L2": "TREASURIES (EX. TIPS) COUPONS DUE IN LESS THAN OR EQUAL TO 2 YEARS: DEALER POSITION - NET",
33
+ "PDPOSGSC-G2L3": "TREASURIES (EX. TIPS) COUPONS DUE IN MORE THAN 2 YEARS BUT LESS THAN OR EQUAL TO 3 YEARS: DEALER POSITION - NET",
34
+ "PDPOSGSC-G3L6": "TREASURIES (EX. TIPS) COUPONS DUE IN MORE THAN 3 YEARS BUT LESS THAN OR EQUAL TO 6 YEARS: DEALER POSITION - NET",
35
+ "PDPOSGSC-G6L7": "TREASURIES (EX. TIPS) COUPONS DUE IN MORE THAN 6 YEARS BUT LESS THAN OR EQUAL TO 7 YEARS: DEALER POSITION - NET",
36
+ "PDPOSGSC-G7L11": "TREASURIES (EX. TIPS) COUPONS DUE IN MORE THAN 7 YEARS BUT LESS THAN OR EQUAL TO 11 YEARS: DEALER POSITION - NET",
37
+ "PDPOSGSC-G11L21": "TREASURIES (EX. TIPS): COUPONS DUE IN MORE THAN 11 YEARS BUT LESS THAN OR EQUAL TO 21 YEARS: OUTRIGHT POSITIONS - NET",
38
+ "PDPOSGSC-G21": "TREASURIES (EX. TIPS): COUPONS DUE IN MORE THAN 21 YEARS: OUTRIGHT POSITIONS - NET",
39
+ "PDPOSTIPS-L2": "TIPS DUE IN LESS THAN OR EQUAL TO 2 YEARS: DEALER POSITION - NET",
40
+ "PDPOSTIPS-G2": "TIPS DUE IN MORE THAN 2 YEARS BUT LESS THAN OR EQUAL TO 6 YEARS: DEALER POSITION - NET",
41
+ "PDPOSTIPS-G6L11": "TIPS DUE IN MORE THAN 6 YEARS BUT LESS THAN OR EQUAL TO 11 YEARS: DEALER POSITION - NET",
42
+ "PDPOSTIPS-G11": "TIPS DUE IN MORE THAN 11 YEARS: DEALER POSITION - NET",
43
+ "PDPOSGS-BFRN": "FLOATING RATE NOTES: DEALER POSITION - NET",
44
+ "PDPOSFGS-C": "AGENCY AND GSE (EX. MBS) - COUPONS: DEALER POSITION - NET",
45
+ "PDPOSFGS-DN": "AGENCY AND GSE (EX. MBS) - DISCOUNT NOTES: DEALER POSITION - NET",
46
+ "PDPOSMBSFGS-TBA": "MBS: FEDERAL AGENCY AND GSE MBS: TBAs - OUTRIGHT POSITIONS - NET",
47
+ "PDPOSMBSFGS-OR": "MBS - ALL OTHER FEDERAL AGENCY AND GSE RESIDENTIAL MBS: DEALER POSITION - NET",
48
+ "PDPOSMBSFGS-ST": "MBS: FEDERAL AGENCY AND GSE MBS: SPECIFIED POOLS - OUTRIGHT POSITIONS - NET",
49
+ "PDPOSMBSNA-R": "MBS - NON-AGENCY RESIDENTIAL MBS: DEALER POSITION - NET",
50
+ "PDPOSMBSFGS-C": "MBS - FEDERAL AGENCY AND GSE CMBS: DEALER POSITION - NET",
51
+ "PDPOSMBSNA-O": "MBS - NON-AGENCY OTHER CMBS: DEALER POSITION - NET",
52
+ "PDPOSSMGO-L13": "STATE AND MUNICIPAL GOVERNMENT OBLIGATIONS DUE IN LESS THAN OR EQUAL TO 13 MONTHS: DEALER POSITION - NET",
53
+ "PDPOSSMGO-G13": "STATE AND MUNICIPAL GOVERNMENT OBLIGATIONS DUE IN MORE THAN 13 MONTHS BUT LESS THAN OR EQUAL TO 5 YEARS: DEALER POSITION - NET",
54
+ "PDPOSSMGO-G5L10": "STATE AND MUNICIPAL GOVERNMENT OBLIGATIONS DUE IN MORE THAN 5 YEARS BUT LESS THAN OR EQUAL TO 10 YEARS: DEALER POSITION - NET",
55
+ "PDPOSSMGO-G10": "STATE AND MUNICIPAL GOVERNMENT OBLIGATIONS DUE IN MORE THAN 10 YEARS: DEALER POSITION - NET",
56
+ "PDPOSCSCP": "COMMERCIAL PAPER: DEALER POSITION - NET",
57
+ "PDPOSCSBND-L13": "CORPORATE SECURITIES: INVESTMENT GRADE BONDS, NOTES AND DEBENTURES DUE IN LESS THAN OR EQUAL TO 13 MONTHS: DEALER POSITION - NET",
58
+ "PDPOSCSBND-G13": "CORPORATE SECURITIES: INVESTMENT GRADE BONDS NOTES AND DEBENTURES DUE IN MORE THAN 13 MONTHS BUT LESS THAN OR EQUAL TO 5 YEARS: DEALER POSITION - NET",
59
+ "PDPOSCSBND-G5L10": "CORPORATE SECURITIES INVESTMENT GRADE BONDS NOTES AND DEBENTURES DUE IN MORE THAN 5 YEARS BUT LESS THAN OR EQUAL TO 10 YEARS: DEALER POSITION - NET",
60
+ "PDPOSCSBND-G10": "CORPORATE SECURITIES INVESTMENT GRADE BONDS NOTES AND DEBENTURES DUE IN MORE THAN 10 YEARS: DEALER POSITION - NET",
61
+ "PDPOSCSBND-BELL13": "CORPORATE SECURITIES BELOW INVESTMENT GRADE DUE IN LESS THAN OR EQUAL TO 13 MONTHS: DEALER POSITION - NET",
62
+ "PDPOSCSBND-BELG13": "CORPORATE SECURITIES BELOW INVESTMENT GRADE BONDS NOTES AND DEBENTURES DUE IN MORE THAN 13 MONTHS BUT LESS THAN OR EQUAL TO 5 YEARS: DEALER POSITION - NET",
63
+ "PDPOSCSBND-BELG5L10": "CORPORATE SECURITIES BELOW INVESTMENT GRADE BONDS NOTES AND DEBENTURES DUE IN MORE THAN 5 YEARS BUT LESS THAN OR EQUAL TO 10 YEARS: DEALER POSITION - NET",
64
+ "PDPOSCSBND-BELG10": "CORPORATE SECURITIES BELOW INVESTMENT GRADE BONDS NOTES AND DEBENTURES DUE IN MORE THAN 10 YEARS: DEALER POSITION - NET",
65
+ "PDPOSABS-ALB": "AUTOMOBILE LOAN-BACKED SECURITIES: DEALER POSITION - NET",
66
+ "PDPOSABS-CCB": "CREDIT CARD-BACKED SECURITIES: DEALER POSITION - NET",
67
+ "PDPOSABS-SLB": "STUDENT LOAN-BACKED SECURITIES: DEALER POSITION - NET",
68
+ "PDPOSABS-OAB": "OTHER DEALER POSITION - NET",
69
+ }
70
+
71
+ POSITION_SERIES_TO_FIELD = {
72
+ "dealer_position": {
73
+ "PDPOSGS-B": "bills",
74
+ "PDPOSGSC-L2": "coupons_lte_2_years",
75
+ "PDPOSGSC-G2L3": "coupons_gt_2_years_lt_3_years",
76
+ "PDPOSGSC-G3L6": "coupons_gt_3_years_lt_6_years",
77
+ "PDPOSGSC-G6L7": "coupons_gt_6_years_lt_7_years",
78
+ "PDPOSGSC-G7L11": "coupons_gt_7_years_lt_11_years",
79
+ "PDPOSGSC-G11L21": "coupons_gt_11_years_lt_21_years",
80
+ "PDPOSGSC-G21": "coupons_gt_21_years",
81
+ "PDPOSTIPS-L2": "tips_lt_2_years",
82
+ "PDPOSTIPS-G2": "tips_gt_2_years_lt_6_years",
83
+ "PDPOSTIPS-G6L11": "tips_gt_6_years_lt_11_years",
84
+ "PDPOSTIPS-G11": "tips_gt_11_years",
85
+ "PDPOSGS-BFRN": "floating_rate_notes",
86
+ "PDPOSFGS-DN": "discount_notes",
87
+ "PDPOSFGS-C": "coupons_agency",
88
+ "PDPOSMBSFGS-TBA": "mbs_agency_and_gse_tba",
89
+ "PDPOSMBSFGS-OR": "mbs_agency_and_gse_other_residential",
90
+ "PDPOSMBSFGS-ST": "mbs_agency_and_gse_specified_pools",
91
+ "PDPOSMBSNA-R": "mbs_non_agency_residential",
92
+ "PDPOSMBSFGS-C": "cmbs_agency_and_gse",
93
+ "PDPOSMBSNA-O": "cmbs_non_agency",
94
+ "PDPOSSMGO-L13": "municipal_lt_13_months",
95
+ "PDPOSSMGO-G13": "municipal_gt_13_months_lt_5_years",
96
+ "PDPOSSMGO-G5L10": "municipal_gt_5_years_lt_10_years",
97
+ "PDPOSSMGO-G10": "municipal_gt_10_years",
98
+ "PDPOSCSCP": "commercial_paper",
99
+ "PDPOSCSBND-L13": "corporate_investment_grade_lt_13_months",
100
+ "PDPOSCSBND-G13": "corporate_investment_grade_gt_13_months_lt_5_years",
101
+ "PDPOSCSBND-G5L10": "corporate_investment_grade_gt_5_years_lt_10_years",
102
+ "PDPOSCSBND-G10": "corporate_investment_grade_gt_10_years",
103
+ "PDPOSCSBND-BELL13": "corporate_junk_lt_13_months",
104
+ "PDPOSCSBND-BELG13": "corporate_junk_gt_13_months_lt_5_years",
105
+ "PDPOSCSBND-BELG5L10": "corporate_junk_gt_5_years_lt_10_years",
106
+ "PDPOSCSBND-BELG10": "corporate_junk_gt_10_years",
107
+ "PDPOSABS-ALB": "abs_autos",
108
+ "PDPOSABS-CCB": "abs_credit_cards",
109
+ "PDPOSABS-SLB": "abs_student_loans",
110
+ "PDPOSABS-OAB": "abs_other",
111
+ },
112
+ }
113
+
114
+ POSITION_GROUPS_TO_SERIES = {
115
+ "treasuries": [
116
+ "PDPOSGS-B",
117
+ "PDPOSGSC-L2",
118
+ "PDPOSGSC-G2L3",
119
+ "PDPOSGSC-G3L6",
120
+ "PDPOSGSC-G6L7",
121
+ "PDPOSGSC-G7L11",
122
+ "PDPOSGSC-G11L21",
123
+ "PDPOSGSC-G21",
124
+ "PDPOSFGS-C",
125
+ "PDPOSTIPS-L2",
126
+ "PDPOSTIPS-G2",
127
+ "PDPOSTIPS-G6L11",
128
+ "PDPOSTIPS-G11",
129
+ "PDPOSGS-BFRN",
130
+ "PDPOSFGS-DN",
131
+ ],
132
+ "bills": ["PDPOSGS-B"],
133
+ "coupons": [
134
+ "PDPOSGSC-L2",
135
+ "PDPOSGSC-G2L3",
136
+ "PDPOSGSC-G3L6",
137
+ "PDPOSGSC-G6L7",
138
+ "PDPOSGSC-G7L11",
139
+ "PDPOSGSC-G11L21",
140
+ "PDPOSGSC-G21",
141
+ ],
142
+ "notes": ["PDPOSGS-BFRN", "PDPOSFGS-DN"],
143
+ "tips": ["PDPOSTIPS-L2", "PDPOSTIPS-G2", "PDPOSTIPS-G6L11", "PDPOSTIPS-G11"],
144
+ "mbs": [
145
+ "PDPOSMBSFGS-TBA",
146
+ "PDPOSMBSFGS-OR",
147
+ "PDPOSMBSFGS-ST",
148
+ "PDPOSMBSNA-R",
149
+ "PDPOSMBSFGS-C",
150
+ "PDPOSMBSNA-O",
151
+ ],
152
+ "cmbs": ["PDPOSMBSFGS-C", "PDPOSMBSNA-O"],
153
+ "municipal": ["PDPOSSMGO-L13", "PDPOSSMGO-G13", "PDPOSSMGO-G5L10", "PDPOSSMGO-G10"],
154
+ "corporate": [
155
+ "PDPOSCSCP",
156
+ "PDPOSCSBND-L13",
157
+ "PDPOSCSBND-G13",
158
+ "PDPOSCSBND-G5L10",
159
+ "PDPOSCSBND-G10",
160
+ "PDPOSCSBND-BELL13",
161
+ "PDPOSCSBND-BELG13",
162
+ "PDPOSCSBND-BELG5L10",
163
+ "PDPOSCSBND-BELG10",
164
+ ],
165
+ "commercial_paper": ["PDPOSCSCP"],
166
+ "corporate_ig": [
167
+ "PDPOSCSBND-L13",
168
+ "PDPOSCSBND-G13",
169
+ "PDPOSCSBND-G5L10",
170
+ "PDPOSCSBND-G10",
171
+ ],
172
+ "corporate_junk": [
173
+ "PDPOSCSBND-BELL13",
174
+ "PDPOSCSBND-BELG13",
175
+ "PDPOSCSBND-BELG5L10",
176
+ "PDPOSCSBND-BELG10",
177
+ ],
178
+ "abs": ["PDPOSABS-ALB", "PDPOSABS-CCB", "PDPOSABS-SLB", "PDPOSABS-OAB"],
179
+ }
openbb_platform/providers/federal_reserve/poetry.lock ADDED
The diff for this file is too large to render. See raw diff
 
openbb_platform/providers/federal_reserve/pyproject.toml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [tool.poetry]
2
+ name = "openbb-federal-reserve"
3
+ version = "1.4.3"
4
+ description = "US Federal Reserve Data Extension for OpenBB"
5
+ authors = ["OpenBB <hello@openbb.co>"]
6
+ license = "AGPL-3.0-only"
7
+ readme = "README.md"
8
+ packages = [{ include = "openbb_federal_reserve" }]
9
+
10
+ [tool.poetry.dependencies]
11
+ python = ">=3.9.21,<3.13"
12
+ openbb-core = "^1.4.7"
13
+ beautifulsoup4 = "^4.13.4"
14
+
15
+ [build-system]
16
+ requires = ["poetry-core"]
17
+ build-backend = "poetry.core.masonry.api"
18
+
19
+ [tool.poetry.plugins."openbb_provider_extension"]
20
+ federal_reserve = "openbb_federal_reserve:federal_reserve_provider"
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_central_bank_holdings_fetcher_urllib3_v1.yaml ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ interactions:
2
+ - request:
3
+ body: null
4
+ headers:
5
+ Accept:
6
+ - application/json
7
+ Accept-Encoding:
8
+ - gzip, deflate
9
+ Connection:
10
+ - keep-alive
11
+ method: GET
12
+ uri: https://markets.newyorkfed.org/api/soma/asofdates/list.json
13
+ response:
14
+ body:
15
+ string: !!binary |
16
+ H4sIAAAAAAAEA6pWKs7PTVSyqlZKLPZPc0ksSS1WsopWMjIwMtE1MNU1MlLSgXMMTZE4BhbIHEM4
17
+ x0TXyASJY2iOzDFA4hgYwznGukYIZca6RghlxrqGyMoMzOB6jHSNEC4w0jVCuMBI1xDhAiNdA4TR
18
+ hrrGCGWGyA411EVyqKGuIcIFhrowhxrrGhrBHQrhQJWBOTCHgjkwhxrrGhrqGllCXA3hQEMUzIGF
19
+ KJgDC1EIB+pQY11DA10jaMCDOYZQb0M4yMoMoN421jWwRHIoiAN3qIElPETByhAONbDQNUYos9A1
20
+ gga8sa6Bha4hNODBHAO4fwwsdA3g/jEw1zVCKDPXNUQoM9c1RFZmAPePgRk8Go11QRy4fwzM4NEI
21
+ loFFozEoWcKiEcyBpTcwBxaNEA7CP6ZI0WhgguxQE2SHmiA7FJQDYDFnYIwUjSAOwj/GuohoNAAF
22
+ EJIeA4R/jOCZyVjXwAhZj5EuIuoNjHSR9BgiRb2BoS4i6kEchNGGurCoNwKnUWgKgXCgysAcWMYA
23
+ c2AhagRKo7CoB3NgUQ/mwKIezIFFPYQDDQMjcBqFRj2YA4t6CAdZGSzqjcBpFO5QUBqFOxSURqFJ
24
+ GawM4VBQGkUos4DnYFAIwnMwhAONejAHloNBhQE8Y0A4CGXm8IwBloFlDCNwsoQmZQgH7h9QGoUm
25
+ ZbAMLBohHIRDTeHRaARKvbBohHCQlSGiEZRGoQWXkS6Ig3CoCbJDTXSRHGoMz8FGuqA0Cs3BYA4i
26
+ GkFpFOEfUGKEJFgjULJERD0ojcLjFJQsEXpAKuF6DOGZCZR04ZkJwkEElaEuLOoNwWkUahqEA1UG
27
+ 5sAyE5gDC1EIBxpUhqAEC8v1YA4s10M40KACc2BRDyrT4VEP4SCUGcBDFCwDC1FDcBqFOxSURuEO
28
+ BaVRaNSDlSEcamAJz8GGoKITVniDObCoh3Dg/gGVo9AUb6gLKkehGQPCQSgzh5eJYBlYxjAEpVFY
29
+ DgZzYNEI5sCiHsyB5WAIB+EfU3g0gmIKHo0QDrIyRDSCkiXCoSbwOhhUHCE71AReB4MqU3gdDOYg
30
+ otHAGJ6DwTKwOhjMQUSjgRE81xuCEiwi6kEJFh6noAQLTf6GugaGSFEP4iCUGSJFvQEoTCDp2gCU
31
+ RmEhCubAQhTMgYUomAMLUQgHGlQG4DQKTSFgDizqIRyoC8AcWK43AJej0BCFcKBRD+bACm8wBxb1
32
+ BqA0inAoKI1CvQ2WQTgUlCyhSRksA6u3DcBpFJrRwRxY4Q3hwP0DSqNw/4DSKMI0c3jVZgBKvbAc
33
+ DObAMgaEA/cPqK6HpngDUOqFRSOEAw8dAzN4vW0AKjph7UQIB6HMFB6NYBlYDjYAF50Ih5ogO9QE
34
+ XgeDlSE51ASegw3A5SjC28bwOhgsY4jwjzG8DjYAJUtYSwjMQQpRUM0LS2KgNIowGtFONAAnWETA
35
+ GyI7FFRygA0wtASnUYgLIBxoZoJwoOkNykFWBk1vIBlDWPMLyoGEKIQDbdBCONAQBXEMYLUMhAPN
36
+ GBAONL1BONCMAeVA/GNoCUqw0DIRwkE4FFSowh0KSrCQFAJSZoHkUAMLWFEDkYFmDAgHmjFAHHNY
37
+ UQPhIELHwBxW1EBkoEUNhAMtakAcM1iZCOFAoxHKQfjHDFa1gWRMYe1EKAehzBQWjRAZaHqDchDe
38
+ hnegQDImyA41gfVLIDJIDoV3oEAy8A4UhIOIRlDFD8noIBl4XwbKgUc9qByFlCEQGUTUGxgiRT2o
39
+ HEUoM4R1EUB6QDUiLI2CClVoGFiAEiw0YxiCObAQhXCQlUFrGZAyRBq1ABeqCGWGsFoGogwW9Rag
40
+ chTaRQDJGMBqDAgHWtRAOVBvg/XAQtQCnEahQQXmIBwKSqNwF4DSKCQHG1qAy1FIUQPlIJRZwKMe
41
+ rAwW9RAONOotQEUnLGOAObCMAeEgK4PlYAtQ0QktE0GWmsH6zhAOLOrBymDRaAEqR6E1BkiZKayn
42
+ B+HAcjBYGSwHQzgI/5jAGrQgPSawMhHKQTjUBFYmgmSM4TnYAlyoIpQZI0UjKI1C2r0gPfBOPpSD
43
+ 0APv5ENkEFEPSqMIZfBOPkgZvJMP5cCjHpRGoUkZ1FOFNRYMIRyoMjAHFqJgDixEzcHJEhr1EA40
44
+ qMAcaHUIMg1ReINloD09kIwBPETNQakXFvUQDtQ/YA4s6s3BaRQaVBAO3KGgNAr3DyiNQpOyOSiN
45
+ wqIezIEV3mAOLOrBHFjUQzhw/4AqfoRp8E6+oTko9UI7+RAOLAebg9MopFUDkjGDF95gGVjhDebA
46
+ otEcnEbh3jYwhedgsAwsB0M4CG/DO/kge+CdfAgHloPNQU0CJIfCO/kgZfBOPpSD8Da8kw+RgeVg
47
+ c1BSRkQjqHGK0APv5IP0gDqikDLRHNQ+QNID7+SDlME7+VAOIgxArWqIAWbgchQaohAOVBmYAwtR
48
+ MAcWomagNAqLejAHFvVgDizqwRxY1EM4UP+YgZIlrPAGc2AhCuEgK4NFvRk4jcIdCmqcwh0KSqPQ
49
+ 6h2sDOFQRCff0AyUYGH1NpgDi3oIBxr1YA6s8DYDpURYmQjhIJTBO/kgo0FJDhaioPYoNAebgRMs
50
+ 3D+ITj5ID8gqJD2waAQ1AeA5GMyB5WAIB+FtU3iZaAZKiUgONYEX3mAZWFED5sCKGlBzGF4HgzmI
51
+ aAR1oKBZEyyDiEZQoYrwD7wDBfKPEbyBYQZKlrCWEJiDFKLwDhRIjyGyQw1hLW+IDMyhpqA0Cktv
52
+ YA7MoWAOLL2BOTCHQjhQh5qCEiysOgRzYCEK4UDjFMyBlYmm4DQKTW8QDjTgwRxYxgBzYOnNFJRG
53
+ EQ4FpVFo0QmWQTgUVI5CUwhYBtqBMjQFp1FowIM5sIwB4cD9g+hAgfSYw9uJpuAEi1BmDm8sgGVg
54
+ RQ2EA/cPKMFC848pKMHCMgaEAw8dRAcKZKkpvGozBZWw0IF2iAwsvYFlENEI6uQjvA3vQIH0wDtQ
55
+ EA6SQ+EdKJCMMTxjgMpneGMBwkH4B96BAukxQtZjhKzHSBfa6TI0BSVYRNSD2qPwqAdxEEYj2omm
56
+ oK4VLOpBg73wLgKYAytqwBxYiEI40BAFc2AZwwScRqFRD+bAoh7CgcYpmAMrE0GNeHjUQzgIZQbw
57
+ qAfLwEIUwoH6xwSUYBEOBZWj0FYAWAaWg8EchENBfSaEMgt4DjYBpV5Y1IM5sKgHjdrAixowB5aD
58
+ wRxYxgBzYDkYwoH7B5RGoc1j0DglPBohHIR/QEUcpFAF1cbwdiKEg1BmCm8ngmUQ0WhgguxQE3iD
59
+ FtT+hPdLwBwkh5rApi4MTUCVOKxqA3MQ0QgqVBH+Ac0qwB1qBO8dgoyCjZiBTIN38iEcRNSDkiU0
60
+ M4GyCGw0AqQM3smHcGBRD55NgvVlwBxY1IM5sDIRwoEGFZgDyxjg2SRYLQPhQJMymAOLejAHFvXg
61
+ qSVYmQjmwKIezIFFPZgDC1EIBxpU4KklWOEN5iAcCkqwcIeCClVoKQaaOYFHPYSDUGYBj3qwDCzq
62
+ jUFFJyJ0QI1ThGmITj5YGSxjgDmwjAGeWoJFPZgDi3oIB+EfUD0OiXpQIoDnYAgHoQzRyQfLIKLR
63
+ AFT0wA1AdPJBxR68DoZw4PFjAEqMcD2ITr4xOMEilMFnSQ3BMohoBLVHobkeNM4Pz/VgDiLqQQNR
64
+ 0FLMGFRAIqIelGCh1SFYBhH1oD4TNCmDZWDVISjtwzMGmAMLUQgHGlRgDixjGIHLUWjhDeFAox7M
65
+ gdXbYA4s6sFTS7CoB3NgGQPMgRXeEA40qMAcWNSDp5ZgUQ/mIBwKSqNwh4LSKLQUAzXi4VEP4SCU
66
+ WcALb7AMLOohHLh/QGkUYZo5vEwETzrBqjYwB8mhZvB6Gzy1BKu3wRxYNII5sKgHTy3BohHMgeVg
67
+ MAcWjWAOLAdDOAj/IDr54BkoWA6GcBD+AZWrkDQKnmeCzsobQjgIZYhOPlgGEY2gNApNSKB5JXiZ
68
+ CObA+s5gDlKIgmaX4JYiOlAgYeQQNYQ3FsAysDIRPJsEcyiEA3UomANLb2AOzKEgo+C1DJgDC1Ew
69
+ BxaiYA4sRCEcaIiCp5Zg6Q3MgaU3CAdZGSxjgAbS4GUihAN3KCiNQgs7sAzCoUgdKNCAA7zvDObA
70
+ MgaEA80YYA4svYGnlmA1BoSDUIboQIFlYOkNNHMCzxgQDtw/SB0osAwsGiEchH/gs6SGkEknaHkA
71
+ 4SArQ0QjqHEKLd9A3WN4+QbmwDIGmIPkUPgsKcgeY3hjATzPhIhGUJ8JmizBMrDyDTzphIh60GAp
72
+ tOgEyyCiHlSoIsIAPksKstQQ3lgAz03BRiPAHFjUg2eToCtHDCEcqGlgDixjgDmwEIVwoEEFnlqC
73
+ lYlgDizqIRxonII5sKgHTy3Boh7CQSgzgPf0wDKwEAXPJiEcCupAwR0KSqPQwg6sDOFQUKEKdyio
74
+ cYpQZgHPwZAZKGRlsKgHzybBcjCEg1AGnyU1BMvAMgZ4aglWJoI5sGgEc2BRD+bAohHCQfgHPksK
75
+ MtoUHo3gSSdYNII5iGgEpVFoUgbPM0FXKoEMMIG3asAySA41hvdLwPNMiGgEtUehKR4sA2vVgDmI
76
+ aAQVqtDCATIDhdADqgQhRSdYBkkPopMPmYGCR70BopMPloFGPSh2jWBlIoQDDVEIBxqiEA40RKEc
77
+ SIiCOPDCG8KB1jJQDsQFEA406kEcA1iZCOVAoh7CgRbeEA40REGJzRLJoaA0CmnVQGQQDgXzwaED
78
+ ZsG6CCCOBaxVA+FAC28oB+4fRCcfJAPv5EM5CGXwTj5EBpoxoBy4f0AdKEg0gmTMYO1EKAceOohO
79
+ PkgG3smHchDK4LOkEBlENILSKKSwA8nAO/kQDrSogXCQHArqwcCDCt7JBymDz5JCOQj/gBq4cD3w
80
+ Tj5IGbyTD+Ug9IAaHHA98MkgkDJD2FAyhIOIelDjFJLiDcBTS9B2IoQDzUwQDrRMhHKgQQXWA80Y
81
+ IBl44Q3hwKIePB0FzfUQGWiuB3EMYNUhlAONevA8EyxEwRxYiEI4UG9bIHXyQUnKEh71YBlorofI
82
+ IBwKKkfh3gZx4P4BOQKa4iGTTpA6C2SAOTxjgOeZYDkYzIFlDDAHloMhHLh/QGkUUniDTDODFd5Q
83
+ DsI/8E4+SMYUnoMtwANRCGXwTj5EGSwHW4AGS6GFN0gG3smHcJAcChr4gCQXsB5ovQ1SZgzPwRag
84
+ DhQiGkGFKsI/oI4b3AD4LCnIACNYAwPCgTYwIBxYZrJA6kCBZAxhDQwIB8mhoFYb3B5Q4wHCAU8t
85
+ QduJoIlqI1gtA+VAHQpWBktv4NkkaHUIUobIGGAZWMYAc2AhCp5NgmUMMAeWMcAcWMaAcKAJCcyB
86
+ pTfIpBM0IYE5sBCFcOAOBeVOaAoBzyZBGwsGEA5CGbwDBZGBZQywMuhAO0jGHDY2COHAagzIDBQ0
87
+ IYE5SA6Fd6BAeuCzpBAOLBpB0wGw1XQgGVN4xgDPM8EyBpgDi0YwB5YxIByEf+AdKJBp8FlSKAfh
88
+ UHgHCiQDnyWFchDK4B0oiAwiGkF1PaSBAZKBL4WGcBBRD2qPQgsHc3AaRRgNnyUF6YHPkkI58KgH
89
+ FarQMgQ8tQRtJ4Ka94iMAZaBhSiYA8sY4NkkWNRDONCgAnNgZSKYA4t6CAfqUPA8E3RQCWSpAbyo
90
+ ActA+84QGVhjATy1hHAoqOKH+gcsg3AoKI1CkzJoigce9WAOLOrBHFjUgzmwqIdw4P4BdfIRpsFn
91
+ SUH1NCjfQjI6eG4KloMhk07QaIRw4N4GeQnaCgDLwKIeNCQFayeCjIbPkkI4sBwMVgarMcAcWMYA
92
+ FcnwMhHMgeVgCAfhH9CAK9zV8FlSkD3GsA47hIOIRlAHCuEf0BgR3AD4UmiQHvgsKYSDiHpQgkWE
93
+ AaKdaAZKvbBcD+EgK4NFPXg2CVYmQjhQZWAOLGOAObAQBc8mwWoZMAcW9WAOLOrBHFjUQzjQoAJP
94
+ LcEKbzAHFqIQDrIyWNSDZ5MQDgWlUbhDQc1YaNSDlSEciujkG4DnmWCFN5gDi3oIB5riwRxY1INn
95
+ k2AZA8JBKIN38kFGg4pFSMyBp5ZgORjCgfsHlEahZTxYBhaNEA7CP/BOPshoU3gOBk86wXIwmIOI
96
+ RlDjFFpwgSZP4XUwmAPLwWAOrKgBTy0hohGxFBpkqTFsRgDCQUQjKMEi/GMEr7fB80yIqAclS2hb
97
+ GSwDa2CAxnfhmQnMQUQ9qAOFMBo0ogEJUfBsEixEIRyoMjAHlpnAHFiIQjjQEAVPLcGiHsyBRT2E
98
+ A41TMAcW9eDZJFjUQzgIZQawTr4BWAYWoqBGFbxBC+HAHQpKo9CoB8sgHAoqVOEOBbVHEcos4FEP
99
+ nnSCRT2YA4t68GwSLGNAOAjT4J18A7AMLGOAp5ZgUQ/mwHIwmAOLRjAHFvUQDsI/8E4+yGh4Jx/K
100
+ QVYGy8GgGhzeoIVwEA6Fd/JBBoDcCot6A3gnHyRjDBumg3AQ0QhqnMLjB5RGoXUweNIJVh2CObAy
101
+ EcJBuADRgQJ12ZAdimgngmVgZSKYAwtR8GwSrJ0I5sDSG5gDcyiEA3UomANLb+CpJViZCObAMgaE
102
+ Aw1RMAcWouDZJFjGgHAQygxgA+3goIFtnoFyoN4GTzohHApKo9AyBCwDqw7BHIRDQWkUoQw+SwoK
103
+ dQt4xoDMQEGrd/BsEiy9gTmw9AbmwNIbmAOYgaVSbG0tFwCnUJCfczcAAA==
104
+ headers:
105
+ Access-Control-Allow-Headers:
106
+ - Content-Type,Content-Disposition
107
+ Access-Control-Allow-Methods:
108
+ - OPTIONS,GET
109
+ Access-Control-Allow-Origin:
110
+ - '*'
111
+ Access-Control-Expose-Headers:
112
+ - Content-Disposition
113
+ Cache-Control:
114
+ - no-store
115
+ Connection:
116
+ - keep-alive
117
+ Content-Encoding:
118
+ - gzip
119
+ Content-Length:
120
+ - '5002'
121
+ Content-Type:
122
+ - application/json; charset=utf-8
123
+ Date:
124
+ - Mon, 27 May 2024 04:35:48 GMT
125
+ Pragma:
126
+ - no-cache
127
+ Set-Cookie:
128
+ - ak_bmsc=5CEBD78D80FAFF663D03C7F967C6BFAE~000000000000000000000000000000~YAAQ0ZUeuLOkqK2PAQAAT0pVuBegPpDjBftM+11du7IGVA3XRL1BwzGFH5f2hUGzz08UJ6iGqzgRnhNTkW61UGe2NCnxaGQuLjbT3RfUlhlyJ6c+5AlTAln7EkxWqArPuN45q5t9sFrQcPPOamu/kmm8EevoYrrLPKe3JPnfMjN3eUY0IGG7zxrPudMxlMHjRxegzJ57hedgBfhrDVYcJYGMaDde6XRV8AoHDkqfbbLl35kUqTWtgKcib8dyRQxH14YuQG/Ay+TFnpwFF8YrJ2vZOI8H64Yz9PoPTQVVWIBK5uQmjdFO5U4gO6UyMtHyBukhJSMoOkXDbRdHfBclPjkPadi2FFG3prnP2SoddDyKOaqTrzom2ff/XUu0e9FDr2ilHFvTBnqhaV8dfsggEb5wUJKVhzzpl9g=;
129
+ Domain=.newyorkfed.org; Path=/; Expires=Mon, 27 May 2024 06:35:48 GMT; Max-Age=7200
130
+ Vary:
131
+ - Accept-Encoding
132
+ strict-transport-security:
133
+ - max-age=31536000; includeSubDomains
134
+ x-amz-apigw-id:
135
+ - Yab7FEkDiYcF61w=
136
+ x-amzn-requestid:
137
+ - a5a539bf-df2c-42e7-a2bd-d72e1699a6cc
138
+ x-amzn-trace-id:
139
+ - Root=1-66540d13-1201517398dc2f4fc4ec8c51;Parent=3b5499d8af4b6284;Sampled=0;lineage=e7c0e2ee:0
140
+ x-frame-options:
141
+ - SAMEORIGIN
142
+ x-xss-protection:
143
+ - 1; mode=block
144
+ status:
145
+ code: 200
146
+ message: OK
147
+ - request:
148
+ body: null
149
+ headers:
150
+ Accept:
151
+ - application/json
152
+ Accept-Encoding:
153
+ - gzip, deflate
154
+ Connection:
155
+ - keep-alive
156
+ method: GET
157
+ uri: https://markets.newyorkfed.org/api/soma/agency/get/agency%20debts/asof/2019-01-02.json
158
+ response:
159
+ body:
160
+ string: !!binary |
161
+ H4sIAAAAAAAEA6pWKs7PTVSyUqhWUMrIz0nJzEsvVrJSiAbxE4v901wSS1KVrBSUjAwMLXUNDHUN
162
+ jJR0FJSSS4szC0DCxobG5q6Ozo6mINHcxJLSosySSlQ9xrpG5iDZzOLi0tQikCY3Dx9fZ5BQcUFR
163
+ amIKSAjES84vLcjPA/GM9czBBhYkFoUl5pSCHWBmZAAGIJWZeWk5iSWZ+XnO+bkFqXnFYDZII0iy
164
+ ILUoOTWvxL+0pLgkMQ/kIZhMckZiXnqqW1F+bkBRZn5ReGpqNkjKAKQLTS4yNRHsVLBccWoy2F8h
165
+ lQVgpzimp+YlVyq4pCaVFCsp1OoQH1amlr6uocYg+zDDyshS18BU1xDscaSw8vN1BKnHFVRmekam
166
+ IHnkoDKxMAMHFdjxQzms3LzAKQczrIwNQGmR1LAy1zPEDCwzM9NhElgBOBIWKLBIT1jmephhZWQx
167
+ TMLK3Rt3WBkakpEJzTADy9hiOJRYJo4mjo7gMh9LLjTUNTDGDCxCpbsZltLd2HA4FFkmjibeEYag
168
+ 4hhLYBnpGpiTE1iYKcvI0HiwFlmAKcTW1gIANAgYDFMIAAA=
169
+ headers:
170
+ Access-Control-Allow-Headers:
171
+ - Content-Type,Content-Disposition
172
+ Access-Control-Allow-Methods:
173
+ - OPTIONS,GET
174
+ Access-Control-Allow-Origin:
175
+ - '*'
176
+ Access-Control-Expose-Headers:
177
+ - Content-Disposition
178
+ Cache-Control:
179
+ - no-store
180
+ Connection:
181
+ - keep-alive
182
+ Content-Encoding:
183
+ - gzip
184
+ Content-Length:
185
+ - '434'
186
+ Content-Type:
187
+ - application/json; charset=utf-8
188
+ Date:
189
+ - Mon, 27 May 2024 04:35:48 GMT
190
+ Pragma:
191
+ - no-cache
192
+ Vary:
193
+ - Accept-Encoding
194
+ strict-transport-security:
195
+ - max-age=31536000; includeSubDomains
196
+ x-amz-apigw-id:
197
+ - Yab8DG_2CYcFRVQ=
198
+ x-amzn-requestid:
199
+ - 77389215-2812-484c-b360-32319652a4d5
200
+ x-amzn-trace-id:
201
+ - Root=1-66540d19-704c63158c84edcacd8d9686;Parent=243faa5217608a67;Sampled=0;lineage=e7c0e2ee:0
202
+ x-frame-options:
203
+ - SAMEORIGIN
204
+ x-xss-protection:
205
+ - 1; mode=block
206
+ status:
207
+ code: 200
208
+ message: OK
209
+ version: 1
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_central_bank_holdings_fetcher_urllib3_v2.yaml ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ interactions:
2
+ - request:
3
+ body: null
4
+ headers:
5
+ Accept:
6
+ - application/json
7
+ Accept-Encoding:
8
+ - gzip, deflate
9
+ Connection:
10
+ - keep-alive
11
+ method: GET
12
+ uri: https://markets.newyorkfed.org/api/soma/asofdates/list.json
13
+ response:
14
+ body:
15
+ string: !!binary |
16
+ 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
104
+ headers:
105
+ Access-Control-Allow-Headers:
106
+ - Content-Type,Content-Disposition
107
+ Access-Control-Allow-Methods:
108
+ - OPTIONS,GET
109
+ Access-Control-Allow-Origin:
110
+ - '*'
111
+ Access-Control-Expose-Headers:
112
+ - Content-Disposition
113
+ Cache-Control:
114
+ - no-store
115
+ Connection:
116
+ - keep-alive
117
+ Content-Encoding:
118
+ - gzip
119
+ Content-Length:
120
+ - '5006'
121
+ Content-Type:
122
+ - application/json; charset=utf-8
123
+ Date:
124
+ - Thu, 27 Jun 2024 10:22:35 GMT
125
+ Pragma:
126
+ - no-cache
127
+ Vary:
128
+ - Accept-Encoding
129
+ strict-transport-security:
130
+ - max-age=31536000; includeSubDomains
131
+ x-amz-apigw-id:
132
+ - aA3xpHqSiYcFjnQ=
133
+ x-amzn-requestid:
134
+ - fcdac34d-710d-4be2-af46-792d9ed26c8e
135
+ x-amzn-trace-id:
136
+ - Root=1-667d0670-18c72df81c639990d129e0f5;Parent=27525fc962873525;Sampled=0;lineage=e7c0e2ee:0
137
+ x-frame-options:
138
+ - SAMEORIGIN
139
+ x-xss-protection:
140
+ - 1; mode=block
141
+ status:
142
+ code: 200
143
+ message: OK
144
+ - request:
145
+ body: null
146
+ headers:
147
+ Accept:
148
+ - application/json
149
+ Accept-Encoding:
150
+ - gzip, deflate
151
+ Connection:
152
+ - keep-alive
153
+ method: GET
154
+ uri: https://markets.newyorkfed.org/api/soma/agency/get/agency%20debts/asof/2019-01-02.json
155
+ response:
156
+ body:
157
+ string: !!binary |
158
+ H4sIAAAAAAAEA6pWKs7PTVSyUqhWUMrIz0nJzEsvVrJSiAbxE4v901wSS1KVrBSUjAwMLXUNDHUN
159
+ jJR0FJSSS4szC0DCxobG5q6Ozo6mINHcxJLSosySSlQ9xrpG5iDZzOLi0tQikCY3Dx9fZ5BQcUFR
160
+ amIKSAjES84vLcjPA/GM9czBBhYkFoUl5pSCHWBmZAAGIJWZeWk5iSWZ+XnO+bkFqXnFYDZII0iy
161
+ ILUoOTWvxL+0pLgkMQ/kIZhMckZiXnqqW1F+bkBRZn5ReGpqNkjKAKQLTS4yNRHsVLBccWoy2F8h
162
+ lQVgpzimp+YlVyq4pCaVFCsp1OoQH1amlr6uocYg+zDDyshS18BU1xDscaSw8vN1BKnHFVRmekam
163
+ IHnkoDKxMAMHFdjxQzms3LzAKQczrIwNQGmR1LAy1zPEDCwzM9NhElgBOBIWKLBIT1jmephhZWQx
164
+ TMLK3Rt3WBkakpEJzTADy9hiOJRYJo4mjo7gMh9LLjTUNTDGDCxCpbsZltLd2HA4FFkmjibeEYag
165
+ 4hhLYBnpGpiTE1iYKcvI0HiwFlmAKcTW1gIANAgYDFMIAAA=
166
+ headers:
167
+ Access-Control-Allow-Headers:
168
+ - Content-Type,Content-Disposition
169
+ Access-Control-Allow-Methods:
170
+ - OPTIONS,GET
171
+ Access-Control-Allow-Origin:
172
+ - '*'
173
+ Access-Control-Expose-Headers:
174
+ - Content-Disposition
175
+ Cache-Control:
176
+ - no-store
177
+ Connection:
178
+ - keep-alive
179
+ Content-Encoding:
180
+ - gzip
181
+ Content-Length:
182
+ - '434'
183
+ Content-Type:
184
+ - application/json; charset=utf-8
185
+ Date:
186
+ - Thu, 27 Jun 2024 10:22:36 GMT
187
+ Pragma:
188
+ - no-cache
189
+ Vary:
190
+ - Accept-Encoding
191
+ strict-transport-security:
192
+ - max-age=31536000; includeSubDomains
193
+ x-amz-apigw-id:
194
+ - aBaI-FAMCYcF_nw=
195
+ x-amzn-requestid:
196
+ - 8ffcfa84-16ba-46e5-9d09-42e8da2acd00
197
+ x-amzn-trace-id:
198
+ - Root=1-667d3d6c-3442d57f02ec8c1424ab574d;Parent=54f3710835abe975;Sampled=0;lineage=e7c0e2ee:0
199
+ x-frame-options:
200
+ - SAMEORIGIN
201
+ x-xss-protection:
202
+ - 1; mode=block
203
+ status:
204
+ code: 200
205
+ message: OK
206
+ version: 1
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_federal_funds_rate_fetcher_urllib3_v1.yaml ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ interactions:
2
+ - request:
3
+ body: null
4
+ headers:
5
+ Accept:
6
+ - application/json
7
+ Accept-Encoding:
8
+ - gzip, deflate
9
+ Connection:
10
+ - keep-alive
11
+ method: GET
12
+ uri: https://markets.newyorkfed.org/api/rates/unsecured/effr/search.json?startDate=2023-01-01&endDate=2023-06-06
13
+ response:
14
+ body:
15
+ string: !!binary |
16
+ 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
48
+ YHcAAA==
49
+ headers:
50
+ Access-Control-Allow-Headers:
51
+ - Content-Type,Content-Disposition
52
+ Access-Control-Allow-Methods:
53
+ - OPTIONS,GET
54
+ Access-Control-Allow-Origin:
55
+ - '*'
56
+ Access-Control-Expose-Headers:
57
+ - Content-Disposition
58
+ Cache-Control:
59
+ - no-store
60
+ Connection:
61
+ - keep-alive
62
+ Content-Encoding:
63
+ - gzip
64
+ Content-Length:
65
+ - '1828'
66
+ Content-Type:
67
+ - application/json; charset=utf-8
68
+ Date:
69
+ - Thu, 06 Jun 2024 20:57:40 GMT
70
+ Pragma:
71
+ - no-cache
72
+ Set-Cookie:
73
+ - ak_bmsc=708282FD0DF0D37D7B8EEC7F6E7FE0D5~000000000000000000000000000000~YAAQ1pUeuGBXpLmPAQAAQ9BX7xhONWLFcCw0okbGYS1e9pk21yRgiUPaNTZNMp5Sv9xCMmLwMKLdnw8O6Hc7zrRz89eYCSlfosascqu+Yqns9+dnqyMafbNYXR1i4J9ECjdQLp8lM2L6xh8gQsdf6ZZVkGVSqC5IDB3Pi1i4wvt78Ceorh+Mf4dGp/TidQtDSRT6Ed4NntmHOWnqzNYlBqwdeijotrIOFBRsrkEbmcsTX+4Ohj+5tKKfXG9+EdvLCrb2eJvB7+U9cthYZec/uWt5lDrA7WEnXvXskwrJFBCOTrHgZnk6pJQtGhkE9oewQLQl0h0gV7izDf/SYN64eCW7wHrSnKgkOj4nXN4Zj0ZdDBdI1o+h6pD9xB1d7PiDHAtWWuMlPcqXReNef/lMse81AoQXJSvvXB4=;
74
+ Domain=.newyorkfed.org; Path=/; Expires=Thu, 06 Jun 2024 22:57:40 GMT; Max-Age=7200
75
+ Vary:
76
+ - Accept-Encoding
77
+ strict-transport-security:
78
+ - max-age=31536000; includeSubDomains
79
+ x-amz-apigw-id:
80
+ - Y9pewFa8CYcFueA=
81
+ x-amzn-requestid:
82
+ - 6cc5ccab-5d40-4dfc-a97f-37ab9cdd7ef5
83
+ x-amzn-trace-id:
84
+ - Root=1-666222c4-11bb458333c0ee1d7b67d155;Parent=42d70ec18dfba284;Sampled=0;lineage=e7c0e2ee:0
85
+ x-frame-options:
86
+ - SAMEORIGIN
87
+ x-xss-protection:
88
+ - 1; mode=block
89
+ status:
90
+ code: 200
91
+ message: OK
92
+ version: 1
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_federal_funds_rate_fetcher_urllib3_v2.yaml ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ interactions:
2
+ - request:
3
+ body: null
4
+ headers:
5
+ Accept:
6
+ - application/json
7
+ Accept-Encoding:
8
+ - gzip, deflate
9
+ Connection:
10
+ - keep-alive
11
+ method: GET
12
+ uri: https://markets.newyorkfed.org/api/rates/unsecured/effr/search.json?startDate=2023-01-01&endDate=2023-06-06
13
+ response:
14
+ body:
15
+ string: !!binary |
16
+ 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
48
+ YHcAAA==
49
+ headers:
50
+ Access-Control-Allow-Headers:
51
+ - Content-Type,Content-Disposition
52
+ Access-Control-Allow-Methods:
53
+ - OPTIONS,GET
54
+ Access-Control-Allow-Origin:
55
+ - '*'
56
+ Access-Control-Expose-Headers:
57
+ - Content-Disposition
58
+ Cache-Control:
59
+ - no-store
60
+ Connection:
61
+ - keep-alive
62
+ Content-Encoding:
63
+ - gzip
64
+ Content-Length:
65
+ - '1828'
66
+ Content-Type:
67
+ - application/json; charset=utf-8
68
+ Date:
69
+ - Thu, 27 Jun 2024 10:22:35 GMT
70
+ Pragma:
71
+ - no-cache
72
+ Vary:
73
+ - Accept-Encoding
74
+ strict-transport-security:
75
+ - max-age=31536000; includeSubDomains
76
+ x-amz-apigw-id:
77
+ - aBaIwHoWiYcFhkQ=
78
+ x-amzn-requestid:
79
+ - e7fb1759-2758-4603-93d2-6fd7dc6cb84e
80
+ x-amzn-trace-id:
81
+ - Root=1-667d3d6a-20954503ee4954595abe5cae;Parent=0c6de0f786049405;Sampled=0;lineage=e7c0e2ee:0
82
+ x-frame-options:
83
+ - SAMEORIGIN
84
+ x-xss-protection:
85
+ - 1; mode=block
86
+ status:
87
+ code: 200
88
+ message: OK
89
+ version: 1
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_fomc_documents_fetcher_urllib3_v1.yaml ADDED
@@ -0,0 +1,311 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ interactions:
2
+ - request:
3
+ body: null
4
+ headers:
5
+ Accept:
6
+ - '*/*'
7
+ Accept-Encoding:
8
+ - gzip, deflate
9
+ Connection:
10
+ - keep-alive
11
+ method: GET
12
+ uri: https://www.federalreserve.gov/monetarypolicy/fomccalendars.htm
13
+ response:
14
+ body:
15
+ string: !!binary |
16
+ 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
277
+ headers:
278
+ CF-Cache-Status:
279
+ - HIT
280
+ CF-RAY:
281
+ - 920506b69bf398dc-YVR
282
+ Connection:
283
+ - keep-alive
284
+ Content-Encoding:
285
+ - gzip
286
+ Content-Type:
287
+ - text/html
288
+ Date:
289
+ - Fri, 14 Mar 2025 16:07:49 GMT
290
+ Last-Modified:
291
+ - Wed, 19 Feb 2025 19:00:45 GMT
292
+ Server:
293
+ - cloudflare
294
+ Set-Cookie:
295
+ - __cf_bm=gBemx_ArIsqRSTFARnkuhxG7wDowyML2lcNBQNJuPlI-1741968469-1.0.1.1-NlCP8uodX1p.KyojVGUL46iC6.0yS4G0dS0xEbb9L7rIszAgpYPHQLWIwqmBb0oYOuK5oSZdr79ZEaU1U8ttLLE6DCvtuFG_Pr3gwx2IXWU;
296
+ path=/; expires=Fri, 14-Mar-25 16:37:49 GMT; domain=.federalreserve.gov; HttpOnly;
297
+ Secure; SameSite=None
298
+ - _cfuvid=Zb.eHsA.OmFG7nd3ikj09NAVXFd79rgr8b3pSK0Q87I-1741968469629-0.0.1.1-604800000;
299
+ path=/; domain=.federalreserve.gov; HttpOnly; Secure; SameSite=None
300
+ Strict-Transport-Security:
301
+ - max-age=31536000; includeSubDomains; preload
302
+ Transfer-Encoding:
303
+ - chunked
304
+ Vary:
305
+ - Accept-Encoding
306
+ X-Frame-Options:
307
+ - SAMEORIGIN
308
+ status:
309
+ code: 200
310
+ message: OK
311
+ version: 1
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_fomc_documents_fetcher_urllib3_v2.yaml ADDED
The diff for this file is too large to render. See raw diff
 
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_money_measures_fetcher_urllib3_v1.yaml ADDED
The diff for this file is too large to render. See raw diff
 
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_money_measures_fetcher_urllib3_v2.yaml ADDED
The diff for this file is too large to render. See raw diff
 
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_overnight_bank_funding_rate_fetcher_urllib3_v1.yaml ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ interactions:
2
+ - request:
3
+ body: null
4
+ headers:
5
+ Accept:
6
+ - application/json
7
+ Accept-Encoding:
8
+ - gzip, deflate
9
+ Connection:
10
+ - keep-alive
11
+ method: GET
12
+ uri: https://markets.newyorkfed.org/api/rates/unsecured/obfr/search.json?startDate=2024-06-01&endDate=2024-06-06
13
+ response:
14
+ body:
15
+ string: !!binary |
16
+ H4sIAAAAAAAEA6pWUCpKTQtKLEktVrJSiFaoVlBKTUtLTS7JLEt1SSxJVbJSUDIyMDLRNTDTNTBT
17
+ 0lFQKqksAIv6O7kFKSnoKBWkFiWn5pWAjFCyUjDVMzZCCAZA5DJzUg3Bckam2OSMTMGSxobYJM2h
18
+ ksbYJC0tITotFXSUyvJzSnNTPfOcMnNyMvPzQN4xsgDZV5RallmcmZ/nmZeSmZxYkl8E8pOSQq0O
19
+ fs+aDlbPWuDwrDlIgkzPmgw1z1oYKOgokelZ46HmWXN8yRgwhViFWgD5Rz99xgMAAA==
20
+ headers:
21
+ Access-Control-Allow-Headers:
22
+ - Content-Type,Content-Disposition
23
+ Access-Control-Allow-Methods:
24
+ - OPTIONS,GET
25
+ Access-Control-Allow-Origin:
26
+ - '*'
27
+ Access-Control-Expose-Headers:
28
+ - Content-Disposition
29
+ Cache-Control:
30
+ - no-store
31
+ Connection:
32
+ - keep-alive
33
+ Content-Encoding:
34
+ - gzip
35
+ Content-Length:
36
+ - '220'
37
+ Content-Type:
38
+ - application/json; charset=utf-8
39
+ Date:
40
+ - Tue, 11 Jun 2024 02:34:03 GMT
41
+ Pragma:
42
+ - no-cache
43
+ Set-Cookie:
44
+ - cookiesession1=678A3E0EE607407E823ED4EA4F0C28B9;Expires=Wed, 11 Jun 2025 02:34:03
45
+ GMT;Path=/;Secure;HttpOnly
46
+ Vary:
47
+ - Accept-Encoding
48
+ strict-transport-security:
49
+ - max-age=31536000; includeSubDomains
50
+ x-amz-apigw-id:
51
+ - ZLmgUG4BCYcFe8Q=
52
+ x-amzn-requestid:
53
+ - b77d47db-cd3e-492d-a63f-1ab9a17c16f8
54
+ x-amzn-trace-id:
55
+ - Root=1-6667b79b-358f5ab1a50c2313c1e18089;Parent=15119c60494acd17;Sampled=0;lineage=e7c0e2ee:0
56
+ x-frame-options:
57
+ - SAMEORIGIN
58
+ x-xss-protection:
59
+ - 1; mode=block
60
+ status:
61
+ code: 200
62
+ message: OK
63
+ version: 1
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_overnight_bank_funding_rate_fetcher_urllib3_v2.yaml ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ interactions:
2
+ - request:
3
+ body: null
4
+ headers:
5
+ Accept:
6
+ - application/json
7
+ Accept-Encoding:
8
+ - gzip, deflate
9
+ Connection:
10
+ - keep-alive
11
+ method: GET
12
+ uri: https://markets.newyorkfed.org/api/rates/unsecured/obfr/search.json?startDate=2024-06-01&endDate=2024-06-06
13
+ response:
14
+ body:
15
+ string: !!binary |
16
+ H4sIAAAAAAAEA6pWUCpKTQtKLEktVrJSiFaoVlBKTUtLTS7JLEt1SSxJVbJSUDIyMDLRNTDTNTBT
17
+ 0lFQKqksAIv6O7kFKSnoKBWkFiWn5pWAjFCyUjDVMzZCCAZA5DJzUg3Bckam2OSMTMGSxobYJM2h
18
+ ksbYJC0tITotFXSUyvJzSnNTPfOcMnNyMvPzQN4xsgDZV5RallmcmZ/nmZeSmZxYkl8E8pOSQq0O
19
+ fs+aDlbPWuDwrDlIgkzPmgw1z1oYKOgokelZ46HmWXN8yRgwhViFWgD5Rz99xgMAAA==
20
+ headers:
21
+ Access-Control-Allow-Headers:
22
+ - Content-Type,Content-Disposition
23
+ Access-Control-Allow-Methods:
24
+ - OPTIONS,GET
25
+ Access-Control-Allow-Origin:
26
+ - '*'
27
+ Access-Control-Expose-Headers:
28
+ - Content-Disposition
29
+ Cache-Control:
30
+ - no-store
31
+ Connection:
32
+ - keep-alive
33
+ Content-Encoding:
34
+ - gzip
35
+ Content-Length:
36
+ - '220'
37
+ Content-Type:
38
+ - application/json; charset=utf-8
39
+ Date:
40
+ - Thu, 27 Jun 2024 10:22:37 GMT
41
+ Pragma:
42
+ - no-cache
43
+ Vary:
44
+ - Accept-Encoding
45
+ strict-transport-security:
46
+ - max-age=31536000; includeSubDomains
47
+ x-amz-apigw-id:
48
+ - aBaJFF_RiYcFrCQ=
49
+ x-amzn-requestid:
50
+ - 1ca86d24-755a-4112-a2d6-7755eacd57ec
51
+ x-amzn-trace-id:
52
+ - Root=1-667d3d6d-bbbfce79698eea6b630f7dbe;Parent=316f2a5810eaac9b;Sampled=0;lineage=e7c0e2ee:0
53
+ x-frame-options:
54
+ - SAMEORIGIN
55
+ x-xss-protection:
56
+ - 1; mode=block
57
+ status:
58
+ code: 200
59
+ message: OK
60
+ version: 1
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_primary_dealer_fails_fetcher_urllib3_v1.yaml ADDED
The diff for this file is too large to render. See raw diff
 
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_primary_dealer_fails_fetcher_urllib3_v2.yaml ADDED
The diff for this file is too large to render. See raw diff
 
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_primary_dealer_positioning_fetcher_urllib3_v1.yaml ADDED
@@ -0,0 +1,332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ interactions:
2
+ - request:
3
+ body: null
4
+ headers:
5
+ Accept:
6
+ - application/json
7
+ Accept-Encoding:
8
+ - gzip, deflate
9
+ Connection:
10
+ - keep-alive
11
+ method: GET
12
+ uri: https://markets.newyorkfed.org/api/pd/get/PDPOSMBSFGS-C.json
13
+ response:
14
+ body:
15
+ string: !!binary |
16
+ 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
125
+ headers:
126
+ Access-Control-Allow-Headers:
127
+ - Content-Type,Content-Disposition
128
+ Access-Control-Allow-Methods:
129
+ - OPTIONS,GET
130
+ Access-Control-Allow-Origin:
131
+ - '*'
132
+ Access-Control-Expose-Headers:
133
+ - Content-Disposition
134
+ Cache-Control:
135
+ - no-store
136
+ Connection:
137
+ - keep-alive
138
+ Content-Encoding:
139
+ - gzip
140
+ Content-Length:
141
+ - '6198'
142
+ Content-Type:
143
+ - application/json; charset=utf-8
144
+ Date:
145
+ - Mon, 08 Jul 2024 18:11:23 GMT
146
+ Pragma:
147
+ - no-cache
148
+ Set-Cookie:
149
+ - ak_bmsc=0B65662A9954DFA743EEB73F011D118F~000000000000000000000000000000~YAAQ0ZUeuCg54JCQAQAAshKLkxhGjDMoJmwYISW851j4waSXYIebQT++w978bp5zg4H1iFu2jap0KCWK3+ammrivZxnn33J/BO/dQwS3Nuri6ljgAmXhNJcW2znKo8smy443fHh7Dq16wkHiSo0Q42QwDXT7XbSwe7VwLfFcP7Vtl4j3CkKyQc4yinimxskfGORGGWWcux/FVqXOIjRRophoBs2bN+mCITM+WaUb8ARtYaqG80aFhUxwgY1UN/jPyUnTZAFFeht272UuHx4VP9Zo/zEQf/KYt9Rjvg6aGC5lI3qBUhZQ1um0WfeKS3krQCFRylz6wF9mtE0AUHaGyf9IJol4ShRSO3Z2WfvjSqk357t1TCNr+WKcNHrQ6FEhCxrNU9uEV4MRgEUDhqGR+jbUNTrfQYwg4XI=;
150
+ Domain=.newyorkfed.org; Path=/; Expires=Mon, 08 Jul 2024 20:11:23 GMT; Max-Age=7200
151
+ Vary:
152
+ - Accept-Encoding
153
+ strict-transport-security:
154
+ - max-age=31536000; includeSubDomains
155
+ x-amz-apigw-id:
156
+ - amkp9FBDCYcFt5g=
157
+ x-amzn-requestid:
158
+ - 4a2dbdb4-e23d-4e94-bbcf-916957a7902b
159
+ x-amzn-trace-id:
160
+ - Root=1-668c1b0c-de48952568b0d573f4edc0ce;Parent=294993a21cb67610;Sampled=0;lineage=e7c0e2ee:0
161
+ x-frame-options:
162
+ - SAMEORIGIN
163
+ x-xss-protection:
164
+ - 1; mode=block
165
+ status:
166
+ code: 200
167
+ message: OK
168
+ - request:
169
+ body: null
170
+ headers:
171
+ Accept:
172
+ - application/json
173
+ Accept-Encoding:
174
+ - gzip, deflate
175
+ Connection:
176
+ - keep-alive
177
+ method: GET
178
+ uri: https://markets.newyorkfed.org/api/pd/get/PDPOSMBSNA-O.json
179
+ response:
180
+ body:
181
+ string: !!binary |
182
+ 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
289
+ headers:
290
+ Access-Control-Allow-Headers:
291
+ - Content-Type,Content-Disposition
292
+ Access-Control-Allow-Methods:
293
+ - OPTIONS,GET
294
+ Access-Control-Allow-Origin:
295
+ - '*'
296
+ Access-Control-Expose-Headers:
297
+ - Content-Disposition
298
+ Cache-Control:
299
+ - no-store
300
+ Connection:
301
+ - keep-alive
302
+ Content-Encoding:
303
+ - gzip
304
+ Content-Length:
305
+ - '6073'
306
+ Content-Type:
307
+ - application/json; charset=utf-8
308
+ Date:
309
+ - Mon, 08 Jul 2024 18:11:23 GMT
310
+ Pragma:
311
+ - no-cache
312
+ Set-Cookie:
313
+ - ak_bmsc=D00965083550F1E90FB1207197FEBD4B~000000000000000000000000000000~YAAQ0ZUeuCo54JCQAQAAwBKLkxilxtmYV+I3KvT4zBHiAvl38pmDVoszKQEum3Faxkf9XXxtv69xS3HKUypFYAgGYZMXD8Ob6Lob0wXZ/YFVgePdwc38PSKHAnfHrYf02RO1s8pRgBAvN9kjIT+PdKc2HJInS0/UMXqCJ2JX3fLlSN7NePJBFRWrQKfGWV0xyQMJx/ox640WUja5kSUsgsMjYEhjTolmRoKOVOk2bYFEwG3lGYCQM1fcrKNFMtTZ2Wpyw811hvt/6nVAEOSCl5JHGLCSwwbtxlE6oMehD0gTgsZJNs13VoSt6/md4NvqPFadYccsxdR5NWEt26wMPpGIg02Sjr+Q6OIW4HcRDDZv+PdA0axglt0tU8ZhPsvAz4+R/JJVOaNK4RjWrUHffV3QuAwrHB7Yc4U=;
314
+ Domain=.newyorkfed.org; Path=/; Expires=Mon, 08 Jul 2024 20:11:23 GMT; Max-Age=7200
315
+ Vary:
316
+ - Accept-Encoding
317
+ strict-transport-security:
318
+ - max-age=31536000; includeSubDomains
319
+ x-amz-apigw-id:
320
+ - amkp-FS6CYcFaEg=
321
+ x-amzn-requestid:
322
+ - c6d1cded-25f6-4f12-a453-97f1d0c6586f
323
+ x-amzn-trace-id:
324
+ - Root=1-668c1b0c-a8849b395e07d52704e58320;Parent=668155561a1cf466;Sampled=0;lineage=e7c0e2ee:0
325
+ x-frame-options:
326
+ - SAMEORIGIN
327
+ x-xss-protection:
328
+ - 1; mode=block
329
+ status:
330
+ code: 200
331
+ message: OK
332
+ version: 1
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_primary_dealer_positioning_fetcher_urllib3_v2.yaml ADDED
@@ -0,0 +1,326 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ interactions:
2
+ - request:
3
+ body: null
4
+ headers:
5
+ Accept:
6
+ - application/json
7
+ Accept-Encoding:
8
+ - gzip, deflate
9
+ Connection:
10
+ - keep-alive
11
+ method: GET
12
+ uri: https://markets.newyorkfed.org/api/pd/get/PDPOSMBSNA-O.json
13
+ response:
14
+ body:
15
+ string: !!binary |
16
+ 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
123
+ headers:
124
+ Access-Control-Allow-Headers:
125
+ - Content-Type,Content-Disposition
126
+ Access-Control-Allow-Methods:
127
+ - OPTIONS,GET
128
+ Access-Control-Allow-Origin:
129
+ - '*'
130
+ Access-Control-Expose-Headers:
131
+ - Content-Disposition
132
+ Cache-Control:
133
+ - no-store
134
+ Connection:
135
+ - keep-alive
136
+ Content-Encoding:
137
+ - gzip
138
+ Content-Length:
139
+ - '6073'
140
+ Content-Type:
141
+ - application/json; charset=utf-8
142
+ Date:
143
+ - Mon, 08 Jul 2024 18:03:04 GMT
144
+ Pragma:
145
+ - no-cache
146
+ Vary:
147
+ - Accept-Encoding
148
+ strict-transport-security:
149
+ - max-age=31536000; includeSubDomains
150
+ x-amz-apigw-id:
151
+ - amkp-FS6CYcFaEg=
152
+ x-amzn-requestid:
153
+ - c6d1cded-25f6-4f12-a453-97f1d0c6586f
154
+ x-amzn-trace-id:
155
+ - Root=1-668c1b0c-a8849b395e07d52704e58320;Parent=668155561a1cf466;Sampled=0;lineage=e7c0e2ee:0
156
+ x-frame-options:
157
+ - SAMEORIGIN
158
+ x-xss-protection:
159
+ - 1; mode=block
160
+ status:
161
+ code: 200
162
+ message: OK
163
+ - request:
164
+ body: null
165
+ headers:
166
+ Accept:
167
+ - application/json
168
+ Accept-Encoding:
169
+ - gzip, deflate
170
+ Connection:
171
+ - keep-alive
172
+ method: GET
173
+ uri: https://markets.newyorkfed.org/api/pd/get/PDPOSMBSFGS-C.json
174
+ response:
175
+ body:
176
+ string: !!binary |
177
+ H4sIAAAAAAAEA6pWKkhRslKoVlAqycxNLU4tykwtVrJSiAaJJBbnp6UklqQqWSkoGRkYGusamOga
178
+ GCvpKChlp1ZmgrQpBbgE+Af7OgW7uQfrOoNkyhJzSsEaLA1NjZQUahV0cJlkaABST4xJZmam+E0y
179
+ J9YkQyNDvCYZmRBrkpGJBR6TTHUNDIk0ycLCyBK/SRbEmmRpaYLXJENTIk2yNLLA7zsjI6JNMjDH
180
+ 6yYjS2JNMjHAl57MdA2I9p2hOT7fmekaEu07A0t8cWema0i07wwNzPCEk5mukRmx4WRogs8kc+Jz
181
+ sIWZkTEeN5nrEp2DLUwNDfCbRGwOtjAxwBfi5rpE52ALU1N8ucVc15joHGxqgi9lWugaEO87C/wm
182
+ GRJbPlmYGuM3yYho3xnhzS0WukZEl08GxvjSk6WuAbG+Mzc3x5fGLXUNifadgQW+lGmpa0i074xN
183
+ 8ZV0lrpGxJZPFiaWeNxkaKBrQGz5ZGFojieNg0witnyyMDDCU2YaGugaEls+WRha4HeTEbEtDAsD
184
+ Mzwhbmiga0xsC8PC0BBPu8DQUNeAWN+ZW+INcUNdQ2J9Z25ugSeNGxrqGhHtOwNDPO0nkElEl09G
185
+ hvjizoj4HGxhbI7PTUYk5GAzM3xxZ0RCDrYwxu8m4nOwOe4cbKJrYEhC69Acd0sMYhLR5ZOZCc6a
186
+ E2wS0a1DCxMDnOUT2CSiW4cWJuY44w5iEtHlkwnussBE18CI+NahhTHuOhhsEtGtQ3NzY5zlE8Qk
187
+ Yn1nbm6JL5yMiG8dmhtZ4KyDQZ074sPJ3NgIZwsDbBLx4WRkgt9NRLeizQ3xhrgxCeFkijcHg6KP
188
+ yPa4uYkZzprTBNyjJjoVmBjiS08mxNfBZpbG+NKTiS7RdbCZpQHOMhPsO6LrYHMD3O0nE10DU+Jb
189
+ 0eYGZvhKOlNdolvRZia4a06wm4huRZuZGeN3E9GtaHMDU3whbkZ8HWyGv0YwI74ONjMxwZcyzYiv
190
+ g81MjHC2MEx0Dcx0ia6DzUzxxp058a1oMzNLfCFurmtAbA42M8fdNzfRNTDXJboVbWZijC+czEnI
191
+ wfjrFnPiW9FmlrjHC0x0DSyIb0WbWeLuI4BNIr4VbWCJr/S1IL4VbW6At76z0DUithVtZoF7ZNRE
192
+ 18CS+BEaMzMLfPnOkvgRGjMD3L18sJsMifWduSHucTqwSUSP0JhZ4mvTgXqvhkTWwWYW+GopkEnE
193
+ tqLNLA3xtFVA/WBie/lmeEbXTHQNDXSJbkWbG+Ae1YaYRHT5ZGaBp10A6gcT7TsTM3zhZEj8GKuZ
194
+ Ce4RZBNdQ0Pix1jNjHCPtINNInqM1czEFF84GZGQg43x1eaGRiTkYEN8LXuQScTmYDMTczwte0Mj
195
+ 4sdYzQxM8NRShkbEj7GaGZjj7HOCJluIbx2aGZjjbImBTSK+dYhn9B9sEtGtQ3Mj3GUmxCRiyydz
196
+ Q1N84UTCCI2ZJe5ZN1NQj5roMVYzUyOc7SeIScT6zswEd8sebBLxrUNzc5zlk6muAWiqk8i6hUCI
197
+ GxPfijY3tMAXTsbEt6ItjM3wpQJj4lvRFoa425mm4N4rsXWwhTHuMhNiErGpwMIM99wr2CTiR7IM
198
+ cLfEwCYRXQdb4M93JrpEz3OaWxjhiztT4lvR5iZGOEeQTUE9auJb0ea4x8TAJhE9Fm1uYYSzxQox
199
+ idhaysIA9/g4KJCIr4PNLXH3NsAmET3PSSDuzHSJb0VbmOArC8yIr4MtjHGPP4EGVUgYi7bA3R6H
200
+ mER0DrbA3cIAm0R8DjYzxVeOmxPfirYwNcHZpgO7iegcbGGCuxVtCu4HE9uKtjAxwdkSA5tE9Bir
201
+ hSXe0teC+Fa0pQHuHhDYTUS3oi0NzfGVBZbEj9BYWhjjKzMtiR+hsTTBm54siR+hsTDHPd9iCurl
202
+ Ez3GamGBt3VoSfwIjTnefAfqBxNb+pqb4kvjoH6wCbHtJyMLPO1xUD+Y2BaGuYEZntwCMsmCSDeZ
203
+ meBe12MK6nMSvVLBzAz3/B3YJOJb0XjbdKB+MPG+w1cWgOaDiS2fzIyMcY6umeoaGhGfg82M8aVx
204
+ kElEj2GYGONp9YD6wcTO5ZuZmuL3HdE52MwY9xw1OJyIniUxM8bdlzIDzywT7Tsj3OEENono1qGZ
205
+ Me6RdrBJRLcOzYxw91sgJhFbPpkZ426rmIF6r0SvYzUzxt0DAptEdOvQzBj3/B3EJGJ9Z2qEe/UE
206
+ 2CSix1hNTXG3xMzA/WBi1xqZGuEuVSAmEZuDTQ1wry8Am0T0LImJOe5aCmwS0TnYxBx3LQU2iegc
207
+ bGKJe4YLNHlHfP/OFM88J9gkonOwqQHu1V1gk4jOwSbmZjhLX4hJxKZxEyPcM/BmoN4r0XWwsTnu
208
+ vhTYJKLrYBM8ayEhJhFbB5sY4e5zgk0ieiTLBE8v3ww0Y0r0SnRTPCOjEJOI9Z0pnlW6YJOI7t+Z
209
+ GhvibNOBTSJ6hMbUFPfaNYhJlkS2Dk2Ncc8Hm+kamJOQg/GsNQKbRHwONjTFl+/MiZ/nNDXE3QMC
210
+ u8mI2BxsaoC7V2YG7gcTuxbSxBJvu8CC+FkSE1NLnOMFYDcRPUJjYmGIL8QtiB+hMTHGW2ZaED9L
211
+ YmKGe/2TGajPSfRKdBNTvG6yJH4NjYkZ7jUPYDcRPUtiYo57jwTEJGLLJxMLfG0VUD+Y2B6QiTkB
212
+ k4geoTExwj1zYwaaDyZ6FZwxnrEesElEj9CYWOBrsYLmg4ltHZpYWOLJLSCTiC19Tcxxz3abgfrm
213
+ JLQO8ZVPoH4w0eWTBe71dGA3Ed86xO87I+LnOU0NDXD2Xs1AfXOi5zlNDQxwjoyCTSI+B1vgXq8C
214
+ MYnYHGyKZ8bUHNwPJnb8ycwId48abBLRrUMzQ9wtDIhJRPvOEvcYK9gkoluHpua419aag/vBxI6u
215
+ mVrgnkeAmES070xwj4aATSK6dWhigXuVCdgkoluHJqa4dxSZg/vBxIaTiQnuUW2IScSGkwmedRhg
216
+ k4gPJxPc83dgk4gPJzzjTxCTLIltReOZvzMHzywTXQdb4l4bAjaJ6DrY1NAS54wExCSifWeMe/8d
217
+ 2CSi62BTPPtezcH9YGJrKVML3GuQwSYRPZJlYoJ7vxTEJGL7CCbmuNeMgk0ifiTLwAhf3JkS34o2
218
+ NcA9agTq3JFQBxvjHh8Hm0R8HYxn/AlsEtF1sKk53rrFjPj9nGaGljj75ua6oH4wsTnYzAB3nxNs
219
+ EvE52AL3jiKISUTnYBMCviMhB+PuI5iD+8HEtqJNTXDvoIWYRLzvcK/3BZtEdCva1AhvfWdB/Ep0
220
+ Am0VC+LnOU3x9BTNwf1gomdJDHDvXAebRPwIjSXu1V1gk4geYzU1wj23ATGJ2NLX1AL33IY5qM9J
221
+ 9BirqQHu1adgk4huRZtY4muPg2aWiW4/meMrC0DzwcSWT6YGuPffmYP6nMSPsRriXrUEMYlY35ma
222
+ m+Bc8wA2iejWoZEx7rFosElEtw6NzHCvz4SYRGz5ZIRnL645qPdK9I5sYzyj2mCTiM7Bxsa419OB
223
+ TSI6Bxub4d4vBTGJ2BxsbI57TbsFuB9MbOvQ2Bx37xVsEtGtQ2MT3GcqQEwi1ndGZrhLX7BJRLcO
224
+ jY1wt8fBJhF92oexCe4VHRbgHjXRvsPTRwCbRHTr0NgMr++MdIluHRqb4S4LwG4iep+isQnukXYL
225
+ cI+a2HAytsQ9kgU2iehwMjHAvbYWbBLR4WRigrvfAjGJ2HLcxBh3X8oC3A8mdiTLBE85DjaJ+DrY
226
+ APd4JsQkon1ngHvMHmwS0SNZJnhWBViA+8HEtqJN8LTpICYRW0sZW+KedQObRHQr2sQA95gY2CTi
227
+ VyoY4j7XCGwS8WPR+FMmaNKUyLEeExPcJ2tYgOaoia6DTczw+s6M+HlOwiYRWz6ZmOI+k8oC3A8m
228
+ PgfjHi8Am0R8DjbBfRYcxCSic7Ap7jlFsEnE52A85xpZgPvBRI+xmuKel4KYRLzvcO8uBJtEdCva
229
+ xAT3uh6wSUS3ok3wrByGmERs+WSCPxVYEn/ah4kJ7vk7C1CPmugRGhMjvOnJkviV6Cb4aylLXaJH
230
+ aEzMca+ztwD3g4ltRZsY4x4NAZtEdCvaxBD3+nGISUSXTyYETCK6FW1igXseAewmolvRJpa41x1a
231
+ gHvURPsObx1saEj8SgVTPPuDwW4iunVoimelJ8QkYssnUyN8LQxDEs41MjXCfTKZBahHTXQONjXE
232
+ vfoUYhKx5ZOpCe6xHrBJROdgUzxnMFqC+8FEtw7xnLsGMYlY35lY4p5NAptEfOvQEne+A5tEfOvQ
233
+ Evf4E9gk4luH5rj3SFiC+8HEjrGaGuBuP4FNIr51aGmIcy8J2CQjYs/MM7HEPVcGMYno8skc99pa
234
+ S3A/mNhwMjHBPZ4JNon4cDLFm56MSWhFG+NeFw12E9GrBU2McY+PW4L7wcTWwcZ4TlQGm0R0HWxs
235
+ gXsmEGIS0anAAPdsEtgkoutgUzwntYAadLpEj0WbGOJe0QExidhayhjPehWwSUS3oo0tcY9qg00i
236
+ uhVtbIG7LwUxiehy3BD3SJYlqPdK9MnTJga4V5mATSK6DjYxwz1CAzGJaN9Z4F53CDaJ6DrYxBz3
237
+ ejpLcD+Y2BxsYoj73BCwScTnYEvcI+0Qk4jNwcbmuFusYJOIzsEmhrhHQ8AmEd2KNrbAPSNhqWsA
238
+ 6p4TO0JjgLetYkF8K9rEEG8qsCB+LNrEEG8aJ+HkaXx7JCxBvVei5zlNjHCPIINNInqExtgSb6uH
239
+ hJOnjS3w5hYSTp42tsS9s8ES3A8muhVtaIBznT3EJKLLJzzjvmCTiG5FG1vgXokONonoVrSxBe6d
240
+ oWCTiG5FG1sY4DwhyRLcDya2dWhshrunCDaJ6NahsSXukxDAJhHfijbCPQoJMYnY0tfEFF/bF9QP
241
+ NiG2pDPHvaPIEtwPJnoU0gL3CUkQk4htP5mY4u6bg00ieozV1BhnO9PIANwPJtZ3psY4Z92gJhHr
242
+ O1NDnLOTEJOIbh2aGuJciQ4xyYjo8gn3qZdQk4gun0xx9u9AJpEwQmNiiXNUG2IS8a1Dc5x1C9Qk
243
+ on2He1UAxCSiW4d4dhGATCLhxC1TU5wlHcQkoutgU3OcpS/UJGLTuBnuMQyIScTnYAucM/Agk0yI
244
+ 79+ZGuHsS0FNItZ3phY4d2RDTCI+B5vhXKsNMYnoHGxmhHNmGWoSsWnczABnexxkkikJ+zlx7y6E
245
+ mER0HWyKe70KxCSi62BTS5x7JKAmEVsHmxngnOECmWRG/IlbprjPgoOYRHT/ztQY5wohqEnE+s7U
246
+ HOfaNYhJRPfvzHCvMgGZZE5CDjbBWxaY6xoQnYNxj9NB3ER8DsZ92gfEJKJzsCnu8XGoScTmYBMz
247
+ nH1zkEkWxM9zGuPeBwQxieg62NjcENf+O6hJRPvOAucsCcQkoutgPDPLIJNAA9vEtqKNce7kg5pE
248
+ tO9MjHDtIoCYRHT/zsQI5/lPEJOI7t+ZmuM80QZiEtH9O1PcK1+MDMA9amLLJxNjfLW5oQEJIzSm
249
+ OE+9hLiJ6HlOE1MCbiJ6taCZAc7+HchNhsTfamCK+zwxiEnEtw4NcI6MQk0iuvQ1wBtOhroktA5x
250
+ rlQAuYmEE7dMDXCuw4CaRGwONjXCuSsFYhLROdjUDOeoEcQkonOwGe41oxCTiM7BZiY4V3QYGYJ7
251
+ 1MSO0JhY4NxzAzGJ6NahsQXO8zAgJhHdOjS2xLnqG2oS0eWTOc75FpBJJJyJbmSOu5dvCJpZJrp1
252
+ aGKAc04R4iaiT/swNsO5TgxiEtGtQ2MTnOcXgEwyJr4VjWdFLMQk4sPJEG/cGRN/bq2JMc795hA3
253
+ ER1OJma4Wz2GoHlz4mdJTHH3OUEVC/H7OU0McJ6KAvKdCfF1sLEZ3pRpQvwsibElzjlqiJuIroNN
254
+ DHD3NgzBK6yJ3S9lYojzLieQm0x1iW9F4xldA7uJ+FNRcI/WQtxEfCvaBOfZ8SCTzIg/9dLEyAjX
255
+ nmWoScTWwSbmOHcRQEwiug42wX1WJcQkoutgU0Oce5MgJhFdB5sa49wfDDLJnIQcjL9UMSc+B5sY
256
+ 4dwTCHET8a1oM5yrcaAmEdvOxLMvH2SSBfGtaBNDnHtMISYR3Yo2NsObWyx0DYn2nQHOPaYQNxHd
257
+ ijbBfUYsyCRL4kdoTEzw1pygSXhie9R45jYMQXPURI/QmBjg7puDTSJ6hMbEFG+NYKlL9JnoJia4
258
+ +5yG4H4w0a1oI5z3txiBTSK6FW1qgLuXDzaJ6Fa0Ke6z4yFuInoVnKkBzv0tIJNADR9i05Ml7rkN
259
+ Q9DMMvGtQwvc474Qk4juI1jgKwsMDYk/M8/UFOfaNVA4GRGfg00t8dWcoJllCyJD3NQUX7/F0EiX
260
+ 6Bxsjvs8VojviM7B5sY4bz6DmkRsC8PcCOe5IUag4CZ+jNUcT68MbBLRrUMzY5xnxELcRHTrEM95
261
+ 0RCTiG4dmuM+sRRkEgkjNGaWOO8uhJpEbNyZWeA86xtiEtGtQzMjnCsYISYR3To0M8fdKwMNFugS
262
+ fcu9uSFeNxkTf/uDmRnOFR0g3xkTf/uDmRHuugXsO6LDydwA5zmjEDcR3Yo2N8K5ng5kkgnx85wE
263
+ 0rgJCbfcW+Ju2RvpGpgQvxLdwgT3KhOIScTWUhZmuHv5RuB+sAmRNYIl7nWsoBA3Jf5uMAtL3OO+
264
+ YDcR3Yo2NDDAuUkC4iiim9GGhoa455aNwCujiV1tZGhgjLvhAzGK2GrY0ADP/CvYKKLrYUsTvGWU
265
+ GfG3C1nimVECu4nolrShAe5tj6D4Myc+Gxsa4JkJMtI1MCc+HxsaGOMeSAYbRXRj2tAA91nWEA8S
266
+ 3Zo2NLDEPeRuBF4gTeySdEMDc5w3dYJcZUH8GdSGBmZGOId9wK4ielja0AD33UAQVxE93mpoYIJ7
267
+ QgjsKqIHXA0NjHCvHTQC9WWJPofa0AD3gmuQBy2JH7AxNMDT0ge7iugRG0MD3FcQQlxF9KArgTxI
268
+ ylnUIFfhSVegKWJil0caGuBZL2IE6q8T3bI2NDDCV4gaGhC/TdvQwBz3/KARqE9LdJvR0MAU94QO
269
+ xChiG9eGBnjWt4KNIrp1bWhggnNhuRHYKKKbjYYGuHfsQ4wiut1oaIB7ezzIKFDxTmSDyNAA96n5
270
+ EKOIPsvH0NAUX8PYkIRDjwwNzXDeEAJxFfHZ2dAM9wJsY/B0MbGNR0NDPHPYYKOIHoM1NMS9ycsI
271
+ YhTRrSsjQ5w7YCBGEd98NDLEudEAZBRoLIDYdGVkgHskwBg0Z0z0SjlDQ0vcw6dgo4huPhoa4j4n
272
+ F+JBosdxDA2NcG63BhkFikRiw8oQTykKmn7WJT6sjPAsUwUbRXxYGVngHtcFG0V8WBlZ4F6yATGK
273
+ 6LLdyAL3uiRjUP+U6L2fhsYGZri2+oBi0IT4SVFDIxPcDUiwq4ivnY0McA9/go0ieuDL0MgQ58l4
274
+ IA+aEr+ywdDIEHdb1BjUBSd68BpU9OELdlNd4hvbhqZ4k6gp8cPXhoamuEfCwR4kvrFtaIJz8xAo
275
+ 2M2Inxw1NMQz92sM6s8TXzsbWOBeAgA2ivjGtqER3jxIwonVhoa4L5AHhZU58YPYhobGOE9EghhF
276
+ 9Ci2oaEhzm1yUKOILq8MjXGPExnrGpiT0Ng2NMC57R3kKgviB2gNDfCMoxiDu+FEe9DABPciX7BR
277
+ JDS28axkBxtFQmPbEPfAMdgoEhrbhrg7JqChbOKHdywtcM/9gE0ieqYU1GzHuUgbbBTxozuGeGbx
278
+ IUYRO05raIB7+7uRMaiTSvS2btCQDK79yhCjiG9rG5jiHvwAu4qEoVoj3Pv4wEYR3da2tMQ9A2QM
279
+ 7jkTP1KL+zgxUFAZktB8NDDGvfYf7Crim48GuA/WhriK6OajpQXuJYxgRxE9VGtpji8rg6aWiV30
280
+ YGhggHuHizF41zLxA5l4phXBRpGQl3Hf1wsKdCNd4kdqDU1wt45NwP1moj1oaIq7hwo2ioTGoyHu
281
+ zb0Qo4gurAwNce/uBRtF/EitoRHuYTCwUSQ0Hs1xF1Ym4H4zCR7EeQyFEdgoEhqPeFbHgo0ivvFo
282
+ YIY7N0OMInrkw9AI58kmIA+CWrVEd8ENcWdnE10DYxImXgxNce+ABBtFQnY2w71gE2IU0YkB39CO
283
+ CbjfTHx2tsTdmwcbRXx2NjLAvVoPYhTxHsQzswQ2ivjsbGyCe6WWCaiza0B03WxsgfNYclASNSWh
284
+ bjY2xXlqKMQo4utmYxPcw6tgDxJdNxsam+ItkE11ia6cDY3NTXBu0DQBdXaJH9oxMcO9AwpsFPF9
285
+ QRMj3L0uiFFEd5VMDHCviAAbRfzQjrEpZJQIsFiFWoVaAIhQu2IzqgAA
286
+ headers:
287
+ Access-Control-Allow-Headers:
288
+ - Content-Type,Content-Disposition
289
+ Access-Control-Allow-Methods:
290
+ - OPTIONS,GET
291
+ Access-Control-Allow-Origin:
292
+ - '*'
293
+ Access-Control-Expose-Headers:
294
+ - Content-Disposition
295
+ Cache-Control:
296
+ - no-store
297
+ Connection:
298
+ - keep-alive
299
+ Content-Encoding:
300
+ - gzip
301
+ Content-Length:
302
+ - '6198'
303
+ Content-Type:
304
+ - application/json; charset=utf-8
305
+ Date:
306
+ - Mon, 08 Jul 2024 18:03:04 GMT
307
+ Pragma:
308
+ - no-cache
309
+ Vary:
310
+ - Accept-Encoding
311
+ strict-transport-security:
312
+ - max-age=31536000; includeSubDomains
313
+ x-amz-apigw-id:
314
+ - amkp9FBDCYcFt5g=
315
+ x-amzn-requestid:
316
+ - 4a2dbdb4-e23d-4e94-bbcf-916957a7902b
317
+ x-amzn-trace-id:
318
+ - Root=1-668c1b0c-de48952568b0d573f4edc0ce;Parent=294993a21cb67610;Sampled=0;lineage=e7c0e2ee:0
319
+ x-frame-options:
320
+ - SAMEORIGIN
321
+ x-xss-protection:
322
+ - 1; mode=block
323
+ status:
324
+ code: 200
325
+ message: OK
326
+ version: 1
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_sofr_fetcher_urllib3_v1.yaml ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ interactions:
2
+ - request:
3
+ body: null
4
+ headers:
5
+ Accept:
6
+ - application/json
7
+ Accept-Encoding:
8
+ - gzip, deflate
9
+ Connection:
10
+ - keep-alive
11
+ method: GET
12
+ uri: https://markets.newyorkfed.org/api/rates/secured/sofr/search.json?startDate=2024-06-01&endDate=2024-06-06
13
+ response:
14
+ body:
15
+ string: !!binary |
16
+ H4sIAAAAAAAEA6pWUCpKTQtKLEktVrJSiFaoVlBKTUtLTS7JLEt1SSxJVbJSUDIyMDLRNTDTNTBT
17
+ 0lFQKqksAIsG+7sFKSnoKBWkFiWn5pWAjFCyUjDVMzZGCAZA5DJzUg3BckaW2OSMTMGSxkbYJM0h
18
+ kiYG2CQtLcE6TUwUdJTK8nNKc1M985wyc3Iy8/NA3jEyMLBQ0FEqSi3LLM7Mz/PMS8lMTizJLwJ5
19
+ SkmhVge/b00p9a0xVjcT41tjrOEE8y0ogLH41tDSAqSNTN+aUOpbusetJSi9kOlbY6J8a4otzQ1I
20
+ Sja0NMTnW8AUYhVqAQ8xhrzKAwAA
21
+ headers:
22
+ Access-Control-Allow-Headers:
23
+ - Content-Type,Content-Disposition
24
+ Access-Control-Allow-Methods:
25
+ - OPTIONS,GET
26
+ Access-Control-Allow-Origin:
27
+ - '*'
28
+ Access-Control-Expose-Headers:
29
+ - Content-Disposition
30
+ Cache-Control:
31
+ - no-store
32
+ Connection:
33
+ - keep-alive
34
+ Content-Encoding:
35
+ - gzip
36
+ Content-Length:
37
+ - '249'
38
+ Content-Type:
39
+ - application/json; charset=utf-8
40
+ Date:
41
+ - Sat, 08 Jun 2024 05:59:35 GMT
42
+ Pragma:
43
+ - no-cache
44
+ Set-Cookie:
45
+ - cookiesession1=678A3E0EBA19E6E38D9D5186C73F260F;Expires=Sun, 08 Jun 2025 05:59:35
46
+ GMT;Path=/;Secure;HttpOnly
47
+ Vary:
48
+ - Accept-Encoding
49
+ strict-transport-security:
50
+ - max-age=31536000; includeSubDomains
51
+ x-amz-apigw-id:
52
+ - ZCLzNFtZiYcFmHQ=
53
+ x-amzn-requestid:
54
+ - 67713ca6-2c16-438f-a2a5-fd48b4fb02a1
55
+ x-amzn-trace-id:
56
+ - Root=1-6663f347-775ee28c7594e08357ca5722;Parent=7fe874cce0755572;Sampled=0;lineage=e7c0e2ee:0
57
+ x-frame-options:
58
+ - SAMEORIGIN
59
+ x-xss-protection:
60
+ - 1; mode=block
61
+ status:
62
+ code: 200
63
+ message: OK
64
+ version: 1
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_sofr_fetcher_urllib3_v2.yaml ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ interactions:
2
+ - request:
3
+ body: null
4
+ headers:
5
+ Accept:
6
+ - application/json
7
+ Accept-Encoding:
8
+ - gzip, deflate
9
+ Connection:
10
+ - keep-alive
11
+ method: GET
12
+ uri: https://markets.newyorkfed.org/api/rates/secured/sofr/search.json?startDate=2024-06-01&endDate=2024-06-06
13
+ response:
14
+ body:
15
+ string: !!binary |
16
+ H4sIAAAAAAAEA6pWUCpKTQtKLEktVrJSiFaoVlBKTUtLTS7JLEt1SSxJVbJSUDIyMDLRNTDTNTBT
17
+ 0lFQKqksAIsG+7sFKSnoKBWkFiWn5pWAjFCyUjDVMzZGCAZA5DJzUg3BckaW2OSMTMGSxkbYJM0h
18
+ kiYG2CQtLcE6TUwUdJTK8nNKc1M985wyc3Iy8/NA3jEyMLBQ0FEqSi3LLM7Mz/PMS8lMTizJLwJ5
19
+ SkmhVge/b00p9a0xVjcT41tjrOEE8y0ogLH41tDSAqSNTN+aUOpbusetJSi9kOlbY6J8a4otzQ1I
20
+ Sja0NMTnW8AUYhVqAQ8xhrzKAwAA
21
+ headers:
22
+ Access-Control-Allow-Headers:
23
+ - Content-Type,Content-Disposition
24
+ Access-Control-Allow-Methods:
25
+ - OPTIONS,GET
26
+ Access-Control-Allow-Origin:
27
+ - '*'
28
+ Access-Control-Expose-Headers:
29
+ - Content-Disposition
30
+ Cache-Control:
31
+ - no-store
32
+ Connection:
33
+ - keep-alive
34
+ Content-Encoding:
35
+ - gzip
36
+ Content-Length:
37
+ - '249'
38
+ Content-Type:
39
+ - application/json; charset=utf-8
40
+ Date:
41
+ - Thu, 27 Jun 2024 10:22:36 GMT
42
+ Pragma:
43
+ - no-cache
44
+ Vary:
45
+ - Accept-Encoding
46
+ strict-transport-security:
47
+ - max-age=31536000; includeSubDomains
48
+ x-amz-apigw-id:
49
+ - aBaJCEsPiYcFdlQ=
50
+ x-amzn-requestid:
51
+ - 79bfb88b-47c7-4921-a8c4-f1bb33fd1e41
52
+ x-amzn-trace-id:
53
+ - Root=1-667d3d6c-1dc4236a875e19392ac99ad5;Parent=7e8d1f0f7d2a5a62;Sampled=0;lineage=e7c0e2ee:0
54
+ x-frame-options:
55
+ - SAMEORIGIN
56
+ x-xss-protection:
57
+ - 1; mode=block
58
+ status:
59
+ code: 200
60
+ message: OK
61
+ version: 1
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_treasury_rates_fetcher_urllib3_v1.yaml ADDED
The diff for this file is too large to render. See raw diff
 
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_treasury_rates_fetcher_urllib3_v2.yaml ADDED
The diff for this file is too large to render. See raw diff
 
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_yield_curve_fetcher_urllib3_v1.yaml ADDED
The diff for this file is too large to render. See raw diff
 
openbb_platform/providers/federal_reserve/tests/record/http/test_federal_reserve_fetchers/test_federal_reserve_yield_curve_fetcher_urllib3_v2.yaml ADDED
The diff for this file is too large to render. See raw diff
 
openbb_platform/providers/federal_reserve/tests/test_federal_reserve_fetchers.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Tests for the Federal Reserve fetchers."""
2
+
3
+ from datetime import date
4
+
5
+ import pytest
6
+ from openbb_core.app.service.user_service import UserService
7
+ from openbb_federal_reserve.models.central_bank_holdings import (
8
+ FederalReserveCentralBankHoldingsFetcher,
9
+ )
10
+ from openbb_federal_reserve.models.federal_funds_rate import (
11
+ FederalReserveFederalFundsRateFetcher,
12
+ )
13
+ from openbb_federal_reserve.models.fomc_documents import (
14
+ FederalReserveFomcDocumentsFetcher,
15
+ )
16
+ from openbb_federal_reserve.models.money_measures import (
17
+ FederalReserveMoneyMeasuresFetcher,
18
+ )
19
+ from openbb_federal_reserve.models.overnight_bank_funding_rate import (
20
+ FederalReserveOvernightBankFundingRateFetcher,
21
+ )
22
+ from openbb_federal_reserve.models.primary_dealer_fails import (
23
+ FederalReservePrimaryDealerFailsFetcher,
24
+ )
25
+ from openbb_federal_reserve.models.primary_dealer_positioning import (
26
+ FederalReservePrimaryDealerPositioningFetcher,
27
+ )
28
+ from openbb_federal_reserve.models.sofr import FederalReserveSOFRFetcher
29
+ from openbb_federal_reserve.models.treasury_rates import (
30
+ FederalReserveTreasuryRatesFetcher,
31
+ )
32
+ from openbb_federal_reserve.models.yield_curve import FederalReserveYieldCurveFetcher
33
+
34
+ test_credentials = UserService().default_user_settings.credentials.model_dump(
35
+ mode="json"
36
+ )
37
+
38
+
39
+ @pytest.fixture(scope="module")
40
+ def vcr_config():
41
+ """VCR config."""
42
+ return {
43
+ "filter_headers": [("User-Agent", None)],
44
+ "filter_query_parameters": [],
45
+ }
46
+
47
+
48
+ @pytest.mark.record_http
49
+ def test_federal_reserve_treasury_rates_fetcher(credentials=test_credentials):
50
+ """Test the Federal Reserve Treasury Rates fetcher."""
51
+ params = {"start_date": date(2023, 1, 1), "end_date": date(2023, 5, 10)}
52
+
53
+ fetcher = FederalReserveTreasuryRatesFetcher()
54
+ result = fetcher.test(params, credentials)
55
+ assert result is None
56
+
57
+
58
+ @pytest.mark.record_http
59
+ def test_federal_reserve_money_measures_fetcher(credentials=test_credentials):
60
+ """Test the Federal Reserve Money Measures fetcher."""
61
+ params = {"start_date": date(2023, 1, 1), "end_date": date(2023, 5, 10)}
62
+
63
+ fetcher = FederalReserveMoneyMeasuresFetcher()
64
+ result = fetcher.test(params, credentials)
65
+ assert result is None
66
+
67
+
68
+ @pytest.mark.record_http
69
+ def test_federal_reserve_federal_funds_rate_fetcher(credentials=test_credentials):
70
+ """Test the Federal Reserve Federal Funds Rate fetcher."""
71
+ params = {"start_date": date(2023, 1, 1), "end_date": date(2023, 6, 6)}
72
+
73
+ fetcher = FederalReserveFederalFundsRateFetcher()
74
+ result = fetcher.test(params, credentials)
75
+ assert result is None
76
+
77
+
78
+ @pytest.mark.record_http
79
+ def test_federal_reserve_yield_curve_fetcher(credentials=test_credentials):
80
+ """Test the Federal Reserve yield curve fetcher."""
81
+ params = {"date": "2024-05-13,2020-05-09"}
82
+
83
+ fetcher = FederalReserveYieldCurveFetcher()
84
+ result = fetcher.test(params, credentials)
85
+ assert result is None
86
+
87
+
88
+ @pytest.mark.record_http
89
+ def test_federal_reserve_central_bank_holdings_fetcher(credentials=test_credentials):
90
+ """Test the Federal Reserve Central Bank Holdings Fetcher."""
91
+ params = {"date": date(2019, 1, 2), "holding_type": "agency_debts"}
92
+
93
+ fetcher = FederalReserveCentralBankHoldingsFetcher()
94
+ result = fetcher.test(params, credentials)
95
+ assert result is None
96
+
97
+
98
+ @pytest.mark.record_http
99
+ def test_federal_reserve_sofr_fetcher(credentials=test_credentials):
100
+ """Test the Federal Reserve SOFR Fetcher."""
101
+ params = {"start_date": date(2024, 6, 1), "end_date": date(2024, 6, 6)}
102
+
103
+ fetcher = FederalReserveSOFRFetcher()
104
+ result = fetcher.test(params, credentials)
105
+ assert result is None
106
+
107
+
108
+ @pytest.mark.record_http
109
+ def test_federal_reserve_overnight_bank_funding_rate_fetcher(
110
+ credentials=test_credentials,
111
+ ):
112
+ """Test the Federal Reserve Overnight Bank Funding Rate Fetcher."""
113
+ params = {"start_date": date(2024, 6, 1), "end_date": date(2024, 6, 6)}
114
+
115
+ fetcher = FederalReserveOvernightBankFundingRateFetcher()
116
+ result = fetcher.test(params, credentials)
117
+ assert result is None
118
+
119
+
120
+ @pytest.mark.record_http
121
+ def test_federal_reserve_primary_dealer_positioning_fetcher(
122
+ credentials=test_credentials,
123
+ ):
124
+ """Test the Federal Reserve Primary Dealer Positioning Fetcher."""
125
+ params = {
126
+ "category": "cmbs",
127
+ "start_date": date(2024, 6, 1),
128
+ "end_date": date(2024, 6, 30),
129
+ }
130
+
131
+ fetcher = FederalReservePrimaryDealerPositioningFetcher()
132
+ result = fetcher.test(params, credentials)
133
+ assert result is None
134
+
135
+
136
+ @pytest.mark.record_http
137
+ def test_federal_reserve_primary_dealer_fails_fetcher(
138
+ credentials=test_credentials,
139
+ ):
140
+ """Test the Federal Reserve Primary Dealer Fails Fetcher."""
141
+ params = {}
142
+
143
+ fetcher = FederalReservePrimaryDealerFailsFetcher()
144
+ result = fetcher.test(params, credentials)
145
+ assert result is None
146
+
147
+
148
+ @pytest.mark.record_http
149
+ def test_federal_reserve_fomc_documents_fetcher(
150
+ credentials=test_credentials,
151
+ ):
152
+ """Test the Federal Reserve FOMC Documents Fetcher."""
153
+ params = {}
154
+
155
+ fetcher = FederalReserveFomcDocumentsFetcher()
156
+ result = fetcher.test(params, credentials)
157
+ assert result is None
openbb_platform/providers/finra/README.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # OpenBB FINRA Provider
2
+
3
+ This extension integrates the [FINRA](https://finra.org/) data provider into the OpenBB Platform.
4
+
5
+ ## Installation
6
+
7
+ To install the extension:
8
+
9
+ ```bash
10
+ pip install openbb-finra
11
+ ```
12
+
13
+ Documentation available [here](https://docs.openbb.co/platform/developer_guide/contributing).
openbb_platform/providers/finra/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ """FINRA provider for OpenBB Platform."""
openbb_platform/providers/finra/openbb_finra/__init__.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FINRA provider module."""
2
+
3
+ from openbb_core.provider.abstract.provider import Provider
4
+ from openbb_finra.models.equity_short_interest import FinraShortInterestFetcher
5
+ from openbb_finra.models.otc_aggregate import FinraOTCAggregateFetcher
6
+
7
+ finra_provider = Provider(
8
+ name="finra",
9
+ website="https://www.finra.org/finra-data",
10
+ description="""FINRA Data provides centralized access to the abundance of data FINRA
11
+ makes available to the public, media, researchers and member firms.""",
12
+ credentials=None,
13
+ fetcher_dict={
14
+ "OTCAggregate": FinraOTCAggregateFetcher,
15
+ "EquityShortInterest": FinraShortInterestFetcher,
16
+ },
17
+ repr_name="Financial Industry Regulatory Authority (FINRA)",
18
+ )
openbb_platform/providers/finra/openbb_finra/models/equity_short_interest.py ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FINRA Equity Short Interest Model."""
2
+
3
+ # pylint: disable=unused-argument
4
+
5
+ from typing import Any, Dict, List, Optional
6
+
7
+ from openbb_core.provider.abstract.fetcher import Fetcher
8
+ from openbb_core.provider.standard_models.equity_short_interest import (
9
+ ShortInterestData,
10
+ ShortInterestQueryParams,
11
+ )
12
+
13
+
14
+ class FinraShortInterestQueryParams(ShortInterestQueryParams):
15
+ """FINRA Equity Short Interest Query."""
16
+
17
+
18
+ class FinraShortInterestData(ShortInterestData):
19
+ """FINRA Equity Short Interest Data."""
20
+
21
+ __alias_dict__ = {
22
+ "symbol": "symbolCode",
23
+ "issue_name": "issueName",
24
+ "market_class": "marketClassCode",
25
+ "current_short_position": "currentShortPositionQuantity",
26
+ "previous_short_position": "previousShortPositionQuantity",
27
+ "avg_daily_volume": "averageDailyVolumeQuantity",
28
+ "days_to_cover": "daysToCoverQuantity",
29
+ "change": "changePreviousNumber",
30
+ "change_pct": "changePercent",
31
+ "settlement_date": "settlementDate",
32
+ }
33
+
34
+
35
+ class FinraShortInterestFetcher(
36
+ Fetcher[FinraShortInterestQueryParams, List[FinraShortInterestData]]
37
+ ):
38
+ """Transform the query, extract and transform the data from the FINRA endpoints."""
39
+
40
+ @staticmethod
41
+ def transform_query(params: Dict[str, Any]) -> FinraShortInterestQueryParams:
42
+ """Transform query params."""
43
+ return FinraShortInterestQueryParams(**params)
44
+
45
+ @staticmethod
46
+ def extract_data(
47
+ query: FinraShortInterestQueryParams,
48
+ credentials: Optional[Dict[str, str]],
49
+ **kwargs: Any,
50
+ ) -> List[Dict]:
51
+ """Extract the data from the Finra endpoint."""
52
+ # pylint: disable=import-outside-toplevel
53
+ import sqlite3 # noqa
54
+ from openbb_finra.utils.data_storage import get_db_path, prepare_data # noqa
55
+
56
+ DB_PATH = get_db_path()
57
+ # Put the data in the cache
58
+ prepare_data()
59
+ # Get the data from the cache
60
+ cnx = sqlite3.connect(DB_PATH)
61
+ cursor = cnx.cursor()
62
+ cursor.execute(
63
+ "SELECT * FROM short_interest where symbolCode = ?", (query.symbol,)
64
+ )
65
+ # TODO: Check if we should allow general queries, it's more than 500k rows
66
+ # cursor.execute("SELECT * FROM short_interest")
67
+ result = cursor.fetchall()
68
+
69
+ titles = [
70
+ "symbolCode",
71
+ "issueName",
72
+ "marketClassCode",
73
+ "currentShortPositionQuantity",
74
+ "previousShortPositionQuantity",
75
+ "averageDailyVolumeQuantity",
76
+ "daysToCoverQuantity",
77
+ "changePercent",
78
+ "changePreviousNumber",
79
+ "settlementDate",
80
+ ]
81
+ return [dict(zip(titles, list(row)[1:])) for row in result]
82
+
83
+ @staticmethod
84
+ def transform_data(
85
+ query: FinraShortInterestQueryParams, data: List[Dict], **kwargs: Any
86
+ ) -> List[FinraShortInterestData]:
87
+ """Transform the data."""
88
+ return [FinraShortInterestData.model_validate(d) for d in data]
openbb_platform/providers/finra/openbb_finra/models/otc_aggregate.py ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """FINRA OTC Aggregate Model."""
2
+
3
+ from typing import Any, Dict, List, Literal, Optional
4
+
5
+ from openbb_core.provider.abstract.fetcher import Fetcher
6
+ from openbb_core.provider.standard_models.otc_aggregate import (
7
+ OTCAggregateData,
8
+ OTCAggregateQueryParams,
9
+ )
10
+ from pydantic import Field
11
+
12
+
13
+ class FinraOTCAggregateQueryParams(OTCAggregateQueryParams):
14
+ """FINRA OTC Aggregate Query."""
15
+
16
+ tier: Literal["T1", "T2", "OTCE"] = Field(
17
+ default="T1",
18
+ description=""""T1 - Securities included in the S&P 500, Russell 1000 and selected exchange-traded products;
19
+ T2 - All other NMS stocks; OTC - Over-the-Counter equity securities""",
20
+ )
21
+ is_ats: bool = Field(
22
+ default=True, description="ATS data if true, NON-ATS otherwise"
23
+ )
24
+
25
+
26
+ class FinraOTCAggregateData(OTCAggregateData):
27
+ """FINRA OTC Aggregate Data."""
28
+
29
+ __alias_dict__ = {
30
+ "share_quantity": "totalWeeklyShareQuantity",
31
+ "trade_quantity": "totalWeeklyTradeCount",
32
+ "update_date": "lastUpdateDate",
33
+ }
34
+
35
+
36
+ class FinraOTCAggregateFetcher(
37
+ Fetcher[FinraOTCAggregateQueryParams, List[FinraOTCAggregateData]]
38
+ ):
39
+ """Transform the query, extract and transform the data from the FINRA endpoints."""
40
+
41
+ @staticmethod
42
+ def transform_query(params: Dict[str, Any]) -> FinraOTCAggregateQueryParams:
43
+ """Transform query params."""
44
+ return FinraOTCAggregateQueryParams(**params)
45
+
46
+ # pylint: disable=unused-argument
47
+ @staticmethod
48
+ def extract_data(
49
+ query: FinraOTCAggregateQueryParams,
50
+ credentials: Optional[Dict[str, str]],
51
+ **kwargs: Any,
52
+ ) -> List[Dict]:
53
+ """Extract the data from the FINRA endpoint."""
54
+ # pylint: disable=import-outside-toplevel
55
+ from openbb_finra.utils.helpers import get_full_data
56
+
57
+ return get_full_data(query.symbol, query.tier, query.is_ats)
58
+
59
+ @staticmethod
60
+ def transform_data(
61
+ query: FinraOTCAggregateQueryParams, data: List[Dict], **kwargs: Any
62
+ ) -> List[FinraOTCAggregateData]:
63
+ """Transform the data."""
64
+ return [FinraOTCAggregateData.model_validate(d) for d in data if d]
openbb_platform/providers/finra/openbb_finra/utils/data_storage.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Utility for FINRA data storage.
2
+
3
+ This was created as a way to handle short interest data from the FINRA.
4
+ The files do not change, so there is no need to download them every time.
5
+ """
6
+
7
+ from typing import List
8
+
9
+ from openbb_core.app.utils import get_user_cache_directory
10
+ from openbb_finra.utils.helpers import get_short_interest_dates
11
+
12
+
13
+ def get_db_path():
14
+ """Return the path to the database."""
15
+ # pylint: disable=import-outside-toplevel
16
+ from pathlib import Path
17
+
18
+ DB_PATH = Path(get_user_cache_directory()) / "caches/finra_short_volume.db"
19
+ DB_PATH.parent.mkdir(parents=True, exist_ok=True)
20
+
21
+ return DB_PATH
22
+
23
+
24
+ def get_cached_dates() -> List:
25
+ """Return the dates that are cached in the DB file."""
26
+ # pylint: disable=import-outside-toplevel
27
+ import sqlite3 # noqa
28
+
29
+ DB_PATH = get_db_path()
30
+ cnx = sqlite3.connect(DB_PATH)
31
+ cursor = cnx.cursor()
32
+
33
+ # Check if the table exists
34
+ cursor.execute(
35
+ "SELECT * FROM sqlite_master WHERE type='table' AND name='short_interest'"
36
+ )
37
+ if cursor.fetchone() is None:
38
+ # The table does not exist
39
+ return []
40
+
41
+ # If the table exists, fetch the data
42
+ cursor.execute("SELECT distinct settlementDate FROM short_interest")
43
+ result = cursor.fetchall()
44
+ return [row[0] for row in result]
45
+
46
+
47
+ def get_data_from_date_and_store(date):
48
+ """Get data from a specific date and place it in the cache."""
49
+ # pylint: disable=import-outside-toplevel
50
+ import random # noqa
51
+ import sqlite3 # noqa
52
+ from io import StringIO # noqa
53
+ from openbb_core.provider.utils.helpers import make_request # noqa
54
+ from pandas import read_csv # noqa
55
+
56
+ DB_PATH = get_db_path()
57
+ url = f"https://cdn.finra.org/equity/otcmarket/biweekly/shrt{date}.csv"
58
+ # add a random string to user agent to avoid getting blocked
59
+ headers = {
60
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
61
+ + str(random.randint(0, 9)) # noqa: S311
62
+ }
63
+ req = make_request(url, headers=headers, timeout=1)
64
+ if req.status_code != 200:
65
+ return
66
+ data = read_csv(StringIO(req.text), delimiter="|")
67
+ data = data.drop(
68
+ columns=[
69
+ "accountingYearMonthNumber",
70
+ "issuerServicesGroupExchangeCode",
71
+ "stockSplitFlag",
72
+ "revisionFlag",
73
+ ]
74
+ )
75
+ data.to_sql("short_interest", sqlite3.connect(DB_PATH), if_exists="append")
76
+
77
+
78
+ def prepare_data():
79
+ """Prepare the data."""
80
+ date_list = get_short_interest_dates()
81
+ cached_urls = get_cached_dates()
82
+ for date in date_list:
83
+ if f"{date[:4]}-{date[4:6]}-{date[6:]}" not in cached_urls:
84
+ get_data_from_date_and_store(date)
openbb_platform/providers/finra/openbb_finra/utils/helpers.py ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Helper functions for FINRA API."""
2
+
3
+ import datetime
4
+ from typing import List
5
+
6
+ # pylint: disable=W0621
7
+
8
+
9
+ def get_finra_weeks(tier: str = "T1", is_ats: bool = True):
10
+ """Fetch the available weeks from FINRA that can be used."""
11
+ # pylint: disable=import-outside-toplevel
12
+ from openbb_core.provider.utils.helpers import make_request
13
+
14
+ request_header = {"Accept": "application/json", "Content-Type": "application/json"}
15
+
16
+ request_data = {
17
+ "compareFilters": [
18
+ {
19
+ "compareType": "EQUAL",
20
+ "fieldName": "summaryTypeCode",
21
+ "fieldValue": "ATS_W_SMBL" if is_ats else "OTC_W_SMBL",
22
+ },
23
+ {
24
+ "compareType": "EQUAL",
25
+ "fieldName": "tierIdentifier",
26
+ "fieldValue": tier,
27
+ },
28
+ ],
29
+ "delimiter": "|",
30
+ "fields": ["weekStartDate"],
31
+ "limit": 52,
32
+ "quoteValues": False,
33
+ "sortFields": ["-weekStartDate"],
34
+ }
35
+
36
+ response = make_request(
37
+ method="POST",
38
+ url="https://api.finra.org/data/group/otcMarket/name/weeklyDownloadDetails",
39
+ headers=request_header,
40
+ json=request_data,
41
+ timeout=3,
42
+ )
43
+
44
+ return response.json() if response.status_code == 200 else []
45
+
46
+
47
+ def get_finra_data(symbol, week_start, tier: str = "T1", is_ats: bool = True):
48
+ """Get the data for a symbol from FINRA."""
49
+ # pylint: disable=import-outside-toplevel
50
+ from openbb_core.provider.utils.helpers import make_request
51
+
52
+ req_hdr = {
53
+ "Accept": "application/json",
54
+ "Content-Type": "application/json",
55
+ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) ",
56
+ }
57
+
58
+ filters = [
59
+ {
60
+ "compareType": "EQUAL",
61
+ "fieldName": "weekStartDate",
62
+ "fieldValue": week_start,
63
+ },
64
+ {"compareType": "EQUAL", "fieldName": "tierIdentifier", "fieldValue": tier},
65
+ {
66
+ "compareType": "EQUAL",
67
+ "description": "",
68
+ "fieldName": "summaryTypeCode",
69
+ "fieldValue": "ATS_W_SMBL" if is_ats else "OTC_W_SMBL",
70
+ },
71
+ ]
72
+
73
+ if symbol:
74
+ filters.append(
75
+ {
76
+ "compareType": "EQUAL",
77
+ "fieldName": "issueSymbolIdentifier",
78
+ "fieldValue": symbol,
79
+ }
80
+ )
81
+
82
+ req_data = {
83
+ "compareFilters": filters,
84
+ "delimiter": "|",
85
+ "fields": [
86
+ "issueSymbolIdentifier",
87
+ "totalWeeklyShareQuantity",
88
+ "totalWeeklyTradeCount",
89
+ "lastUpdateDate",
90
+ ],
91
+ "limit": 5000,
92
+ "quoteValues": False,
93
+ "sortFields": ["totalWeeklyShareQuantity"],
94
+ }
95
+ response = make_request(
96
+ url="https://api.finra.org/data/group/otcMarket/name/weeklySummary",
97
+ method="POST",
98
+ headers=req_hdr,
99
+ json=req_data,
100
+ timeout=20,
101
+ )
102
+ return response
103
+
104
+
105
+ def get_full_data(symbol, tier: str = "T1", is_ats: bool = True):
106
+ """Get the full data for a symbol from FINRA."""
107
+ weeks = [week["weekStartDate"] for week in get_finra_weeks(tier, is_ats)]
108
+
109
+ data = []
110
+ for week in weeks:
111
+ response = get_finra_data(symbol, week, tier, is_ats)
112
+ r_json = response.json()
113
+ if response.status_code == 200 and r_json:
114
+ data.append(response.json()[0])
115
+
116
+ return data
117
+
118
+
119
+ def get_adjusted_date(year, month, day):
120
+ """Find the closest date if the date falls on a weekend."""
121
+ # Get the date
122
+ date = datetime.date(year, month, day)
123
+
124
+ # If the date is a Saturday, subtract one day
125
+ if date.weekday() == 5:
126
+ date -= datetime.timedelta(days=1)
127
+ # If the date is a Sunday, subtract two days
128
+ elif date.weekday() == 6:
129
+ date -= datetime.timedelta(days=2)
130
+
131
+ return date
132
+
133
+
134
+ def get_short_interest_dates() -> List[str]:
135
+ """Get a list of dates for which the short interest data is available.
136
+
137
+ It is reported on the 15th and the last day of each month,but if the date falls on a weekend,
138
+ the date is adjusted to the closest friday.
139
+ """
140
+
141
+ def get_adjusted_date(year, month, day):
142
+ """Find the closest date if the date falls on a weekend."""
143
+ # Get the date
144
+ date = datetime.date(year, month, day)
145
+
146
+ # If the date is a Saturday, subtract one day
147
+ if date.weekday() == 5:
148
+ date -= datetime.timedelta(days=1)
149
+ # If the date is a Sunday, subtract two days
150
+ elif date.weekday() == 6:
151
+ date -= datetime.timedelta(days=2)
152
+
153
+ return date
154
+
155
+ start_year = 2021
156
+ today = datetime.date.today() # Get today's date
157
+ end_year = today.year
158
+ dates_list = []
159
+
160
+ for yr in range(start_year, end_year + 1):
161
+ start_month = 7 if yr == start_year else 1
162
+ end_month = 12 if yr < today.year else today.month - 1
163
+ for month in range(start_month, end_month + 1): # Start from July for 2021
164
+ # Date for the 15th of the month
165
+ date_15 = get_adjusted_date(yr, month, 15)
166
+ dates_list.append(date_15.strftime("%Y%m%d"))
167
+
168
+ # Date for the last day of the month
169
+ if month == 2: # February
170
+ last_day = (
171
+ 29 if (yr % 4 == 0 and yr % 100 != 0) or (yr % 400 == 0) else 28
172
+ )
173
+ elif month in [4, 6, 9, 11]: # Months with 30 days
174
+ last_day = 30
175
+ else: # Months with 31 days
176
+ last_day = 31
177
+
178
+ last_date = get_adjusted_date(yr, month, last_day)
179
+ dates_list.append(last_date.strftime("%Y%m%d"))
180
+
181
+ # Manually replace '20220415' with '20220414' due to holiday
182
+ if "20220415" in dates_list:
183
+ index = dates_list.index("20220415")
184
+ dates_list[index] = "20220414"
185
+
186
+ return dates_list