Skip to content

Commit 45842f5

Browse files
authored
Merge pull request #61 from EodHistoricalData/v1.3.2
V1.3.2 - up-to date version of EODHD python library
2 parents 4c7759b + 5fe8681 commit 45842f5

38 files changed

Lines changed: 1749 additions & 354 deletions

README.md

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Official EODHD APIs Python Library
2+
23
[Full documentation](https://eodhd.com/financial-apis/python-financial-libraries-and-code-samples/)
34

45
This is the official Python library developed by [EODHD](https://eodhd.com) for accessing various financial data via API in your code. If you have any feedback or questions, you can reach out to our support team, available 24/7 via live chat on [our website](https://eodhd.com).
@@ -9,7 +10,6 @@ To access our APIs, you need to register on our site (it’s free) and obtain an
910

1011
* End of the Day Historical Stock Market Data
1112
* Live (Delayed) Stock Prices and Macroeconomic Data
12-
* Bonds Fundamentals
1313
* Intraday Historical Data
1414
* Historical Dividends
1515
* Historical Splits
@@ -28,22 +28,70 @@ To access our APIs, you need to register on our site (it’s free) and obtain an
2828

2929
All functions are described in our [documentation](https://eodhd.com/financial-apis/python-financial-libraries-and-code-samples/).
3030

31+
---
32+
33+
## Additional supported data (latest updates)
34+
35+
The library also includes newer endpoints and Marketplace datasets:
36+
37+
### Financial News (extended)
38+
39+
* **News Sentiment** (daily sentiment data for tickers)
40+
* **News Word Weights** (weighted keywords from financial news for a ticker over a date range)
41+
42+
### Live v2 US Stocks
43+
44+
* **Extended Quotes (Delayed, exchange-compliant)** via `/us-quote-delayed`
45+
Batch tickers supported, optional pagination, JSON/CSV output.
46+
47+
### CBOE Indices Data
48+
49+
* **CBOE Indices List** via `/cboe/indices`
50+
* **CBOE Index Feed (index + full constituents)** via `/cboe/index`
51+
Uses deep-object filters: `filter[index_code]`, `filter[feed_type]`, `filter[date]`.
52+
53+
### Identifier Resolution
54+
55+
* **ID Mapping API** (`CUSIP / ISIN / FIGI / LEI / CIK ↔ Symbol`) via `/id-mapping`
56+
Uses deep-object filters (e.g. `filter[symbol]`, `filter[isin]`) and supports pagination.
57+
58+
### Marketplace datasets (UnicornBay)
59+
60+
* **S&P Global / Indices List** via `/mp/unicornbay/spglobal/list`
61+
* **Index Components (+ optional historical changes)** via `/mp/unicornbay/spglobal/comp/{symbol}`
62+
63+
### Marketplace datasets (US Stock Options Data API)
64+
65+
* **Underlying symbols list** via `/mp/unicornbay/options/underlying-symbols`
66+
* **Options contracts** via `/mp/unicornbay/options/contracts`
67+
* **Options EOD data** via `/mp/unicornbay/options/eod`
68+
Supports filters, sorting, pagination, field selection, and compact mode (where applicable).
69+
70+
### Technical Indicators (enhanced)
71+
72+
* Includes full function coverage from the current Technical Indicator API, including **BETA** and **DX (alias)**, plus support for:
73+
74+
* `fmt=json|csv`
75+
* `filter` (e.g. `filter=last_ema`) where supported by the endpoint
76+
77+
---
3178

3279
## Installation
3380

3481
In short:
3582

83+
```bash
3684
python3 -m pip install eodhd -U
85+
```
3786

3887
If you have any difficulties, go to our full [documentation](https://eodhd.com/financial-apis/python-financial-libraries-and-code-samples/) with step by step instructions.
3988

4089
## Sample code and examples
4190

4291
The files below contain examples of available functions:
4392

44-
* example_api.py: describes the functions that can be used in the APIClient class.
45-
* example_scanner.py: describes the functions that can be used in the ScannerClient class.
46-
* example_websockets.py: describes the functions that can be used in the WebSocketClient class.
47-
93+
* `example_api.py`: describes the functions that can be used in the `APIClient` class (including new endpoints: Options, CBOE, ID Mapping, Live v2 Extended Quotes, News Word Weights, etc.).
94+
* `example_scanner.py`: describes the functions that can be used in the `ScannerClient` class.
95+
* `example_websockets.py`: describes the functions that can be used in the `WebSocketClient` class.
4896

4997
New features will be added to the example files. The most relevant functions can be viewed directly in the code files.

eodhd/APIs/BaseAPI.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# APIs/BaseAPI.py
2+
13
from json.decoder import JSONDecodeError
24
import sys
35
from requests import get as requests_get
@@ -6,16 +8,16 @@
68
from requests.exceptions import HTTPError as requests_HTTPError
79
from rich.console import Console
810

11+
912
class BaseAPI:
1013

1114
def __init__(self) -> None:
1215
self._api_url = "https://eodhd.com/api"
1316
self.console = Console()
1417

15-
1618
def _rest_get_method(self, api_key: str, endpoint: str = "", uri: str = "", querystring: str = ""):
1719
"""Generic REST GET"""
18-
20+
1921
if endpoint.strip() == "":
2022
raise ValueError("endpoint is empty!")
2123

eodhd/APIs/BondsFundamentalsAPI.py

Lines changed: 0 additions & 14 deletions
This file was deleted.

eodhd/APIs/BulkEodSplitsDividendsAPI.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
# APIs/BulkEodSplitsDividendsAPI.py
2+
13
from .BaseAPI import BaseAPI
24

5+
36
class BulkEodSplitsDividendsDataAPI(BaseAPI):
47

5-
def get_eod_splits_dividends_data(self, api_token: str, country = 'US', type = None, date = None,
6-
symbols = None, filter = None):
7-
8+
def get_eod_splits_dividends_data(self, api_token: str, country='US', type=None, date=None,
9+
symbols=None, filter=None):
10+
811
endpoint = 'eod-bulk-last-day'
912
uri = f'{country}'
1013

@@ -19,5 +22,4 @@ def get_eod_splits_dividends_data(self, api_token: str, country = 'US', type = N
1922
if filter is not None:
2023
query_string += '&filter=' + str(filter)
2124

22-
23-
return self._rest_get_method(api_key = api_token, endpoint = endpoint, querystring = query_string, uri = uri)
25+
return self._rest_get_method(api_key=api_token, endpoint=endpoint, querystring=query_string, uri=uri)

eodhd/APIs/CBOEIndexFeedAPI.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#APIs/CBOEIndexFeedAPI.py
2+
3+
from .BaseAPI import BaseAPI
4+
5+
6+
class CBOEIndexFeedAPI(BaseAPI):
7+
"""
8+
Wrapper for the CBOE Index Feed endpoint:
9+
10+
GET /api/cboe/index
11+
12+
Required (deep object style):
13+
filter[index_code]
14+
filter[feed_type]
15+
filter[date] (YYYY-MM-DD)
16+
17+
Optional:
18+
fmt (json/xml)
19+
"""
20+
21+
def get_cboe_index_data(
22+
self,
23+
api_token: str,
24+
index_code: str,
25+
feed_type: str,
26+
date: str,
27+
fmt: str = None,
28+
):
29+
"""
30+
Parameters
31+
----------
32+
api_token : str
33+
Your EODHD API token.
34+
index_code : str
35+
CBOE index code, e.g. "BDE30P"
36+
feed_type : str
37+
Feed type, e.g. "snapshot_official_closing"
38+
date : str
39+
Trading date in YYYY-MM-DD format, e.g. "2017-02-01"
40+
fmt : str, optional
41+
"json" or "xml". If omitted, API default applies (usually json).
42+
43+
Returns
44+
-------
45+
dict
46+
JSON response with keys like meta, data (array), etc.
47+
"""
48+
if not index_code or not isinstance(index_code, str):
49+
raise ValueError("Parameter 'index_code' is required and must be a non-empty string (e.g. 'BDE30P').")
50+
51+
if not feed_type or not isinstance(feed_type, str):
52+
raise ValueError("Parameter 'feed_type' is required and must be a non-empty string (e.g. 'snapshot_official_closing').")
53+
54+
if not date or not isinstance(date, str):
55+
raise ValueError("Parameter 'date' is required and must be a non-empty string in 'YYYY-MM-DD' format (e.g. '2017-02-01').")
56+
57+
if fmt is not None:
58+
fmt = str(fmt).lower()
59+
if fmt not in ("json", "xml"):
60+
raise ValueError("fmt must be 'json' or 'xml'.")
61+
62+
endpoint = "cboe/index"
63+
query_string = (
64+
f"&filter[index_code]={index_code}"
65+
f"&filter[feed_type]={feed_type}"
66+
f"&filter[date]={date}"
67+
)
68+
69+
if fmt is not None:
70+
query_string += f"&fmt={fmt}"
71+
72+
return self._rest_get_method(
73+
api_key=api_token,
74+
endpoint=endpoint,
75+
querystring=query_string,
76+
)
77+
78+
def get_cboe_indices_list(self, api_token: str, fmt: str = None):
79+
"""
80+
Parameters
81+
----------
82+
api_token : str
83+
Your EODHD API token.
84+
fmt : str, optional
85+
"json" or "xml" (default is json on API side)
86+
87+
Returns
88+
-------
89+
dict
90+
JSON response: { "meta": {...}, "data": [...], "links": {"next": ...} }
91+
"""
92+
if fmt is not None:
93+
fmt = str(fmt).lower()
94+
if fmt not in ("json", "xml"):
95+
raise ValueError("fmt must be 'json' or 'xml'.")
96+
97+
endpoint = "cboe/indices"
98+
query_string = ""
99+
100+
if fmt is not None:
101+
query_string += f"&fmt={fmt}"
102+
103+
return self._rest_get_method(
104+
api_key=api_token,
105+
endpoint=endpoint,
106+
querystring=query_string,
107+
)
108+

eodhd/APIs/EarningTrendsAPI.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1+
# APIs/EarningTrendsAPI.py
2+
13
from .BaseAPI import BaseAPI
24

5+
36
class EarningTrendsAPI(BaseAPI):
47

58
def get_earning_trends_data(self, api_token: str, symbols):
6-
79
endpoint = 'calendar/trends'
810

911
query_string = ''
1012

1113
query_string += '&symbols=' + str(symbols)
1214

13-
14-
return self._rest_get_method(api_key = api_token, endpoint = endpoint, querystring = query_string)
15+
return self._rest_get_method(api_key=api_token, endpoint=endpoint, querystring=query_string)

eodhd/APIs/EconomicEventsDataAPI.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
1+
# APIs/EconomicEventsDataAPI.py
2+
13
from .BaseAPI import BaseAPI
24

5+
36
class EconomicEventsDataAPI(BaseAPI):
47

58
def get_economic_events_data(self, api_token: str, date_from: str = None, date_to: str = None,
69
country: str = None, comparison: str = None, offset: int = None, limit: int = None):
7-
10+
811
endpoint = 'economic-events'
912

1013
query_string = ''
@@ -21,5 +24,5 @@ def get_economic_events_data(self, api_token: str, date_from: str = None, date_t
2124
query_string += "&offset=" + str(offset)
2225
if limit is not None:
2326
query_string += "&limit=" + str(limit)
24-
25-
return self._rest_get_method(api_key = api_token, endpoint = endpoint, querystring = query_string)
27+
28+
return self._rest_get_method(api_key=api_token, endpoint=endpoint, querystring=query_string)
Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,32 @@
1+
# APIs/EodHistoricalStockMarketDataAPI.py
2+
13
from .BaseAPI import BaseAPI
24

5+
36
class EodHistoricalStockMarketDataAPI(BaseAPI):
47

5-
def get_eod_historical_stock_market_data(self, api_token: str, symbol: str, period: str,
6-
from_date: str = None, to_date: str = None, order = None):
8+
def get_eod_historical_stock_market_data(self, api_token: str, symbol: str, period: str,
9+
from_date: str = None, to_date: str = None, order=None):
710

811
possible_periods = ['d', 'w', 'm']
9-
12+
1013
endpoint = 'eod'
1114

1215
if symbol.strip() == "" or symbol is None:
1316
raise ValueError("Ticker is empty. You need to add ticker to args")
1417
if period not in possible_periods:
1518
raise ValueError("Interval must be in ['d', 'w', 'm'] values")
16-
19+
1720
uri = f'{symbol}'
1821
query_string = ''
1922

2023
query_string += '&period=' + str(period)
21-
22-
if from_date is not None:
24+
25+
if from_date is not None:
2326
query_string += '&from=' + str(from_date)
24-
if to_date is not None:
27+
if to_date is not None:
2528
query_string += '&to=' + str(to_date)
26-
if order is not None:
29+
if order is not None:
2730
query_string += '&order=' + str(order)
2831

29-
30-
return self._rest_get_method(api_key = api_token, endpoint = endpoint, querystring = query_string, uri = uri)
32+
return self._rest_get_method(api_key=api_token, endpoint=endpoint, querystring=query_string, uri=uri)

0 commit comments

Comments
 (0)