Open FIGI
OpenFIGI (Financial Instrument Global Identifier) is a system developed to help with consistent identification of a companies securities.
It is an open-source, non-proprietary standard for identifying financial instruments like stocks, bonds, futures, and options.
OpenFIGI was created to solve three main problems:
Fragmentation: Different systems used different codes for the same thing.
Cost: Many identifiers are "pay-to-play," which creates a barrier for smaller firms or developers.
Persistence: Unlike a ticker symbol, which can change if a company rebrands, an FIGI stays the same forever.
An FIGI is a 12-character unique alphanumeric code
Structure: It starts with a two-character prefix (to avoid clashing with other standards), followed by a 'G' as the third character, eight characters of unique ID, and a final check digit.
Hierarchy: It can identify an asset at three levels:
Global Share Class: The overarching asset (e.g., Apple Inc. Common Stock).
Country level: The asset as traded within a specific country.
Exchange level: The specific listing on a specific exchange (e.g., Apple on the NASDAQ).
OpenFIGI vs Ticker
The "Open" in OpenFIGI is its superpower. Because it is managed by Bloomberg but released as an open standard, anyone can use the API to map their messy data to a clean, universal ID without getting a bill in the mail.
Access to open FIGI via website
The OpenFIGI API allows FIGI mapping to other market identifiers, data and standards. The static output returns the FIGI and related Open Symbology metadata in the exact order requested for easier absorption. Results can be narrowed down using a variety of related descriptive filters.
Need to create an account
Obtain a Key
KEY d2506477-3e19-4d6e-8830-281ae7766338
https://github.com/OpenFIGI/api-examples/tree/main/python
OpenFIGI Python3 example
This script is written to be run by python3.12 without any external libraries. Example code is tested with Python 3.12.7.
Instructions
Prerequisites: Python3.12 must be installed.
# Optional: Export your API key
export OPENFIGI_API_KEY=<YOUR_KEY_HERE>
export OPENFIGI_API_KEY= "d2506477-3e19-4d6e-8830-281ae7766338 "
python3 example.py
Docker Instructions
Prerequisites: Docker must be installed.
docker build --tag 'openfigi-python' .
docker run --rm -it --entrypoint ./example.py --volume ./:/OpenFIGI 'openfigi-python'
# OR: If you have acquired an API Key
docker run --rm -it --entrypoint ./example.py --volume ./:/OpenFIGI 'openfigi-python' -e OPENFIGI_API_KEY=<YOUR_KEY_HERE>
Dockerfile
==================================================
# Copyright 2017 Bloomberg Finance L.P.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
FROM python:3.12
WORKDIR /OpenFIGI
COPY . .
=====================================================
=========================================================
#!/usr/bin/env python3.12
# Copyright 2017 Bloomberg Finance L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import urllib.request
import urllib.parse
import os
"""
See https://www.openfigi.com/api for more information.
This script is written to be run by python3 - tested with python3.12 - without any external libraries.
For more involved use cases, consider using open source packages: https://pypi.org/
"""
JsonType = None | int | str | bool | list["JsonType"] | dict[str, "JsonType"]
OPENFIGI_API_KEY = os.environ.get(
"OPENFIGI_API_KEY", None
) # Put your API key here or in env var
OPENFIGI_BASE_URL = "https://api.openfigi.com"
def api_call(
path: str,
data: dict | None = None,
method: str = "POST",
) -> JsonType:
"""
Make an api call to `api.openfigi.com`.
Uses builtin `urllib` library, end users may prefer to
swap out this function with another library of their choice
Args:
path (str): API endpoint, for example "search"
method (str, optional): HTTP request method. Defaults to "POST".
data (dict | None, optional): HTTP request data. Defaults to None.
Returns:
JsonType: Response of the api call parsed as a JSON object
"""
headers = {"Content-Type": "application/json"}
if OPENFIGI_API_KEY:
headers |= {"X-OPENFIGI-APIKEY": OPENFIGI_API_KEY}
request = urllib.request.Request(
url=urllib.parse.urljoin(OPENFIGI_BASE_URL, path),
data=data and bytes(json.dumps(data), encoding="utf-8"),
headers=headers,
method=method,
)
with urllib.request.urlopen(request) as response:
json_response_as_string = response.read().decode("utf-8")
json_obj = json.loads(json_response_as_string)
return json_obj
def main():
"""
Make search and mapping API requests and print the results
to the console
Returns:
None
"""
search_request = {"query": "APPLE"}
print("Making a search request:", search_request)
search_response = api_call("/v3/search", search_request)
print("Search response:", json.dumps(search_response, indent=2))
mapping_request = [
{"idType":"ID_BB_GLOBAL","idValue":"BBG000BLNNH6","exchCode":"US"},
]
print("Making a mapping request:", mapping_request)
mapping_response = api_call("/v3/mapping", mapping_request)
print("Mapping response:", json.dumps(mapping_response, indent=2))
if __name__ == "__main__":
main()
===================================================
Sample of output
{
"figi": "BBG000N896W8",
"name": "APPLE INC",
"ticker": "AAPL",
"exchCode": "E1",
"compositeFIGI": "BBG000N88V36",
"securityType": "Common Stock",
"marketSector": "Equity",
"shareClassFIGI": "BBG001S5N8V8",
"securityType2": "Common Stock",
"securityDescription": "AAPL"
},
This script is a clean, lightweight Python client for the OpenFIGI API. OpenFIGI is a free, open-access database used to identify financial instruments (like stocks and bonds) using the Financial Instrument Global Identifier (FIGI) standard.
What makes this specific script interesting is that it is "zero-dependency"—it uses only Python's built-in libraries, so you don't need to pip install anything.
1. Setup and Configuration
The top of the script handles the "plumbing":
Imports: It uses urllib to handle web requests and json to format the data.
JsonType: This is a modern Python type hint. It recursively defines what a JSON object looks like (a mix of strings, numbers, lists, and dictionaries). It's great for code clarity but doesn't actually "do" anything at runtime.
API Key: It looks for an environment variable named OPENFIGI_API_KEY.
Pro-tip: If you don't have an API key, the script still works, but you'll be hit by much stricter rate limits (fewer requests per minute).
2. The Engine: api_call()
This function is the heart of the script. It handles the communication with Bloomberg’s servers.
Headers: It sets the Content-Type to application/json. If you provided an API key, it adds it to the headers as X-OPENFIGI-APIKEY.
Request Construction: It uses urllib.parse.urljoin to combine the base URL (https://api.openfigi.com) with specific endpoints like /v3/search.
Data Encoding: Since APIs don't speak "Python dictionaries," json.dumps(data) converts your Python data into a JSON string, and .encode("utf-8") converts that string into raw bytes for transport.
The Response: It opens the connection, reads the response, decodes it back from bytes to a string, and finally parses that string back into a Python object using json.loads().
3. The Driver: main()
This section demonstrates the two primary ways people use OpenFIGI:
A. The Search Request (/v3/search)
This is like a "Google Search" for stocks. In the code, it searches for "GOOGLE". The API will return a list of all instruments matching that name, including their FIGI codes, ticker symbols, and exchange info.
B. The Mapping Request (/v3/mapping)
Mapping is more precise. It takes a known identifier and "maps" it to others.
In the example, it sends an ID_BB_GLOBAL (the FIGI code BBG000BLNNH6) and specifies the exchange code US.
The API will return the associated ticker (GOOGL), the company name, and other metadata.
How to run it
Save it: Save the code as openfigi.py.
Set your key (Optional): * Mac/Linux: export OPENFIGI_API_KEY='your_key_here'
Windows: set OPENFIGI_API_KEY=your_key_here
Execute: Run python3 openfigi.py.
Why use this instead of a library?
While there are libraries like requests that make this shorter, using urllib (as seen here) is excellent for production environments where you want to minimize security vulnerabilities or avoid managing external dependencies.
Would you like me to help you modify the mapping_request to look up a specific list of stocks or tickers you're interested in?
Now we change the program so it only shows 1 security
Let gemini do it
change this code so the record output is when ticker=XLK and exchCode=us -
#!/usr/bin/env python3.12
# Copyright 2017 Bloomberg Finance L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import urllib.request
import urllib.parse
import os
"""
See https://www.openfigi.com/api for more information.
This script is written to be run by python3 - tested with python3.12 - without any external libraries.
For more involved use cases, consider using open source packages: https://pypi.org/
"""
JsonType = None | int | str | bool | list["JsonType"] | dict[str, "JsonType"]
OPENFIGI_API_KEY = os.environ.get(
"OPENFIGI_API_KEY", None
) # Put your API key here or in env var
OPENFIGI_BASE_URL = "https://api.openfigi.com"
def api_call(
path: str,
data: dict | None = None,
method: str = "POST",
) -> JsonType:
"""
Make an api call to `api.openfigi.com`.
Uses builtin `urllib` library, end users may prefer to
swap out this function with another library of their choice
Args:
path (str): API endpoint, for example "search"
method (str, optional): HTTP request method. Defaults to "POST".
data (dict | None, optional): HTTP request data. Defaults to None.
Returns:
JsonType: Response of the api call parsed as a JSON object
"""
headers = {"Content-Type": "application/json"}
if OPENFIGI_API_KEY:
headers |= {"X-OPENFIGI-APIKEY": OPENFIGI_API_KEY}
request = urllib.request.Request(
url=urllib.parse.urljoin(OPENFIGI_BASE_URL, path),
data=data and bytes(json.dumps(data), encoding="utf-8"),
headers=headers,
method=method,
)
with urllib.request.urlopen(request) as response:
json_response_as_string = response.read().decode("utf-8")
json_obj = json.loads(json_response_as_string)
return json_obj
def main():
"""
Make search and mapping API requests and print the results
to the console
Returns:
None
"""
search_request = {"query": "APPLE"}
print("Making a search request:", search_request)
search_response = api_call("/v3/search", search_request)
print("Search response:", json.dumps(search_response, indent=2))
mapping_request = [
{"idType":"ID_BB_GLOBAL","idValue":"BBG000BLNNH6","exchCode":"US"},
]
print("Making a mapping request:", mapping_request)
mapping_response = api_call("/v3/mapping", mapping_request)
print("Mapping response:", json.dumps(mapping_response, indent=2))
if __name__ == "__main__":
main()
New code
=====================================================
#!/usr/bin/env python3.12
# Copyright 2017 Bloomberg Finance L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import urllib.request
import urllib.parse
import os
"""
See https://www.openfigi.com/api for more information.
"""
JsonType = None | int | str | bool | list["JsonType"] | dict[str, "JsonType"]
OPENFIGI_API_KEY = os.environ.get(
"OPENFIGI_API_KEY", None
) # Put your API key here or in env var
OPENFIGI_BASE_URL = "https://api.openfigi.com"
def api_call(
path: str,
data: dict | None = None,
method: str = "POST",
) -> JsonType:
headers = {"Content-Type": "application/json"}
if OPENFIGI_API_KEY:
headers |= {"X-OPENFIGI-APIKEY": OPENFIGI_API_KEY}
request = urllib.request.Request(
url=urllib.parse.urljoin(OPENFIGI_BASE_URL, path),
data=data and bytes(json.dumps(data), encoding="utf-8"),
headers=headers,
method=method,
)
with urllib.request.urlopen(request) as response:
json_response_as_string = response.read().decode("utf-8")
json_obj = json.loads(json_response_as_string)
return json_obj
def main():
"""
Modified to request ticker XLK on the US exchange
"""
# 1. Update the Mapping Request for XLK
mapping_request = [
{
"idType": "TICKER",
"idValue": "XLK",
"exchCode": "US"
},
]
print("Making a mapping request for XLK...")
mapping_response = api_call("/v3/mapping", mapping_request)
# Display the result
print("Mapping response:")
print(json.dumps(mapping_response, indent=2))
if __name__ == "__main__":
main()
===================================================
Output
Making a mapping request for XLK...
Mapping response:
[
{
"data": [
{
"figi": "BBG000BJ7007",
"name": "SS TECHNOLOGY SELECT SECTOR",
"ticker": "XLK",
"exchCode": "US",
"compositeFIGI": "BBG000BJ7007",
"securityType": "ETP",
"marketSector": "Equity",
"shareClassFIGI": "BBG001S7TCZ5",
"securityType2": "Mutual Fund",
"securityDescription": "XLK"
}
]
}
]
john_iacovacci1@cloudshell:~/trading-system (cloud-project-examples)$
No comments:
Post a Comment