From 9eca7b9f2374d24c79a486e081398e5723c4c4cf Mon Sep 17 00:00:00 2001 From: Danglewood <85772166+deeleeramone@users.noreply.github.com> Date: Mon, 20 Apr 2026 15:36:41 -0700 Subject: [PATCH] [Enhancement] `openbb-cftc`: Improve CFTC Endpoints and Make a Standalone Workspace App For COT Data (#7449) * improve cftc endpoints and make a standalone workspace app * mypy * forgot couple of files to commit * test params * integration test param name * fix sec-sic-search * fill some contracts missing category and subcategory, add a workspace workchoices endpoint * linter * integration test for cot_choices --- .../provider/standard_models/cot.py | 10 +- .../provider/standard_models/cot_search.py | 17 +- .../integration/test_regulators_api.py | 45 - .../integration/test_regulators_python.py | 39 - .../openbb_regulators/cftc/__init__.py | 1 - .../openbb_regulators/cftc/cftc_router.py | 67 - .../openbb_regulators/regulators_router.py | 4 - openbb_platform/providers/cftc/README.md | 90 +- .../cftc/integration/test_cftc_api.py | 93 + .../cftc/integration/test_cftc_python.py | 84 + .../providers/cftc/openbb_cftc/apps.json | 107 + .../cftc/openbb_cftc/assets/__init__.py | 1 - .../cftc/openbb_cftc/assets/cot_ids.json | 1 - .../providers/cftc/openbb_cftc/cftc_router.py | 159 ++ .../providers/cftc/openbb_cftc/models/cot.py | 1952 ++++++++++++++++- .../cftc/openbb_cftc/models/cot_search.py | 214 +- .../cftc/openbb_cftc/utils/__init__.py | 10 + openbb_platform/providers/cftc/poetry.lock | 311 +-- openbb_platform/providers/cftc/pyproject.toml | 8 +- .../test_cftc_cot_fetcher_urllib3_v2.yaml | 10 +- ...est_cftc_cot_sarch_fetcher_urllib3_v2.yaml | 60 + .../cftc/tests/test_cftc_fetchers.py | 4 +- .../openbb_sec/models/institutions_search.py | 6 +- .../sec/openbb_sec/models/sic_search.py | 7 +- openbb_platform/pyproject.toml | 2 +- 25 files changed, 2917 insertions(+), 385 deletions(-) delete mode 100644 openbb_platform/extensions/regulators/openbb_regulators/cftc/__init__.py delete mode 100644 openbb_platform/extensions/regulators/openbb_regulators/cftc/cftc_router.py create mode 100644 openbb_platform/providers/cftc/integration/test_cftc_api.py create mode 100644 openbb_platform/providers/cftc/integration/test_cftc_python.py create mode 100644 openbb_platform/providers/cftc/openbb_cftc/apps.json delete mode 100644 openbb_platform/providers/cftc/openbb_cftc/assets/__init__.py delete mode 100644 openbb_platform/providers/cftc/openbb_cftc/assets/cot_ids.json create mode 100644 openbb_platform/providers/cftc/openbb_cftc/cftc_router.py create mode 100644 openbb_platform/providers/cftc/tests/record/http/test_cftc_fetchers/test_cftc_cot_sarch_fetcher_urllib3_v2.yaml diff --git a/openbb_platform/core/openbb_core/provider/standard_models/cot.py b/openbb_platform/core/openbb_core/provider/standard_models/cot.py index 4a87bf3228f..a8d9572b883 100644 --- a/openbb_platform/core/openbb_core/provider/standard_models/cot.py +++ b/openbb_platform/core/openbb_core/provider/standard_models/cot.py @@ -8,17 +8,15 @@ from openbb_core.provider.utils.descriptions import ( DATA_DESCRIPTIONS, QUERY_DESCRIPTIONS, ) -from pydantic import Field +from pydantic import AliasChoices, Field class COTQueryParams(QueryParams): """Commitment of Traders Reports Query.""" - id: str = Field( - description="A string with the CFTC market code or other identifying string," - + " such as the contract market name, commodity name, or commodity group - i.e, 'gold' or 'japanese yen'." - + "Default report is Fed Funds Futures. Use the 'cftc_market_code' for an exact match.", - default="045601", + code: str = Field( + description="A string with the market code.", + validation_alias=AliasChoices("code", "id"), ) start_date: dateType | None = Field( default=None, diff --git a/openbb_platform/core/openbb_core/provider/standard_models/cot_search.py b/openbb_platform/core/openbb_core/provider/standard_models/cot_search.py index 1eca8838ed3..44d745c638f 100644 --- a/openbb_platform/core/openbb_core/provider/standard_models/cot_search.py +++ b/openbb_platform/core/openbb_core/provider/standard_models/cot_search.py @@ -9,13 +9,28 @@ from pydantic import Field class CotSearchQueryParams(QueryParams): """Commitment of Traders Reports Search Query.""" + code: str | None = Field( + default=None, + description="A string with the market contract code (can be partial).", + ) query: str = Field(description="Search query.", default="") class CotSearchData(Data): """Commitment of Traders Reports Search Data.""" - code: str = Field(description="CFTC market contract code of the report.") + code: str = Field( + description="CFTC market contract code of the report.", + json_schema_extra={ + "x-widget_config": { + "renderFn": "cellOnClick", + "renderFnParams": { + "actionType": "groupBy", + "groupByParamName": "code", + }, + }, + }, + ) name: str = Field(description="Name of the underlying asset.") category: str | None = Field( default=None, description="Category of the underlying asset." diff --git a/openbb_platform/extensions/regulators/integration/test_regulators_api.py b/openbb_platform/extensions/regulators/integration/test_regulators_api.py index df7b9690155..367e87061c9 100644 --- a/openbb_platform/extensions/regulators/integration/test_regulators_api.py +++ b/openbb_platform/extensions/regulators/integration/test_regulators_api.py @@ -136,51 +136,6 @@ def test_regulators_sec_sic_search(params, headers): assert result.status_code == 200 -@pytest.mark.parametrize( - "params", - [ - ({"query": "grain", "provider": "cftc"}), - ], -) -@pytest.mark.integration -def test_regulators_cftc_cot_search(params, headers): - """Test the CFTC COT search endpoint.""" - params = {p: v for p, v in params.items() if v} - - query_str = get_querystring(params, []) - url = f"http://0.0.0.0:8000/api/v1/regulators/cftc/cot_search?{query_str}" - result = requests.get(url, headers=headers, timeout=10) - assert isinstance(result, requests.Response) - assert result.status_code == 200 - - -@pytest.mark.parametrize( - "params", - [ - ( - { - "id": "045601", - "report_type": "legacy", - "start_date": "2023-01-01", - "end_date": "2023-06-06", - "futures_only": False, - "provider": "cftc", - } - ), - ], -) -@pytest.mark.integration -def test_regulators_cftc_cot(params, headers): - """Test the CFTC COT endpoint.""" - params = {p: v for p, v in params.items() if v} - - query_str = get_querystring(params, []) - url = f"http://0.0.0.0:8000/api/v1/regulators/cftc/cot?{query_str}" - result = requests.get(url, headers=headers, timeout=10) - assert isinstance(result, requests.Response) - assert result.status_code == 200 - - @pytest.mark.parametrize( "params", [ diff --git a/openbb_platform/extensions/regulators/integration/test_regulators_python.py b/openbb_platform/extensions/regulators/integration/test_regulators_python.py index 380a6ae38f9..8b01e41a525 100644 --- a/openbb_platform/extensions/regulators/integration/test_regulators_python.py +++ b/openbb_platform/extensions/regulators/integration/test_regulators_python.py @@ -117,45 +117,6 @@ def test_regulators_sec_sic_search(params, obb): assert len(result.results) > 0 -@pytest.mark.parametrize( - "params", - [ - ({"query": "grain", "provider": "cftc"}), - ], -) -@pytest.mark.integration -def test_regulators_cftc_cot_search(params, obb): - """Test the CFTC COT search endpoint.""" - result = obb.regulators.cftc.cot_search(**params) - assert result - assert isinstance(result, OBBject) - assert len(result.results) > 0 - - -@pytest.mark.parametrize( - "params", - [ - ( - { - "id": "045601", - "report_type": "legacy", - "start_date": "2023-01-01", - "end_date": "2023-06-06", - "futures_only": False, - "provider": "cftc", - } - ), - ], -) -@pytest.mark.integration -def test_regulators_cftc_cot(params, obb): - """Test the CFTC COT endpoint.""" - result = obb.regulators.cftc.cot(**params) - assert result - assert isinstance(result, OBBject) - assert len(result.results) > 0 - - @pytest.mark.parametrize( "params", [ diff --git a/openbb_platform/extensions/regulators/openbb_regulators/cftc/__init__.py b/openbb_platform/extensions/regulators/openbb_regulators/cftc/__init__.py deleted file mode 100644 index 42b690c9e1b..00000000000 --- a/openbb_platform/extensions/regulators/openbb_regulators/cftc/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""Commodity Futures Trading Commission (CFTC).""" diff --git a/openbb_platform/extensions/regulators/openbb_regulators/cftc/cftc_router.py b/openbb_platform/extensions/regulators/openbb_regulators/cftc/cftc_router.py deleted file mode 100644 index 62512877acd..00000000000 --- a/openbb_platform/extensions/regulators/openbb_regulators/cftc/cftc_router.py +++ /dev/null @@ -1,67 +0,0 @@ -# pylint: disable=W0613:unused-argument -"""Commodity Futures Trading Commission (CFTC) Router.""" - -from openbb_core.app.model.command_context import CommandContext -from openbb_core.app.model.example import APIEx -from openbb_core.app.model.obbject import OBBject -from openbb_core.app.provider_interface import ( - ExtraParams, - ProviderChoices, - StandardParams, -) -from openbb_core.app.query import Query -from openbb_core.app.router import Router - -router = Router(prefix="/cftc") - - -@router.command( - model="COTSearch", - examples=[ - APIEx(parameters={"provider": "cftc"}), - APIEx(parameters={"query": "gold", "provider": "cftc"}), - ], -) -async def cot_search( - cc: CommandContext, - provider_choices: ProviderChoices, - standard_params: StandardParams, - extra_params: ExtraParams, -) -> OBBject: - """Get the current Commitment of Traders Reports. - - Search a list of the current Commitment of Traders Reports series information. - """ - return await OBBject.from_query(Query(**locals())) - - -@router.command( - model="COT", - examples=[ - APIEx(parameters={"provider": "ctfc"}), - APIEx( - description="Get the latest report for all items classified as, GOLD.", - parameters={"id": "gold", "provider": "cftc"}, - ), - APIEx( - description="Enter the entire history for a single CFTC Market Contract Code.", - parameters={"id": "088691", "provider": "cftc"}, - ), - APIEx( - description="Get the report for futures only.", - parameters={"id": "088691", "futures_only": True, "provider": "cftc"}, - ), - APIEx( - description="Get the most recent Commodity Index Traders Supplemental Report.", - parameters={"id": "all", "report_type": "supplemental", "provider": "cftc"}, - ), - ], -) -async def cot( - cc: CommandContext, - provider_choices: ProviderChoices, - standard_params: StandardParams, - extra_params: ExtraParams, -) -> OBBject: - """Get Commitment of Traders Reports.""" - return await OBBject.from_query(Query(**locals())) diff --git a/openbb_platform/extensions/regulators/openbb_regulators/regulators_router.py b/openbb_platform/extensions/regulators/openbb_regulators/regulators_router.py index 22232ea19a2..a4efe46d677 100644 --- a/openbb_platform/extensions/regulators/openbb_regulators/regulators_router.py +++ b/openbb_platform/extensions/regulators/openbb_regulators/regulators_router.py @@ -5,11 +5,7 @@ from openbb_core.app.router import Router -from .cftc.cftc_router import ( - router as cftc_router, -) from .sec.sec_router import router as sec_router router = Router(prefix="", description="Financial market regulators data.") router.include_router(sec_router) -router.include_router(cftc_router) diff --git a/openbb_platform/providers/cftc/README.md b/openbb_platform/providers/cftc/README.md index cd6a901ea11..776e160459e 100644 --- a/openbb_platform/providers/cftc/README.md +++ b/openbb_platform/providers/cftc/README.md @@ -1,17 +1,20 @@ # CFTC Provider Extension +This package provides full access to the CFTC Commitment of Traders database. +Reports are fetched by CFTC Code (e.g. `13874+`) and returns the full history of the contract. + ## Installation -Install from PyPI with: +Install into a Python environment (3.10 - 3.14) from PyPI with: ```sh pip install openbb-cftc ``` -Install this extension locally with: +Then build the Python static assets: ```sh -pip install -e . +openbb-build ``` ## Credentials @@ -28,3 +31,84 @@ Then, generate the app_token by signing in with the credentials here: https://pu If adding a token, use `cftc_app_token` as the key in the `user_settings.json` file. The value expected value is the app_token and not the `secret` or `api_key`. +The token can be set as an environment variable: + +```env +CFTC_APP_TOKEN +``` + +## Coverage + +This extension provides a dedicated router module with two endpoints, and one OpenBB Workspace application. + +- `obb.cftc.cot` +- `obb.cftc.cot_search` + +## Usage + +The package can be used as a Python module, or a REST API. + +### REST API + +Start the server over localhost with: + +```sh +openbb-api +``` + +### Python + +```python +from openbb import obb + +search_results = obb.cftc.cot_search(query="gold") + +print(search_results.to_df()) +``` + +| code | name | category | subcategory | commodity_name | contract_units | +|:------------|:-------------------|:------------------|:----------------|:-----------------|:-------------------------------| +| CFTC_088691 | GOLD | NATURAL RESOURCES | PRECIOUS METALS | GOLD | (CONTRACTS OF 100 TROY OUNCES) | +| CFTC_088LM1 | GOLD -1 TROY OUNCE | NATURAL RESOURCES | PRECIOUS METALS | GOLD | (1 troy ounce x $2,300) | +| CFTC_088695 | MICRO GOLD | NATURAL RESOURCES | PRECIOUS METALS | GOLD | (CONTRACTS OF 10 TROY OUNCES) | + +```python +report = obb.cftc.cot(code="CFTC_088695", measure="percent_of_oi", limit=4) +print(report.to_df().T) +``` + +| | 2026-03-03 | 2026-03-10 | 2026-03-17 | 2026-03-24 | +|:--------------------------------------------|-------------:|-------------:|-------------:|-------------:| +| open_interest_all | 60933 | 58119 | 64124 | 71998 | +| open_interest_pct_all | 1 | 1 | 1 | 1 | +| open_interest_pct_non_commercial_long_all | 0.186 | 0.18 | 0.168 | 0.285 | +| open_interest_pct_non_commercial_short_all | 0.527 | 0.546 | 0.555 | 0.515 | +| open_interest_pct_non_commercial_spread | 0.058 | 0.06 | 0.078 | 0.124 | +| open_interest_pct_commercial_long_all | 0.088 | 0.095 | 0.091 | 0.083 | +| open_interest_pct_commercial_short_all | 0 | 0 | 0 | 0 | +| open_interest_pct_total_reportable_long_all | 0.333 | 0.335 | 0.336 | 0.492 | +| open_interest_pct_total_reportable_short | 0.585 | 0.606 | 0.632 | 0.64 | +| open_interest_pct_non_reportable_long_all | 0.667 | 0.665 | 0.664 | 0.508 | +| open_interest_pct_non_reportable_short_all | 0.415 | 0.394 | 0.368 | 0.36 | + +## Report Types + +Reports can be filtered by measure, or include all reported fields. Report types come as 'Futures Only', or 'Combined' (futures and options combined positions), selectable by setting the `futures_only` boolean parameter. + +### Legacy + +The Legacy report is broken down by exchange with reported open interest further broken down into three trader classifications: commercial, non-commercial and non-reportable. + +### Disaggregated + +The Disaggregated reports are broken down by Agriculture and Natural Resource contracts. The Disaggregated reports break down reportable open interest positions into four classifications: Producer/Merchant, Swap Dealers, Managed Money and Other Reportables. + +### Financial + +The Traders in Financial Futures (TFF) report includes financial contracts. The TFF report breaks down the reported open interest into five classifications: Dealer, Asset Manager, Leveraged Money, Other Reportables and Non-Reportables. + +### Supplemental + +The Supplemental report includes 13 select agricultural commodity contracts for combined futures and options positions. Supplemental reports break down the reportable open interest positions into three trader classifications: non-commercial, commercial, and index traders. + +Visit the CFTC [website](https://www.cftc.gov/MarketReports/CommitmentsofTraders/index.htm) for detailed descriptions of reports and classification methodology. diff --git a/openbb_platform/providers/cftc/integration/test_cftc_api.py b/openbb_platform/providers/cftc/integration/test_cftc_api.py new file mode 100644 index 00000000000..00e8c3b0a7e --- /dev/null +++ b/openbb_platform/providers/cftc/integration/test_cftc_api.py @@ -0,0 +1,93 @@ +"""Integration tests for the regulators API.""" + +# pylint: disable=redefined-outer-name + +import base64 + +import pytest +import requests +from openbb_core.env import Env +from openbb_core.provider.utils.helpers import get_querystring + + +@pytest.fixture(scope="session") +def headers(): + """Get the headers for the API request.""" + userpass = f"{Env().API_USERNAME}:{Env().API_PASSWORD}" + userpass_bytes = userpass.encode("ascii") + base64_bytes = base64.b64encode(userpass_bytes) + + return {"Authorization": f"Basic {base64_bytes.decode('ascii')}"} + + +@pytest.mark.parametrize( + "params", + [ + ( + { + "query": "grain", + "report_type": "legacy", + "futures_only": False, + "category": None, + "subcategory": None, + "code": None, + "provider": "cftc", + } + ), + ], +) +@pytest.mark.integration +def test_cftc_cot_search(params, headers): + """Test the CFTC COT search endpoint.""" + params = {p: v for p, v in params.items() if v} + + query_str = get_querystring(params, []) + url = f"http://localhost:8000/api/v1/cftc/cot_search?{query_str}" + result = requests.get(url, headers=headers, timeout=10) + assert isinstance(result, requests.Response) + assert result.status_code == 200 + + +@pytest.mark.parametrize( + "params", + [ + ( + { + "code": "045601", + "report_type": "legacy", + "start_date": None, + "end_date": None, + "limit": 1, + "futures_only": False, + "measure": "all", + "provider": "cftc", + } + ), + ], +) +@pytest.mark.integration +def test_cftc_cot(params, headers): + """Test the CFTC COT endpoint.""" + params = {p: v for p, v in params.items() if v} + + query_str = get_querystring(params, []) + url = f"http://localhost:8000/api/v1/cftc/cot?{query_str}" + result = requests.get(url, headers=headers, timeout=10) + assert isinstance(result, requests.Response) + assert result.status_code == 200 + + +@pytest.mark.parametrize( + "params", + [ + ({}), + ], +) +@pytest.mark.integration +def test_cftc_get_cot_choices(params, headers): + """Test the CFTC get_cot_choices endpoint.""" + query_str = get_querystring(params, []) + url = f"http://localhost:8000/api/v1/cftc/get_cot_choices?{query_str}" + result = requests.get(url, headers=headers, timeout=10) + assert isinstance(result, requests.Response) + assert result.status_code == 200 diff --git a/openbb_platform/providers/cftc/integration/test_cftc_python.py b/openbb_platform/providers/cftc/integration/test_cftc_python.py new file mode 100644 index 00000000000..8e4d6f4027a --- /dev/null +++ b/openbb_platform/providers/cftc/integration/test_cftc_python.py @@ -0,0 +1,84 @@ +"""Test Regulators extension.""" + +# pylint: disable=redefined-outer-name + +import pytest +from openbb_core.app.model.obbject import OBBject + + +# pylint: disable=inconsistent-return-statements +@pytest.fixture(scope="session") +def obb(pytestconfig): + """Fixture to setup obb.""" + + if pytestconfig.getoption("markexpr") != "not integration": + import openbb # pylint: disable=import-outside-toplevel + + return openbb.obb + + +@pytest.mark.parametrize( + "params", + [ + ( + { + "query": "grain", + "report_type": "legacy", + "futures_only": False, + "category": None, + "subcategory": None, + "code": None, + "provider": "cftc", + } + ), + ], +) +@pytest.mark.integration +def test_cftc_cot_search(params, obb): + """Test the CFTC COT search endpoint.""" + result = obb.cftc.cot_search(**params) + assert result + assert isinstance(result, OBBject) + assert len(result.results) > 0 + + +@pytest.mark.parametrize( + "params", + [ + ( + { + "code": "045601", + "report_type": "legacy", + "start_date": None, + "end_date": None, + "limit": 1, + "futures_only": False, + "measure": "all", + "provider": "cftc", + } + ), + ], +) +@pytest.mark.integration +def test_cftc_cot(params, obb): + """Test the CFTC COT endpoint.""" + result = obb.cftc.cot(**params) + assert result + assert isinstance(result, OBBject) + assert len(result.results) > 0 + + +@pytest.mark.parametrize( + "params", + [ + ({}), + ], +) +@pytest.mark.integration +@pytest.mark.skip(reason="This is not included in the Python interface.") +def test_cftc_get_cot_choices(params, obb): + """Test the CFTC get_cot_choices endpoint.""" + result = obb.cftc.get_cot_choices(**params) + assert result + assert isinstance(result, OBBject) + assert len(result.results) > 0 diff --git a/openbb_platform/providers/cftc/openbb_cftc/apps.json b/openbb_platform/providers/cftc/openbb_cftc/apps.json new file mode 100644 index 00000000000..6ab18aee11b --- /dev/null +++ b/openbb_platform/providers/cftc/openbb_cftc/apps.json @@ -0,0 +1,107 @@ +[ + { + "name": "CFTC Commitment of Traders", + "img": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/Commodity_Futures_Trading_Commission_seal.svg/1920px-Commodity_Futures_Trading_Commission_seal.svg.png", + "img_dark": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/Commodity_Futures_Trading_Commission_seal.svg/1920px-Commodity_Futures_Trading_Commission_seal.svg.png", + "img_light": "https://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/Commodity_Futures_Trading_Commission_seal.svg/1920px-Commodity_Futures_Trading_Commission_seal.svg.png", + "description": "Search and query the full historical database of reports for contracts covering commodity and financial futures.", + "allowCustomization": true, + "tabs": { + "": { + "id": "", + "name": "", + "layout": [ + { + "i": "cftc_cot_cftc_obb", + "x": 0, + "y": 15, + "w": 40, + "h": 22, + "state": { + "params": { + "code": "CFTC_13874+", + "measure": "changes", + "futures_only": "true", + "limit": "52" + }, + "chartView": { + "enabled": false, + "chartType": "line" + }, + "columnState": { + "default": { + "columnPinning": { + "leftColIds": [ + "date" + ], + "rightColIds": [] + }, + "columnOrder": { + "orderedColIds": [ + "date", + "open_interest_all", + "change_in_open_interest_all", + "change_in_non_commercial_long_all", + "change_in_non_commercial_short_all", + "change_in_non_commercial_spread_all", + "change_in_commercial_long_all", + "change_in_commercial_short_all", + "change_in_total_reportable_long_all", + "change_in_total_reportable_short", + "change_in_non_reportable_long_all", + "change_in_non_reportable_short_all" + ] + } + } + } + }, + "groups": [ + "Group 1" + ] + }, + { + "i": "cftc_cot_search_cftc_obb", + "x": 0, + "y": 0, + "w": 40, + "h": 15, + "state": { + "params": { + "subcategory": "stock_indices" + }, + "chartView": { + "enabled": false, + "chartType": "line" + }, + "columnState": { + "default": { + "columnOrder": { + "orderedColIds": [ + "code", + "name", + "category", + "subcategory", + "commodity_name", + "contract_units" + ] + } + } + } + }, + "groups": [ + "Group 1" + ] + } + ] + } + }, + "groups": [ + { + "name": "Group 1", + "type": "param", + "paramName": "code", + "defaultValue": "CFTC_13874+" + } + ] + } +] \ No newline at end of file diff --git a/openbb_platform/providers/cftc/openbb_cftc/assets/__init__.py b/openbb_platform/providers/cftc/openbb_cftc/assets/__init__.py deleted file mode 100644 index 6a1e97d446a..00000000000 --- a/openbb_platform/providers/cftc/openbb_cftc/assets/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""CFTC Provider Module Static Assets.""" diff --git a/openbb_platform/providers/cftc/openbb_cftc/assets/cot_ids.json b/openbb_platform/providers/cftc/openbb_cftc/assets/cot_ids.json deleted file mode 100644 index 2eff3236cdb..00000000000 --- a/openbb_platform/providers/cftc/openbb_cftc/assets/cot_ids.json +++ /dev/null @@ -1 +0,0 @@ -[{"cftc_contract_market_code":"050642","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"DAIRY PRODUCTS","commodity_name":"BUTTER","contract_market_name":"BUTTER (CASH SETTLED)"},{"cftc_contract_market_code":"063642","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"DAIRY PRODUCTS","commodity_name":"CHEESE","contract_market_name":"CHEESE (CASH-SETTLED)"},{"cftc_contract_market_code":"052644","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"DAIRY PRODUCTS","commodity_name":"MILK","contract_market_name":"CME MILK IV"},{"cftc_contract_market_code":"052641","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"DAIRY PRODUCTS","commodity_name":"MILK","contract_market_name":"MILK, Class III"},{"cftc_contract_market_code":"052642","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"DAIRY PRODUCTS","commodity_name":"MILK","contract_market_name":"NON FAT DRY MILK"},{"cftc_contract_market_code":"033661","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"FIBER","commodity_name":"COTTON","contract_market_name":"COTTON NO. 2"},{"cftc_contract_market_code":"073732","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"FOODSTUFFS\/SOFTS","commodity_name":"COCOA","contract_market_name":"COCOA"},{"cftc_contract_market_code":"083731","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"FOODSTUFFS\/SOFTS","commodity_name":"COFFEE","contract_market_name":"COFFEE C"},{"cftc_contract_market_code":"040701","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"FOODSTUFFS\/SOFTS","commodity_name":"FROZEN CONCENTRATED ORANGE JUICE","contract_market_name":"FRZN CONCENTRATED ORANGE JUICE"},{"cftc_contract_market_code":"080732","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"FOODSTUFFS\/SOFTS","commodity_name":"SUGAR","contract_market_name":"SUGAR NO. 11"},{"cftc_contract_market_code":"002602","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"GRAINS","commodity_name":"CORN","contract_market_name":"CORN"},{"cftc_contract_market_code":"004603","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"GRAINS","commodity_name":"OATS","contract_market_name":"OATS"},{"cftc_contract_market_code":"039601","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"GRAINS","commodity_name":"RICE","contract_market_name":"ROUGH RICE"},{"cftc_contract_market_code":"001626","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"GRAINS","commodity_name":"WHEAT","contract_market_name":"WHEAT-HRSpring"},{"cftc_contract_market_code":"001612","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"GRAINS","commodity_name":"WHEAT","contract_market_name":"WHEAT-HRW"},{"cftc_contract_market_code":"001602","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"GRAINS","commodity_name":"WHEAT","contract_market_name":"WHEAT-SRW"},{"cftc_contract_market_code":"061641","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"LIVESTOCK\/MEAT PRODUCTS","commodity_name":"FEEDER CATTLE","contract_market_name":"FEEDER CATTLE"},{"cftc_contract_market_code":"054642","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"LIVESTOCK\/MEAT PRODUCTS","commodity_name":"LEAN HOGS","contract_market_name":"LEAN HOGS"},{"cftc_contract_market_code":"057642","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"LIVESTOCK\/MEAT PRODUCTS","commodity_name":"LIVE CATTLE","contract_market_name":"LIVE CATTLE"},{"cftc_contract_market_code":"135731","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"OILSEED and PRODUCTS","commodity_name":"CANOLA AND PRODUCTS","contract_market_name":"CANOLA"},{"cftc_contract_market_code":"037021","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"OILSEED and PRODUCTS","commodity_name":"PALM OIL","contract_market_name":"USD Malaysian Crude Palm Oil C"},{"cftc_contract_market_code":"026603","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"OILSEED and PRODUCTS","commodity_name":"SOYBEAN MEAL","contract_market_name":"SOYBEAN MEAL"},{"cftc_contract_market_code":"007601","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"OILSEED and PRODUCTS","commodity_name":"SOYBEAN OIL","contract_market_name":"SOYBEAN OIL"},{"cftc_contract_market_code":"005602","commodity_group_name":"AGRICULTURE","commodity_subgroup_name":"OILSEED and PRODUCTS","commodity_name":"SOYBEANS","contract_market_name":"SOYBEANS"},{"cftc_contract_market_code":"133742","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CRYPTOCURRENCIES","commodity_name":"BITCOIN","contract_market_name":"MICRO BITCOIN"},{"cftc_contract_market_code":"133741","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CRYPTOCURRENCIES","commodity_name":"BITCOIN","contract_market_name":"BITCOIN"},{"cftc_contract_market_code":"133LM1","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CRYPTOCURRENCIES","commodity_name":"BITCOIN","contract_market_name":"Nano Bitcoin"},{"cftc_contract_market_code":"146022","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CRYPTOCURRENCIES","commodity_name":"ETHER","contract_market_name":"MICRO ETHER"},{"cftc_contract_market_code":"146021","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CRYPTOCURRENCIES","commodity_name":"ETHER","contract_market_name":"ETHER CASH SETTLED"},{"cftc_contract_market_code":"146LM1","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CRYPTOCURRENCIES","commodity_name":"ETHER","contract_market_name":"NANO ETHER"},{"cftc_contract_market_code":"232741","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CURRENCY","commodity_name":"AUSTRALIAN DOLLAR","contract_market_name":"AUSTRALIAN DOLLAR"},{"cftc_contract_market_code":"090741","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CURRENCY","commodity_name":"CANADIAN DOLLAR","contract_market_name":"CANADIAN DOLLAR"},{"cftc_contract_market_code":"299741","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CURRENCY","commodity_name":"EUROPEAN CURRENCY UNIT","contract_market_name":"EURO FX\/BRITISH POUND XRATE"},{"cftc_contract_market_code":"099741","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CURRENCY","commodity_name":"EUROPEAN CURRENCY UNIT","contract_market_name":"EURO FX"},{"cftc_contract_market_code":"097741","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CURRENCY","commodity_name":"JAPANESE YEN","contract_market_name":"JAPANESE YEN"},{"cftc_contract_market_code":"096742","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CURRENCY","commodity_name":"POUND STERLING","contract_market_name":"BRITISH POUND"},{"cftc_contract_market_code":"092741","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CURRENCY","commodity_name":"SWISS FRANC","contract_market_name":"SWISS FRANC"},{"cftc_contract_market_code":"102741","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CURRENCY(NON-MAJOR)","commodity_name":"BRAZILIAN REAL","contract_market_name":"BRAZILIAN REAL"},{"cftc_contract_market_code":"095741","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CURRENCY(NON-MAJOR)","commodity_name":"MEXICAN PESO","contract_market_name":"MEXICAN PESO"},{"cftc_contract_market_code":"112741","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CURRENCY(NON-MAJOR)","commodity_name":"NEW ZEALAND DOLLAR","contract_market_name":"NZ DOLLAR"},{"cftc_contract_market_code":"122741","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"CURRENCY(NON-MAJOR)","commodity_name":"SOUTH AFRICAN RAND","contract_market_name":"SO AFRICAN RAND"},{"cftc_contract_market_code":"342603","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"INTEREST RATE SWAPS","commodity_name":"1-2-YEAR INTEREST RATE SWAPS ERIS & MAC","contract_market_name":"2 YEAR ERIS SOFR SWAP"},{"cftc_contract_market_code":"344605","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"INTEREST RATE SWAPS","commodity_name":"2-7-YEAR INTEREST RATE SWAPS ERIS & MAC","contract_market_name":"5 YEAR ERIS SOFR SWAP"},{"cftc_contract_market_code":"343603","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"INTEREST RATE SWAPS","commodity_name":"8-14-YEAR INTEREST RATE SWAPS ERIS & MAC","contract_market_name":"10 YEAR ERIS SOFR SWAP"},{"cftc_contract_market_code":"020604","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"INTEREST RATES - U.S. TREASURY","commodity_name":"T-BONDS","contract_market_name":"ULTRA UST BOND"},{"cftc_contract_market_code":"020601","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"INTEREST RATES - U.S. TREASURY","commodity_name":"T-BONDS","contract_market_name":"UST BOND"},{"cftc_contract_market_code":"042601","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"INTEREST RATES - U.S. TREASURY","commodity_name":"T-NOTES, 1-2 YEAR","contract_market_name":"UST 2Y NOTE"},{"cftc_contract_market_code":"044601","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"INTEREST RATES - U.S. TREASURY","commodity_name":"T-NOTES, 4-6 YEAR","contract_market_name":"UST 5Y NOTE"},{"cftc_contract_market_code":"043607","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"INTEREST RATES - U.S. TREASURY","commodity_name":"T-NOTES, 6.5-10 YEAR","contract_market_name":"ULTRA UST 10Y"},{"cftc_contract_market_code":"043602","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"INTEREST RATES - U.S. TREASURY","commodity_name":"T-NOTES, 6.5-10 YEAR","contract_market_name":"UST 10Y NOTE"},{"cftc_contract_market_code":"04360Y","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"INTEREST RATES - U.S. TREASURY","commodity_name":"T-NOTES, 6.5-10 YEAR","contract_market_name":"MICRO 10 YEAR YIELD"},{"cftc_contract_market_code":"045601","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"INTEREST RATES - NON U.S. TREASURY","commodity_name":"30 DAY RATES","contract_market_name":"FED FUNDS"},{"cftc_contract_market_code":"134742","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"INTEREST RATES - NON U.S. TREASURY","commodity_name":"SECURED OVERNIGHT FINANCING RATE","contract_market_name":"SOFR-1M"},{"cftc_contract_market_code":"134741","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"INTEREST RATES - NON U.S. TREASURY","commodity_name":"SECURED OVERNIGHT FINANCING RATE","contract_market_name":"SOFR-3M"},{"cftc_contract_market_code":"221602","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"OTHER FINANCIAL INSTRUMENTS","commodity_name":"BLOOMBERG COMMODITY INDEX","contract_market_name":"BBG COMMODITY"},{"cftc_contract_market_code":"098662","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"OTHER FINANCIAL INSTRUMENTS","commodity_name":"U.S. DOLLAR INDEX","contract_market_name":"USD INDEX"},{"cftc_contract_market_code":"1170E1","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"OTHER FINANCIAL INSTRUMENTS","commodity_name":"VOLATILITY\/VARIANCE INDEX","contract_market_name":"VIX FUTURES"},{"cftc_contract_market_code":"43874A","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"DIVIDEND INDICES","contract_market_name":"S&P 500 ANNUAL DIVIDEND INDEX"},{"cftc_contract_market_code":"43874Q","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"DIVIDEND INDICES","contract_market_name":"S&P 500 QUARTERLY DIVIDEND IND"},{"cftc_contract_market_code":"12460+","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"DOW JONES BROAD BASED INDICES","contract_market_name":"DJIA Consolidated"},{"cftc_contract_market_code":"124606","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"DOW JONES BROAD BASED INDICES","contract_market_name":"DOW JONES U.S. REAL ESTATE IDX"},{"cftc_contract_market_code":"124603","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"DOW JONES BROAD BASED INDICES","contract_market_name":"DJIA x $5"},{"cftc_contract_market_code":"244041","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"MSCI INDICES","contract_market_name":"MSCI EAFE"},{"cftc_contract_market_code":"244042","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"MSCI INDICES","contract_market_name":"MSCI EM INDEX"},{"cftc_contract_market_code":"209747","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"NASDAQ BROADBASED INDICES","contract_market_name":"MICRO E-MINI NASDAQ-100 INDEX"},{"cftc_contract_market_code":"209742","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"NASDAQ BROADBASED INDICES","contract_market_name":"NASDAQ MINI"},{"cftc_contract_market_code":"20974+","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"NASDAQ BROADBASED INDICES","contract_market_name":"NASDAQ-100 Consolidated"},{"cftc_contract_market_code":"240741","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"NIKKEI STOCK AVERAGE","contract_market_name":"NIKKEI STOCK AVERAGE"},{"cftc_contract_market_code":"240743","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"NIKKEI STOCK AVERAGE","contract_market_name":"NIKKEI STOCK AVERAGE YEN DENOM"},{"cftc_contract_market_code":"239744","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"RUSSELL INDEX","contract_market_name":"EMINI RUSSELL 1000 VALUE INDEX"},{"cftc_contract_market_code":"239742","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"RUSSELL INDEX","contract_market_name":"RUSSELL E-MINI"},{"cftc_contract_market_code":"239747","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"RUSSELL INDEX","contract_market_name":"MICRO E-MINI RUSSELL 2000 INDX"},{"cftc_contract_market_code":"13874I","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"S&P BROAD BASED STOCK INDICES","contract_market_name":"E-MINI S&P TECHNOLOGY INDEX"},{"cftc_contract_market_code":"138748","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"S&P BROAD BASED STOCK INDICES","contract_market_name":"E-MINI S&P CONSU STAPLES INDEX"},{"cftc_contract_market_code":"13874A","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"S&P BROAD BASED STOCK INDICES","contract_market_name":"E-MINI S&P 500"},{"cftc_contract_market_code":"138749","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"S&P BROAD BASED STOCK INDICES","contract_market_name":"E-MINI S&P ENERGY INDEX"},{"cftc_contract_market_code":"13874W","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"S&P BROAD BASED STOCK INDICES","contract_market_name":"ADJUSTED INT RATE S&P 500 TOTL"},{"cftc_contract_market_code":"13874+","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"S&P BROAD BASED STOCK INDICES","contract_market_name":"S&P 500 Consolidated"},{"cftc_contract_market_code":"13874C","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"S&P BROAD BASED STOCK INDICES","contract_market_name":"E-MINI S&P FINANCIAL INDEX"},{"cftc_contract_market_code":"33874A","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"S&P BROAD BASED STOCK INDICES","contract_market_name":"E-MINI S&P 400 STOCK INDEX"},{"cftc_contract_market_code":"13874U","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"S&P BROAD BASED STOCK INDICES","contract_market_name":"MICRO E-MINI S&P 500 INDEX"},{"cftc_contract_market_code":"13874J","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"S&P BROAD BASED STOCK INDICES","contract_market_name":"E-MINI S&P UTILITIES INDEX"},{"cftc_contract_market_code":"13874R","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"STOCK INDICES","commodity_name":"S&P BROAD BASED STOCK INDICES","contract_market_name":"E-MINI S&P REAL ESTATE INDEX"},{"cftc_contract_market_code":"191696","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"BASE METALS","commodity_name":"ALUMINUM","contract_market_name":"ALUMINIUM EURO PREM DUTY-PAID"},{"cftc_contract_market_code":"191693","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"BASE METALS","commodity_name":"ALUMINUM","contract_market_name":"ALUMINUM MWP"},{"cftc_contract_market_code":"191691","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"BASE METALS","commodity_name":"ALUMINUM","contract_market_name":"ALUMINUM"},{"cftc_contract_market_code":"188691","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"BASE METALS","commodity_name":"COBALT","contract_market_name":"COBALT"},{"cftc_contract_market_code":"085692","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"BASE METALS","commodity_name":"COPPER","contract_market_name":"COPPER- #1"},{"cftc_contract_market_code":"189691","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"BASE METALS","commodity_name":"LITHIUM","contract_market_name":"LITHIUM HYDROXIDE"},{"cftc_contract_market_code":"192691","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"BASE METALS","commodity_name":"STEEL","contract_market_name":"NORTH EURO HOT-ROLL COIL STEEL"},{"cftc_contract_market_code":"192651","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"BASE METALS","commodity_name":"STEEL","contract_market_name":"STEEL-HRC"},{"cftc_contract_market_code":"406651","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"CHEMICALS","commodity_name":"PROPYLENE","contract_market_name":"PGP PROPYLENE (PCW) CAL"},{"cftc_contract_market_code":"06439B","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM AEP DAYTON RT PEAK FIXED"},{"cftc_contract_market_code":"064394","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM WESTERN HUB RT OFF"},{"cftc_contract_market_code":"06439Q","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT Houston 345KV RT OFF FIX"},{"cftc_contract_market_code":"06439F","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM AEP DAYTON DA PEAK"},{"cftc_contract_market_code":"064392","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"MID-C DAY-AHEAD OFF-PEAK"},{"cftc_contract_market_code":"064396","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"CAISO SP-15 DA OFF-PK FIXED"},{"cftc_contract_market_code":"06439L","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"MISO IN. REAL-TIME OFF-PEAK"},{"cftc_contract_market_code":"064395","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"SP15 FIN DA PEAK FIXED"},{"cftc_contract_market_code":"06439V","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT WEST 345KV RT PEAK"},{"cftc_contract_market_code":"0643A5","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT NORTH 345KV DA PK DLY FI"},{"cftc_contract_market_code":"06439U","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT-SOUTH MONTHLY OFFPEAK"},{"cftc_contract_market_code":"06439C","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM AEP DAYTON HUB DA OFF-PK"},{"cftc_contract_market_code":"0643BG","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ISO NE MASS HUB DA PEAK"},{"cftc_contract_market_code":"0643BW","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"NYISO ZONE J DA PEAK"},{"cftc_contract_market_code":"0643BT","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM N. IL HUB RT PEAK"},{"cftc_contract_market_code":"0643BR","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"CAISO NP-15 DA OFF-PK FIXED"},{"cftc_contract_market_code":"0643A8","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT - NORTH MONTHLY OFF-PEAK"},{"cftc_contract_market_code":"06439K","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"MISO INDIANA OFF-PEAK"},{"cftc_contract_market_code":"0643DB","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM WESTERN HUB DA OFF-PK"},{"cftc_contract_market_code":"0643BX","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"NYISO ZONE J DA OFF-PK FIXED"},{"cftc_contract_market_code":"064AAB","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ISONE.H.INTERNAL_HB_mo_off_dap"},{"cftc_contract_market_code":"064DEV","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"NYISO.WEST_month_off_dap"},{"cftc_contract_market_code":"0643BF","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ISO NE MASS HUB DA OFF-PK FIXD"},{"cftc_contract_market_code":"06439R","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT NORTH 345KV RT PK FIX"},{"cftc_contract_market_code":"0643DL","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM PSEG DAY-AHEAD PEAK"},{"cftc_contract_market_code":"0643CB","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PALO VERDE DA PEAK"},{"cftc_contract_market_code":"064EUZ","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.PECO_month_off_dap"},{"cftc_contract_market_code":"064DPQ","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.BGE_month_on_dap"},{"cftc_contract_market_code":"0643BM","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"CAISO NP-15 PEAK"},{"cftc_contract_market_code":"06439S","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT SOUTH 345 KV RT PEAK FIX"},{"cftc_contract_market_code":"064EVH","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.PEPCO_month_off_dap"},{"cftc_contract_market_code":"0643D8","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM PPL ZONE DA PEAK"},{"cftc_contract_market_code":"064EVB","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.PENELEC_month_off_dap"},{"cftc_contract_market_code":"064EUY","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.PECO_month_on_dap"},{"cftc_contract_market_code":"0643BS","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM NI HUB RT OFF-PK FIXED"},{"cftc_contract_market_code":"06439W","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT WEST 345K RT OFF-PEAK"},{"cftc_contract_market_code":"064FKD","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.N ILLINOIS HUB_mo_off_rtp"},{"cftc_contract_market_code":"064BFI","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"MISO.INDIANA.HUB_month_on_dap"},{"cftc_contract_market_code":"064IBM","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT North 345KV Hub RT 7x16"},{"cftc_contract_market_code":"064EVA","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.PENELEC_month_on_dap"},{"cftc_contract_market_code":"0643C3","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"NYISO ZONE G DA PEAK"},{"cftc_contract_market_code":"064391","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"MID-C DAY-AHEAD PEAK"},{"cftc_contract_market_code":"0643B3","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"MISO INDIANA HUB RT PEAK"},{"cftc_contract_market_code":"064BFJ","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"MISO.INDIANA.HUB_month_off_dap"},{"cftc_contract_market_code":"06439A","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM AEP DAYTON RT OFF-PK FIXED"},{"cftc_contract_market_code":"064EWU","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.PPL_month_on_dap"},{"cftc_contract_market_code":"0643IB","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT N 345KV REAL T PK DALY M"},{"cftc_contract_market_code":"0643AZ","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"MISO IN. DAY-AHEAD PEAK"},{"cftc_contract_market_code":"0643BY","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"NYISO ZONE A DA PEAK"},{"cftc_contract_market_code":"064CZS","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"NYISO.N.Y.C._month_on_dap"},{"cftc_contract_market_code":"06439N","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT HOUSTON 345KV RT PK FIX"},{"cftc_contract_market_code":"064FJZ","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"MISO.INDIANA.HUB_month_off_rtp"},{"cftc_contract_market_code":"064AAA","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ISONE.H.INTERNAL_HUB_mo_on_dap"},{"cftc_contract_market_code":"0643BC","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM N. IL HUB DA OFF-PK"},{"cftc_contract_market_code":"0643C4","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"NYISO ZONE G DA OFF-PK"},{"cftc_contract_market_code":"064CZT","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"NYISO.N.Y.C._month_off_dap"},{"cftc_contract_market_code":"0643BZ","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"NYISO ZONE A DA OFF-PK FIX PR"},{"cftc_contract_market_code":"064FKF","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.WESTERN HUB_month_off_rtp"},{"cftc_contract_market_code":"064CTQ","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"NYISO.CENTRL_month_on_dap"},{"cftc_contract_market_code":"0643BE","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM N. IL HUB DA PEAK"},{"cftc_contract_market_code":"0643D7","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM PPL ZONE DA OFF-PEAK FIXED"},{"cftc_contract_market_code":"064DLW","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.AEP-DAYTON HUB_mo_on_dap"},{"cftc_contract_market_code":"0643DM","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM PSEG DA OFF-PK FIXED PRICE"},{"cftc_contract_market_code":"064CXO","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"NYISO.HUD VL_month_on_dap"},{"cftc_contract_market_code":"0643CC","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PALO VERDE DA OFF-PK FiXED PR"},{"cftc_contract_market_code":"0643DC","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM WESTERN HUB DA PEAK"},{"cftc_contract_market_code":"064DZS","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.DOM_month_on_dap"},{"cftc_contract_market_code":"0643IK","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT North 345KV Hub RT 7x8"},{"cftc_contract_market_code":"064DPR","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.BGE_month_off_dap"},{"cftc_contract_market_code":"064CXP","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"NYISO.HUD VL_month_off_dap"},{"cftc_contract_market_code":"0643DF","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM WESTERN HUB RT PEAK MINI"},{"cftc_contract_market_code":"064ERN","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.N ILLINOIS HUB_mo_off_dap"},{"cftc_contract_market_code":"064DLX","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.AEP-DAYTON HUB_mo_off_dap"},{"cftc_contract_market_code":"064EJI","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.JCPL_month_on_dap"},{"cftc_contract_market_code":"064EJJ","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.JCPL_month_off_dap"},{"cftc_contract_market_code":"0643ID","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT N 345KV REAL T PK 2x16"},{"cftc_contract_market_code":"064EWV","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.PPL_month_off_dap"},{"cftc_contract_market_code":"064DZT","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.DOM_month_off_dap"},{"cftc_contract_market_code":"064IAZ","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM DOM ZONE DAY AHEAD PEAK"},{"cftc_contract_market_code":"064FHL","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.WESTERN HUB_month_off_dap"},{"cftc_contract_market_code":"0643IL","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT Houston 345KV Hub RT 7x8"},{"cftc_contract_market_code":"064FKA","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.AEP-DAYTON HUB_mo_on_rtp"},{"cftc_contract_market_code":"064EVG","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.PEPCO_month_on_dap"},{"cftc_contract_market_code":"064FOL","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT.HB_NORTH_month_off_rtp"},{"cftc_contract_market_code":"064DEU","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"NYISO.WEST_month_on_dap"},{"cftc_contract_market_code":"064FKC","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.N ILLINOIS HUB_mo_on_rtp"},{"cftc_contract_market_code":"064FJY","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"MISO.INDIANA.HUB_month_on_rtp"},{"cftc_contract_market_code":"064EOW","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.METED_month_on_dap"},{"cftc_contract_market_code":"064FKB","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.AEP-DAYTON HUB_mo_off_rtp"},{"cftc_contract_market_code":"064ERM","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.N ILLINOIS HUB_mo_on_dap"},{"cftc_contract_market_code":"064FKE","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.WESTERN HUB_month_on_rtp"},{"cftc_contract_market_code":"064EXE","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.PSEG_month_on_dap"},{"cftc_contract_market_code":"064FOK","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"ERCOT.HB_NORTH_month_on_rtp"},{"cftc_contract_market_code":"064EXF","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.PSEG_month_off_dap"},{"cftc_contract_market_code":"064FHK","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"ELECTRICITY AND SOURCES","commodity_name":"ELECTRICITY","contract_market_name":"PJM.WESTERN HUB_month_on_dap"},{"cftc_contract_market_code":"0063E5","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"CALIF CARBON ALL VINTAGE 2025"},{"cftc_contract_market_code":"0063CH","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"PJM TRI-RECs CLASS 1"},{"cftc_contract_market_code":"0063DA","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"PA SOLAR ALTER ENERGY CREDIT"},{"cftc_contract_market_code":"0063DM","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"MARYLAND COMPLIANCE REC TIER1"},{"cftc_contract_market_code":"006NGF","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"CALIF LOW CARBON FUEL STANDARD"},{"cftc_contract_market_code":"0063CU","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"CALIF LOW CARBON FSC-OPIS"},{"cftc_contract_market_code":"006NHU","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"TX REC CRS V27 BACK HALF"},{"cftc_contract_market_code":"0063DG","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"D4 BIODIESEL RINs OPIS CURR YR"},{"cftc_contract_market_code":"0063DL","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"MASS COMPLIANCE RECs CLASS 1"},{"cftc_contract_market_code":"006NHT","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"TX REC CRS V26 BACK HALF"},{"cftc_contract_market_code":"0063CW","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"D6 RINs OPIS CURRENT YEAR"},{"cftc_contract_market_code":"006NHZ","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"TX REC CRS V27 FRONT HALF"},{"cftc_contract_market_code":"006NH2","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"PENNSYLVANIA AEC TIER 2-V2025"},{"cftc_contract_market_code":"0063E2","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"CALIF CARBON ALLOWANCE V2024"},{"cftc_contract_market_code":"0063DN","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"MARYLAND SOLAR REC"},{"cftc_contract_market_code":"006NHY","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"TX REC CRS V26 FRONT HALF"},{"cftc_contract_market_code":"006NFH","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"TX GREEN-E REC V24 FRONT HALF"},{"cftc_contract_market_code":"0063DT","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"PA COMPLIANCE AECs TIER1"},{"cftc_contract_market_code":"00665T","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"CBL NATURE GLOBAL EMISSIONS"},{"cftc_contract_market_code":"006NG3","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"TX GREEN-E REC V24 BACK HALF"},{"cftc_contract_market_code":"006NFJ","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"TX GREEN-E REC V25 FRONT HALF"},{"cftc_contract_market_code":"006NJZ","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"CBL GLOBAL EMISSIONS OFFSET"},{"cftc_contract_market_code":"006NKV","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"NEW JERSEY RECs CLASS 2 V2025"},{"cftc_contract_market_code":"0063CC","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"NJ SRECS"},{"cftc_contract_market_code":"0063DB","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"CALIF CARBON CURRENT AUCTION"},{"cftc_contract_market_code":"006NG4","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"TX GREEN-E REC V25 BACK HALF"},{"cftc_contract_market_code":"006NGQ","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"CALIF CARBON ALLOWANCE V2024"},{"cftc_contract_market_code":"023393","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"SOCAL BORDER FIN BASIS"},{"cftc_contract_market_code":"0233AG","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"HENRY HUB BASIS"},{"cftc_contract_market_code":"023397","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"CHICAGO FIN BASIS"},{"cftc_contract_market_code":"023392","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"NAT GAS ICE PEN"},{"cftc_contract_market_code":"02339W","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"TCO Basis"},{"cftc_contract_market_code":"02339E","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"ALGONQUIN CITYGATES BASIS"},{"cftc_contract_market_code":"0233BB","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"NNG VENTURA BASIS"},{"cftc_contract_market_code":"023398","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"HSC FIN BASIS"},{"cftc_contract_market_code":"023394","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"PG&E CITYGATE FIN BASIS"},{"cftc_contract_market_code":"0233A3","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"DOMINION - SOUTH POINT (BASIS)"},{"cftc_contract_market_code":"0233AH","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"HENRY HUB INDEX"},{"cftc_contract_market_code":"0233CW","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"TRANSCO STATION 85-ZONE 4 BASI"},{"cftc_contract_market_code":"02339S","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"CIG ROCKIES FINANCIAL INDEX"},{"cftc_contract_market_code":"023396","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"AECO FIN BASIS"},{"cftc_contract_market_code":"0233AY","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"NGPL MIDCONT BASIS"},{"cftc_contract_market_code":"0233AQ","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"MICHCON BASIS"},{"cftc_contract_market_code":"0233AT","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"NAT GAS LD1 for GDD -TEXOK"},{"cftc_contract_market_code":"02339U","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"CIG ROCKIES BASIS"},{"cftc_contract_market_code":"0233BW","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"SOCAL (INDEX)"},{"cftc_contract_market_code":"0233B1","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"NGPL TXOK BASIS"},{"cftc_contract_market_code":"0233CS","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"TRANSCO STN 85 MONTHLY INDEX"},{"cftc_contract_market_code":"023391","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"NAT GAS ICE LD1"},{"cftc_contract_market_code":"02339Y","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"CG Mainline Basis"},{"cftc_contract_market_code":"0233DR","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"TETCO M2 Basis (Receipts)"},{"cftc_contract_market_code":"0233BL","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"PANHANDLE BASIS"},{"cftc_contract_market_code":"0233CV","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"TRANSCO ZONE 6 MONTHLY INDEX"},{"cftc_contract_market_code":"023395","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"NWP ROCKIES FIN BASIS"},{"cftc_contract_market_code":"0233BH","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"MALIN (BASIS)"},{"cftc_contract_market_code":"0233BD","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"NWP Rockies Index"},{"cftc_contract_market_code":"0233DW","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"TETCO M2 Index (Receipts)"},{"cftc_contract_market_code":"0233BY","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"SOCAL CITYGATE FINANCIAL BASIS"},{"cftc_contract_market_code":"0233DT","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"TRANSCO LEIDY BASIS"},{"cftc_contract_market_code":"02339Q","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"CHICAGO CITYGATE (INDEX)"},{"cftc_contract_market_code":"0233CH","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"TETCO M3 BASIS"},{"cftc_contract_market_code":"0233D4","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"WAHA INDEX"},{"cftc_contract_market_code":"0233EB","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"REX ZONE 3 BASIS"},{"cftc_contract_market_code":"0233FK","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"TRANSCO ZONE 5 SOUTH INDEX"},{"cftc_contract_market_code":"0233AM","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"HOUSTON SHIP CHANNEL (INDEX)"},{"cftc_contract_market_code":"0233CM","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"TGT ZONE 1 BASIS"},{"cftc_contract_market_code":"023A55","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"HENRY HUB LAST DAY FIN"},{"cftc_contract_market_code":"0233FJ","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"Transco Zone 5 South Basis"},{"cftc_contract_market_code":"0233CG","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"TETCO M3 INDEX"},{"cftc_contract_market_code":"0233CU","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"TRANSCO ZONE 6 BASIS"},{"cftc_contract_market_code":"023A84","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"NATURAL GAS CAL SPREAD OPT FIN"},{"cftc_contract_market_code":"023A56","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"HENRY HUB PENULTIMATE FIN"},{"cftc_contract_market_code":"03565B","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"HENRY HUB"},{"cftc_contract_market_code":"0233ED","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"REX ZONE 3 INDEX"},{"cftc_contract_market_code":"023399","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"WAHA FIN BASIS"},{"cftc_contract_market_code":"0233A2","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"DOMINION - SOUTH POINT"},{"cftc_contract_market_code":"023651","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"NAT GAS NYME"},{"cftc_contract_market_code":"0233A8","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"EP SAN JUAN BASIS"},{"cftc_contract_market_code":"0233AN","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"MICHCON FINANCIAL INDEX"},{"cftc_contract_market_code":"02365U","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"EUR STYLE NATURAL GAS OPTIONS"},{"cftc_contract_market_code":"0233AW","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"ALGONQUIN CITYGATES INDEX"},{"cftc_contract_market_code":"0233BC","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"NWP SUMAS BASIS"},{"cftc_contract_market_code":"0233C1","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"SONAT - TIER 1 POOL (ZONE 0)"},{"cftc_contract_market_code":"03565C","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS","contract_market_name":"HENRY HUB PENULTIMATE NAT GAS"},{"cftc_contract_market_code":"06665P","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"MT BELVIEU ETHANE OPIS"},{"cftc_contract_market_code":"066416","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"ETHANE, MT. BELV-ENTERPRISE"},{"cftc_contract_market_code":"06665T","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"CONWAY PROPANE (OPIS)"},{"cftc_contract_market_code":"06641F","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"PROPANE OPIS MT BELV NONTET FP"},{"cftc_contract_market_code":"06641A","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"NAT GASLNE OPIS MT B NONTET FP"},{"cftc_contract_market_code":"066413","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"ARGUS FAR EAST PROPANE"},{"cftc_contract_market_code":"066393","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"PROPANE ARGUS FAR EAST MINI"},{"cftc_contract_market_code":"06665B","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"ARGUS PROPANE FAR EAST INDEX"},{"cftc_contract_market_code":"06641E","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"PROPANE OPIS CONWAY INWELL FP"},{"cftc_contract_market_code":"06665O","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"PROPANE"},{"cftc_contract_market_code":"06641G","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"PROPANE OPIS MT BELVIEU TET FP"},{"cftc_contract_market_code":"06665R","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"MT BELV NAT GASOLINE OPIS"},{"cftc_contract_market_code":"06665G","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"PROPANE NON-LDH MT BEL"},{"cftc_contract_market_code":"06641H","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"PROPANE ARGUS SAUDI CP FP"},{"cftc_contract_market_code":"06641D","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"BUTANE OPIS MT BELV NONTET FP"},{"cftc_contract_market_code":"06665Q","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"NATURAL GAS AND PRODUCTS","commodity_name":"NATURAL GAS LIQUIDS","contract_market_name":"MT BELV NORM BUTANE OPIS"},{"cftc_contract_market_code":"06765T","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"CRUDE OIL","contract_market_name":"BRENT LAST DAY"},{"cftc_contract_market_code":"06739C","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"CRUDE OIL","contract_market_name":"CRUDE DIFF-WCS HOUSTON\/WTI 1ST"},{"cftc_contract_market_code":"06743A","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"CRUDE OIL","contract_market_name":"CONDENSATE DIF-TMX C5 1A INDEX"},{"cftc_contract_market_code":"06742G","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"CRUDE OIL","contract_market_name":"CRUDE DIFF-TMX WCS 1A INDEX"},{"cftc_contract_market_code":"06765A","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"CRUDE OIL","contract_market_name":"WTI FINANCIAL CRUDE OIL"},{"cftc_contract_market_code":"067A28","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"CRUDE OIL","contract_market_name":"CRUDE OIL CAL SPREAD OPT FIN"},{"cftc_contract_market_code":"06765C","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"CRUDE OIL","contract_market_name":"CRUDE OIL AVG PRICE OPTIONS"},{"cftc_contract_market_code":"0676A5","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"CRUDE OIL","contract_market_name":"WTI HOUSTON ARGUS\/WTI TR MO"},{"cftc_contract_market_code":"06742T","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"CRUDE OIL","contract_market_name":"CRUDE DIFF-TMX SW 1A INDEX"},{"cftc_contract_market_code":"067A71","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"CRUDE OIL","contract_market_name":"WTI MIDLAND ARGUS VS WTI TRADE"},{"cftc_contract_market_code":"067651","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"CRUDE OIL","contract_market_name":"WTI-PHYSICAL"},{"cftc_contract_market_code":"067411","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"CRUDE OIL","contract_market_name":"CRUDE OIL, LIGHT SWEET-WTI"},{"cftc_contract_market_code":"025608","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"ETHANOL","contract_market_name":"ETHANOL T2 FOB INCL DUTY"},{"cftc_contract_market_code":"025651","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"ETHANOL","contract_market_name":"ETHANOL"},{"cftc_contract_market_code":"02165A","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"FUEL OIL","contract_market_name":"GULF # 6 FUEL 3.0% SULFUR"},{"cftc_contract_market_code":"021397","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"FUEL OIL","contract_market_name":"MARINE FUEL OIL 0.5% FOB USGC"},{"cftc_contract_market_code":"02141B","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"FUEL OIL","contract_market_name":"USGC HSFO (PLATTS)"},{"cftc_contract_market_code":"02141C","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"FUEL OIL","contract_market_name":"FUEL OIL-3% USGC\/3.5% FOB RDAM"},{"cftc_contract_market_code":"02141R","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"FUEL OIL","contract_market_name":"USGC HSFO-PLATTS\/BRENT 1ST LN"},{"cftc_contract_market_code":"86565A","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"FUEL OIL\/CRUDE OIL","contract_market_name":"GULF # 6 FUEL OIL CRACK"},{"cftc_contract_market_code":"865392","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"FUEL OIL\/CRUDE OIL","contract_market_name":"MARINE .5% FOB USGC\/BRENT 1st"},{"cftc_contract_market_code":"111659","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"GASOLINE","contract_market_name":"GASOLINE RBOB"},{"cftc_contract_market_code":"111415","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"GASOLINE","contract_market_name":"GASOLINE CRK-RBOB\/BRENT 1st"},{"cftc_contract_market_code":"111A34","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"GASOLINE","contract_market_name":"GULF COAST CBOB GAS A2 PL RBOB"},{"cftc_contract_market_code":"022A13","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"HEATING OIL-DIESEL-GASOIL","contract_market_name":"UP DOWN GC ULSD VS HO SPR"},{"cftc_contract_market_code":"022651","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"HEATING OIL-DIESEL-GASOIL","contract_market_name":"NY HARBOR ULSD"},{"cftc_contract_market_code":"86465A","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PETROLEUM AND PRODUCTS","commodity_name":"JET FUEL\/HEATING OIL","contract_market_name":"GULF JET NY HEAT OIL SPR"},{"cftc_contract_market_code":"088695","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PRECIOUS METALS","commodity_name":"GOLD","contract_market_name":"MICRO GOLD"},{"cftc_contract_market_code":"088691","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PRECIOUS METALS","commodity_name":"GOLD","contract_market_name":"GOLD"},{"cftc_contract_market_code":"075651","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PRECIOUS METALS","commodity_name":"PALLADIUM","contract_market_name":"PALLADIUM"},{"cftc_contract_market_code":"076651","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PRECIOUS METALS","commodity_name":"PLATINUM","contract_market_name":"PLATINUM"},{"cftc_contract_market_code":"084691","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"PRECIOUS METALS","commodity_name":"SILVER","contract_market_name":"SILVER"},{"cftc_contract_market_code":"058644","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"WOOD PRODUCTS","commodity_name":"LUMBER","contract_market_name":"LUMBER"},{"cftc_contract_market_code":"047745","commodity_group_name":"FINANCIAL INSTRUMENTS","commodity_subgroup_name":"INTEREST RATES - NON U.S. TREASURY","commodity_name":"OVERNIGHT RATES","contract_market_name":"EURO SHORT TERM RATE"},{"cftc_contract_market_code":"0063E9","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"WASHINGTON CARBON ALL V2024"},{"cftc_contract_market_code":"0063EB","commodity_group_name":"NATURAL RESOURCES","commodity_subgroup_name":"EMISSIONS","commodity_name":"POLLUTION","contract_market_name":"RGGI V2024"}] \ No newline at end of file diff --git a/openbb_platform/providers/cftc/openbb_cftc/cftc_router.py b/openbb_platform/providers/cftc/openbb_cftc/cftc_router.py new file mode 100644 index 00000000000..8a794d1b5aa --- /dev/null +++ b/openbb_platform/providers/cftc/openbb_cftc/cftc_router.py @@ -0,0 +1,159 @@ +"""Commodity Futures Trading Commission (CFTC) Router.""" + +# pylint: disable=W0212,W0613 + +from typing import Any + +from openbb_core.app.model.command_context import CommandContext +from openbb_core.app.model.example import APIEx +from openbb_core.app.model.obbject import OBBject +from openbb_core.app.provider_interface import ( + ExtraParams, + ProviderChoices, + StandardParams, +) +from openbb_core.app.query import Query +from openbb_core.app.router import Router + +router = Router(prefix="") +COT_CHOICES: list[dict[str, str | dict[str, str | None]]] = [] + + +async def build_choices(): + """Build the choices for Workspace.""" + # pylint: disable=import-outside-toplevel + from openbb_cftc.models.cot_search import CftcCotSearchFetcher + + contracts = await CftcCotSearchFetcher.fetch_data({}, {}) + choices: list[dict[str, str | dict[str, str | None]]] = [] + + for d in contracts: + choice: dict[str, str | dict[str, str | None]] = { + "label": d.name.strip(), # type: ignore + "value": d.code.strip(), # type: ignore + "extraInfo": {"description": f"{d.subcategory.strip()} | {d.code.strip()}", "rightOfDescription": ""}, # type: ignore + } + choices.append(choice) + + global COT_CHOICES # noqa: PLW0603 # pylint: disable=W0603 + + COT_CHOICES = choices + + +router.api_router.add_event_handler("startup", build_choices) + + +async def get_cot_choices() -> list[dict[str, str | dict[str, str | None]]]: + """Get the choices for the COT command in Workspace.""" + return COT_CHOICES + + +router._api_router.add_api_route( + path="/get_cot_choices", + endpoint=get_cot_choices, + methods=["GET"], + include_in_schema=False, +) + + +@router.command( + model="COTSearch", + examples=[ + APIEx(parameters={"provider": "cftc"}), + APIEx(parameters={"query": "gold", "provider": "cftc"}), + ], + widget_config={ + "name": "Commitment of Traders Search", + "description": "Search for CFTC Commitment of Traders (COT) report series.", + "category": "CFTC", + "subCategory": "COT", + "refetchInterval": False, + }, +) +async def cot_search( + cc: CommandContext, + provider_choices: ProviderChoices, + standard_params: StandardParams, + extra_params: ExtraParams, +) -> OBBject: + """Search current Commitment of Traders Reports.""" + return await OBBject.from_query(Query(**locals())) + + +@router.command( + model="COT", + examples=[ + APIEx(parameters={"provider": "ctfc"}), + APIEx( + description="Get the latest report for all items classified as, GOLD.", + parameters={"code": "CFTC_088691", "limit": 1, "provider": "cftc"}, + ), + APIEx( + description="Get the report for futures only.", + parameters={ + "code": "CFTC_088691", + "futures_only": True, + "limit": 1, + "provider": "cftc", + }, + ), + APIEx( + description="Filter the report down to a specific section.", + parameters={ + "code": "CFTC_088691", + "futures_only": True, + "measure": "changes", + "limit": 1, + "provider": "cftc", + }, + ), + ], + widget_config={ + "name": "Commitment of Traders", + "description": "CFTC Commitment of Traders (COT) reports.", + "category": "CFTC", + "subCategory": "COT", + "refetchInterval": False, + }, +) +async def cot( + cc: CommandContext, + provider_choices: ProviderChoices, + standard_params: StandardParams, + extra_params: ExtraParams, +) -> OBBject: + """Get Commitment of Traders Reports.""" + return await OBBject.from_query(Query(**locals())) + + +async def get_cftc_apps_json() -> list[dict[str, Any]]: + """Get the IMF apps.json file. + + This endpoint serves the apps.json file containing OpenBB Workspace app configurations. + It is automatically merged with any existing apps.json files in the Workspace and API. + + Returns + ------- + list[dict[str, Any]] + A list of OpenBB Workspace app configurations. + """ + # pylint: disable=import-outside-toplevel + import json + from pathlib import Path + + apps_file = Path(__file__).parent / "apps.json" + + try: + with apps_file.open("r", encoding="utf-8") as f: + apps_json = json.load(f) + return apps_json + except Exception: + return [] + + +router._api_router.add_api_route( + path="/apps.json", + endpoint=get_cftc_apps_json, + methods=["GET"], + include_in_schema=False, +) diff --git a/openbb_platform/providers/cftc/openbb_cftc/models/cot.py b/openbb_platform/providers/cftc/openbb_cftc/models/cot.py index 2cb0a3a79e0..ed28dbe599b 100644 --- a/openbb_platform/providers/cftc/openbb_cftc/models/cot.py +++ b/openbb_platform/providers/cftc/openbb_cftc/models/cot.py @@ -1,27 +1,21 @@ """CFTC Commitment of Traders Reports Model.""" -# pylint: disable=unused-argument +# pylint: disable=unused-argument,too-many-lines from datetime import ( datetime, ) from typing import Any, Literal +from openbb_cftc.utils import reports_dict from openbb_core.app.model.abstract.error import OpenBBError +from openbb_core.app.service.system_service import SystemService from openbb_core.provider.abstract.fetcher import Fetcher from openbb_core.provider.standard_models.cot import COTData, COTQueryParams from openbb_core.provider.utils.errors import EmptyDataError from pydantic import Field -reports_dict = { - "legacy_futures_only": "6dca-aqww", - "legacy_combined": "jun7-fc8e", - "disaggregated_futures_only": "72hh-3qpy", - "disaggregated_combined": "kh3c-gbw2", - "tff_futures_only": "gpe5-46if", - "tff_combined": "yw9f-hn96", - "supplemental": "4zgm-a668", -} +api_prefix = SystemService().system_settings.api_settings.prefix class CftcCotQueryParams(COTQueryParams): @@ -31,42 +25,1812 @@ class CftcCotQueryParams(COTQueryParams): """ __json_schema_extra__ = { + "code": { + "multiple_items_allowed": False, + "x-widget_config": { + "type": "endpoint", + "optionsEndpoint": f"{api_prefix}/cftc/get_cot_choices", + "style": {"popupWidth": 650}, + }, + }, "report_type": { "multiple_items_allowed": False, "choices": ["legacy", "disaggregated", "financial", "supplemental"], - } + }, + "measure": { + "multiple_items_allowed": False, + "choices": [ + "all", + "positions", + "changes", + "percent_of_oi", + "traders", + "concentration", + ], + }, } report_type: Literal["legacy", "disaggregated", "financial", "supplemental"] = ( Field( default="legacy", - description="""The type of report to retrieve. Set `id` as 'all' to return all items in the report - type (default date range returns the latest report). The Legacy report is broken down by exchange - with reported open interest further broken down into three trader classifications: commercial, - non-commercial and non-reportable. The Disaggregated reports are broken down by Agriculture and - Natural Resource contracts. The Disaggregated reports break down reportable open interest positions - into four classifications: Producer/Merchant, Swap Dealers, Managed Money and Other Reportables. - The Traders in Financial Futures (TFF) report includes financial contracts. The TFF report breaks - down the reported open interest into five classifications: Dealer, Asset Manager, Leveraged Money, - Other Reportables and Non-Reportables.""", + description="The type of report to retrieve.", ) ) + measure: Literal[ + "all", "positions", "changes", "percent_of_oi", "traders", "concentration" + ] = Field( + default="all", + description="Filter columns by measure type. Open interest is always included.", + ) futures_only: bool = Field( default=False, description="Returns the futures-only report. Default is False, for the combined report.", ) + limit: int | None = Field( + default=None, + description="Number of most recent reports to return. Default is all available.", + ) class CftcCotData(COTData): - """CFTC Commitment of Traders Reports Data.""" + """CFTC Commitment of Traders Reports Data. + + Fields are populated based on the report type selected. The Legacy report has + non-commercial and commercial classifications. The Disaggregated report has + producer/merchant, swap dealer, managed money, and other reportable classifications. + The Financial (TFF) report has dealer, asset manager, leveraged money, and other + reportable classifications. The Supplemental report adds commodity index trader (CIT) + and non-CIT breakdowns. Position data is reported for all contracts, with old crop year + and other crop year splits where applicable (Legacy and Disaggregated only). + """ __alias_dict__ = { - "date": "report_date_as_yyyy_mm_dd", - "report_week": "yyyy_report_week_ww", - "commodity_group": "commodity_group_name", + "asset_manager_positions_long": "asset_mgr_positions_long", + "asset_manager_positions_short": "asset_mgr_positions_short", + "asset_manager_positions_spread": "asset_mgr_positions_spread", + "change_commercial_long_all_non_cit": "change_comm_long_all_nocit", + "change_commercial_short_all_non_cit": "change_comm_short_all_nocit", + "change_in_asset_manager_long": "change_in_asset_mgr_long", + "change_in_asset_manager_short": "change_in_asset_mgr_short", + "change_in_asset_manager_spread": "change_in_asset_mgr_spread", + "change_in_commercial_long_all": "change_in_comm_long_all", + "change_in_commercial_short_all": "change_in_comm_short_all", + "change_in_leveraged_funds_long": "change_in_lev_money_long", + "change_in_leveraged_funds_short": "change_in_lev_money_short", + "change_in_leveraged_funds_spread": "change_in_lev_money_spread", + "change_in_managed_money_long_all": "change_in_m_money_long_all", + "change_in_managed_money_short_all": "change_in_m_money_short_all", + "change_in_managed_money_spread": "change_in_m_money_spread", + "change_in_non_commercial_long_all": "change_in_noncomm_long_all", + "change_in_non_commercial_short_all": "change_in_noncomm_short_all", + "change_in_non_commercial_spread_all": "change_in_noncomm_spead_all", + "change_in_non_reportable_long_all": "change_in_nonrept_long_all", + "change_in_non_reportable_short_all": "change_in_nonrept_short_all", + "change_in_other_reportable_long": "change_in_other_rept_long", + "change_in_other_reportable_short": "change_in_other_rept_short", + "change_in_other_reportable_spread": "change_in_other_rept_spread", + "change_in_producer_merchant_long": "change_in_prod_merc_long", + "change_in_producer_merchant_short": "change_in_prod_merc_short", + "change_in_total_reportable_long_all": "change_in_tot_rept_long_all", + "change_in_total_reportable_short": "change_in_tot_rept_short", + "change_non_commercial_long_all_non_cit": "change_noncomm_long_all_nocit", + "change_non_commercial_short_all_non_cit": "change_noncomm_short_all_nocit", + "change_non_commercial_spread_all_non_cit": "change_noncomm_spead_all_nocit", + "change_non_reportable_long_all": "change_nonrept_long_all", + "change_non_reportable_short_all": "change_nonrept_short_all", + "change_total_reportable_long_all": "change_tot_rept_long_all", + "change_total_reportable_short_all": "change_tot_rept_short_all", + "commercial_positions_long_all": "comm_positions_long_all", + "commercial_positions_long_all_non_cit": "comm_positions_long_all_nocit", + "commercial_positions_long_old": "comm_positions_long_old", + "commercial_positions_long_other": "comm_positions_long_other", + "commercial_positions_short_all": "comm_positions_short_all", + "commercial_positions_short_all_non_cit": "comm_positions_short_all_nocit", + "commercial_positions_short_old": "comm_positions_short_old", + "commercial_positions_short_other": "comm_positions_short_other", "commodity": "commodity_name", + "commodity_group": "commodity_group_name", "commodity_subgroup": "commodity_subgroup_name", + "concentration_gross_top_4_traders_long": "conc_gross_le_4_tdr_long", + "concentration_gross_top_4_traders_long_1": "conc_gross_le_4_tdr_long_1", + "concentration_gross_top_4_traders_long_2": "conc_gross_le_4_tdr_long_2", + "concentration_gross_top_4_traders_short": "conc_gross_le_4_tdr_short", + "concentration_gross_top_4_traders_short_1": "conc_gross_le_4_tdr_short_1", + "concentration_gross_top_4_traders_short_2": "conc_gross_le_4_tdr_short_2", + "concentration_gross_top_8_traders_long": "conc_gross_le_8_tdr_long", + "concentration_gross_top_8_traders_long_1": "conc_gross_le_8_tdr_long_1", + "concentration_gross_top_8_traders_long_2": "conc_gross_le_8_tdr_long_2", + "concentration_gross_top_8_traders_short": "conc_gross_le_8_tdr_short", + "concentration_gross_top_8_traders_short_1": "conc_gross_le_8_tdr_short_1", + "concentration_gross_top_8_traders_short_2": "conc_gross_le_8_tdr_short_2", + "concentration_net_top_4_traders_long_all": "conc_net_le_4_tdr_long_all", + "concentration_net_top_4_traders_long_old": "conc_net_le_4_tdr_long_old", + "concentration_net_top_4_traders_long_other": "conc_net_le_4_tdr_long_other", + "concentration_net_top_4_traders_short_all": "conc_net_le_4_tdr_short_all", + "concentration_net_top_4_traders_short_old": "conc_net_le_4_tdr_short_old", + "concentration_net_top_4_traders_short_other": "conc_net_le_4_tdr_short_other", + "concentration_net_top_8_traders_long_all": "conc_net_le_8_tdr_long_all", + "concentration_net_top_8_traders_long_old": "conc_net_le_8_tdr_long_old", + "concentration_net_top_8_traders_long_other": "conc_net_le_8_tdr_long_other", + "concentration_net_top_8_traders_short_all": "conc_net_le_8_tdr_short_all", + "concentration_net_top_8_traders_short_old": "conc_net_le_8_tdr_short_old", + "concentration_net_top_8_traders_short_other": "conc_net_le_8_tdr_short_other", + "date": "report_date_as_yyyy_mm_dd", + "leveraged_funds_positions_long": "lev_money_positions_long", + "leveraged_funds_positions_short": "lev_money_positions_short", + "leveraged_funds_positions_spread": "lev_money_positions_spread", + "managed_money_positions_long_all": "m_money_positions_long_all", + "managed_money_positions_long_old": "m_money_positions_long_old", + "managed_money_positions_long_other": "m_money_positions_long_other", + "managed_money_positions_short_all": "m_money_positions_short_all", + "managed_money_positions_short_old": "m_money_positions_short_old", + "managed_money_positions_short_other": "m_money_positions_short_other", + "managed_money_positions_spread": "m_money_positions_spread", + "managed_money_positions_spread_1": "m_money_positions_spread_1", + "managed_money_positions_spread_2": "m_money_positions_spread_2", + "non_commercial_positions_long_all": "noncomm_positions_long_all", + "non_commercial_positions_long_all_non_cit": "ncomm_postions_long_all_nocit", + "non_commercial_positions_long_old": "noncomm_positions_long_old", + "non_commercial_positions_long_other": "noncomm_positions_long_other", + "non_commercial_positions_short_all": "noncomm_positions_short_all", + "non_commercial_positions_short_all_non_cit": "ncomm_postions_short_all_nocit", + "non_commercial_positions_short_old": "noncomm_positions_short_old", + "non_commercial_positions_short_other": "noncomm_positions_short_other", + "non_commercial_positions_spread": "noncomm_positions_spread", + "non_commercial_positions_spread_1": "noncomm_positions_spread_1", + "non_commercial_positions_spread_all": "noncomm_postions_spread_all", + "non_commercial_positions_spread_all_non_cit": "ncomm_postions_spread_all_nocit", + "non_reportable_positions_long_all": "nonrept_positions_long_all", + "non_reportable_positions_long_old": "nonrept_positions_long_old", + "non_reportable_positions_long_other": "nonrept_positions_long_other", + "non_reportable_positions_short_all": "nonrept_positions_short_all", + "non_reportable_positions_short_old": "nonrept_positions_short_old", + "non_reportable_positions_short_other": "nonrept_positions_short_other", + "other_reportable_positions_long": "other_rept_positions_long", + "other_reportable_positions_long_1": "other_rept_positions_long_1", + "other_reportable_positions_long_2": "other_rept_positions_long_2", + "other_reportable_positions_short": "other_rept_positions_short", + "other_reportable_positions_short_1": "other_rept_positions_short_1", + "other_reportable_positions_short_2": "other_rept_positions_short_2", + "other_reportable_positions_spread": "other_rept_positions_spread", + "other_reportable_positions_spread_1": "other_rept_positions_spread_1", + "other_reportable_positions_spread_2": "other_rept_positions_spread_2", + "open_interest_pct_all": "pct_of_open_interest_all", + "open_interest_pct_asset_manager_long": "pct_of_oi_asset_mgr_long", + "open_interest_pct_asset_manager_short": "pct_of_oi_asset_mgr_short", + "open_interest_pct_asset_manager_spread": "pct_of_oi_asset_mgr_spread", + "open_interest_pct_commercial_long_all": "pct_of_oi_comm_long_all", + "open_interest_pct_commercial_long_old": "pct_of_oi_comm_long_old", + "open_interest_pct_commercial_long_other": "pct_of_oi_comm_long_other", + "open_interest_pct_commercial_short_all": "pct_of_oi_comm_short_all", + "open_interest_pct_commercial_short_old": "pct_of_oi_comm_short_old", + "open_interest_pct_commercial_short_other": "pct_of_oi_comm_short_other", + "open_interest_pct_dealer_long_all": "pct_of_oi_dealer_long_all", + "open_interest_pct_dealer_short_all": "pct_of_oi_dealer_short_all", + "open_interest_pct_dealer_spread_all": "pct_of_oi_dealer_spread_all", + "open_interest_pct_leveraged_funds_long": "pct_of_oi_lev_money_long", + "open_interest_pct_leveraged_funds_short": "pct_of_oi_lev_money_short", + "open_interest_pct_leveraged_funds_spread": "pct_of_oi_lev_money_spread", + "open_interest_pct_managed_money_long_all": "pct_of_oi_m_money_long_all", + "open_interest_pct_managed_money_long_old": "pct_of_oi_m_money_long_old", + "open_interest_pct_managed_money_long_other": "pct_of_oi_m_money_long_other", + "open_interest_pct_managed_money_short_all": "pct_of_oi_m_money_short_all", + "open_interest_pct_managed_money_short_old": "pct_of_oi_m_money_short_old", + "open_interest_pct_managed_money_short_other": "pct_of_oi_m_money_short_other", + "open_interest_pct_managed_money_spread": "pct_of_oi_m_money_spread", + "open_interest_pct_managed_money_spread_1": "pct_of_oi_m_money_spread_1", + "open_interest_pct_managed_money_spread_2": "pct_of_oi_m_money_spread_2", + "open_interest_pct_non_commercial_long_all": "pct_of_oi_noncomm_long_all", + "open_interest_pct_non_commercial_long_old": "pct_of_oi_noncomm_long_old", + "open_interest_pct_non_commercial_long_other": "pct_of_oi_noncomm_long_other", + "open_interest_pct_non_commercial_short_all": "pct_of_oi_noncomm_short_all", + "open_interest_pct_non_commercial_short_old": "pct_of_oi_noncomm_short_old", + "open_interest_pct_non_commercial_short_other": "pct_of_oi_noncomm_short_other", + "open_interest_pct_non_commercial_spread": "pct_of_oi_noncomm_spread", + "open_interest_pct_non_commercial_spread_1": "pct_of_oi_noncomm_spread_1", + "open_interest_pct_non_commercial_spread_2": "pct_of_oi_noncomm_spread_2", + "open_interest_pct_non_reportable_long_all": "pct_of_oi_nonrept_long_all", + "open_interest_pct_non_reportable_long_old": "pct_of_oi_nonrept_long_old", + "open_interest_pct_non_reportable_long_other": "pct_of_oi_nonrept_long_other", + "open_interest_pct_non_reportable_short_all": "pct_of_oi_nonrept_short_all", + "open_interest_pct_non_reportable_short_old": "pct_of_oi_nonrept_short_old", + "open_interest_pct_non_reportable_short_other": "pct_of_oi_nonrept_short_other", + "open_interest_pct_other_reportable_long": "pct_of_oi_other_rept_long", + "open_interest_pct_other_reportable_long_1": "pct_of_oi_other_rept_long_1", + "open_interest_pct_other_reportable_long_2": "pct_of_oi_other_rept_long_2", + "open_interest_pct_other_reportable_short": "pct_of_oi_other_rept_short", + "open_interest_pct_other_reportable_short_1": "pct_of_oi_other_rept_short_1", + "open_interest_pct_other_reportable_short_2": "pct_of_oi_other_rept_short_2", + "open_interest_pct_other_reportable_spread": "pct_of_oi_other_rept_spread", + "open_interest_pct_other_reportable_spread_1": "pct_of_oi_other_rept_spread_1", + "open_interest_pct_other_reportable_spread_2": "pct_of_oi_other_rept_spread_2", + "open_interest_pct_producer_merchant_long": "pct_of_oi_prod_merc_long", + "open_interest_pct_producer_merchant_long_1": "pct_of_oi_prod_merc_long_1", + "open_interest_pct_producer_merchant_long_2": "pct_of_oi_prod_merc_long_2", + "open_interest_pct_producer_merchant_short": "pct_of_oi_prod_merc_short", + "open_interest_pct_producer_merchant_short_1": "pct_of_oi_prod_merc_short_1", + "open_interest_pct_producer_merchant_short_2": "pct_of_oi_prod_merc_short_2", + "open_interest_pct_swap_long_all": "pct_of_oi_swap_long_all", + "open_interest_pct_swap_long_old": "pct_of_oi_swap_long_old", + "open_interest_pct_swap_long_other": "pct_of_oi_swap_long_other", + "open_interest_pct_swap_short_all": "pct_of_oi_swap_short_all", + "open_interest_pct_swap_short_old": "pct_of_oi_swap_short_old", + "open_interest_pct_swap_short_other": "pct_of_oi_swap_short_other", + "open_interest_pct_swap_spread_all": "pct_of_oi_swap_spread_all", + "open_interest_pct_swap_spread_old": "pct_of_oi_swap_spread_old", + "open_interest_pct_swap_spread_other": "pct_of_oi_swap_spread_other", + "open_interest_pct_total_reportable_long_all": "pct_of_oi_tot_rept_long_all", + "open_interest_pct_total_reportable_long_old": "pct_of_oi_tot_rept_long_old", + "open_interest_pct_total_reportable_long_other": "pct_of_oi_tot_rept_long_other", + "open_interest_pct_total_reportable_short": "pct_of_oi_tot_rept_short", + "open_interest_pct_total_reportable_short_1": "pct_of_oi_tot_rept_short_1", + "open_interest_pct_total_reportable_short_2": "pct_of_oi_tot_rept_short_2", + "open_interest_pct_commercial_long_all_non_cit": "pct_oi_comm_long_all_nocit", + "open_interest_pct_commercial_short_all_non_cit": "pct_oi_comm_short_all_nocit", + "open_interest_pct_non_commercial_long_all_non_cit": "pct_oi_noncomm_long_all_nocit", + "open_interest_pct_non_commercial_short_all_non_cit": "pct_oi_noncomm_short_all_nocit", + "open_interest_pct_non_commercial_spread_all_non_cit": "pct_oi_noncomm_spread_all_nocit", + "open_interest_pct_non_reportable_long_all_non_cit": "pct_oi_nonrept_long_all_nocit", + "open_interest_pct_non_reportable_short_all_non_cit": "pct_oi_nonrept_short_all_nocit", + "open_interest_pct_total_reportable_long_all_non_cit": "pct_oi_tot_rept_long_all_nocit", + "open_interest_pct_total_reportable_short_all_non_cit": "pct_oi_tot_rept_short_all_nocit", + "producer_merchant_positions_long": "prod_merc_positions_long", + "producer_merchant_positions_long_1": "prod_merc_positions_long_1", + "producer_merchant_positions_long_2": "prod_merc_positions_long_2", + "producer_merchant_positions_short": "prod_merc_positions_short", + "producer_merchant_positions_short_1": "prod_merc_positions_short_1", + "producer_merchant_positions_short_2": "prod_merc_positions_short_2", + "report_week": "yyyy_report_week_ww", + "total_reportable_positions_long_all": "tot_rept_positions_long_all", + "total_reportable_positions_long_old": "tot_rept_positions_long_old", + "total_reportable_positions_long_other": "tot_rept_positions_long_other", + "total_reportable_positions_short": "tot_rept_positions_short", + "total_reportable_positions_short_1": "tot_rept_positions_short_1", + "total_reportable_positions_short_2": "tot_rept_positions_short_2", + "traders_asset_manager_long_all": "traders_asset_mgr_long_all", + "traders_asset_manager_short_all": "traders_asset_mgr_short_all", + "traders_asset_manager_spread": "traders_asset_mgr_spread", + "traders_commercial_long_all": "traders_comm_long_all", + "traders_commercial_long_all_non_cit": "traders_comm_long_all_nocit", + "traders_commercial_long_old": "traders_comm_long_old", + "traders_commercial_long_other": "traders_comm_long_other", + "traders_commercial_short_all": "traders_comm_short_all", + "traders_commercial_short_all_non_cit": "traders_comm_short_all_nocit", + "traders_commercial_short_old": "traders_comm_short_old", + "traders_commercial_short_other": "traders_comm_short_other", + "traders_leveraged_funds_long_all": "traders_lev_money_long_all", + "traders_leveraged_funds_short_all": "traders_lev_money_short_all", + "traders_leveraged_funds_spread": "traders_lev_money_spread", + "traders_managed_money_long_all": "traders_m_money_long_all", + "traders_managed_money_long_old": "traders_m_money_long_old", + "traders_managed_money_long_other": "traders_m_money_long_other", + "traders_managed_money_short_all": "traders_m_money_short_all", + "traders_managed_money_short_old": "traders_m_money_short_old", + "traders_managed_money_short_other": "traders_m_money_short_other", + "traders_managed_money_spread_all": "traders_m_money_spread_all", + "traders_managed_money_spread_old": "traders_m_money_spread_old", + "traders_managed_money_spread_other": "traders_m_money_spread_other", + "traders_non_commercial_long_all": "traders_noncomm_long_all", + "traders_non_commercial_long_all_non_cit": "traders_noncomm_long_all_nocit", + "traders_non_commercial_long_old": "traders_noncomm_long_old", + "traders_non_commercial_long_other": "traders_noncomm_long_other", + "traders_non_commercial_short_all": "traders_noncomm_short_all", + "traders_non_commercial_short_all_non_cit": "traders_noncomm_short_all_nocit", + "traders_non_commercial_short_old": "traders_noncomm_short_old", + "traders_non_commercial_short_other": "traders_noncomm_short_other", + "traders_non_commercial_spread_all": "traders_noncomm_spread_all", + "traders_non_commercial_spread_all_non_cit": "traders_noncomm_spread_all_nocit", + "traders_non_commercial_spread_old": "traders_noncomm_spead_old", + "traders_non_commercial_spread_other": "traders_noncomm_spread_other", + "traders_other_reportable_long_all": "traders_other_rept_long_all", + "traders_other_reportable_long_old": "traders_other_rept_long_old", + "traders_other_reportable_long_other": "traders_other_rept_long_other", + "traders_other_reportable_short": "traders_other_rept_short", + "traders_other_reportable_short_1": "traders_other_rept_short_1", + "traders_other_reportable_short_2": "traders_other_rept_short_2", + "traders_other_reportable_spread": "traders_other_rept_spread", + "traders_other_reportable_spread_1": "traders_other_rept_spread_1", + "traders_other_reportable_spread_2": "traders_other_rept_spread_2", + "traders_producer_merchant_long_all": "traders_prod_merc_long_all", + "traders_producer_merchant_long_old": "traders_prod_merc_long_old", + "traders_producer_merchant_long_other": "traders_prod_merc_long_other", + "traders_producer_merchant_short_all": "traders_prod_merc_short_all", + "traders_producer_merchant_short_old": "traders_prod_merc_short_old", + "traders_producer_merchant_short_other": "traders_prod_merc_short_other", + "traders_total_all": "traders_tot_all", + "traders_total_old": "traders_tot_old", + "traders_total_other": "traders_tot_other", + "traders_total_reportable_long_all": "traders_tot_rept_long_all", + "traders_total_reportable_long_all_non_cit": "traders_tot_rept_long_all_nocit", + "traders_total_reportable_long_old": "traders_tot_rept_long_old", + "traders_total_reportable_long_other": "traders_tot_rept_long_other", + "traders_total_reportable_short_all": "traders_tot_rept_short_all", + "traders_total_reportable_short_all_non_cit": "traders_tot_rept_short_all_nocit", + "traders_total_reportable_short_old": "traders_tot_rept_short_old", + "traders_total_reportable_short_other": "traders_tot_rept_short_other", } + __alias_dict__.update( + { + "open_interest_pct_old": "pct_of_open_interest_old", + "open_interest_pct_other": "pct_of_open_interest_other", + "open_interest_pct_cit_long_all": "pct_oi_cit_long_all", + "open_interest_pct_cit_short_all": "pct_oi_cit_short_all", + } + ) + + contract_market_name: str | None = Field( + default=None, description="Short contract market name." + ) + + # -- Open Interest -- + + open_interest_all: int | None = Field( + default=None, description="Total open interest, all contracts." + ) + open_interest_old: int | None = Field( + default=None, + description="Total open interest, old crop year. Legacy/Disaggregated reports.", + ) + open_interest_other: int | None = Field( + default=None, + description="Total open interest, other crop year. Legacy/Disaggregated reports.", + ) + + # -- Legacy Report: Non-Commercial Positions -- + + non_commercial_positions_long_all: int | None = Field( + default=None, + description="Non-commercial long positions, all contracts. Legacy report.", + ) + non_commercial_positions_short_all: int | None = Field( + default=None, + description="Non-commercial short positions, all contracts. Legacy report.", + ) + non_commercial_positions_spread_all: int | None = Field( + default=None, + description="Non-commercial spreading positions, all contracts. Legacy report.", + ) + non_commercial_positions_long_old: int | None = Field( + default=None, + description="Non-commercial long positions, old crop year. Legacy report.", + ) + non_commercial_positions_short_old: int | None = Field( + default=None, + description="Non-commercial short positions, old crop year. Legacy report.", + ) + non_commercial_positions_spread: int | None = Field( + default=None, + description="Non-commercial spreading positions, old crop year. Legacy report.", + ) + non_commercial_positions_long_other: int | None = Field( + default=None, + description="Non-commercial long positions, other crop year. Legacy report.", + ) + non_commercial_positions_short_other: int | None = Field( + default=None, + description="Non-commercial short positions, other crop year. Legacy report.", + ) + non_commercial_positions_spread_1: int | None = Field( + default=None, + description="Non-commercial spreading positions, other crop year. Legacy report.", + ) + + # -- Legacy Report: Commercial Positions -- + + commercial_positions_long_all: int | None = Field( + default=None, + description="Commercial long positions, all contracts. Legacy report.", + ) + commercial_positions_short_all: int | None = Field( + default=None, + description="Commercial short positions, all contracts. Legacy report.", + ) + commercial_positions_long_old: int | None = Field( + default=None, + description="Commercial long positions, old crop year. Legacy report.", + ) + commercial_positions_short_old: int | None = Field( + default=None, + description="Commercial short positions, old crop year. Legacy report.", + ) + commercial_positions_long_other: int | None = Field( + default=None, + description="Commercial long positions, other crop year. Legacy report.", + ) + commercial_positions_short_other: int | None = Field( + default=None, + description="Commercial short positions, other crop year. Legacy report.", + ) + + # -- Disaggregated Report: Producer/Merchant/Processor/User Positions -- + + producer_merchant_positions_long: int | None = Field( + default=None, + description="Producer/merchant long positions, all contracts. Disaggregated report.", + ) + producer_merchant_positions_short: int | None = Field( + default=None, + description="Producer/merchant short positions, all contracts. Disaggregated report.", + ) + producer_merchant_positions_long_1: int | None = Field( + default=None, + description="Producer/merchant long positions, old crop year. Disaggregated report.", + ) + producer_merchant_positions_short_1: int | None = Field( + default=None, + description="Producer/merchant short positions, old crop year. Disaggregated report.", + ) + producer_merchant_positions_long_2: int | None = Field( + default=None, + description="Producer/merchant long positions, other crop year. Disaggregated report.", + ) + producer_merchant_positions_short_2: int | None = Field( + default=None, + description="Producer/merchant short positions, other crop year. Disaggregated report.", + ) + + # -- Disaggregated Report: Swap Dealer Positions -- + + swap_positions_long_all: int | None = Field( + default=None, + description="Swap dealer long positions, all contracts. Disaggregated report.", + ) + swap_positions_short_all: int | None = Field( + default=None, + description="Swap dealer short positions, all contracts. Disaggregated report.", + ) + swap_positions_spread_all: int | None = Field( + default=None, + description="Swap dealer spreading positions, all contracts. Disaggregated report.", + ) + swap_positions_long_old: int | None = Field( + default=None, + description="Swap dealer long positions, old crop year. Disaggregated report.", + ) + swap_positions_short_old: int | None = Field( + default=None, + description="Swap dealer short positions, old crop year. Disaggregated report.", + ) + swap_positions_spread_old: int | None = Field( + default=None, + description="Swap dealer spreading positions, old crop year. Disaggregated report.", + ) + swap_positions_long_other: int | None = Field( + default=None, + description="Swap dealer long positions, other crop year. Disaggregated report.", + ) + swap_positions_short_other: int | None = Field( + default=None, + description="Swap dealer short positions, other crop year. Disaggregated report.", + ) + swap_positions_spread_other: int | None = Field( + default=None, + description="Swap dealer spreading positions, other crop year. Disaggregated report.", + ) + + # -- Disaggregated Report: Managed Money Positions -- + + managed_money_positions_long_all: int | None = Field( + default=None, + description="Managed money long positions, all contracts. Disaggregated report.", + ) + managed_money_positions_short_all: int | None = Field( + default=None, + description="Managed money short positions, all contracts. Disaggregated report.", + ) + managed_money_positions_spread: int | None = Field( + default=None, + description="Managed money spreading positions, all contracts. Disaggregated report.", + ) + managed_money_positions_long_old: int | None = Field( + default=None, + description="Managed money long positions, old crop year. Disaggregated report.", + ) + managed_money_positions_short_old: int | None = Field( + default=None, + description="Managed money short positions, old crop year. Disaggregated report.", + ) + managed_money_positions_spread_1: int | None = Field( + default=None, + description="Managed money spreading positions, old crop year. Disaggregated report.", + ) + managed_money_positions_long_other: int | None = Field( + default=None, + description="Managed money long positions, other crop year. Disaggregated report.", + ) + managed_money_positions_short_other: int | None = Field( + default=None, + description="Managed money short positions, other crop year. Disaggregated report.", + ) + managed_money_positions_spread_2: int | None = Field( + default=None, + description="Managed money spreading positions, other crop year. Disaggregated report.", + ) + + # -- Financial (TFF) Report: Dealer/Intermediary Positions -- + + dealer_positions_long_all: int | None = Field( + default=None, + description="Dealer/intermediary long positions, all contracts. TFF report.", + ) + dealer_positions_short_all: int | None = Field( + default=None, + description="Dealer/intermediary short positions, all contracts. TFF report.", + ) + dealer_positions_spread_all: int | None = Field( + default=None, + description="Dealer/intermediary spreading positions, all contracts. TFF report.", + ) + + # -- Financial (TFF) Report: Asset Manager/Institutional Positions -- + + asset_manager_positions_long: int | None = Field( + default=None, + description="Asset manager/institutional long positions, all contracts. TFF report.", + ) + asset_manager_positions_short: int | None = Field( + default=None, + description="Asset manager/institutional short positions, all contracts. TFF report.", + ) + asset_manager_positions_spread: int | None = Field( + default=None, + description="Asset manager/institutional spreading positions, all contracts. TFF report.", + ) + + # -- Financial (TFF) Report: Leveraged Funds Positions -- + + leveraged_funds_positions_long: int | None = Field( + default=None, + description="Leveraged funds long positions, all contracts. TFF report.", + ) + leveraged_funds_positions_short: int | None = Field( + default=None, + description="Leveraged funds short positions, all contracts. TFF report.", + ) + leveraged_funds_positions_spread: int | None = Field( + default=None, + description="Leveraged funds spreading positions, all contracts. TFF report.", + ) + + # -- Disaggregated + Financial (TFF): Other Reportable Positions -- + + other_reportable_positions_long: int | None = Field( + default=None, + description="Other reportable long positions, all contracts. Disaggregated/TFF reports.", + ) + other_reportable_positions_short: int | None = Field( + default=None, + description="Other reportable short positions, all contracts. Disaggregated/TFF reports.", + ) + other_reportable_positions_spread: int | None = Field( + default=None, + description="Other reportable spreading positions, all contracts. Disaggregated/TFF reports.", + ) + other_reportable_positions_long_1: int | None = Field( + default=None, + description="Other reportable long positions, old crop year. Disaggregated report.", + ) + other_reportable_positions_short_1: int | None = Field( + default=None, + description="Other reportable short positions, old crop year. Disaggregated report.", + ) + other_reportable_positions_spread_1: int | None = Field( + default=None, + description="Other reportable spreading positions, old crop year. Disaggregated report.", + ) + other_reportable_positions_long_2: int | None = Field( + default=None, + description="Other reportable long positions, other crop year. Disaggregated report.", + ) + other_reportable_positions_short_2: int | None = Field( + default=None, + description="Other reportable short positions, other crop year. Disaggregated report.", + ) + other_reportable_positions_spread_2: int | None = Field( + default=None, + description="Other reportable spreading positions, other crop year. Disaggregated report.", + ) + + # -- Supplemental Report: Non-Commercial (Excluding CIT) Positions -- + + non_commercial_positions_long_all_non_cit: int | None = Field( + default=None, + description="Non-commercial long positions excluding CIT, all contracts. Supplemental report.", + ) + non_commercial_positions_short_all_non_cit: int | None = Field( + default=None, + description="Non-commercial short positions excluding CIT, all contracts. Supplemental report.", + ) + non_commercial_positions_spread_all_non_cit: int | None = Field( + default=None, + description="Non-commercial spreading positions excluding CIT, all contracts. Supplemental report.", + ) + + # -- Supplemental Report: Commercial (Excluding CIT) Positions -- + + commercial_positions_long_all_non_cit: int | None = Field( + default=None, + description="Commercial long positions excluding CIT, all contracts. Supplemental report.", + ) + commercial_positions_short_all_non_cit: int | None = Field( + default=None, + description="Commercial short positions excluding CIT, all contracts. Supplemental report.", + ) + + # -- Supplemental Report: Commodity Index Trader (CIT) Positions -- + + cit_positions_long_all: int | None = Field( + default=None, + description="Commodity index trader (CIT) long positions, all contracts. Supplemental report.", + ) + cit_positions_short_all: int | None = Field( + default=None, + description="Commodity index trader (CIT) short positions, all contracts. Supplemental report.", + ) + + # -- Total Reportable Positions -- + + total_reportable_positions_long_all: int | None = Field( + default=None, description="Total reportable long positions, all contracts." + ) + total_reportable_positions_short: int | None = Field( + default=None, description="Total reportable short positions, all contracts." + ) + total_reportable_positions_long_old: int | None = Field( + default=None, + description="Total reportable long positions, old crop year. Legacy/Disaggregated reports.", + ) + total_reportable_positions_short_1: int | None = Field( + default=None, + description="Total reportable short positions, old crop year. Legacy/Disaggregated reports.", + ) + total_reportable_positions_long_other: int | None = Field( + default=None, + description="Total reportable long positions, other crop year. Legacy/Disaggregated reports.", + ) + total_reportable_positions_short_2: int | None = Field( + default=None, + description="Total reportable short positions, other crop year. Legacy/Disaggregated reports.", + ) + + # -- Non-Reportable Positions -- + + non_reportable_positions_long_all: int | None = Field( + default=None, description="Non-reportable long positions, all contracts." + ) + non_reportable_positions_short_all: int | None = Field( + default=None, description="Non-reportable short positions, all contracts." + ) + non_reportable_positions_long_old: int | None = Field( + default=None, + description="Non-reportable long positions, old crop year. Legacy/Disaggregated reports.", + ) + non_reportable_positions_short_old: int | None = Field( + default=None, + description="Non-reportable short positions, old crop year. Legacy/Disaggregated reports.", + ) + non_reportable_positions_long_other: int | None = Field( + default=None, + description="Non-reportable long positions, other crop year. Legacy/Disaggregated reports.", + ) + non_reportable_positions_short_other: int | None = Field( + default=None, + description="Non-reportable short positions, other crop year. Legacy/Disaggregated reports.", + ) + + # -- Changes: Open Interest -- + + change_in_open_interest_all: int | None = Field( + default=None, description="Weekly change in total open interest, all contracts." + ) + change_open_interest_all: int | None = Field( + default=None, + description="Weekly change in total open interest, all contracts. Supplemental report.", + ) + + # -- Changes: Legacy Non-Commercial -- + + change_in_non_commercial_long_all: int | None = Field( + default=None, + description="Weekly change in non-commercial long positions. Legacy report.", + ) + change_in_non_commercial_short_all: int | None = Field( + default=None, + description="Weekly change in non-commercial short positions. Legacy report.", + ) + change_in_non_commercial_spread_all: int | None = Field( + default=None, + description="Weekly change in non-commercial spreading positions. Legacy report.", + ) + + # -- Changes: Legacy Commercial -- + + change_in_commercial_long_all: int | None = Field( + default=None, + description="Weekly change in commercial long positions. Legacy report.", + ) + change_in_commercial_short_all: int | None = Field( + default=None, + description="Weekly change in commercial short positions. Legacy report.", + ) + + # -- Changes: Disaggregated Producer/Merchant -- + + change_in_producer_merchant_long: int | None = Field( + default=None, + description="Weekly change in producer/merchant long positions. Disaggregated report.", + ) + change_in_producer_merchant_short: int | None = Field( + default=None, + description="Weekly change in producer/merchant short positions. Disaggregated report.", + ) + + # -- Changes: Disaggregated Swap Dealer -- + + change_in_swap_long_all: int | None = Field( + default=None, + description="Weekly change in swap dealer long positions. Disaggregated report.", + ) + change_in_swap_short_all: int | None = Field( + default=None, + description="Weekly change in swap dealer short positions. Disaggregated report.", + ) + change_in_swap_spread_all: int | None = Field( + default=None, + description="Weekly change in swap dealer spreading positions. Disaggregated report.", + ) + + # -- Changes: Disaggregated Managed Money -- + + change_in_managed_money_long_all: int | None = Field( + default=None, + description="Weekly change in managed money long positions. Disaggregated report.", + ) + change_in_managed_money_short_all: int | None = Field( + default=None, + description="Weekly change in managed money short positions. Disaggregated report.", + ) + change_in_managed_money_spread: int | None = Field( + default=None, + description="Weekly change in managed money spreading positions. Disaggregated report.", + ) + + # -- Changes: Financial (TFF) Dealer -- + + change_in_dealer_long_all: int | None = Field( + default=None, + description="Weekly change in dealer/intermediary long positions. TFF report.", + ) + change_in_dealer_short_all: int | None = Field( + default=None, + description="Weekly change in dealer/intermediary short positions. TFF report.", + ) + change_in_dealer_spread_all: int | None = Field( + default=None, + description="Weekly change in dealer/intermediary spreading positions. TFF report.", + ) + + # -- Changes: Financial (TFF) Asset Manager -- + + change_in_asset_manager_long: int | None = Field( + default=None, + description="Weekly change in asset manager/institutional long positions. TFF report.", + ) + change_in_asset_manager_short: int | None = Field( + default=None, + description="Weekly change in asset manager/institutional short positions. TFF report.", + ) + change_in_asset_manager_spread: int | None = Field( + default=None, + description="Weekly change in asset manager/institutional spreading positions. TFF report.", + ) + + # -- Changes: Financial (TFF) Leveraged Funds -- + + change_in_leveraged_funds_long: int | None = Field( + default=None, + description="Weekly change in leveraged funds long positions. TFF report.", + ) + change_in_leveraged_funds_short: int | None = Field( + default=None, + description="Weekly change in leveraged funds short positions. TFF report.", + ) + change_in_leveraged_funds_spread: int | None = Field( + default=None, + description="Weekly change in leveraged funds spreading positions. TFF report.", + ) + + # -- Changes: Other Reportable -- + + change_in_other_reportable_long: int | None = Field( + default=None, + description="Weekly change in other reportable long positions. Disaggregated/TFF reports.", + ) + change_in_other_reportable_short: int | None = Field( + default=None, + description="Weekly change in other reportable short positions. Disaggregated/TFF reports.", + ) + change_in_other_reportable_spread: int | None = Field( + default=None, + description="Weekly change in other reportable spreading positions. Disaggregated/TFF reports.", + ) + + # -- Changes: Supplemental Non-Commercial NoCIT -- + + change_non_commercial_long_all_non_cit: int | None = Field( + default=None, + description="Weekly change in non-commercial long positions excluding CIT. Supplemental report.", + ) + change_non_commercial_short_all_non_cit: int | None = Field( + default=None, + description="Weekly change in non-commercial short positions excluding CIT. Supplemental report.", + ) + change_non_commercial_spread_all_non_cit: int | None = Field( + default=None, + description="Weekly change in non-commercial spreading positions excluding CIT. Supplemental report.", + ) + + # -- Changes: Supplemental Commercial NoCIT -- + + change_commercial_long_all_non_cit: int | None = Field( + default=None, + description="Weekly change in commercial long positions excluding CIT. Supplemental report.", + ) + change_commercial_short_all_non_cit: int | None = Field( + default=None, + description="Weekly change in commercial short positions excluding CIT. Supplemental report.", + ) + + # -- Changes: Supplemental CIT -- + + change_cit_long_all: int | None = Field( + default=None, + description="Weekly change in commodity index trader long positions. Supplemental report.", + ) + change_cit_short_all: int | None = Field( + default=None, + description="Weekly change in commodity index trader short positions. Supplemental report.", + ) + + # -- Changes: Total Reportable -- + + change_in_total_reportable_long_all: int | None = Field( + default=None, description="Weekly change in total reportable long positions." + ) + change_in_total_reportable_short: int | None = Field( + default=None, description="Weekly change in total reportable short positions." + ) + change_total_reportable_long_all: int | None = Field( + default=None, + description="Weekly change in total reportable long positions. Supplemental report.", + ) + change_total_reportable_short_all: int | None = Field( + default=None, + description="Weekly change in total reportable short positions. Supplemental report.", + ) + + # -- Changes: Non-Reportable -- + + change_in_non_reportable_long_all: int | None = Field( + default=None, description="Weekly change in non-reportable long positions." + ) + change_in_non_reportable_short_all: int | None = Field( + default=None, description="Weekly change in non-reportable short positions." + ) + change_non_reportable_long_all: int | None = Field( + default=None, + description="Weekly change in non-reportable long positions. Supplemental report.", + ) + change_non_reportable_short_all: int | None = Field( + default=None, + description="Weekly change in non-reportable short positions. Supplemental report.", + ) + + # -- Percent of Open Interest: Totals -- + + open_interest_pct_all: float | None = Field( + default=None, + description="Percent of total open interest, all contracts.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_old: float | None = Field( + default=None, + description="Percent of total open interest, old crop year. Legacy/Disaggregated reports.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_other: float | None = Field( + default=None, + description="Percent of total open interest, other crop year. Legacy/Disaggregated reports.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + # -- Percent of OI: Legacy Non-Commercial -- + + open_interest_pct_non_commercial_long_all: float | None = Field( + default=None, + description="Non-commercial long as percent of open interest, all contracts. Legacy report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_commercial_short_all: float | None = Field( + default=None, + description="Non-commercial short as percent of open interest, all contracts. Legacy report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_commercial_spread: float | None = Field( + default=None, + description="Non-commercial spreading as percent of open interest, all contracts. Legacy report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_commercial_long_old: float | None = Field( + default=None, + description="Non-commercial long as percent of open interest, old crop year. Legacy report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_commercial_short_old: float | None = Field( + default=None, + description="Non-commercial short as percent of open interest, old crop year. Legacy report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_commercial_spread_1: float | None = Field( + default=None, + description="Non-commercial spreading as percent of open interest, old crop year. Legacy report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_commercial_long_other: float | None = Field( + default=None, + description="Non-commercial long as percent of open interest, other crop year. Legacy report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_commercial_short_other: float | None = Field( + default=None, + description="Non-commercial short as percent of open interest, other crop year. Legacy report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_commercial_spread_2: float | None = Field( + default=None, + description="Non-commercial spreading as percent of open interest, other crop year. Legacy report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + # -- Percent of OI: Legacy Commercial -- + + open_interest_pct_commercial_long_all: float | None = Field( + default=None, + description="Commercial long as percent of open interest, all contracts. Legacy report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_commercial_short_all: float | None = Field( + default=None, + description="Commercial short as percent of open interest, all contracts. Legacy report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_commercial_long_old: float | None = Field( + default=None, + description="Commercial long as percent of open interest, old crop year. Legacy report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_commercial_short_old: float | None = Field( + default=None, + description="Commercial short as percent of open interest, old crop year. Legacy report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_commercial_long_other: float | None = Field( + default=None, + description="Commercial long as percent of open interest, other crop year. Legacy report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_commercial_short_other: float | None = Field( + default=None, + description="Commercial short as percent of open interest, other crop year. Legacy report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + # -- Percent of OI: Disaggregated Producer/Merchant -- + + open_interest_pct_producer_merchant_long: float | None = Field( + default=None, + description="Producer/merchant long as percent of open interest, all contracts. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_producer_merchant_short: float | None = Field( + default=None, + description="Producer/merchant short as percent of open interest, all contracts. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_producer_merchant_long_1: float | None = Field( + default=None, + description="Producer/merchant long as percent of open interest, old crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_producer_merchant_short_1: float | None = Field( + default=None, + description="Producer/merchant short as percent of open interest, old crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_producer_merchant_long_2: float | None = Field( + default=None, + description="Producer/merchant long as percent of open interest, other crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_producer_merchant_short_2: float | None = Field( + default=None, + description="Producer/merchant short as percent of open interest, other crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + # -- Percent of OI: Disaggregated Swap Dealer -- + + open_interest_pct_swap_long_all: float | None = Field( + default=None, + description="Swap dealer long as percent of open interest, all contracts. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_swap_short_all: float | None = Field( + default=None, + description="Swap dealer short as percent of open interest, all contracts. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_swap_spread_all: float | None = Field( + default=None, + description="Swap dealer spreading as percent of open interest, all contracts. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_swap_long_old: float | None = Field( + default=None, + description="Swap dealer long as percent of open interest, old crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_swap_short_old: float | None = Field( + default=None, + description="Swap dealer short as percent of open interest, old crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_swap_spread_old: float | None = Field( + default=None, + description="Swap dealer spreading as percent of open interest, old crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_swap_long_other: float | None = Field( + default=None, + description="Swap dealer long as percent of open interest, other crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_swap_short_other: float | None = Field( + default=None, + description="Swap dealer short as percent of open interest, other crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_swap_spread_other: float | None = Field( + default=None, + description="Swap dealer spreading as percent of open interest, other crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + # -- Percent of OI: Disaggregated Managed Money -- + + open_interest_pct_managed_money_long_all: float | None = Field( + default=None, + description="Managed money long as percent of open interest, all contracts. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_managed_money_short_all: float | None = Field( + default=None, + description="Managed money short as percent of open interest, all contracts. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_managed_money_spread: float | None = Field( + default=None, + description="Managed money spreading as percent of open interest, all contracts. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_managed_money_long_old: float | None = Field( + default=None, + description="Managed money long as percent of open interest, old crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_managed_money_short_old: float | None = Field( + default=None, + description="Managed money short as percent of open interest, old crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_managed_money_spread_1: float | None = Field( + default=None, + description="Managed money spreading as percent of open interest, old crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_managed_money_long_other: float | None = Field( + default=None, + description="Managed money long as percent of open interest, other crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_managed_money_short_other: float | None = Field( + default=None, + description="Managed money short as percent of open interest, other crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_managed_money_spread_2: float | None = Field( + default=None, + description="Managed money spreading as percent of open interest, other crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + # -- Percent of OI: Financial (TFF) Dealer -- + + open_interest_pct_dealer_long_all: float | None = Field( + default=None, + description="Dealer/intermediary long as percent of open interest, all contracts. TFF report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_dealer_short_all: float | None = Field( + default=None, + description="Dealer/intermediary short as percent of open interest, all contracts. TFF report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_dealer_spread_all: float | None = Field( + default=None, + description="Dealer/intermediary spreading as percent of open interest, all contracts. TFF report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + # -- Percent of OI: Financial (TFF) Asset Manager -- + + open_interest_pct_asset_manager_long: float | None = Field( + default=None, + description="Asset manager/institutional long as percent of open interest, all contracts. TFF report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_asset_manager_short: float | None = Field( + default=None, + description="Asset manager/institutional short as percent of open interest, all contracts. TFF report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_asset_manager_spread: float | None = Field( + default=None, + description="Asset manager/institutional spreading as percent of open interest, all contracts. TFF report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + # -- Percent of OI: Financial (TFF) Leveraged Funds -- + + open_interest_pct_leveraged_funds_long: float | None = Field( + default=None, + description="Leveraged funds long as percent of open interest, all contracts. TFF report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_leveraged_funds_short: float | None = Field( + default=None, + description="Leveraged funds short as percent of open interest, all contracts. TFF report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_leveraged_funds_spread: float | None = Field( + default=None, + description="Leveraged funds spreading as percent of open interest, all contracts. TFF report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + # -- Percent of OI: Other Reportable -- + + open_interest_pct_other_reportable_long: float | None = Field( + default=None, + description="Other reportable long as percent of open interest, all contracts. Disaggregated/TFF reports.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_other_reportable_short: float | None = Field( + default=None, + description="Other reportable short as percent of open interest, all contracts. Disaggregated/TFF reports.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_other_reportable_spread: float | None = Field( + default=None, + description="Other reportable spreading as percent of open interest, all contracts. Disaggregated/TFF reports.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_other_reportable_long_1: float | None = Field( + default=None, + description="Other reportable long as percent of open interest, old crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_other_reportable_short_1: float | None = Field( + default=None, + description="Other reportable short as percent of open interest, old crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_other_reportable_spread_1: float | None = Field( + default=None, + description="Other reportable spreading as percent of open interest, old crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_other_reportable_long_2: float | None = Field( + default=None, + description="Other reportable long as percent of open interest, other crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_other_reportable_short_2: float | None = Field( + default=None, + description="Other reportable short as percent of open interest, other crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_other_reportable_spread_2: float | None = Field( + default=None, + description="Other reportable spreading as percent of open interest, other crop year. Disaggregated report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + # -- Percent of OI: Supplemental NoCIT -- + + open_interest_pct_non_commercial_long_all_non_cit: float | None = Field( + default=None, + description="Non-commercial long excluding CIT as percent of open interest. Supplemental report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_commercial_short_all_non_cit: float | None = Field( + default=None, + description="Non-commercial short excluding CIT as percent of open interest. Supplemental report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_commercial_spread_all_non_cit: float | None = Field( + default=None, + description="Non-commercial spreading excluding CIT as percent of open interest. Supplemental report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_commercial_long_all_non_cit: float | None = Field( + default=None, + description="Commercial long excluding CIT as percent of open interest. Supplemental report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_commercial_short_all_non_cit: float | None = Field( + default=None, + description="Commercial short excluding CIT as percent of open interest. Supplemental report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + # -- Percent of OI: Supplemental CIT -- + + open_interest_pct_cit_long_all: float | None = Field( + default=None, + description="Commodity index trader long as percent of open interest. Supplemental report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_cit_short_all: float | None = Field( + default=None, + description="Commodity index trader short as percent of open interest. Supplemental report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + # -- Percent of OI: Supplemental Totals NoCIT -- + + open_interest_pct_total_reportable_long_all_non_cit: float | None = Field( + default=None, + description="Total reportable long excluding CIT as percent of open interest. Supplemental report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_total_reportable_short_all_non_cit: float | None = Field( + default=None, + description="Total reportable short excluding CIT as percent of open interest. Supplemental report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_reportable_long_all_non_cit: float | None = Field( + default=None, + description="Non-reportable long excluding CIT as percent of open interest. Supplemental report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_reportable_short_all_non_cit: float | None = Field( + default=None, + description="Non-reportable short excluding CIT as percent of open interest. Supplemental report.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + # -- Percent of OI: Total Reportable -- + + open_interest_pct_total_reportable_long_all: float | None = Field( + default=None, + description="Total reportable long as percent of open interest, all contracts.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_total_reportable_short: float | None = Field( + default=None, + description="Total reportable short as percent of open interest, all contracts.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_total_reportable_long_old: float | None = Field( + default=None, + description="Total reportable long as percent of open interest, old crop year. Legacy/Disaggregated reports.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_total_reportable_short_1: float | None = Field( + default=None, + description="Total reportable short as percent of open interest, old crop year. Legacy/Disaggregated reports.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_total_reportable_long_other: float | None = Field( + default=None, + description="Total reportable long as percent of open interest, other crop year. Legacy/Disaggregated reports.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_total_reportable_short_2: float | None = Field( + default=None, + description="Total reportable short as percent of open interest, other crop year. Legacy/Disaggregated reports.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + # -- Percent of OI: Non-Reportable -- + + open_interest_pct_non_reportable_long_all: float | None = Field( + default=None, + description="Non-reportable long as percent of open interest, all contracts.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_reportable_short_all: float | None = Field( + default=None, + description="Non-reportable short as percent of open interest, all contracts.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_reportable_long_old: float | None = Field( + default=None, + description="Non-reportable long as percent of open interest, old crop year. Legacy/Disaggregated reports.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_reportable_short_old: float | None = Field( + default=None, + description="Non-reportable short as percent of open interest, old crop year. Legacy/Disaggregated reports.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_reportable_long_other: float | None = Field( + default=None, + description="Non-reportable long as percent of open interest, other crop year. Legacy/Disaggregated reports.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + open_interest_pct_non_reportable_short_other: float | None = Field( + default=None, + description="Non-reportable short as percent of open interest, other crop year. Legacy/Disaggregated reports.", + json_schema_extra={"x-unit_measurement": "percent", "x-frontend_multiply": 100}, + ) + + # -- Number of Traders: Totals -- + + traders_total_all: int | None = Field( + default=None, description="Total number of reportable traders, all contracts." + ) + traders_total_old: int | None = Field( + default=None, + description="Total number of reportable traders, old crop year. Legacy/Disaggregated reports.", + ) + traders_total_other: int | None = Field( + default=None, + description="Total number of reportable traders, other crop year. Legacy/Disaggregated reports.", + ) + + # -- Number of Traders: Legacy Non-Commercial -- + + traders_non_commercial_long_all: int | None = Field( + default=None, + description="Number of non-commercial long traders, all contracts. Legacy report.", + ) + traders_non_commercial_short_all: int | None = Field( + default=None, + description="Number of non-commercial short traders, all contracts. Legacy report.", + ) + traders_non_commercial_spread_all: int | None = Field( + default=None, + description="Number of non-commercial spreading traders, all contracts. Legacy report.", + ) + traders_non_commercial_long_old: int | None = Field( + default=None, + description="Number of non-commercial long traders, old crop year. Legacy report.", + ) + traders_non_commercial_short_old: int | None = Field( + default=None, + description="Number of non-commercial short traders, old crop year. Legacy report.", + ) + traders_non_commercial_spread_old: int | None = Field( + default=None, + description="Number of non-commercial spreading traders, old crop year. Legacy report.", + ) + traders_non_commercial_long_other: int | None = Field( + default=None, + description="Number of non-commercial long traders, other crop year. Legacy report.", + ) + traders_non_commercial_short_other: int | None = Field( + default=None, + description="Number of non-commercial short traders, other crop year. Legacy report.", + ) + traders_non_commercial_spread_other: int | None = Field( + default=None, + description="Number of non-commercial spreading traders, other crop year. Legacy report.", + ) + + # -- Number of Traders: Legacy Commercial -- + + traders_commercial_long_all: int | None = Field( + default=None, + description="Number of commercial long traders, all contracts. Legacy report.", + ) + traders_commercial_short_all: int | None = Field( + default=None, + description="Number of commercial short traders, all contracts. Legacy report.", + ) + traders_commercial_long_old: int | None = Field( + default=None, + description="Number of commercial long traders, old crop year. Legacy report.", + ) + traders_commercial_short_old: int | None = Field( + default=None, + description="Number of commercial short traders, old crop year. Legacy report.", + ) + traders_commercial_long_other: int | None = Field( + default=None, + description="Number of commercial long traders, other crop year. Legacy report.", + ) + traders_commercial_short_other: int | None = Field( + default=None, + description="Number of commercial short traders, other crop year. Legacy report.", + ) + + # -- Number of Traders: Disaggregated Producer/Merchant -- + + traders_producer_merchant_long_all: int | None = Field( + default=None, + description="Number of producer/merchant long traders, all contracts. Disaggregated report.", + ) + traders_producer_merchant_short_all: int | None = Field( + default=None, + description="Number of producer/merchant short traders, all contracts. Disaggregated report.", + ) + traders_producer_merchant_long_old: int | None = Field( + default=None, + description="Number of producer/merchant long traders, old crop year. Disaggregated report.", + ) + traders_producer_merchant_short_old: int | None = Field( + default=None, + description="Number of producer/merchant short traders, old crop year. Disaggregated report.", + ) + traders_producer_merchant_long_other: int | None = Field( + default=None, + description="Number of producer/merchant long traders, other crop year. Disaggregated report.", + ) + traders_producer_merchant_short_other: int | None = Field( + default=None, + description="Number of producer/merchant short traders, other crop year. Disaggregated report.", + ) + + # -- Number of Traders: Disaggregated Swap Dealer -- + + traders_swap_long_all: int | None = Field( + default=None, + description="Number of swap dealer long traders, all contracts. Disaggregated report.", + ) + traders_swap_short_all: int | None = Field( + default=None, + description="Number of swap dealer short traders, all contracts. Disaggregated report.", + ) + traders_swap_spread_all: int | None = Field( + default=None, + description="Number of swap dealer spreading traders, all contracts. Disaggregated report.", + ) + traders_swap_long_old: int | None = Field( + default=None, + description="Number of swap dealer long traders, old crop year. Disaggregated report.", + ) + traders_swap_short_old: int | None = Field( + default=None, + description="Number of swap dealer short traders, old crop year. Disaggregated report.", + ) + traders_swap_spread_old: int | None = Field( + default=None, + description="Number of swap dealer spreading traders, old crop year. Disaggregated report.", + ) + traders_swap_long_other: int | None = Field( + default=None, + description="Number of swap dealer long traders, other crop year. Disaggregated report.", + ) + traders_swap_short_other: int | None = Field( + default=None, + description="Number of swap dealer short traders, other crop year. Disaggregated report.", + ) + traders_swap_spread_other: int | None = Field( + default=None, + description="Number of swap dealer spreading traders, other crop year. Disaggregated report.", + ) + + # -- Number of Traders: Disaggregated Managed Money -- + + traders_managed_money_long_all: int | None = Field( + default=None, + description="Number of managed money long traders, all contracts. Disaggregated report.", + ) + traders_managed_money_short_all: int | None = Field( + default=None, + description="Number of managed money short traders, all contracts. Disaggregated report.", + ) + traders_managed_money_spread_all: int | None = Field( + default=None, + description="Number of managed money spreading traders, all contracts. Disaggregated report.", + ) + traders_managed_money_long_old: int | None = Field( + default=None, + description="Number of managed money long traders, old crop year. Disaggregated report.", + ) + traders_managed_money_short_old: int | None = Field( + default=None, + description="Number of managed money short traders, old crop year. Disaggregated report.", + ) + traders_managed_money_spread_old: int | None = Field( + default=None, + description="Number of managed money spreading traders, old crop year. Disaggregated report.", + ) + traders_managed_money_long_other: int | None = Field( + default=None, + description="Number of managed money long traders, other crop year. Disaggregated report.", + ) + traders_managed_money_short_other: int | None = Field( + default=None, + description="Number of managed money short traders, other crop year. Disaggregated report.", + ) + traders_managed_money_spread_other: int | None = Field( + default=None, + description="Number of managed money spreading traders, other crop year. Disaggregated report.", + ) + + # -- Number of Traders: Financial (TFF) Dealer -- + + traders_dealer_long_all: int | None = Field( + default=None, + description="Number of dealer/intermediary long traders, all contracts. TFF report.", + ) + traders_dealer_short_all: int | None = Field( + default=None, + description="Number of dealer/intermediary short traders, all contracts. TFF report.", + ) + traders_dealer_spread_all: int | None = Field( + default=None, + description="Number of dealer/intermediary spreading traders, all contracts. TFF report.", + ) + + # -- Number of Traders: Financial (TFF) Asset Manager -- + + traders_asset_manager_long_all: int | None = Field( + default=None, + description="Number of asset manager/institutional long traders, all contracts. TFF report.", + ) + traders_asset_manager_short_all: int | None = Field( + default=None, + description="Number of asset manager/institutional short traders, all contracts. TFF report.", + ) + traders_asset_manager_spread: int | None = Field( + default=None, + description="Number of asset manager/institutional spreading traders, all contracts. TFF report.", + ) + + # -- Number of Traders: Financial (TFF) Leveraged Funds -- + + traders_leveraged_funds_long_all: int | None = Field( + default=None, + description="Number of leveraged funds long traders, all contracts. TFF report.", + ) + traders_leveraged_funds_short_all: int | None = Field( + default=None, + description="Number of leveraged funds short traders, all contracts. TFF report.", + ) + traders_leveraged_funds_spread: int | None = Field( + default=None, + description="Number of leveraged funds spreading traders, all contracts. TFF report.", + ) + + # -- Number of Traders: Other Reportable -- + + traders_other_reportable_long_all: int | None = Field( + default=None, + description="Number of other reportable long traders, all contracts. Disaggregated/TFF reports.", + ) + traders_other_reportable_short: int | None = Field( + default=None, + description="Number of other reportable short traders, all contracts. Disaggregated/TFF reports.", + ) + traders_other_reportable_spread: int | None = Field( + default=None, + description="Number of other reportable spreading traders, all contracts. Disaggregated report.", + ) + traders_other_reportable_long_old: int | None = Field( + default=None, + description="Number of other reportable long traders, old crop year. Disaggregated report.", + ) + traders_other_reportable_short_1: int | None = Field( + default=None, + description="Number of other reportable short traders, old crop year. Disaggregated report.", + ) + traders_other_reportable_spread_1: int | None = Field( + default=None, + description="Number of other reportable spreading traders, old crop year. Disaggregated report.", + ) + traders_other_reportable_long_other: int | None = Field( + default=None, + description="Number of other reportable long traders, other crop year. Disaggregated report.", + ) + traders_other_reportable_short_2: int | None = Field( + default=None, + description="Number of other reportable short traders, other crop year. Disaggregated report.", + ) + traders_other_reportable_spread_2: int | None = Field( + default=None, + description="Number of other reportable spreading traders, other crop year. Disaggregated report.", + ) + + # -- Number of Traders: Supplemental NoCIT -- + + traders_non_commercial_long_all_non_cit: int | None = Field( + default=None, + description="Number of non-commercial long traders excluding CIT. Supplemental report.", + ) + traders_non_commercial_short_all_non_cit: int | None = Field( + default=None, + description="Number of non-commercial short traders excluding CIT. Supplemental report.", + ) + traders_non_commercial_spread_all_non_cit: int | None = Field( + default=None, + description="Number of non-commercial spreading traders excluding CIT. Supplemental report.", + ) + traders_commercial_long_all_non_cit: int | None = Field( + default=None, + description="Number of commercial long traders excluding CIT. Supplemental report.", + ) + traders_commercial_short_all_non_cit: int | None = Field( + default=None, + description="Number of commercial short traders excluding CIT. Supplemental report.", + ) + + # -- Number of Traders: Supplemental CIT -- + + traders_cit_long_all: int | None = Field( + default=None, + description="Number of commodity index trader long traders. Supplemental report.", + ) + traders_cit_short_all: int | None = Field( + default=None, + description="Number of commodity index trader short traders. Supplemental report.", + ) + + # -- Number of Traders: Supplemental Totals NoCIT -- + + traders_total_reportable_long_all_non_cit: int | None = Field( + default=None, + description="Total reportable long traders excluding CIT. Supplemental report.", + ) + traders_total_reportable_short_all_non_cit: int | None = Field( + default=None, + description="Total reportable short traders excluding CIT. Supplemental report.", + ) + + # -- Number of Traders: Total Reportable -- + + traders_total_reportable_long_all: int | None = Field( + default=None, + description="Total number of reportable long traders, all contracts.", + ) + traders_total_reportable_short_all: int | None = Field( + default=None, + description="Total number of reportable short traders, all contracts.", + ) + traders_total_reportable_long_old: int | None = Field( + default=None, + description="Total number of reportable long traders, old crop year. Legacy/Disaggregated reports.", + ) + traders_total_reportable_short_old: int | None = Field( + default=None, + description="Total number of reportable short traders, old crop year. Legacy/Disaggregated reports.", + ) + traders_total_reportable_long_other: int | None = Field( + default=None, + description="Total number of reportable long traders, other crop year. Legacy/Disaggregated reports.", + ) + traders_total_reportable_short_other: int | None = Field( + default=None, + description="Total number of reportable short traders, other crop year. Legacy/Disaggregated reports.", + ) + + # -- Concentration Ratios: All Contracts -- + + concentration_gross_top_4_traders_long: float | None = Field( + default=None, + description="Gross long position concentration of top 4 traders, all contracts.", + ) + concentration_gross_top_4_traders_short: float | None = Field( + default=None, + description="Gross short position concentration of top 4 traders, all contracts.", + ) + concentration_gross_top_8_traders_long: float | None = Field( + default=None, + description="Gross long position concentration of top 8 traders, all contracts.", + ) + concentration_gross_top_8_traders_short: float | None = Field( + default=None, + description="Gross short position concentration of top 8 traders, all contracts.", + ) + concentration_net_top_4_traders_long_all: float | None = Field( + default=None, + description="Net long position concentration of top 4 traders, all contracts.", + ) + concentration_net_top_4_traders_short_all: float | None = Field( + default=None, + description="Net short position concentration of top 4 traders, all contracts.", + ) + concentration_net_top_8_traders_long_all: float | None = Field( + default=None, + description="Net long position concentration of top 8 traders, all contracts.", + ) + concentration_net_top_8_traders_short_all: float | None = Field( + default=None, + description="Net short position concentration of top 8 traders, all contracts.", + ) + + # -- Concentration Ratios: Old Crop Year -- + + concentration_gross_top_4_traders_long_1: float | None = Field( + default=None, + description="Gross long position concentration of top 4 traders, old crop year. Legacy/Disaggregated reports.", + ) + concentration_gross_top_4_traders_short_1: float | None = Field( + default=None, + description="Gross short position concentration of top 4 traders, old crop year. Legacy/Disaggregated reports.", + ) + concentration_gross_top_8_traders_long_1: float | None = Field( + default=None, + description="Gross long position concentration of top 8 traders, old crop year. Legacy/Disaggregated reports.", + ) + concentration_gross_top_8_traders_short_1: float | None = Field( + default=None, + description="Gross short position concentration of top 8 traders, old crop year. Legacy/Disaggregated reports.", + ) + concentration_net_top_4_traders_long_old: float | None = Field( + default=None, + description="Net long position concentration of top 4 traders, old crop year. Legacy/Disaggregated reports.", + ) + concentration_net_top_4_traders_short_old: float | None = Field( + default=None, + description="Net short position concentration of top 4 traders, old crop year. Legacy/Disaggregated reports.", + ) + concentration_net_top_8_traders_long_old: float | None = Field( + default=None, + description="Net long position concentration of top 8 traders, old crop year. Legacy/Disaggregated reports.", + ) + concentration_net_top_8_traders_short_old: float | None = Field( + default=None, + description="Net short position concentration of top 8 traders, old crop year. Legacy/Disaggregated reports.", + ) + + # -- Concentration Ratios: Other Crop Year -- + + concentration_gross_top_4_traders_long_2: float | None = Field( + default=None, + description="Gross long position concentration of top 4 traders, other crop year. Legacy/Disaggregated reports.", + ) + concentration_gross_top_4_traders_short_2: float | None = Field( + default=None, + description="Gross short position concentration of top 4 traders, other crop year. Legacy/Disaggregated reports.", + ) + concentration_gross_top_8_traders_long_2: float | None = Field( + default=None, + description="Gross long position concentration of top 8 traders, other crop year. Legacy/Disaggregated reports.", + ) + concentration_gross_top_8_traders_short_2: float | None = Field( + default=None, + description="Gross short position concentration of top 8 traders, other crop year. Legacy/Disaggregated reports.", + ) + concentration_net_top_4_traders_long_other: float | None = Field( + default=None, + description="Net long position concentration of top 4 traders, other crop year. Legacy/Disaggregated reports.", + ) + concentration_net_top_4_traders_short_other: float | None = Field( + default=None, + description="Net short position concentration of top 4 traders, other crop year. Legacy/Disaggregated reports.", + ) + concentration_net_top_8_traders_long_other: float | None = Field( + default=None, + description="Net long position concentration of top 8 traders, other crop year. Legacy/Disaggregated reports.", + ) + concentration_net_top_8_traders_short_other: float | None = Field( + default=None, + description="Net short position concentration of top 8 traders, other crop year. Legacy/Disaggregated reports.", + ) class CftcCotFetcher(Fetcher[CftcCotQueryParams, list[CftcCotData]]): @@ -87,17 +1851,29 @@ class CftcCotFetcher(Fetcher[CftcCotQueryParams, list[CftcCotData]]): ) -> list[dict]: """Extract the data from the CFTC API.""" # pylint: disable=import-outside-toplevel - from datetime import timedelta # noqa + import os # noqa + from datetime import timedelta from openbb_core.provider.utils.helpers import amake_request - app_token = credentials.get("cftc_app_token") if credentials else "" + app_token = ( + credentials.get("cftc_app_token") + if credentials + else os.getenv("CFTC_APP_TOKEN") or "" + ) today = datetime.now() - # If the ID is a CFTC code, we'll get the complete history by default. + + _id = "" if query.code == "all" else query.code # type: ignore + if _id.startswith("CFTC_"): + _id = _id[5:] + + is_code = _id and _id[:3].isdigit() _start = ( - (today - timedelta(days=(today.weekday() - 1) % 7)).strftime("%Y-%m-%d") - if query.id in (500, "500") or not query.id[:3].isdigit() - else "1995-01-01" + "1995-01-01" + if is_code + else ( + (today - timedelta(days=(today.weekday() - 1) % 7)).strftime("%Y-%m-%d") + ) ) start_date = ( query.start_date.strftime("%Y-%m-%d") if query.start_date else _start @@ -108,30 +1884,32 @@ class CftcCotFetcher(Fetcher[CftcCotQueryParams, list[CftcCotData]]): else f"{today.year}-12-31" ) date_range = ( - f"$where=Report_Date_as_YYYY_MM_DD between '{start_date}' AND '{end_date}'" + "$where=Report_Date_as_YYYY_MM_DD" + f" between '{start_date}' AND '{end_date}'" ) report_type = query.report_type.replace("financial", "tff") + if query.futures_only is True and report_type != "supplemental": report_type += "_futures_only" elif query.futures_only is False and report_type != "supplemental": report_type += "_combined" - query.id = "" if query.id == "all" else query.id - if not query.id[:3].isdigit(): - query.id = f"%{query.id}%" - query.id = query.id.replace("+", "%2B").replace("&", "%26") + if not is_code and _id: + _id = f"%{_id}%" + + _id = _id.replace("+", "%2B").replace("&", "%26") base_url = f"https://publicreporting.cftc.gov/resource/{reports_dict[report_type]}.json?$limit=1000000&{date_range}" order = "&$order=Report_Date_as_YYYY_MM_DD ASC" url = ( ( f"{base_url}" - f" AND (UPPER(contract_market_name) like UPPER('{query.id}') " - f"OR UPPER(commodity) like UPPER('{query.id}') " - f"OR UPPER(cftc_contract_market_code) like UPPER('{query.id}') " - f"OR UPPER(commodity_group_name) like UPPER('{query.id}') " - f"OR UPPER(commodity_subgroup_name) like UPPER('{query.id}'))" + f" AND (UPPER(contract_market_name) like UPPER('{_id}') " + f"OR UPPER(commodity) like UPPER('{_id}') " + f"OR UPPER(cftc_contract_market_code) like UPPER('{_id}') " + f"OR UPPER(commodity_group_name) like UPPER('{_id}') " + f"OR UPPER(commodity_subgroup_name) like UPPER('{_id}'))" ) - if query.id + if _id else base_url ) url = f"{url}{order}" @@ -145,7 +1923,7 @@ class CftcCotFetcher(Fetcher[CftcCotQueryParams, list[CftcCotData]]): raise error from error if not response: - raise EmptyDataError(f"No data found for {query.id.replace('%', '')}.") + raise EmptyDataError(f"No data found for {_id.replace('%', '')}.") return response # type: ignore @@ -172,7 +1950,6 @@ class CftcCotFetcher(Fetcher[CftcCotQueryParams, list[CftcCotData]]): "commodity_name", "commodity_subgroup_name", "contract_units", - "report_date_as_yyyy_mm_dd", "yyyy_report_week_ww", "id", "futonly_or_combined", @@ -181,10 +1958,13 @@ class CftcCotFetcher(Fetcher[CftcCotQueryParams, list[CftcCotData]]): for values in response: new_values: dict = {} for key, value in values.items(): - if key in string_cols and value: - new_values[key.lower()] = str(value) - elif key == "report_date_as_yyyy_mm_dd": + if key == "report_date_as_yyyy_mm_dd" and value: new_values["report_date_as_yyyy_mm_dd"] = value.split("T")[0] + elif key in string_cols and value: + v = str(value) + if key == "contract_units": + v = v.strip("()") + new_values[key.lower()] = v elif key.lower().startswith("pct_") and value: new_values[key.lower().replace("__", "_")] = float(value) / 100 elif key.lower().startswith("conc_") and value: @@ -198,4 +1978,84 @@ class CftcCotFetcher(Fetcher[CftcCotQueryParams, list[CftcCotData]]): if new_values: results.append(CftcCotData.model_validate(new_values)) + if results: + dup_fields: set[str] = set() + sample = results[0].model_dump() + for fname in list(sample): + base: str | None = None + if fname.endswith("_old") or fname.endswith("_other"): + base = fname.rsplit("_", 1)[0] + "_all" + elif fname.endswith("_1") or fname.endswith("_2"): + base = fname[:-2] + if base is None or base not in sample: + continue + pairs = [ + (getattr(r, base, None), getattr(r, fname, None)) for r in results + ] + paired = [(a, b) for a, b in pairs if a is not None and b is not None] + if paired and all(a == b for a, b in paired): + dup_fields.add(fname) + if dup_fields: + for r in results: + for col in dup_fields: + object.__setattr__(r, col, None) + + measure = query.measure + if measure != "all" and results: + _metadata = { + "market_and_exchange_names", + "cftc_contract_market_code", + "cftc_market_code", + "cftc_region_code", + "cftc_commodity_code", + "cftc_contract_market_code_quotes", + "cftc_market_code_quotes", + "cftc_commodity_code_quotes", + "cftc_subgroup_code", + "commodity", + "commodity_group", + "commodity_subgroup", + "futonly_or_combined", + "contract_units", + "contract_market_name", + "report_week", + "id", + } + measure_prefixes = { + "changes": "change_", + "percent_of_oi": "open_interest_pct_", + "traders": "traders_", + "concentration": "concentration_", + } + + def _keep(field_name: str) -> bool: + if field_name in ("date", "open_interest_all"): + return True + if field_name in _metadata: + return False + if measure == "positions": + return not any( + field_name.startswith(p) for p in measure_prefixes.values() + ) + return field_name.startswith(measure_prefixes[measure]) + + keep_fields = { + f + for r in results + for f, v in r.model_dump().items() + if _keep(f) and v is not None and v != 0 + } + keep_fields.add("date") + keep_fields.add("open_interest_all") + + filtered: list[CftcCotData] = [] + for r in results: + d = {k: v for k, v in r.model_dump().items() if k in keep_fields} + filtered.append(CftcCotData.model_validate(d)) + results = filtered + + results.sort(key=lambda r: r.date) + if query.limit is not None and query.limit > 0: + results = results[-query.limit :] + return results diff --git a/openbb_platform/providers/cftc/openbb_cftc/models/cot_search.py b/openbb_platform/providers/cftc/openbb_cftc/models/cot_search.py index 21442214f6f..9b06abc167d 100644 --- a/openbb_platform/providers/cftc/openbb_cftc/models/cot_search.py +++ b/openbb_platform/providers/cftc/openbb_cftc/models/cot_search.py @@ -2,13 +2,15 @@ # pylint: disable=unused-argument -from typing import Any +from typing import Any, Literal +from openbb_core.app.model.abstract.error import OpenBBError from openbb_core.provider.abstract.fetcher import Fetcher from openbb_core.provider.standard_models.cot_search import ( CotSearchData, CotSearchQueryParams, ) +from openbb_core.provider.utils.errors import EmptyDataError from pydantic import Field @@ -18,6 +20,74 @@ class CftcCotSearchQueryParams(CotSearchQueryParams): Source: https://publicreporting.cftc.gov/stories/s/r4w3-av2u """ + __json_schema_extra__ = { + "report_type": { + "multiple_items_allowed": False, + "choices": ["legacy", "disaggregated", "financial", "supplemental"], + }, + "category": { + "multiple_items_allowed": False, + "choices": [ + "agriculture", + "financial_instruments", + "natural_resources", + ], + }, + "subcategory": { + "multiple_items_allowed": False, + "choices": [ + "base_metals", + "chemicals", + "currency", + "currency_non_major", + "dairy_products", + "digital_asset", + "digital_asset_non_major", + "electricity_and_sources", + "emissions", + "fertilizer", + "fiber", + "foodstuffs_softs", + "grains", + "interest_rate_swaps", + "interest_rates_non_us_treasury", + "interest_rates_us_treasury", + "livestock_meat_products", + "natural_gas_and_products", + "oilseed_and_products", + "other_agricultural", + "other_financial_instruments", + "petroleum_and_products", + "precious_metals", + "stock_indices", + "weather", + "wood_products", + "yield_insurance", + ], + }, + } + + report_type: Literal["legacy", "disaggregated", "financial", "supplemental"] = ( + Field( + default="legacy", + description="The report type to search within.", + ) + ) + futures_only: bool = Field( + default=False, + description="Search the futures-only report. Default is False, for the combined report.", + ) + category: str | None = Field( + default=None, + description="Filter by commodity group name." + " Underscores are replaced with spaces. E.g, 'natural_resources' -> 'NATURAL RESOURCES'.", + ) + subcategory: str | None = Field( + default=None, + description="Filter by commodity subgroup name." + " Underscores are replaced with spaces. E.g, 'precious_metals' -> 'PRECIOUS METALS'.", + ) + class CftcCotSearchData(CotSearchData): """CFTC Commitment of Traders Reports Search Data.""" @@ -43,48 +113,132 @@ class CftcCotSearchFetcher(Fetcher[CftcCotSearchQueryParams, list[CftcCotSearchD return CftcCotSearchQueryParams(**params) @staticmethod - def extract_data( + async def aextract_data( query: CftcCotSearchQueryParams, credentials: dict[str, str] | None, **kwargs: Any, ) -> list[dict]: - """Search a curated list of CFTC Commitment of Traders Reports.""" + """Search CFTC Commitment of Traders Reports via the live API.""" # pylint: disable=import-outside-toplevel - from importlib.resources import files # noqa - from pathlib import Path - from pandas import read_json + from urllib.parse import quote - assets_path = Path(str(files("openbb_cftc").joinpath("assets"))) + from openbb_cftc.utils import reports_dict + from openbb_core.provider.utils.helpers import amake_request - with open(assets_path.joinpath("cot_ids.json"), encoding="utf-8") as f: - available_cot = read_json(f) + app_token = credentials.get("cftc_app_token") if credentials else "" - query_string = query.query # noqa - return ( - available_cot[ - available_cot["contract_market_name"].str.contains( - query_string, case=False - ) - | available_cot["cftc_contract_market_code"].str.contains( - query_string, case=False - ) - | available_cot["commodity_name"].str.contains(query_string, case=False) - | available_cot["commodity_group_name"].str.contains( - query_string, case=False - ) - | available_cot["commodity_subgroup_name"].str.contains( - query_string, case=False - ) - ] - .reset_index(drop=True) - .to_dict("records") + report_type = query.report_type.replace("financial", "tff") + if query.futures_only is True and report_type != "supplemental": + report_type += "_futures_only" + elif query.futures_only is False and report_type != "supplemental": + report_type += "_combined" + + dataset_id = reports_dict[report_type] + select_cols = ( + "cftc_contract_market_code," + "contract_market_name," + "commodity_name," + "commodity_group_name," + "commodity_subgroup_name," + "contract_units" ) + base_url = ( + f"https://publicreporting.cftc.gov/resource/{dataset_id}.json" + f"?$select={select_cols}" + f"&$group={select_cols}" + "&$limit=50000" + "&$order=commodity_group_name,commodity_subgroup_name,contract_market_name" + ) + + search_term = query.query + where_parts: list[str] = [] + + from datetime import datetime, timedelta + + cutoff = (datetime.now() - timedelta(weeks=52)).strftime("%Y-%m-%d") + where_parts.append(f"Report_Date_as_YYYY_MM_DD > '{cutoff}'") + + if search_term: + escaped = search_term.replace("'", "''") + where_parts.append( + f"(UPPER(contract_market_name) like UPPER('%{escaped}%')" + f" OR UPPER(cftc_contract_market_code) like UPPER('%{escaped}%')" + f" OR UPPER(commodity_name) like UPPER('%{escaped}%')" + f" OR UPPER(commodity_group_name) like UPPER('%{escaped}%')" + f" OR UPPER(commodity_subgroup_name) like UPPER('%{escaped}%'))" + ) + + if query.category: + cat = query.category.replace("_", " ").upper() + where_parts.append(f"UPPER(commodity_group_name) = '{cat}'") + + if query.subcategory: + subcategory_map = { + "currency_non_major": "CURRENCY(NON-MAJOR)", + "digital_asset_non_major": "DIGITAL ASSET (NON-MAJOR)", + "foodstuffs_softs": "FOODSTUFFS/SOFTS", + "interest_rates_non_us_treasury": "INTEREST RATES - NON U.S. TREASURY", + "interest_rates_us_treasury": "INTEREST RATES - U.S. TREASURY", + "livestock_meat_products": "LIVESTOCK/MEAT PRODUCTS", + "oilseed_and_products": "OILSEED AND PRODUCTS", + } + sub = subcategory_map.get( + query.subcategory, + query.subcategory.replace("_", " ").upper(), + ) + where_parts.append(f"UPPER(commodity_subgroup_name) = '{sub}'") + + if where_parts: + base_url += "&$where=" + quote(" AND ".join(where_parts)) + + url = f"{base_url}&$$app_token={app_token}" if app_token else base_url + + try: + response = await amake_request(url, **kwargs) + except OpenBBError as error: + raise error from error + + if not response: + raise EmptyDataError( + f"No results found for '{search_term}'." + if search_term + else "No results returned from the CFTC API." + ) + + return response # type: ignore @staticmethod def transform_data( - query: CotSearchQueryParams, + query: CftcCotSearchQueryParams, data: list[dict], **kwargs: Any, ) -> list[CftcCotSearchData]: """Transform the data.""" - return [CftcCotSearchData.model_validate(d) for d in data] + results: list[CftcCotSearchData] = [] + seen: set[str] = set() + for d in data: + code = d.get("cftc_contract_market_code", "") + if code and code not in seen: + seen.add(code) + name = d.get("commodity_name", "") + + if "commodity_group_name" not in list( + d + ) and name.strip().upper().endswith("INDICES"): + category = "FINANCIAL INSTRUMENTS" + subcategory = "STOCK INDICES" + d["commodity_group_name"] = category + d["commodity_subgroup_name"] = subcategory + elif ( + "commodity_group_name" not in list(d) + and "CRYPTO" in name.strip().upper() + ): + category = "FINANCIAL INSTRUMENTS" + subcategory = "DIGITAL ASSET (NON-MAJOR)" + d["commodity_group_name"] = category + d["commodity_subgroup_name"] = subcategory + + d["cftc_contract_market_code"] = f"CFTC_{code}" + results.append(CftcCotSearchData.model_validate(d)) + + return results diff --git a/openbb_platform/providers/cftc/openbb_cftc/utils/__init__.py b/openbb_platform/providers/cftc/openbb_cftc/utils/__init__.py index f9f4ad0dbb7..07d5c901067 100644 --- a/openbb_platform/providers/cftc/openbb_cftc/utils/__init__.py +++ b/openbb_platform/providers/cftc/openbb_cftc/utils/__init__.py @@ -1 +1,11 @@ """CFTC provider extension utilities.""" + +reports_dict = { + "legacy_futures_only": "6dca-aqww", + "legacy_combined": "jun7-fc8e", + "disaggregated_futures_only": "72hh-3qpy", + "disaggregated_combined": "kh3c-gbw2", + "tff_futures_only": "gpe5-46if", + "tff_combined": "yw9f-hn96", + "supplemental": "4zgm-a668", +} diff --git a/openbb_platform/providers/cftc/poetry.lock b/openbb_platform/providers/cftc/poetry.lock index 2c8102362a4..6f572acddfd 100644 --- a/openbb_platform/providers/cftc/poetry.lock +++ b/openbb_platform/providers/cftc/poetry.lock @@ -419,6 +419,30 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +[[package]] +name = "deepdiff" +version = "9.0.0" +description = "Deep Difference and Search of any Python object/data. Recreate objects by adding adding deltas to each other." +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "deepdiff-9.0.0-py3-none-any.whl", hash = "sha256:b1ae0dd86290d86a03de5fbee728fde43095c1472ae4974bdab23ab4656305bd"}, + {file = "deepdiff-9.0.0.tar.gz", hash = "sha256:4872005306237b5b50829803feff58a1dfd20b2b357a55de22e7ded65b2008a7"}, +] + +[package.dependencies] +orderly-set = ">=5.5.0,<6" + +[package.extras] +cli = ["click (>=8.3.1,<8.4.0)", "pyyaml (>=6.0.3,<6.1.0)"] +coverage = ["coverage (>=7.13.5,<7.14.0)"] +dev = ["bump2version (>=1.0.1,<1.1.0)", "flit-core (==3.12.0)", "ipdb (>=0.13.13,<0.14.0)", "jsonpickle (>=4.1.1,<4.2.0)", "nox (==2026.2.9)", "numpy (>=2.2.0,<2.3.0) ; python_version < \"3.14\"", "numpy (>=2.4.3,<2.5.0) ; python_version >= \"3.14\"", "orjson (>=3.11.7,<3.12.0)", "pandas (>=2.2.0,<2.3.0) ; python_version < \"3.11\"", "pandas (>=3.0.1,<3.1.0) ; python_version >= \"3.11\"", "polars (>=1.39.3,<1.40.0)", "python-dateutil (>=2.9.0.post0,<2.10.0)", "pytz", "tomli (>=2.4.0,<2.5.0)", "tomli-w (>=1.2.0,<1.3.0)", "uuid6 (==2025.0.1)"] +docs = ["Sphinx (>=8.1.3,<8.2.0)", "furo (>=2024.8.6)", "sphinx-sitemap (>=2.9.0,<2.10.0)", "sphinxemoji (>=0.3.2,<0.4.0)"] +optimize = ["orjson"] +static = ["flake8 (>=7.3.0,<7.4.0)", "flake8-pyproject (>=1.2.4,<1.3.0)", "pydantic (>=2.12.5,<2.13.0)"] +test = ["pytest (>=9.0.2,<9.1.0)", "pytest-benchmark (>=5.2.3,<5.3.0)", "pytest-cov (>=7.1.0,<7.2.0)", "python-dotenv (>=1.2.2,<1.3.0)"] + [[package]] name = "exceptiongroup" version = "1.3.1" @@ -1011,6 +1035,41 @@ uuid7 = ">=0.1.0,<0.2.0" uvicorn = ">=0.40.0,<0.41.0" websockets = ">=15.0" +[[package]] +name = "openbb-platform-api" +version = "1.3.5" +description = "OpenBB Platform API: Launch script and widgets builder for the Open Data Platform REST API and Workspace Backend Connector." +optional = false +python-versions = "<4,>=3.10" +groups = ["main"] +files = [ + {file = "openbb_platform_api-1.3.5-py3-none-any.whl", hash = "sha256:dfa0175006aede9e09906b81832105075747d836b135e945e73af51060731066"}, + {file = "openbb_platform_api-1.3.5.tar.gz", hash = "sha256:40816bb6ffe18481d7e023a5c36304761e5334d18098c72af7bd6d44f4235932"}, +] + +[package.dependencies] +deepdiff = ">=8.6.2" +openbb-core = ">=1.6.4,<2.0.0" + +[[package]] +name = "orderly-set" +version = "5.5.0" +description = "Orderly set" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "orderly_set-5.5.0-py3-none-any.whl", hash = "sha256:46f0b801948e98f427b412fcabb831677194c05c3b699b80de260374baa0b1e7"}, + {file = "orderly_set-5.5.0.tar.gz", hash = "sha256:e87185c8e4d8afa64e7f8160ee2c542a475b738bc891dc3f58102e654125e6ce"}, +] + +[package.extras] +coverage = ["coverage (>=7.6.0,<7.7.0)"] +dev = ["bump2version (>=1.0.0,<1.1.0)", "ipdb (>=0.13.0,<0.14.0)"] +optimize = ["orjson"] +static = ["flake8 (>=7.1.0,<7.2.0)", "flake8-pyproject (>=1.2.3,<1.3.0)"] +test = ["pytest (>=8.3.0,<8.4.0)", "pytest-benchmark (>=5.1.0,<5.2.0)", "pytest-cov (>=6.0.0,<6.1.0)", "python-dotenv (>=1.0.0,<1.1.0)"] + [[package]] name = "pandas" version = "2.3.3" @@ -1335,19 +1394,19 @@ files = [ [[package]] name = "pydantic" -version = "2.13.2" +version = "2.13.3" description = "Data validation using Python type hints" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "pydantic-2.13.2-py3-none-any.whl", hash = "sha256:a525087f4c03d7e7456a3de89b64cd693d2229933bb1068b9af6befd5563694e"}, - {file = "pydantic-2.13.2.tar.gz", hash = "sha256:b418196607e61081c3226dcd4f0672f2a194828abb9109e9cfb84026564df2d1"}, + {file = "pydantic-2.13.3-py3-none-any.whl", hash = "sha256:6db14ac8dfc9a1e57f87ea2c0de670c251240f43cb0c30a5130e9720dc612927"}, + {file = "pydantic-2.13.3.tar.gz", hash = "sha256:af09e9d1d09f4e7fe37145c1f577e1d61ceb9a41924bf0094a36506285d0a84d"}, ] [package.dependencies] annotated-types = ">=0.6.0" -pydantic-core = "2.46.2" +pydantic-core = "2.46.3" typing-extensions = ">=4.14.1" typing-inspection = ">=0.4.2" @@ -1357,132 +1416,132 @@ timezone = ["tzdata ; python_version >= \"3.9\" and platform_system == \"Windows [[package]] name = "pydantic-core" -version = "2.46.2" +version = "2.46.3" description = "Core functionality for Pydantic validation and serialization" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "pydantic_core-2.46.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:160ef93541f4f84e3e5068e6c1f64d8fd6f57586e5853d609b467d3333f8146a"}, - {file = "pydantic_core-2.46.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a9124b63f4f40a12a0666df57450b4c24b98407ff74349221b869ec085a5d8e"}, - {file = "pydantic_core-2.46.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de12004a7da7f1eb67ece37439a5a23a915636085dd042176fda362e006e6940"}, - {file = "pydantic_core-2.46.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a070c7769fec277409ad0b3d55b2f0a3703a6f00cf5031fe93090f155bf56382"}, - {file = "pydantic_core-2.46.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:41d701bb34f81f0b11c724cc544b9a10b26a28f4d0d1197f2037c91225708706"}, - {file = "pydantic_core-2.46.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19631e7350b7a574fb6b6db222f4b17e8bd31803074b3307d07df62379d2b2e4"}, - {file = "pydantic_core-2.46.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48b1059e4f2a6ec3e41983148eb1eec5ef9fa3a80bbc4ac0893ac76b115fe039"}, - {file = "pydantic_core-2.46.2-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:df73724fce8ad53c670358c905b37930bd7b9d92e57db640a65c53b2706eee00"}, - {file = "pydantic_core-2.46.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a0891a9be0def16fb320af21a198ece052eed72bf44d73d8ff43f702bd26fd6b"}, - {file = "pydantic_core-2.46.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2ca790779aa1cba1329b8dc42ccebada441d9ac1d932de980183d544682c646d"}, - {file = "pydantic_core-2.46.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:6b865eb702c3af71cf7331919a787563ce2413f7a54ef49ec6709a01b4f22ce6"}, - {file = "pydantic_core-2.46.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:631bec5f951a30a4b332b4a57d0cdd5a2c8187eb71301f966425f2e54a697855"}, - {file = "pydantic_core-2.46.2-cp310-cp310-win32.whl", hash = "sha256:8cbd9d67357f3a925f2af1d44db3e8ef1ce1a293ea0add98081b072d4a12e3b4"}, - {file = "pydantic_core-2.46.2-cp310-cp310-win_amd64.whl", hash = "sha256:dd51dd16182b4bfdcefd27b39b856aa4a57b77f15b231a2d10c45391b0a02028"}, - {file = "pydantic_core-2.46.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d8060f42db3cd204871db0afd51fef54a13fa544c4dd48cdcae2e174ef40c8ba"}, - {file = "pydantic_core-2.46.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:73a9d2809bd8d4a7cda4d336dc996a565eb4feaaa39932f9d85a65fa18382f28"}, - {file = "pydantic_core-2.46.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b0a2dee92dfaabcfb93629188c3e9cf74fdfc0f22e7c369cb444a98814a1e50"}, - {file = "pydantic_core-2.46.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3098446ba8cf774f61cb8d4008c1dba14a30426a15169cd95ac3392a461193b1"}, - {file = "pydantic_core-2.46.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:57c584af6c375ea3f826d8131a94cb212b3d9926eaff67117e3711bbff3a83a5"}, - {file = "pydantic_core-2.46.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:547381cca999be88b4715a0ed7afa11f07fc7e53cb1883687b190d25a92c56cf"}, - {file = "pydantic_core-2.46.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caeed15dcb1233a5a94bc6ff37ef5393cf5b33a45e4bdfb2d6042f3d24e1cb27"}, - {file = "pydantic_core-2.46.2-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:c05f53362568c75476b5c96659377a5dfd982cfbe5a5c07de5106d08a04efc4f"}, - {file = "pydantic_core-2.46.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2643ac7eae296200dbd48762a1c852cf2cad5f5e3eba34e652053cebf03becf8"}, - {file = "pydantic_core-2.46.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:dc4620a47c6fe6a39f89392c00833a82fc050ce90169798f78a25a8d4df03b6e"}, - {file = "pydantic_core-2.46.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:78cb0d2453b50bf2035f85fd0d9cfabdb98c47f9c53ddb7c23873cd83da9560b"}, - {file = "pydantic_core-2.46.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f0c1cbb7d6112932cc188c6be007a5e2867005a069e47f42fe67bf5f122b0908"}, - {file = "pydantic_core-2.46.2-cp311-cp311-win32.whl", hash = "sha256:c1ce5b2366f85cfdbf7f0907755043707f86d09a5b1b1acebbb7bf1600d75c64"}, - {file = "pydantic_core-2.46.2-cp311-cp311-win_amd64.whl", hash = "sha256:f1a6197eadff5bd0bb932f12bb038d403cb75db5b0b391e70e816a647745ddaf"}, - {file = "pydantic_core-2.46.2-cp311-cp311-win_arm64.whl", hash = "sha256:15e42885b283f87846ee79e161002c5c496ef747a73f6e47054f45a13d9035bc"}, - {file = "pydantic_core-2.46.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:ea1ad8c89da31512fe2d249cf0638fb666925bda341901541bc5f3311c6fcc9e"}, - {file = "pydantic_core-2.46.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b308da17b92481e0587244631c5529e5d91d04cb2b08194825627b1eca28e21e"}, - {file = "pydantic_core-2.46.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d333a50bdd814a917d8d6a7ee35ba2395d53ddaa882613bc24e54a9d8b129095"}, - {file = "pydantic_core-2.46.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1d00b99590c5bd1fabbc5d28b170923e32c1b1071b1f1de1851a4d14d89eb192"}, - {file = "pydantic_core-2.46.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9f0e686960ffe9e65066395af856ac2d52c159043144433602c50c221d81c1ba"}, - {file = "pydantic_core-2.46.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d1128da41c9cb474e0a4701f9c363ec645c9d1a02229904c76bf4e0a194fde2"}, - {file = "pydantic_core-2.46.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48649cf2d8c358d79586e9fb2f8235902fcaa2d969ec1c5301f2d1873b2f8321"}, - {file = "pydantic_core-2.46.2-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:b902f0fc7c2cf503865a05718b68147c6cd5d0a3867af38c527be574a9fa6e9d"}, - {file = "pydantic_core-2.46.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e80011f808b03d1d87a8f1e76ae3da19a18eb706c823e17981dcf1fae43744fc"}, - {file = "pydantic_core-2.46.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b839d5c802e31348b949b6473f8190cddbf7d47475856d8ac995a373ee16ec59"}, - {file = "pydantic_core-2.46.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:c6b1064f3f9cf9072e1d59dd2936f9f3b668bec1c37039708c9222db703c0d5b"}, - {file = "pydantic_core-2.46.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:37a68e6f2ac95578ce3c0564802404b27b24988649616e556c07e77111ed3f1d"}, - {file = "pydantic_core-2.46.2-cp312-cp312-win32.whl", hash = "sha256:d9ffa75a7ef4b97d6e5e205fabd4304ef01fec09e6f1bdde04b9ad1b07d20289"}, - {file = "pydantic_core-2.46.2-cp312-cp312-win_amd64.whl", hash = "sha256:0551f2d2ddb68af5a00e26497f8025c538f73ef3cb698f8e5a487042cd2792a8"}, - {file = "pydantic_core-2.46.2-cp312-cp312-win_arm64.whl", hash = "sha256:83aef30f106edcc21a6a4cc44b82d3169a1dbe255508db788e778f3c804d3583"}, - {file = "pydantic_core-2.46.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:d26e9eea3715008a09a74585fe9becd0c67fbb145dc4df9756d597d7230a652c"}, - {file = "pydantic_core-2.46.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:48b36e3235140510dc7861f0cd58b714b1cdd3d48f75e10ce52e69866b746f10"}, - {file = "pydantic_core-2.46.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:36b1f99dc451f1a3981f236151465bcf995bbe712d0727c9f7b236fe228a8133"}, - {file = "pydantic_core-2.46.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8641c8d535c2d95b45c2e19b646ecd23ebba35d461e0ae48a3498277006250ab"}, - {file = "pydantic_core-2.46.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:20fb194788a0a50993e87013e693494ba183a2af5b44e99cf060bbae10912b11"}, - {file = "pydantic_core-2.46.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9262d11d0cd11ee3303a95156939402bed6cedfe5ed0e331b95a283a4da6eb8b"}, - {file = "pydantic_core-2.46.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac204542736aa295fa25f713b7fad6fc50b46ab7764d16087575c85f085174f3"}, - {file = "pydantic_core-2.46.2-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:9a7c43a0584742dface3ca0daf6f719d46c1ac2f87cf080050f9ae052c75e1b2"}, - {file = "pydantic_core-2.46.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fd05e1edb6a90ad446fa268ab09e59202766b837597b714b2492db11ee87fab9"}, - {file = "pydantic_core-2.46.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:91155b110788b5501abc7ea954f1d08606219e4e28e3c73a94124307c06efb80"}, - {file = "pydantic_core-2.46.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:e4e2c72a529fa03ff228be1d2b76944013f428220b764e03cc50ada67e17a42c"}, - {file = "pydantic_core-2.46.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:56291ec1a11c3499890c99a8fd9053b47e60fe837a77ec72c0671b1b8b3dce24"}, - {file = "pydantic_core-2.46.2-cp313-cp313-win32.whl", hash = "sha256:b50f9c5f826ddca1246f055148df939f5f3f2d0d96db73de28e2233f22210d4c"}, - {file = "pydantic_core-2.46.2-cp313-cp313-win_amd64.whl", hash = "sha256:251a57788823230ca8cbc99e6245d1a2ed6e180ec4864f251c94182c580c7f2e"}, - {file = "pydantic_core-2.46.2-cp313-cp313-win_arm64.whl", hash = "sha256:315d32d1a71494d6b4e1e14a9fa7a4329597b4c4340088ad7e1a9dafbeed92a9"}, - {file = "pydantic_core-2.46.2-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:4f59b45f3ef8650c0c736a57f59031d47ed9df4c0a64e83796849d7d14863a2d"}, - {file = "pydantic_core-2.46.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3a075a29ebef752784a91532a1a85be6b234ccffec0a9d7978a92696387c3da6"}, - {file = "pydantic_core-2.46.2-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d12d786e30c04a9d307c5d7080bf720d9bac7f1668191d8e37633a9562749e2"}, - {file = "pydantic_core-2.46.2-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0d5e6d6343b0b5dcacb3503b5de90022968da8ed0ab9ab39d3eda71c20cbf84e"}, - {file = "pydantic_core-2.46.2-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:233eebac0999b6b9ba76eb56f3ec8fce13164aa16b6d2225a36a79e0f95b5973"}, - {file = "pydantic_core-2.46.2-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9cc0eee720dd2f14f3b7c349469402b99ad81a174ab49d3533974529e9d93992"}, - {file = "pydantic_core-2.46.2-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83ee76bf2c9910513dbc19e7d82367131fa7508dedd6186a462393071cc11059"}, - {file = "pydantic_core-2.46.2-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:d61db38eb4ee5192f0c261b7f2d38e420b554df8912245e3546aee5c45e2fd78"}, - {file = "pydantic_core-2.46.2-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8f09a713d17bcd55da8ab02ebd9110c5246a49c44182af213b5212800af8bc83"}, - {file = "pydantic_core-2.46.2-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:30cacc5fb696e64b8ef6fd31d9549d394dd7d52760db072eecb98e37e3af1677"}, - {file = "pydantic_core-2.46.2-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:7ccfb105fcfe91a22bbb5563ad3dc124bc1aa75bfd2e53a780ab05f78cdf6108"}, - {file = "pydantic_core-2.46.2-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:13ffef637dc8370c249e5b26bd18e9a80a4fca3d809618c44e18ec834a7ca7a8"}, - {file = "pydantic_core-2.46.2-cp314-cp314-win32.whl", hash = "sha256:1b0ab6d756ca2704a938e6c31b53f290c2f9c10d3914235410302a149de1a83e"}, - {file = "pydantic_core-2.46.2-cp314-cp314-win_amd64.whl", hash = "sha256:99ebade8c9ada4df975372d8dd25883daa0e379a05f1cd0c99aa0c04368d01a6"}, - {file = "pydantic_core-2.46.2-cp314-cp314-win_arm64.whl", hash = "sha256:de87422197cf7f83db91d89c86a21660d749b3cd76cd8a45d115b8e675670f02"}, - {file = "pydantic_core-2.46.2-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:236f22b4a206b5b61db955396b7cf9e2e1ff77f372efe9570128ccfcd6a525eb"}, - {file = "pydantic_core-2.46.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c2012f64d2cd7cca50f49f22445aa5a88691ac2b4498ee0a9a977f8ca4f7289f"}, - {file = "pydantic_core-2.46.2-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d07d6c63106d3a9c9a333e2636f9c82c703b1a9e3b079299e58747964e4fdb72"}, - {file = "pydantic_core-2.46.2-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c326a2b4b85e959d9a1fc3a11f32f84611b6ec07c053e1828a860edf8d068208"}, - {file = "pydantic_core-2.46.2-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac8a65e798f2462552c00d2e013d532c94d646729dda98458beaf51f9ec7b120"}, - {file = "pydantic_core-2.46.2-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a3c2bc1cc8164bedbc160b7bb1e8cc1e8b9c27f69ae4f9ae2b976cdae02b2dd"}, - {file = "pydantic_core-2.46.2-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e69aa5e10b7e8b1bb4a6888650fd12fcbf11d396ca11d4a44de1450875702830"}, - {file = "pydantic_core-2.46.2-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:4e6df5c3301e65fb42bc5338bf9a1027a02b0a31dc7f54c33775229af474daf0"}, - {file = "pydantic_core-2.46.2-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c2f6e32548ac8d559b47944effcf8ae4d81c161f6b6c885edc53bc08b8f192d"}, - {file = "pydantic_core-2.46.2-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:b089a81c58e6ea0485562bbbbbca4f65c0549521606d5ef27fba217aac9b665a"}, - {file = "pydantic_core-2.46.2-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:7f700a6d6f64112ae9193709b84303bbab84424ad4b47d0253301aabce9dfc70"}, - {file = "pydantic_core-2.46.2-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:67db6814beaa5fefe91101ec7eb9efda613795767be96f7cf58b1ca8c9ca9972"}, - {file = "pydantic_core-2.46.2-cp314-cp314t-win32.whl", hash = "sha256:32fbc7447be8e3be99bf7869f7066308f16be55b61f9882c2cefc7931f5c7664"}, - {file = "pydantic_core-2.46.2-cp314-cp314t-win_amd64.whl", hash = "sha256:b317a2b97019c0b95ce99f4f901ae383f40132da6706cdf1731066a73394c25c"}, - {file = "pydantic_core-2.46.2-cp314-cp314t-win_arm64.whl", hash = "sha256:7dcb9d40930dfad7ab6b20bcc6ca9d2b030b0f347a0cd9909b54bd53ead521b1"}, - {file = "pydantic_core-2.46.2-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:33741359798f9dc3d4244a66031575d8a86c004f7853eb9961a49e4b6fab2d0b"}, - {file = "pydantic_core-2.46.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f557ce9106850c79252792962d78b987e11fcdc10e5c2252443b9a485d3bfe5"}, - {file = "pydantic_core-2.46.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd195af20e53aaac6cf5d7862e34dfdf86351720c858581ccb6563e02ae59421"}, - {file = "pydantic_core-2.46.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5a8e486d238850ddf2b25739317b6551d5bef9925ab004b18c552ff6e645f8a2"}, - {file = "pydantic_core-2.46.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dfff584138be087457cc474791d082fdfe32b0d427613d5494a679fe9f4eaef5"}, - {file = "pydantic_core-2.46.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:387cbe2b2bcace397da91f9b1165a9e75da254bb306b876a43b824cc10f49ce0"}, - {file = "pydantic_core-2.46.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a6572f3238851fde28b3194ef98cec9dbe66f1614caf4646239ea87f324121a"}, - {file = "pydantic_core-2.46.2-cp39-cp39-manylinux_2_31_riscv64.whl", hash = "sha256:b478652b580cd4cf7f2dd40dc9fde594ed1c84e5df4bafefffb8387ddb74049f"}, - {file = "pydantic_core-2.46.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7b1c9bdca33968c0dcd875f8185b3b6275df753fe000178684b0c1738959f3cd"}, - {file = "pydantic_core-2.46.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e698fe2d8f75c4e9368ee3f4e0d3322d1180be2ec4592d3f73b2572765b1c705"}, - {file = "pydantic_core-2.46.2-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:404da669e5e02bf7fb2cc56715a609f63af88aea531287494467109f97865fe3"}, - {file = "pydantic_core-2.46.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:28708faed0b47f9d68906551a3471421ab0b15c31519e08fdb70ae6cad04d10b"}, - {file = "pydantic_core-2.46.2-cp39-cp39-win32.whl", hash = "sha256:5e2b4adb0fa46a842c492423e61063d6639cf9aea56380a02630ddcdd4894067"}, - {file = "pydantic_core-2.46.2-cp39-cp39-win_amd64.whl", hash = "sha256:fa8ab79cea8a1bfe52a21a9b37859c15478d009f242f47737201ecea885b9dd9"}, - {file = "pydantic_core-2.46.2-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:7c5a5b3dbb9e8918e223be6580da5ffcf861c0505bbc196ebed7176ce05b7b4e"}, - {file = "pydantic_core-2.46.2-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:bc1e8ce33d5a337f2ba862e0719b8201cd54aaed967406c748e009191d47efdd"}, - {file = "pydantic_core-2.46.2-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b737c0b280f41143266445de2689c0e49c79307e51c44ce3a77fef2bedad4994"}, - {file = "pydantic_core-2.46.2-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b877d597afb82b4898e35354bba55de6f7f048421ae0edadbb9886ec137b532"}, - {file = "pydantic_core-2.46.2-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:e9fcabd1857492b5bf16f90258babde50f618f55d046b1309972da2396321ff9"}, - {file = "pydantic_core-2.46.2-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:fb3ec2c7f54c07b30d89983ce78dc32c37dd06a972448b8716d609493802d628"}, - {file = "pydantic_core-2.46.2-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:130a6c837d819ef33e8c2bf702ed2c3429237ea69807f1140943d6f4bdaf52fa"}, - {file = "pydantic_core-2.46.2-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2e25417cec5cd9bddb151e33cb08c50160f317479ecc02b22a95ec18f8fe004"}, - {file = "pydantic_core-2.46.2-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c3ad79ed32004d9de91cacd4b5faaff44d56051392fe1d5526feda596f01af25"}, - {file = "pydantic_core-2.46.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:d157c48d28eebe5d46906de06a6a2f2c9e00b67d3e42de1f1b9c2d42b810f77c"}, - {file = "pydantic_core-2.46.2-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b42c6471288dedc979ac8400d9c9770f03967dd187db1f8d3405d4d182cc714"}, - {file = "pydantic_core-2.46.2-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4f27bc4801358dc070d6697b41237fce9923d8e69a1ce1e95606ac36c1552dc1"}, - {file = "pydantic_core-2.46.2-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e094a8f85db41aa7f6a45c5dac2950afc9862e66832934231962252b5d284eed"}, - {file = "pydantic_core-2.46.2-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:807eeda5551f6884d3b4421578be37be50ddb7a58832348e99617a6714a73748"}, - {file = "pydantic_core-2.46.2-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:fcaa1c3c846a7f6686b38fe493d1b2e8007380e293bfef6a9354563c026cbf36"}, - {file = "pydantic_core-2.46.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:154dbfdfb11b8cbd8ff4d00d0b81e3d19f4cb4bedd5aa9f091060ba071474c6a"}, - {file = "pydantic_core-2.46.2.tar.gz", hash = "sha256:37bb079f9ee3f1a519392b73fda2a96379b31f2013c6b467fe693e7f2987f596"}, + {file = "pydantic_core-2.46.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:1da3786b8018e60349680720158cc19161cc3b4bdd815beb0a321cd5ce1ad5b1"}, + {file = "pydantic_core-2.46.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cc0988cb29d21bf4a9d5cf2ef970b5c0e38d8d8e107a493278c05dc6c1dda69f"}, + {file = "pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27f9067c3bfadd04c55484b89c0d267981b2f3512850f6f66e1e74204a4e4ce3"}, + {file = "pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a642ac886ecf6402d9882d10c405dcf4b902abeb2972cd5fb4a48c83cd59279a"}, + {file = "pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79f561438481f28681584b89e2effb22855e2179880314bcddbf5968e935e807"}, + {file = "pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:57a973eae4665352a47cf1a99b4ee864620f2fe663a217d7a8da68a1f3a5bfda"}, + {file = "pydantic_core-2.46.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83d002b97072a53ea150d63e0a3adfae5670cef5aa8a6e490240e482d3b22e57"}, + {file = "pydantic_core-2.46.3-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:b40ddd51e7c44b28cfaef746c9d3c506d658885e0a46f9eeef2ee815cbf8e045"}, + {file = "pydantic_core-2.46.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ac5ec7fb9b87f04ee839af2d53bcadea57ded7d229719f56c0ed895bff987943"}, + {file = "pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a3b11c812f61b3129c4905781a2601dfdfdea5fe1e6c1cfb696b55d14e9c054f"}, + {file = "pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:1108da631e602e5b3c38d6d04fe5bb3bfa54349e6918e3ca6cf570b2e2b2f9d4"}, + {file = "pydantic_core-2.46.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:de885175515bcfa98ae618c1df7a072f13d179f81376c8007112af20567fd08a"}, + {file = "pydantic_core-2.46.3-cp310-cp310-win32.whl", hash = "sha256:d11058e3201527d41bc6b545c79187c9e4bf85e15a236a6007f0e991518882b7"}, + {file = "pydantic_core-2.46.3-cp310-cp310-win_amd64.whl", hash = "sha256:3612edf65c8ea67ac13616c4d23af12faef1ae435a8a93e5934c2a0cbbdd1fd6"}, + {file = "pydantic_core-2.46.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:ab124d49d0459b2373ecf54118a45c28a1e6d4192a533fbc915e70f556feb8e5"}, + {file = "pydantic_core-2.46.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cca67d52a5c7a16aed2b3999e719c4bcf644074eac304a5d3d62dd70ae7d4b2c"}, + {file = "pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c024e08c0ba23e6fd68c771a521e9d6a792f2ebb0fa734296b36394dc30390e"}, + {file = "pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6645ce7eec4928e29a1e3b3d5c946621d105d3e79f0c9cddf07c2a9770949287"}, + {file = "pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a712c7118e6c5ea96562f7b488435172abb94a3c53c22c9efc1412264a45cbbe"}, + {file = "pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:69a868ef3ff206343579021c40faf3b1edc64b1cc508ff243a28b0a514ccb050"}, + {file = "pydantic_core-2.46.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc7e8c32db809aa0f6ea1d6869ebc8518a65d5150fdfad8bcae6a49ae32a22e2"}, + {file = "pydantic_core-2.46.3-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:3481bd1341dc85779ee506bc8e1196a277ace359d89d28588a9468c3ecbe63fa"}, + {file = "pydantic_core-2.46.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8690eba565c6d68ffd3a8655525cbdd5246510b44a637ee2c6c03a7ebfe64d3c"}, + {file = "pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4de88889d7e88d50d40ee5b39d5dac0bcaef9ba91f7e536ac064e6b2834ecccf"}, + {file = "pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:e480080975c1ef7f780b8f99ed72337e7cc5efea2e518a20a692e8e7b278eb8b"}, + {file = "pydantic_core-2.46.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:de3a5c376f8cd94da9a1b8fd3dd1c16c7a7b216ed31dc8ce9fd7a22bf13b836e"}, + {file = "pydantic_core-2.46.3-cp311-cp311-win32.whl", hash = "sha256:fc331a5314ffddd5385b9ee9d0d2fee0b13c27e0e02dad71b1ae5d6561f51eeb"}, + {file = "pydantic_core-2.46.3-cp311-cp311-win_amd64.whl", hash = "sha256:b5b9c6cf08a8a5e502698f5e153056d12c34b8fb30317e0c5fd06f45162a6346"}, + {file = "pydantic_core-2.46.3-cp311-cp311-win_arm64.whl", hash = "sha256:5dfd51cf457482f04ec49491811a2b8fd5b843b64b11eecd2d7a1ee596ea78a6"}, + {file = "pydantic_core-2.46.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:b11b59b3eee90a80a36701ddb4576d9ae31f93f05cb9e277ceaa09e6bf074a67"}, + {file = "pydantic_core-2.46.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:af8653713055ea18a3abc1537fe2ebc42f5b0bbb768d1eb79fd74eb47c0ac089"}, + {file = "pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:75a519dab6d63c514f3a81053e5266c549679e4aa88f6ec57f2b7b854aceb1b0"}, + {file = "pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a6cd87cb1575b1ad05ba98894c5b5c96411ef678fa2f6ed2576607095b8d9789"}, + {file = "pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f80a55484b8d843c8ada81ebf70a682f3f00a3d40e378c06cf17ecb44d280d7d"}, + {file = "pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3861f1731b90c50a3266316b9044f5c9b405eecb8e299b0a7120596334e4fe9c"}, + {file = "pydantic_core-2.46.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb528e295ed31570ac3dcc9bfdd6e0150bc11ce6168ac87a8082055cf1a67395"}, + {file = "pydantic_core-2.46.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:367508faa4973b992b271ba1494acaab36eb7e8739d1e47be5035fb1ea225396"}, + {file = "pydantic_core-2.46.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ad3c826fe523e4becf4fe39baa44286cff85ef137c729a2c5e269afbfd0905d"}, + {file = "pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ec638c5d194ef8af27db69f16c954a09797c0dc25015ad6123eb2c73a4d271ca"}, + {file = "pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:28ed528c45446062ee66edb1d33df5d88828ae167de76e773a3c7f64bd14e976"}, + {file = "pydantic_core-2.46.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:aed19d0c783886d5bd86d80ae5030006b45e28464218747dcf83dabfdd092c7b"}, + {file = "pydantic_core-2.46.3-cp312-cp312-win32.whl", hash = "sha256:06d5d8820cbbdb4147578c1fe7ffcd5b83f34508cb9f9ab76e807be7db6ff0a4"}, + {file = "pydantic_core-2.46.3-cp312-cp312-win_amd64.whl", hash = "sha256:c3212fda0ee959c1dd04c60b601ec31097aaa893573a3a1abd0a47bcac2968c1"}, + {file = "pydantic_core-2.46.3-cp312-cp312-win_arm64.whl", hash = "sha256:f1f8338dd7a7f31761f1f1a3c47503a9a3b34eea3c8b01fa6ee96408affb5e72"}, + {file = "pydantic_core-2.46.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:12bc98de041458b80c86c56b24df1d23832f3e166cbaff011f25d187f5c62c37"}, + {file = "pydantic_core-2.46.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:85348b8f89d2c3508b65b16c3c33a4da22b8215138d8b996912bb1532868885f"}, + {file = "pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1105677a6df914b1fb71a81b96c8cce7726857e1717d86001f29be06a25ee6f8"}, + {file = "pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:87082cd65669a33adeba5470769e9704c7cf026cc30afb9cc77fd865578ebaad"}, + {file = "pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60e5f66e12c4f5212d08522963380eaaeac5ebd795826cfd19b2dfb0c7a52b9c"}, + {file = "pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b6cdf19bf84128d5e7c37e8a73a0c5c10d51103a650ac585d42dd6ae233f2b7f"}, + {file = "pydantic_core-2.46.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:031bb17f4885a43773c8c763089499f242aee2ea85cf17154168775dccdecf35"}, + {file = "pydantic_core-2.46.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:bcf2a8b2982a6673693eae7348ef3d8cf3979c1d63b54fca7c397a635cc68687"}, + {file = "pydantic_core-2.46.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28e8cf2f52d72ced402a137145923a762cbb5081e48b34312f7a0c8f55928ec3"}, + {file = "pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:17eaface65d9fc5abb940003020309c1bf7a211f5f608d7870297c367e6f9022"}, + {file = "pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:93fd339f23408a07e98950a89644f92c54d8729719a40b30c0a30bb9ebc55d23"}, + {file = "pydantic_core-2.46.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:23cbdb3aaa74dfe0837975dbf69b469753bbde8eacace524519ffdb6b6e89eb7"}, + {file = "pydantic_core-2.46.3-cp313-cp313-win32.whl", hash = "sha256:610eda2e3838f401105e6326ca304f5da1e15393ae25dacae5c5c63f2c275b13"}, + {file = "pydantic_core-2.46.3-cp313-cp313-win_amd64.whl", hash = "sha256:68cc7866ed863db34351294187f9b729964c371ba33e31c26f478471c52e1ed0"}, + {file = "pydantic_core-2.46.3-cp313-cp313-win_arm64.whl", hash = "sha256:f64b5537ac62b231572879cd08ec05600308636a5d63bcbdb15063a466977bec"}, + {file = "pydantic_core-2.46.3-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:afa3aa644f74e290cdede48a7b0bee37d1c35e71b05105f6b340d484af536d9b"}, + {file = "pydantic_core-2.46.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ced3310e51aa425f7f77da8bbbb5212616655bedbe82c70944320bc1dbe5e018"}, + {file = "pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e29908922ce9da1a30b4da490bd1d3d82c01dcfdf864d2a74aacee674d0bfa34"}, + {file = "pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0c9ff69140423eea8ed2d5477df3ba037f671f5e897d206d921bc9fdc39613e7"}, + {file = "pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b675ab0a0d5b1c8fdb81195dc5bcefea3f3c240871cdd7ff9a2de8aa50772eb2"}, + {file = "pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0087084960f209a9a4af50ecd1fb063d9ad3658c07bb81a7a53f452dacbfb2ba"}, + {file = "pydantic_core-2.46.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed42e6cc8e1b0e2b9b96e2276bad70ae625d10d6d524aed0c93de974ae029f9f"}, + {file = "pydantic_core-2.46.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:f1771ce258afb3e4201e67d154edbbae712a76a6081079fe247c2f53c6322c22"}, + {file = "pydantic_core-2.46.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a7610b6a5242a6c736d8ad47fd5fff87fcfe8f833b281b1c409c3d6835d9227f"}, + {file = "pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:ff5e7783bcc5476e1db448bf268f11cb257b1c276d3e89f00b5727be86dd0127"}, + {file = "pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:9d2e32edcc143bc01e95300671915d9ca052d4f745aa0a49c48d4803f8a85f2c"}, + {file = "pydantic_core-2.46.3-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:6e42d83d1c6b87fa56b521479cff237e626a292f3b31b6345c15a99121b454c1"}, + {file = "pydantic_core-2.46.3-cp314-cp314-win32.whl", hash = "sha256:07bc6d2a28c3adb4f7c6ae46aa4f2d2929af127f587ed44057af50bf1ce0f505"}, + {file = "pydantic_core-2.46.3-cp314-cp314-win_amd64.whl", hash = "sha256:8940562319bc621da30714617e6a7eaa6b98c84e8c685bcdc02d7ed5e7c7c44e"}, + {file = "pydantic_core-2.46.3-cp314-cp314-win_arm64.whl", hash = "sha256:5dcbbcf4d22210ced8f837c96db941bdb078f419543472aca5d9a0bb7cddc7df"}, + {file = "pydantic_core-2.46.3-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:d0fe3dce1e836e418f912c1ad91c73357d03e556a4d286f441bf34fed2dbeecf"}, + {file = "pydantic_core-2.46.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9ce92e58abc722dac1bf835a6798a60b294e48eb0e625ec9fd994b932ac5feee"}, + {file = "pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a03e6467f0f5ab796a486146d1b887b2dc5e5f9b3288898c1b1c3ad974e53e4a"}, + {file = "pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2798b6ba041b9d70acfb9071a2ea13c8456dd1e6a5555798e41ba7b0790e329c"}, + {file = "pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9be3e221bdc6d69abf294dcf7aff6af19c31a5cdcc8f0aa3b14be29df4bd03b1"}, + {file = "pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f13936129ce841f2a5ddf6f126fea3c43cd128807b5a59588c37cf10178c2e64"}, + {file = "pydantic_core-2.46.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28b5f2ef03416facccb1c6ef744c69793175fd27e44ef15669201601cf423acb"}, + {file = "pydantic_core-2.46.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:830d1247d77ad23852314f069e9d7ddafeec5f684baf9d7e7065ed46a049c4e6"}, + {file = "pydantic_core-2.46.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0793c90c1a3c74966e7975eaef3ed30ebdff3260a0f815a62a22adc17e4c01c"}, + {file = "pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:d2d0aead851b66f5245ec0c4fb2612ef457f8bbafefdf65a2bf9d6bac6140f47"}, + {file = "pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:2f40e4246676beb31c5ce77c38a55ca4e465c6b38d11ea1bd935420568e0b1ab"}, + {file = "pydantic_core-2.46.3-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:cf489cf8986c543939aeee17a09c04d6ffb43bfef8ca16fcbcc5cfdcbed24dba"}, + {file = "pydantic_core-2.46.3-cp314-cp314t-win32.whl", hash = "sha256:ffe0883b56cfc05798bf994164d2b2ff03efe2d22022a2bb080f3b626176dd56"}, + {file = "pydantic_core-2.46.3-cp314-cp314t-win_amd64.whl", hash = "sha256:706d9d0ce9cf4593d07270d8e9f53b161f90c57d315aeec4fb4fd7a8b10240d8"}, + {file = "pydantic_core-2.46.3-cp314-cp314t-win_arm64.whl", hash = "sha256:77706aeb41df6a76568434701e0917da10692da28cb69d5fb6919ce5fdb07374"}, + {file = "pydantic_core-2.46.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:fa3eb7c2995aa443687a825bc30395c8521b7c6ec201966e55debfd1128bcceb"}, + {file = "pydantic_core-2.46.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3d08782c4045f90724b44c95d35ebec0d67edb8a957a2ac81d5a8e4b8a200495"}, + {file = "pydantic_core-2.46.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:831eb19aa789a97356979e94c981e5667759301fb708d1c0d5adf1bc0098b873"}, + {file = "pydantic_core-2.46.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4335e87c7afa436a0dfa899e138d57a72f8aad542e2cf19c36fb428461caabd0"}, + {file = "pydantic_core-2.46.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99421e7684a60f7f3550a1d159ade5fdff1954baedb6bdd407cba6a307c9f27d"}, + {file = "pydantic_core-2.46.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd81f6907932ebac3abbe41378dac64b2380db1287e2aa64d8d88f78d170f51a"}, + {file = "pydantic_core-2.46.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f247596366f4221af52beddd65af1218797771d6989bc891a0b86ccaa019168"}, + {file = "pydantic_core-2.46.3-cp39-cp39-manylinux_2_31_riscv64.whl", hash = "sha256:6dff8cc884679df229ebc6d8eb2321ea6f8e091bc7d4886d4dc2e0e71452843c"}, + {file = "pydantic_core-2.46.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68ef2f623dda6d5a9067ac014e406c020c780b2a358930a7e5c1b73702900720"}, + {file = "pydantic_core-2.46.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d56bdb4af1767cc15b0386b3c581fdfe659bb9ee4a4f776e92c1cd9d074000d6"}, + {file = "pydantic_core-2.46.3-cp39-cp39-musllinux_1_1_armv7l.whl", hash = "sha256:91249bcb7c165c2fb2a2f852dbc5c91636e2e218e75d96dfdd517e4078e173dd"}, + {file = "pydantic_core-2.46.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4b068543bdb707f5d935dab765d99227aa2545ef2820935f2e5dd801795c7dbd"}, + {file = "pydantic_core-2.46.3-cp39-cp39-win32.whl", hash = "sha256:dcda6583921c05a40533f982321532f2d8db29326c7b95c4026941fa5074bd79"}, + {file = "pydantic_core-2.46.3-cp39-cp39-win_amd64.whl", hash = "sha256:a35cc284c8dd7edae8a31533713b4d2467dfe7c4f1b5587dd4031f28f90d1d13"}, + {file = "pydantic_core-2.46.3-graalpy311-graalpy242_311_native-macosx_10_12_x86_64.whl", hash = "sha256:9715525891ed524a0a1eb6d053c74d4d4ad5017677fb00af0b7c2644a31bae46"}, + {file = "pydantic_core-2.46.3-graalpy311-graalpy242_311_native-macosx_11_0_arm64.whl", hash = "sha256:9d2f400712a99a013aff420ef1eb9be077f8189a36c1e3ef87660b4e1088a874"}, + {file = "pydantic_core-2.46.3-graalpy311-graalpy242_311_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd2aab0e2e9dc2daf36bd2686c982535d5e7b1d930a1344a7bb6e82baab42a76"}, + {file = "pydantic_core-2.46.3-graalpy311-graalpy242_311_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e9d76736da5f362fabfeea6a69b13b7f2be405c6d6966f06b2f6bfff7e64531"}, + {file = "pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_10_12_x86_64.whl", hash = "sha256:b12dd51f1187c2eb489af8e20f880362db98e954b54ab792fa5d92e8bcc6b803"}, + {file = "pydantic_core-2.46.3-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:f00a0961b125f1a47af7bcc17f00782e12f4cd056f83416006b30111d941dfa3"}, + {file = "pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57697d7c056aca4bbb680200f96563e841a6386ac1129370a0102592f4dddff5"}, + {file = "pydantic_core-2.46.3-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd35aa21299def8db7ef4fe5c4ff862941a9a158ca7b63d61e66fe67d30416b4"}, + {file = "pydantic_core-2.46.3-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:13afdd885f3d71280cf286b13b310ee0f7ccfefd1dbbb661514a474b726e2f25"}, + {file = "pydantic_core-2.46.3-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f91c0aff3e3ee0928edd1232c57f643a7a003e6edf1860bc3afcdc749cb513f3"}, + {file = "pydantic_core-2.46.3-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6529d1d128321a58d30afcc97b49e98836542f68dd41b33c2e972bb9e5290536"}, + {file = "pydantic_core-2.46.3-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:975c267cff4f7e7272eacbe50f6cc03ca9a3da4c4fbd66fffd89c94c1e311aa1"}, + {file = "pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:2b8e4f2bbdf71415c544b4b1138b8060db7b6611bc927e8064c769f64bed651c"}, + {file = "pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e61ea8e9fff9606d09178f577ff8ccdd7206ff73d6552bcec18e1033c4254b85"}, + {file = "pydantic_core-2.46.3-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:b504bda01bafc69b6d3c7a0c7f039dcf60f47fab70e06fe23f57b5c75bdc82b8"}, + {file = "pydantic_core-2.46.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:b00b76f7142fc60c762ce579bd29c8fa44aaa56592dd3c54fab3928d0d4ca6ff"}, + {file = "pydantic_core-2.46.3.tar.gz", hash = "sha256:41c178f65b8c29807239d47e6050262eb6bf84eb695e41101e62e38df4a5bc2c"}, ] [package.dependencies] @@ -1984,4 +2043,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4" -content-hash = "5f36b0c7eaace34b3c91fb3cae711fb3f6b38dbfd604ce0d0f9ef102cddb73ba" +content-hash = "a6c8f4724724200e183e448094d277a866c529e9afe622e340c8ba2521d0d8c4" diff --git a/openbb_platform/providers/cftc/pyproject.toml b/openbb_platform/providers/cftc/pyproject.toml index 7a2cfb54ae9..d9b79350e70 100644 --- a/openbb_platform/providers/cftc/pyproject.toml +++ b/openbb_platform/providers/cftc/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "openbb-cftc" -version = "1.3.0" +version = "1.4.0" description = "The mission of the Commodity Futures Trading Commission (CFTC) is to promote the integrity, resilience, and vibrancy of the U.S. derivatives markets through sound regulation." authors = ["OpenBB Team "] license = "AGPL-3.0-only" @@ -9,7 +9,8 @@ packages = [{ include = "openbb_cftc" }] [tool.poetry.dependencies] python = ">=3.10,<4" -openbb-core = "^1.6.3" +openbb-core = "^1.6.7" +openbb-platform-api = "^1.3.5" [build-system] requires = ["poetry-core"] @@ -17,3 +18,6 @@ build-backend = "poetry.core.masonry.api" [tool.poetry.plugins."openbb_provider_extension"] cftc = "openbb_cftc:cftc_provider" + +[tool.poetry.plugins."openbb_core_extension"] +cftc = "openbb_cftc.cftc_router:router" diff --git a/openbb_platform/providers/cftc/tests/record/http/test_cftc_fetchers/test_cftc_cot_fetcher_urllib3_v2.yaml b/openbb_platform/providers/cftc/tests/record/http/test_cftc_fetchers/test_cftc_cot_fetcher_urllib3_v2.yaml index b9b71f4524f..0059098ba24 100644 --- a/openbb_platform/providers/cftc/tests/record/http/test_cftc_fetchers/test_cftc_cot_fetcher_urllib3_v2.yaml +++ b/openbb_platform/providers/cftc/tests/record/http/test_cftc_fetchers/test_cftc_cot_fetcher_urllib3_v2.yaml @@ -34,8 +34,6 @@ interactions: headers: Access-Control-Allow-Origin: - '*' - Age: - - '0' Connection: - keep-alive Content-Encoding: @@ -43,10 +41,10 @@ interactions: Content-Type: - application/json;charset=utf-8 Date: - - Thu, 05 Sep 2024 18:48:26 GMT + - Thu, 02 Apr 2026 04:20:30 GMT Etag: null Last-Modified: - - Fri, 30 Aug 2024 19:30:46 GMT + - Fri, 27 Mar 2026 19:31:05 GMT Server: - nginx Strict-Transport-Security: @@ -60,9 +58,9 @@ interactions: X-SODA2-Fields: - '["id","market_and_exchange_names","report_date_as_yyyy_mm_dd","yyyy_report_week_ww","contract_market_name","cftc_contract_market_code","cftc_market_code","cftc_region_code","cftc_commodity_code","commodity_name","open_interest_all","noncomm_positions_long_all","noncomm_positions_short_all","noncomm_postions_spread_all","comm_positions_long_all","comm_positions_short_all","tot_rept_positions_long_all","tot_rept_positions_short","nonrept_positions_long_all","nonrept_positions_short_all","open_interest_old","noncomm_positions_long_old","noncomm_positions_short_old","noncomm_positions_spread","comm_positions_long_old","comm_positions_short_old","tot_rept_positions_long_old","tot_rept_positions_short_1","nonrept_positions_long_old","nonrept_positions_short_old","open_interest_other","noncomm_positions_long_other","noncomm_positions_short_other","noncomm_positions_spread_1","comm_positions_long_other","comm_positions_short_other","tot_rept_positions_long_other","tot_rept_positions_short_2","nonrept_positions_long_other","nonrept_positions_short_other","change_in_open_interest_all","change_in_noncomm_long_all","change_in_noncomm_short_all","change_in_noncomm_spead_all","change_in_comm_long_all","change_in_comm_short_all","change_in_tot_rept_long_all","change_in_tot_rept_short","change_in_nonrept_long_all","change_in_nonrept_short_all","pct_of_open_interest_all","pct_of_oi_noncomm_long_all","pct_of_oi_noncomm_short_all","pct_of_oi_noncomm_spread","pct_of_oi_comm_long_all","pct_of_oi_comm_short_all","pct_of_oi_tot_rept_long_all","pct_of_oi_tot_rept_short","pct_of_oi_nonrept_long_all","pct_of_oi_nonrept_short_all","pct_of_open_interest_old","pct_of_oi_noncomm_long_old","pct_of_oi_noncomm_short_old","pct_of_oi_noncomm_spread_1","pct_of_oi_comm_long_old","pct_of_oi_comm_short_old","pct_of_oi_tot_rept_long_old","pct_of_oi_tot_rept_short_1","pct_of_oi_nonrept_long_old","pct_of_oi_nonrept_short_old","pct_of_open_interest_other","pct_of_oi_noncomm_long_other","pct_of_oi_noncomm_short_other","pct_of_oi_noncomm_spread_2","pct_of_oi_comm_long_other","pct_of_oi_comm_short_other","pct_of_oi_tot_rept_long_other","pct_of_oi_tot_rept_short_2","pct_of_oi_nonrept_long_other","pct_of_oi_nonrept_short_other","traders_tot_all","traders_noncomm_long_all","traders_noncomm_short_all","traders_noncomm_spread_all","traders_comm_long_all","traders_comm_short_all","traders_tot_rept_long_all","traders_tot_rept_short_all","traders_tot_old","traders_noncomm_long_old","traders_noncomm_short_old","traders_noncomm_spead_old","traders_comm_long_old","traders_comm_short_old","traders_tot_rept_long_old","traders_tot_rept_short_old","traders_tot_other","traders_noncomm_long_other","traders_noncomm_short_other","traders_noncomm_spread_other","traders_comm_long_other","traders_comm_short_other","traders_tot_rept_long_other","traders_tot_rept_short_other","conc_gross_le_4_tdr_long","conc_gross_le_4_tdr_short","conc_gross_le_8_tdr_long","conc_gross_le_8_tdr_short","conc_net_le_4_tdr_long_all","conc_net_le_4_tdr_short_all","conc_net_le_8_tdr_long_all","conc_net_le_8_tdr_short_all","conc_gross_le_4_tdr_long_1","conc_gross_le_4_tdr_short_1","conc_gross_le_8_tdr_long_1","conc_gross_le_8_tdr_short_1","conc_net_le_4_tdr_long_old","conc_net_le_4_tdr_short_old","conc_net_le_8_tdr_long_old","conc_net_le_8_tdr_short_old","conc_gross_le_4_tdr_long_2","conc_gross_le_4_tdr_short_2","conc_gross_le_8_tdr_long_2","conc_gross_le_8_tdr_short_2","conc_net_le_4_tdr_long_other","conc_net_le_4_tdr_short_other","conc_net_le_8_tdr_long_other","conc_net_le_8_tdr_short_other","contract_units","commodity","commodity_subgroup_name","commodity_group_name","futonly_or_combined"]' X-SODA2-Secondary-Last-Modified: - - Fri, 30 Aug 2024 19:30:46 GMT + - Fri, 27 Mar 2026 19:31:05 GMT X-SODA2-Truth-Last-Modified: - - Fri, 30 Aug 2024 19:30:46 GMT + - Fri, 27 Mar 2026 19:31:05 GMT X-SODA2-Types: - '["text","text","floating_timestamp","text","text","text","text","text","text","text","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","number","text","text","text","text","text"]' X-Socrata-Region: null diff --git a/openbb_platform/providers/cftc/tests/record/http/test_cftc_fetchers/test_cftc_cot_sarch_fetcher_urllib3_v2.yaml b/openbb_platform/providers/cftc/tests/record/http/test_cftc_fetchers/test_cftc_cot_sarch_fetcher_urllib3_v2.yaml new file mode 100644 index 00000000000..d1abf57f9d4 --- /dev/null +++ b/openbb_platform/providers/cftc/tests/record/http/test_cftc_fetchers/test_cftc_cot_sarch_fetcher_urllib3_v2.yaml @@ -0,0 +1,60 @@ +interactions: +- request: + body: null + headers: + Accept: + - application/json + Accept-Encoding: + - gzip, deflate + Connection: + - keep-alive + method: GET + uri: https://publicreporting.cftc.gov/resource/jun7-fc8e.json?%24group=cftc_contract_market_code%2Ccontract_market_name%2Ccommodity_name%2Ccommodity_group_name%2Ccommodity_subgroup_name%2Ccontract_units&%24limit=MOCK_LIMIT&%24order=MOCK_ORDER&%24select=cftc_contract_market_code%2Ccontract_market_name%2Ccommodity_name%2Ccommodity_group_name%2Ccommodity_subgroup_name%2Ccontract_units&%24where=MOCK_WHERE + response: + body: + string: !!binary | + H4sIAAAAAAAAANWUUU+DMBSF3/crGmKMxmk6HdH41tGaVFlxpeiMMQsCGqKAgZJojP/dwsSMCRvZ + i/rY3Ht6T7+e9vZd8x6kN/OSWKauJ2eRmz4FUq39QDvVBkcnx8Nrra8t12M3KuoInzu2IBhQJgBH + ggB7+xLoEAJhCbPURVHih/KtUhT1EbcQBiNkK6EtLONCyTE1iF0TPKZJ/lLJzihDzKDIVK224M6Y + MFFvz/L7muLnxl8nyONQZqphZ8Gq2pcT4XBWCMgUvIKtQ31X++j1V/MZFnxQO59qBGLMUTMwvaKY + MDyf0oRnseP3iDTaBdMCCuxApUzN3noqRhJnyXPouzLw/0lWvkno8AB2YVEmZLKexcRBXBBu3tSo + /92INPudsxlA2DEkK54O2R9TRqv/ZLN4LJtXt6b81e6ya5yddqdjanAL1P22v/BNXDeYvut9AmVI + m0G7BQAA + headers: + Access-Control-Allow-Origin: + - '*' + Connection: + - keep-alive + Content-Encoding: + - gzip + Content-Type: + - application/json;charset=utf-8 + Date: + - Thu, 02 Apr 2026 04:20:30 GMT + Etag: null + Last-Modified: + - Fri, 27 Mar 2026 19:31:05 GMT + Server: + - nginx + Strict-Transport-Security: + - max-age=31536000; includeSubDomains + Transfer-Encoding: + - chunked + Vary: + - Accept-Encoding + X-SODA2-Data-Out-Of-Date: + - 'false' + X-SODA2-Fields: + - '["cftc_contract_market_code","contract_market_name","commodity_name","commodity_group_name","commodity_subgroup_name","contract_units"]' + X-SODA2-Secondary-Last-Modified: + - Fri, 27 Mar 2026 19:31:05 GMT + X-SODA2-Truth-Last-Modified: + - Fri, 27 Mar 2026 19:31:05 GMT + X-SODA2-Types: + - '["text","text","text","text","text","text"]' + X-Socrata-Region: null + X-Socrata-RequestId: null + status: + code: 200 + message: OK +version: 1 diff --git a/openbb_platform/providers/cftc/tests/test_cftc_fetchers.py b/openbb_platform/providers/cftc/tests/test_cftc_fetchers.py index 41f8eb22276..cac42e662c5 100644 --- a/openbb_platform/providers/cftc/tests/test_cftc_fetchers.py +++ b/openbb_platform/providers/cftc/tests/test_cftc_fetchers.py @@ -45,7 +45,7 @@ def vcr_config(): def test_cftc_cot_fetcher(credentials=test_credentials): """Test the CFTC COT fetcher.""" params = { - "id": "239747", + "code": "239747", "start_date": date(2024, 8, 19), "end_date": date(2024, 8, 21), } @@ -55,7 +55,7 @@ def test_cftc_cot_fetcher(credentials=test_credentials): assert result is None -# The data for this request are local files, so we can't record them. +@pytest.mark.record_http def test_cftc_cot_sarch_fetcher(credentials=test_credentials): """Test the CFTC COT Search fetcher.""" params = {"query": "S&P 500"} diff --git a/openbb_platform/providers/sec/openbb_sec/models/institutions_search.py b/openbb_platform/providers/sec/openbb_sec/models/institutions_search.py index e6ee5686164..8efe464d5f7 100644 --- a/openbb_platform/providers/sec/openbb_sec/models/institutions_search.py +++ b/openbb_platform/providers/sec/openbb_sec/models/institutions_search.py @@ -6,16 +6,18 @@ from typing import Any from openbb_core.provider.abstract.data import Data from openbb_core.provider.abstract.fetcher import Fetcher -from openbb_core.provider.standard_models.cot_search import CotSearchQueryParams +from openbb_core.provider.abstract.query_params import QueryParams from pydantic import Field -class SecInstitutionsSearchQueryParams(CotSearchQueryParams): +class SecInstitutionsSearchQueryParams(QueryParams): """SEC Institutions Search Query. Source: https://sec.gov/ """ + query: str = Field(description="Search query.", default="") + use_cache: bool | None = Field( default=True, description="Whether or not to use cache.", diff --git a/openbb_platform/providers/sec/openbb_sec/models/sic_search.py b/openbb_platform/providers/sec/openbb_sec/models/sic_search.py index e8d57fc81bf..94f38db09f3 100644 --- a/openbb_platform/providers/sec/openbb_sec/models/sic_search.py +++ b/openbb_platform/providers/sec/openbb_sec/models/sic_search.py @@ -6,16 +6,19 @@ from typing import Any from openbb_core.provider.abstract.data import Data from openbb_core.provider.abstract.fetcher import Fetcher -from openbb_core.provider.standard_models.cot_search import CotSearchQueryParams +from openbb_core.provider.abstract.query_params import QueryParams from pydantic import Field -class SecSicSearchQueryParams(CotSearchQueryParams): +class SecSicSearchQueryParams(QueryParams): """SEC Standard Industrial Classification Code (SIC) Query. Source: https://sec.gov/ """ + query: str = Field( + description="Search query to match against SIC code, industry title, or office." + ) use_cache: bool | None = Field( default=True, description="Whether or not to use cache.", diff --git a/openbb_platform/pyproject.toml b/openbb_platform/pyproject.toml index 57d1167775c..3bcc5d13a77 100644 --- a/openbb_platform/pyproject.toml +++ b/openbb_platform/pyproject.toml @@ -15,7 +15,7 @@ openbb-platform-api = "^1.3.5" openbb-benzinga = "^1.6.0" openbb-bls = "^1.3.0" -openbb-cftc = "^1.3.0" +openbb-cftc = "^1.4.0" openbb-congress-gov = "^1.2.2" openbb-econdb = "^1.5.0" openbb-federal-reserve = "^1.6.1"