├── changelog ├── tests ├── __init__.py ├── resources │ ├── yh_zhihu.json │ ├── gf_zhihu.json │ ├── yh_apple.json │ ├── gf_apple.json │ ├── oc_google.json │ ├── oc_apple.json │ ├── oc_apple.rdf │ └── oc_google.rdf ├── test_init.py ├── helpers.py ├── test_google_finance.py ├── test_yahoo_finance.py └── test_open_calais.py ├── setup.cfg ├── comp_match ├── resources │ ├── iso_10383.csv │ ├── exchanges.csv │ └── iso_countries.json ├── exceptions.py ├── __init__.py ├── helpers.py ├── yahoo_finance.py ├── google_finance.py ├── _utils.py ├── base.py └── open_calais.py ├── requirements.txt ├── .travis.yml ├── docs ├── source │ ├── index.rst │ └── conf.py └── Makefile ├── LICENSE ├── setup.py ├── .gitignore └── README.md /changelog: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal=1 3 | -------------------------------------------------------------------------------- /comp_match/resources/iso_10383.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/franklingu/comp-match/HEAD/comp_match/resources/iso_10383.csv -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pytest>=3.4.1 2 | pylint>=1.8.2 3 | requests[security]>=2.18.4 4 | lxml>=4.2.0 5 | cssselect>=1.0.3 6 | pytest-cov>=2.5.1 7 | -------------------------------------------------------------------------------- /comp_match/exceptions.py: -------------------------------------------------------------------------------- 1 | """comp_match exceptions 2 | """ 3 | class CompMatchException(Exception): 4 | pass 5 | 6 | 7 | class UnkownMatcherException(CompMatchException): 8 | pass 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "3.5" 4 | - "3.6" 5 | # command to install dependencies 6 | install: 7 | - pip install -r requirements.txt 8 | # command to run tests 9 | script: 10 | - py.test 11 | -------------------------------------------------------------------------------- /tests/resources/yh_zhihu.json: -------------------------------------------------------------------------------- 1 | {"ResultSet":{"Query":"zhihu","Result":[{"symbol":"603156.SS","name":"Hebei Yangyuan ZhiHui Beverage Co., Ltd.","exch":"SHH","type":"S","exchDisp":"Shanghai","typeDisp":"Equity"},{"symbol":"300219.SZ","name":"Hongli Zhihui Group Co., Ltd.","exch":"SHZ","type":"S","exchDisp":"Shenzhen","typeDisp":"Equity"},{"symbol":"300645.SZ","name":"Zhejiang Zhengyuan Zhihui Technology Co., Ltd.","exch":"SHZ","type":"S","exchDisp":"Shenzhen","typeDisp":"Equity"}]}} 2 | -------------------------------------------------------------------------------- /tests/test_init.py: -------------------------------------------------------------------------------- 1 | """Test init and helper in comp_match 2 | 3 | Serve as a high-level integration test 4 | """ 5 | from comp_match import match 6 | 7 | 8 | def test_match(): 9 | """Test match function in comp_match.helpers 10 | """ 11 | match_res = match(['Apple']) 12 | assert 'Apple' in match_res 13 | assert match_res['Apple'][0][0].title() == 'Apple Inc.' 14 | assert match_res['Apple'][0][1].ticker == 'AAPL' 15 | assert match_res['Apple'][0][1].country_code == 'US' 16 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. comp-match documentation master file, created by 2 | sphinx-quickstart on Fri Feb 23 18:17:30 2018. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | Welcome to comp-match's documentation! 7 | ====================================== 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Contents: 12 | 13 | 14 | 15 | Indices and tables 16 | ================== 17 | 18 | * :ref:`genindex` 19 | * :ref:`modindex` 20 | * :ref:`search` 21 | -------------------------------------------------------------------------------- /comp_match/__init__.py: -------------------------------------------------------------------------------- 1 | """[WIP]Match company names to stock symbols, compare company names, and etc. 2 | """ 3 | __author__ = 'franklingu' 4 | __author_email__ = 'franklingujunchao@gmail.com' 5 | __ver_major__ = 0 6 | __ver_minor__ = 0 7 | __ver_patch__ = 0 8 | __ver_sub__ = 'dev0' 9 | __version__ = "%d.%d.%d%s" % ( 10 | __ver_major__, __ver_minor__, __ver_patch__, __ver_sub__ 11 | ) 12 | 13 | from .google_finance import GoogleFinanceNameMatcher 14 | from .yahoo_finance import YahooFinanceNameMatcher 15 | from .open_calais import OpenCalaisNameMatcher 16 | from .helpers import match 17 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = comp-match 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 franklingu 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tests/resources/gf_zhihu.json: -------------------------------------------------------------------------------- 1 | ["zhihu",[["\u003cb\u003e603156 hebei yangyuan zhihui beverage co ltd sha\u003c\/b\u003e",81,[5],{"c":"Hebei Yangyuan ZhiHui Beverage Co Ltd","m":"/g/11f4053h33","nf":"/g/11f4053h33","nq":"Hebei Yangyuan ZhiHui Beverage Co Ltd","s":"H4sIAAAAAAAAAONgecRowS3w8sc9YSn9SWtOXmPU5OIKzsgvd80rySypFJLmYoOyBKX4uXj10_UNDdNMDEyNM4yNeQCObA_2PQAAAA","t":"603156","x":"SHA"}],["\u003cb\u003ehongli zhihui group co ltd 300219 she\u003c\/b\u003e",81,[5],{"c":"Hongli Zhihui Group Co Ltd","m":"/g/1dv6wfl6","nf":"/g/1dv6wfl6","nq":"Hongli Zhihui Group Co Ltd","s":"H4sIAAAAAAAAAONgecRoxi3w8sc9YSndSWtOXmNU5-IKzsgvd80rySypFJLkYoOy-KV4ubj10_UNU8rMytNyzHgAPLgd3jsAAAA","t":"300219","x":"SHE"}],["\u003cb\u003ezhejiang zhengyuan zhihui tech co ltd 300645 she\u003c\/b\u003e",81,[5],{"c":"Zhejiang Zhengyuan Zhihui Tech Co Ltd","m":"/g/11c74bbb07","nf":"/g/11c74bbb07","nq":"Zhejiang Zhengyuan Zhihui Tech Co Ltd","s":"H4sIAAAAAAAAAONgecRowS3w8sc9YSn9SWtOXmPU5OIKzsgvd80rySypFJLmYoOyBKX4uXj10_UNDZPNTZKSkgzMeQA8TzfbPQAAAA","t":"300645","x":"SHE"}],["zhihu",0],["zhihua zhou",0],["zhihua temple",0],["zhihua zhang",0],["zhihua zhou google scholar",0],["zhihua qu ucf",0],["zhihua chen",0],["zhihua hu composer",0],["zhihua qu",0],["zhihua cui",0]],{"j":"w2","q":"JMQb0BRACqxF9hgPqJAQgICl2HU"}] 2 | -------------------------------------------------------------------------------- /tests/resources/yh_apple.json: -------------------------------------------------------------------------------- 1 | {"ResultSet":{"Query":"AAPL","Result":[{"symbol":"AAPL","name":"Apple Inc.","exch":"NAS","type":"S","exchDisp":"NASDAQ","typeDisp":"Equity"},{"symbol":"AAPL180329C00175000","name":"AAPL Mar 2018 call 175.000","exch":"OPR","type":"O","exchDisp":"OPR","typeDisp":"Option"},{"symbol":"AAPL.SN","name":"Apple Inc.","exch":"SGO","type":"S","exchDisp":"Santiago Stock Exchange","typeDisp":"Equity"},{"symbol":"AAPL180323C00180000","name":"AAPL Mar 2018 call 180.000","exch":"OPR","type":"O","exchDisp":"OPR","typeDisp":"Option"},{"symbol":"AAPL180323C00185000","name":"AAPL Mar 2018 call 185.000","exch":"OPR","type":"O","exchDisp":"OPR","typeDisp":"Option"},{"symbol":"AAPL180323P00180000","name":"AAPL Mar 2018 put 180.000","exch":"OPR","type":"O","exchDisp":"OPR","typeDisp":"Option"},{"symbol":"AAPL180420P00180000","name":"AAPL Apr 2018 put 180.000","exch":"OPR","type":"O","exchDisp":"OPR","typeDisp":"Option"},{"symbol":"AAPL180420C00180000","name":"AAPL Apr 2018 call 180.000","exch":"OPR","type":"O","exchDisp":"OPR","typeDisp":"Option"},{"symbol":"AAPL.MX","name":"Apple Inc.","exch":"MEX","type":"S","exchDisp":"Mexico","typeDisp":"Equity"},{"symbol":"AAPL180323C00130000","name":"AAPL Mar 2018 call 130.000","exch":"OPR","type":"O","exchDisp":"OPR","typeDisp":"Option"}]}} 2 | -------------------------------------------------------------------------------- /tests/helpers.py: -------------------------------------------------------------------------------- 1 | """Helper for test 2 | """ 3 | import os 4 | import json 5 | 6 | 7 | class MockedResponse(object): 8 | """Helper clas to mock a requests response 9 | """ 10 | def __init__(self, res_paths, fails=0, raises=ValueError): 11 | if isinstance(res_paths, str): 12 | res_paths = [res_paths] 13 | act_paths = [] 14 | for res_path in res_paths: 15 | act_path = os.path.normpath(os.path.join( 16 | os.path.realpath(__file__), '../resources/', res_path 17 | )) 18 | act_paths.append(act_path) 19 | self.act_paths = act_paths 20 | self.fails = fails 21 | self.num = 0 22 | self.raises = raises 23 | 24 | @property 25 | def status_code(self): 26 | """return status code 27 | """ 28 | return 200 29 | 30 | @property 31 | def content(self): 32 | """return content from source file path 33 | """ 34 | self.num = self.num + 1 35 | idx = self.num // (self.fails + 1) - 1 36 | remainder = self.num % (self.fails + 1) 37 | if remainder == 0: 38 | act_path = self.act_paths[idx] 39 | with open(act_path, 'rb') as ifile: 40 | return ifile.read() 41 | else: 42 | raise self.raises('Mocked exception') 43 | 44 | def json(self): 45 | """convert content to json object 46 | """ 47 | content = self.content 48 | return json.loads(content.decode('utf-8')) 49 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from __future__ import absolute_import, print_function 3 | 4 | from setuptools import setup, find_packages 5 | 6 | import comp_match 7 | 8 | NAME = 'comp-match' 9 | PACKAGES = find_packages( 10 | exclude=['*.tests', '*.tests.*', 'tests.*', 'tests'] 11 | ) 12 | PACKAGE_DATA = { 13 | '': ['resources/*.*'] 14 | } 15 | AUTHOR = comp_match.__author__ 16 | AUTHOR_EMAIL = comp_match.__author_email__ 17 | URL = 'https://github.com/franklingu/comp-match' 18 | 19 | 20 | REQUIRES = [] 21 | with open('requirements.txt', 'r') as ifile: 22 | for line in ifile: 23 | REQUIRES.append(line.strip()) 24 | VERSION = comp_match.__version__ 25 | DESCRIPTION = 'Match company names to underline, stock symbols and more' 26 | KEYWORDS = 'match company name stock' 27 | LONG_DESC = comp_match.__doc__ 28 | 29 | setup( 30 | name=NAME, 31 | version=VERSION, 32 | author=AUTHOR, 33 | author_email=AUTHOR_EMAIL, 34 | description=DESCRIPTION, 35 | long_description=LONG_DESC, 36 | url=URL, 37 | keywords=KEYWORDS, 38 | license='MIT', 39 | packages=PACKAGES, 40 | package_data=PACKAGE_DATA, 41 | include_package_data=True, 42 | install_requires=REQUIRES, 43 | python_requires='>=3.5, <4', 44 | classifiers=[ 45 | 'Programming Language :: Python :: 3.5', 46 | 'Programming Language :: Python :: 3.6', 47 | 'Programming Language :: Python', 48 | 'Development Status :: 3 - Alpha', 49 | 'Intended Audience :: Developers', 50 | ], 51 | ) 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # mypy 101 | .mypy_cache/ 102 | 103 | *.swp 104 | 105 | .pytest_cache/ 106 | -------------------------------------------------------------------------------- /tests/resources/gf_apple.json: -------------------------------------------------------------------------------- 1 | ["apple",[["\u003cb\u003eapple aapl nasdaq\u003c\/b\u003e",81,[],{"c":"Apple Inc.","m":"/m/07zmbvf","nf":"/m/07zmbvf","nq":"Apple Inc","s":"H4sIAAAAAAAAAONgecRoyi3w8sc9YSmdSWtOXmNU4-IKzsgvd80rySypFJLgYoOy-KR4uLj0c_UNzKtyk8rSeADviEaCOgAAAA","t":"AAPL","x":"NASDAQ"}],["\u003cb\u003eapple hospitality reit aple nyse\u003c\/b\u003e",81,[],{"c":"Apple Hospitality REIT Inc","m":"/g/11bwqbl2lq","nf":"/g/11bwqbl2lq","nq":"Apple Hospitality REIT Inc","s":"H4sIAAAAAAAAAONgecRowS3w8sc9YSn9SWtOXmPU5OIKzsgvd80rySypFJLmYoOyBKX4uXj10_UNDZPKC5NyjHIKeQDYTVpEPQAAAA","t":"APLE","x":"NYSE"}],["\u003cb\u003eapple rush co inc apru otcmkts\u003c\/b\u003e",81,[],{"c":"APPLE RUSH Co I/SH NEW","m":"/g/1dty4srf","nf":"/g/1dty4srf","nq":"Apple Rush Co Inc","s":"H4sIAAAAAAAAAONgecRoxi3w8sc9YSndSWtOXmNU5-IKzsgvd80rySypFJLkYoOy-KV4ubj10_UNU0oqTYqL0ngAtkcbYzsAAAA","t":"APRU","x":"OTCMKTS"}],["\u003cb\u003eapple inc apc etr\u003c\/b\u003e",81,[],{"c":"Apple Inc.","m":"/g/11f102cqtm","nf":"/m/07zmbvf","nq":"Apple Inc","s":"H4sIAAAAAAAAAONgecRowS3w8sc9YSn9SWtOXmPU5OIKzsgvd80rySypFJLmYoOyBKX4uXj10_UNDdMMDYySC0tyeQATbgXnPQAAAA","t":"APC","x":"ETR"}],["\u003cb\u003eapple aapl bit\u003c\/b\u003e",81,[],{"c":"Apple Inc.","m":"/g/11fzylrvbl","nf":"/m/07zmbvf","nq":"Apple Inc","s":"H4sIAAAAAAAAAONgecRowS3w8sc9YSn9SWtOXmPU5OIKzsgvd80rySypFJLmYoOyBKX4uXj10_UNDdOqKnOKypJyeACNgQK1PQAAAA","t":"AAPL","x":"BIT"}],["\u003cb\u003eapple inc apc fra\u003c\/b\u003e",81,[],{"c":"Apple Inc.","m":"/m/02xl7ls","nf":"/m/07zmbvf","nq":"Apple Inc","s":"H4sIAAAAAAAAAONgecRoyi3w8sc9YSmdSWtOXmNU4-IKzsgvd80rySypFJLgYoOy-KR4uLj0c_UNjCpyzHOKeQDREAF6OgAAAA","t":"APC","x":"FRA"}],["apple",0,[131]],["apple singapore",0],["apple watch",0,[131]],["apple id",0],["apple share price",0],["apple watch 3",0],["apple chan",0],["apple music",0,[131]],["apple support",0,[131]],["apple tv",0]],{"j":"e5","q":"Gxam2eHsYXOfXnE_OwEKv5457eY"}] 2 | -------------------------------------------------------------------------------- /tests/test_google_finance.py: -------------------------------------------------------------------------------- 1 | """Unit test for google_finance 2 | """ 3 | from unittest.mock import patch 4 | 5 | from comp_match.google_finance import GoogleFinanceNameMatcher 6 | from .helpers import MockedResponse 7 | 8 | 9 | @patch('requests.get', return_value=MockedResponse('gf_apple.json')) 10 | def test_gf_success_matching(get_mock): 11 | """Test GoogleFinance match successfully 12 | """ 13 | gf_matcher = GoogleFinanceNameMatcher() 14 | symbols = gf_matcher.match_by('apple') 15 | try: 16 | get_mock.assert_called_once() 17 | except AttributeError: 18 | assert get_mock.call_count == 1 19 | assert 'apple' in symbols 20 | assert len(symbols['apple']) == 6 21 | assert symbols['apple'][0][0] == 'Apple Inc.' 22 | assert symbols['apple'][0][1].ticker == 'AAPL' 23 | assert symbols['apple'][0][1].country_code == 'US' 24 | 25 | @patch('requests.get', return_value=MockedResponse('gf_apple.json', fails=2)) 26 | def test_gf_matching_with_exception(get_mock): 27 | """Test GoogleFinance match with network exception 28 | """ 29 | gf_matcher = GoogleFinanceNameMatcher() 30 | symbols = gf_matcher.match_by('apple', sleep=0) 31 | assert get_mock.call_count == 3 32 | assert symbols['apple'][0][0] == 'Apple Inc.' 33 | assert symbols['apple'][0][1].ticker == 'AAPL' 34 | assert symbols['apple'][0][1].country_code == 'US' 35 | symbols = gf_matcher.match_by('apple', retry=2, sleep=0) 36 | try: 37 | get_mock.assert_called() 38 | except AttributeError: 39 | assert get_mock.called 40 | assert not symbols['apple'] 41 | 42 | @patch('requests.get', return_value=MockedResponse('gf_zhihu.json')) 43 | def test_gf_multiple_matching(get_mock): 44 | """Test GoogleFinance match with multiple result 45 | """ 46 | gf_matcher = GoogleFinanceNameMatcher() 47 | symbols = gf_matcher.match_by('zhihu') 48 | try: 49 | get_mock.assert_called_once() 50 | except AttributeError: 51 | assert get_mock.call_count == 1 52 | assert 'zhihu' in symbols 53 | assert len(symbols['zhihu']) == 3 54 | -------------------------------------------------------------------------------- /tests/test_yahoo_finance.py: -------------------------------------------------------------------------------- 1 | """Test YahooFinanceNameMatcher 2 | """ 3 | from unittest.mock import patch 4 | 5 | from comp_match.yahoo_finance import YahooFinanceNameMatcher 6 | from .helpers import MockedResponse 7 | 8 | 9 | @patch('requests.get', return_value=MockedResponse('yh_apple.json')) 10 | def test_yh_success_matching(get_mock): 11 | """Test YahooFinance match successfully 12 | """ 13 | yh_matcher = YahooFinanceNameMatcher() 14 | symbols = yh_matcher.match_by('Apple') 15 | try: 16 | get_mock.assert_called_once() 17 | except AttributeError: 18 | assert get_mock.call_count == 1 19 | assert 'Apple' in symbols 20 | assert symbols['Apple'][0][1].ticker == 'AAPL' 21 | assert symbols['Apple'][0][1].country_code == 'US' 22 | assert symbols['Apple'][2][1].country_code == 'MX' 23 | 24 | @patch('requests.get', return_value=MockedResponse('yh_apple.json', fails=2)) 25 | def test_yh_matching_with_exception(get_mock): 26 | """Test YahooFinance match with network exception 27 | """ 28 | yh_matcher = YahooFinanceNameMatcher() 29 | symbols = yh_matcher.match_by('Apple', sleep=0) 30 | assert get_mock.call_count == 3 31 | assert 'Apple' in symbols 32 | assert symbols['Apple'][0][1].ticker == 'AAPL' 33 | assert symbols['Apple'][0][1].country_code == 'US' 34 | symbols = yh_matcher.match_by('Apple', retry=2, sleep=0) 35 | try: 36 | get_mock.assert_called() 37 | except AttributeError: 38 | assert get_mock.called 39 | assert not symbols['Apple'] 40 | 41 | @patch('requests.get', return_value=MockedResponse('yh_zhihu.json')) 42 | def test_yh_multiple_matching(get_mock): 43 | """Test YahooFinance match to multiple results 44 | """ 45 | yh_matcher = YahooFinanceNameMatcher() 46 | symbols = yh_matcher.match_by('zhihu') 47 | try: 48 | get_mock.assert_called_once() 49 | except AttributeError: 50 | assert get_mock.call_count == 1 51 | assert 'zhihu' in symbols 52 | assert symbols['zhihu'][0][1].ticker == '603156' 53 | assert symbols['zhihu'][0][1].country_code == 'CN' 54 | -------------------------------------------------------------------------------- /tests/test_open_calais.py: -------------------------------------------------------------------------------- 1 | """Unit test for open_calais 2 | """ 3 | from unittest.mock import patch, MagicMock 4 | 5 | from comp_match.open_calais import OpenCalaisNameMatcher 6 | from .helpers import MockedResponse 7 | 8 | 9 | @patch('requests.post', return_value=MockedResponse('oc_apple.rdf')) 10 | @patch('requests.Session') 11 | def test_oc_success_matching(session_mock, post_mock): 12 | """Test open calais success at first try 13 | """ 14 | act_session = MagicMock() 15 | session_mock.return_value.__enter__.return_value = act_session 16 | act_session.get.return_value = MockedResponse('oc_apple.json') 17 | oc_matcher = OpenCalaisNameMatcher() 18 | symbols = oc_matcher.match_by('Apple', sleep=0) 19 | assert 'Apple' in symbols 20 | assert symbols['Apple'][0][0] == 'APPLE INC.' 21 | assert symbols['Apple'][0][1].ticker == 'AAPL' 22 | assert symbols['Apple'][0][1].country_code == 'US' 23 | # get html page first in session 24 | assert act_session.get.call_count == 2 25 | assert post_mock.call_count == 1 26 | 27 | 28 | @patch('requests.post', return_value=MockedResponse('oc_apple.rdf', fails=2)) 29 | @patch('requests.Session') 30 | def test_oc_retry_matching(session_mock, post_mock): 31 | """Test open calais success after retry 32 | """ 33 | act_session = MagicMock() 34 | session_mock.return_value.__enter__.return_value = act_session 35 | act_session.get.return_value = MockedResponse('oc_apple.json', fails=3) 36 | oc_matcher = OpenCalaisNameMatcher() 37 | symbols = oc_matcher.match_by('Apple', sleep=0) 38 | assert 'Apple' in symbols 39 | assert symbols['Apple'][0][0] == 'APPLE INC.' 40 | assert symbols['Apple'][0][1].ticker == 'AAPL' 41 | assert symbols['Apple'][0][1].country_code == 'US' 42 | assert act_session.get.call_count == 5 43 | assert post_mock.call_count == 3 44 | 45 | 46 | @patch('requests.post', return_value=MockedResponse('oc_google.rdf')) 47 | @patch('requests.Session') 48 | def test_oc_success_matching_with_top(session_mock, post_mock): 49 | """Test open calais success at first try 50 | """ 51 | act_session = MagicMock() 52 | session_mock.return_value.__enter__.return_value = act_session 53 | act_session.get.return_value = MockedResponse('oc_google.json') 54 | oc_matcher = OpenCalaisNameMatcher() 55 | symbols = oc_matcher.match_by('Google', sleep=0) 56 | assert 'Google' in symbols 57 | assert symbols['Google'][0][0] == 'ALPHABET INC.' 58 | assert symbols['Google'][0][1].ticker == 'GOOGL' 59 | assert symbols['Google'][0][1].country_code == 'US' 60 | # get html page first in session 61 | assert act_session.get.call_count == 2 62 | assert post_mock.call_count == 1 63 | -------------------------------------------------------------------------------- /comp_match/helpers.py: -------------------------------------------------------------------------------- 1 | """Helper functions to company names more easily 2 | """ 3 | from .base import BaseNameMatcher 4 | from .exceptions import UnkownMatcherException 5 | 6 | 7 | MATCHERS_MAP = dict( 8 | (cls.AGENT, cls) for cls in BaseNameMatcher.__subclasses__() 9 | ) 10 | MATCHERS_WEIGHT = dict((matcher_name, 1) for matcher_name in MATCHERS_MAP) 11 | # Give Open Calais more weight in matching 12 | MATCHERS_WEIGHT['open_calais'] += 2 13 | 14 | 15 | def match(company_names, matchers=None, matchers_configs=None): 16 | """Match company names to company underlines 17 | 18 | Args: 19 | company_names: company name or list of company names to match underlines for 20 | matchers: list of matcher classes to use 21 | matchers_configs: matcher class custom config 22 | """ 23 | def merge_match_results(match_results): 24 | """Merge match results and compute weight 25 | """ 26 | merged = {} 27 | for company_name, matches in match_results.items(): 28 | match_map = {} 29 | for match_record, weight in matches: 30 | legal_name, underline, extra = match_record 31 | score = weight * float(extra.get('score', 1)) 32 | if underline not in match_map: 33 | extra['score'] = score 34 | match_map[underline] = [legal_name, underline, extra] 35 | else: 36 | legal_name, underline, bextra = match_map[underline] 37 | extra.update(bextra) 38 | extra['score'] += score 39 | match_map[underline][2] = extra 40 | merged[company_name] = sorted( 41 | list(match_map.values()), key=lambda x: -x[2]['score'] 42 | ) 43 | return merged 44 | 45 | if isinstance(company_names, str): 46 | company_names = [company_names] 47 | if matchers_configs is None: 48 | matchers_configs = {} 49 | if matchers is None: 50 | matchers = list(MATCHERS_MAP.keys()) 51 | match_results = {} 52 | for matcher_name in matchers: 53 | try: 54 | if matcher_name not in matchers_configs: 55 | matcher = MATCHERS_MAP[matcher_name]() 56 | else: 57 | config_args, config_kwargs = matchers_configs[matcher_name] 58 | matcher = MATCHERS_MAP[matcher_name]( 59 | *config_args, **config_kwargs 60 | ) 61 | result = matcher.match_by(company_names) 62 | for name, elems in result.items(): 63 | if name not in match_results: 64 | match_results[name] = [] 65 | for elem in elems: 66 | match_results[name].append( 67 | (elem, MATCHERS_WEIGHT.get(matcher_name, 0)) 68 | ) 69 | except KeyError: 70 | raise UnkownMatcherException( 71 | '{} is unkown as a matcher'.format(matcher_name) 72 | ) 73 | except ValueError: 74 | raise 75 | return merge_match_results(match_results) 76 | -------------------------------------------------------------------------------- /comp_match/yahoo_finance.py: -------------------------------------------------------------------------------- 1 | """Match company names via Yahoo Finance 2 | """ 3 | import random 4 | import time 5 | 6 | import requests 7 | 8 | from .base import BaseNameMatcher, CompanyUnderline 9 | from ._utils import get_logger 10 | 11 | 12 | class YahooFinanceNameMatcher( # pylint: disable=too-few-public-methods 13 | BaseNameMatcher): 14 | """Match name using YahooFinance service 15 | """ 16 | AGENT = 'yahoo_finance' 17 | 18 | def __init__(self): 19 | super(YahooFinanceNameMatcher, self).__init__() 20 | self.base_url = 'http://autoc.finance.yahoo.com/autoc' 21 | 22 | def _find_stock_for_name( # pylint: disable=too-many-locals 23 | self, name, retry=5, sleep=30): 24 | params = {'query': name, 'lang': 'en-US'} 25 | symbols = [] 26 | for retry_num in range(retry): 27 | try: 28 | res = requests.get( 29 | self.base_url, headers=self._get_headers(), 30 | params=params, timeout=sleep + 3 31 | ) 32 | data = res.json() 33 | for result in data['ResultSet']['Result']: 34 | ticker = result.get('symbol', '').split('.')[0] 35 | # change A/B share representation 36 | ticker = ticker.replace('-', '.') 37 | type_desc = result.get('typeDisp', '') 38 | if type_desc != 'Equity': 39 | continue 40 | yahoo_exch = '' 41 | if len(result.get('symbol', '').split('.')) > 1: 42 | yahoo_exch = '.' + result.get( 43 | 'symbol', '' 44 | ).split('.')[1] 45 | country = None 46 | else: 47 | country = 'US' 48 | symbols.append(( 49 | result.get('name', ''), 50 | ticker, 51 | yahoo_exch, 52 | country, 53 | result.get('exch', ''), 54 | result.get('exchDisp', '') 55 | )) 56 | break 57 | except Exception as err: # pylint: disable=broad-except 58 | get_logger().debug( 59 | 'Error happened via querying Yahoo Finance: %s', str(err) 60 | ) 61 | symbols = [] 62 | if retry_num == retry - 1: 63 | continue 64 | else: 65 | time.sleep(random.random() * sleep + retry_num * sleep) 66 | return symbols 67 | 68 | def _match_by(self, names, **kwargs): 69 | retry = kwargs.pop('retry', 5) 70 | sleep = kwargs.pop('sleep', 30) 71 | ret = {} 72 | for name in names: 73 | symbols = self._find_stock_for_name(name, retry=retry, sleep=sleep) 74 | ret[name] = [] 75 | for symbol in symbols: 76 | ret[name].append(( 77 | symbol[0], 78 | CompanyUnderline( 79 | ticker=symbol[1], 80 | yahoo_exch=symbol[2], 81 | country_code=symbol[3] 82 | ), 83 | {'exch': symbol[4], 'exch_desc': symbol[5]} 84 | )) 85 | return ret 86 | -------------------------------------------------------------------------------- /comp_match/google_finance.py: -------------------------------------------------------------------------------- 1 | """Match company names via Google Finance 2 | """ 3 | import random 4 | import time 5 | try: 6 | import simplejson as json 7 | except ImportError: 8 | import json 9 | 10 | import requests 11 | 12 | from .base import BaseNameMatcher, CompanyUnderline 13 | from ._utils import get_logger 14 | 15 | 16 | class GoogleFinanceNameMatcher( # pylint: disable=too-few-public-methods 17 | BaseNameMatcher): 18 | """Match name to stock ticker via Google Finance 19 | """ 20 | AGENT = 'google_finance' 21 | 22 | def __init__(self): 23 | super(GoogleFinanceNameMatcher, self).__init__() 24 | self.base_url = 'https://www.google.com/complete/search' 25 | 26 | def _parse_google_finance_response( # pylint: disable=no-self-use 27 | self, name, page_content): 28 | symbols = [] 29 | try: 30 | parsed = json.loads(page_content) 31 | except ValueError: 32 | raise 33 | except TypeError: 34 | parsed = json.loads(page_content.decode('utf-8')) 35 | if (not isinstance(parsed, list) or not parsed or parsed[0] != name 36 | or len(parsed) < 2): 37 | raise ValueError('Google response does not seem normal') 38 | for candidate in parsed[1]: 39 | if len(candidate) < 4 or not isinstance(candidate[3], dict): 40 | continue 41 | ticker = candidate[3].get('t', '') 42 | google_exch = candidate[3].get('x', '') 43 | mapped_name = candidate[3].get('c', '') 44 | if not ticker or not google_exch: 45 | continue 46 | symbols.append((mapped_name, ticker, google_exch)) 47 | return symbols 48 | 49 | def _find_stock_for_name(self, name, retry=5, sleep=30): 50 | params = { 51 | 'client': 'finance-immersive', 52 | 'q': name, 53 | 'xhr': 't', 54 | } 55 | headers = self._get_headers() 56 | symbols = [] 57 | for retry_num in range(retry): 58 | try: 59 | res = requests.get( 60 | self.base_url, headers=headers, params=params, 61 | timeout=sleep + 3 62 | ) 63 | symbols = self._parse_google_finance_response( 64 | name, res.content 65 | ) 66 | break 67 | except Exception as err: # pylint: disable=broad-except 68 | get_logger().debug( 69 | 'Error happened when querying Google Finance: %s', str(err) 70 | ) 71 | symbols = [] 72 | if retry_num == retry - 1: 73 | continue 74 | else: 75 | time.sleep(random.random() * sleep + retry_num * sleep) 76 | return symbols 77 | 78 | def _match_by(self, names, **kwargs): 79 | ret = {} 80 | retry = kwargs.pop('retry', 5) 81 | sleep = int(kwargs.pop('sleep', 30)) 82 | for name in names: 83 | symbols = self._find_stock_for_name( 84 | name, retry=retry, sleep=sleep, 85 | ) 86 | ret[name] = [] 87 | for symbol in symbols: 88 | ret[name].append( 89 | (symbol[0], CompanyUnderline( 90 | ticker=symbol[1], google_exch=symbol[2] 91 | ), {}) 92 | ) 93 | return ret 94 | -------------------------------------------------------------------------------- /comp_match/_utils.py: -------------------------------------------------------------------------------- 1 | """Collection of util functions 2 | """ 3 | import os 4 | import csv 5 | import logging 6 | try: 7 | import simplejson as json 8 | except ImportError: 9 | import json 10 | 11 | 12 | __all__ = [ 13 | 'get_logger', 'resource_manager', 14 | ] 15 | 16 | 17 | class ResourceManager(object): 18 | def __init__(self, exchange_path=None, country_path=None, mic_path=None): 19 | super(ResourceManager, self).__init__() 20 | dirpath = os.path.dirname(os.path.abspath(__file__)) 21 | if exchange_path is None: 22 | exchange_path = os.path.normpath(os.path.join( 23 | dirpath, './resources/exchanges.csv' 24 | )) 25 | if country_path is None: 26 | country_path = os.path.normpath(os.path.join( 27 | dirpath, './resources/iso_countries.json' 28 | )) 29 | if mic_path is None: 30 | mic_path = os.path.normpath(os.path.join( 31 | dirpath, './resources/iso_10383.csv' 32 | )) 33 | with open(exchange_path, 'r') as ifile: 34 | reader = csv.reader(ifile, delimiter='|') 35 | exchanges, google_exches, yahoo_exches, mics = {}, {}, {}, {} 36 | headers = None 37 | for row in reader: 38 | if headers is None: 39 | headers = row 40 | continue 41 | rec = dict(zip(headers, row)) 42 | exchanges[rec['Exchange Name']] = rec 43 | if rec.get('Google Exchange'): 44 | google_exches[rec['Google Exchange']] = rec 45 | if rec.get('Yahoo Exchange'): 46 | yahoo_exches[rec['Yahoo Exchange']] = rec 47 | if rec.get('MIC'): 48 | mics[rec['MIC']] = rec 49 | self.exchanges = exchanges 50 | self.google_exches = google_exches 51 | self.yahoo_exches = yahoo_exches 52 | self.mics = mics 53 | with open(mic_path, 'r', encoding='latin1') as ifile: 54 | reader = csv.reader(ifile, delimiter=',') 55 | mheaders = None 56 | for row in reader: 57 | if mheaders is None: 58 | mheaders = row 59 | continue 60 | mrec = dict(zip(mheaders, row)) 61 | rec = dict((h, '') for h in headers) 62 | rec['Country Name'] = mrec['COUNTRY'] 63 | rec['Country Code'] = mrec['ISO COUNTRY CODE (ISO 3166)'] 64 | rec['MIC'] = mrec['MIC'] 65 | rec['Operating MIC'] = mrec['OPERATING MIC'] 66 | rec['Exchange Name'] = mrec['NAME-INSTITUTION DESCRIPTION'] 67 | if rec['MIC'] not in self.mics: 68 | self.mics[rec['MIC']] = rec 69 | with open(country_path, 'r') as ifile: 70 | raw_countries = json.load(ifile)['3166-1'] 71 | countries = {} 72 | for country in raw_countries: 73 | countries[country['name']] = country 74 | self.countries = countries 75 | 76 | def find_exchange_by(self, **kwargs): 77 | """match to raw exchange dict by given criteria 78 | """ 79 | if 'exchange' in kwargs: 80 | return self.exchanges.get(kwargs['exchange']) 81 | elif 'google_exch' in kwargs: 82 | return self.google_exches.get(kwargs['google_exch']) 83 | elif 'yahoo_exch' in kwargs: 84 | return self.yahoo_exches.get(kwargs['yahoo_exch']) 85 | elif 'mic' in kwargs: 86 | return self.mics.get(kwargs['mic']) 87 | else: 88 | raise ValueError('Unknown exchange type for matching') 89 | 90 | def find_country_by(self, **kwargs): 91 | """match to raw country dict by given criteria 92 | """ 93 | if kwargs['country'] in self.countries: 94 | return self.countries[kwargs['country']] 95 | return None 96 | 97 | 98 | resource_manager = ResourceManager() 99 | 100 | 101 | def get_logger(): 102 | """Return internal logger 103 | """ 104 | return logging.getLogger('comp_match') 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # comp-match 2 | 3 | [![Build Status](https://travis-ci.org/franklingu/comp-match.svg?branch=master)](https://travis-ci.org/franklingu/comp-match)  4 | [![Documentation Status](https://readthedocs.org/projects/comp-match/badge/?version=latest)](http://comp-match.readthedocs.io/en/latest/?badge=latest) 5 | 6 | *Match company names to legal names and underlines with a snap of finger* 7 | 8 | ## Contents 9 | 10 | * [Intro](#intro) 11 | * [Quick Start](#quick-start) 12 | * [Documentation](#documentation) 13 | * [Roadmap](#roadmap) 14 | * [Contribution Guide](#contribution-guide) 15 | * [Changelog](#changelog) 16 | * [Notes](#notes) 17 | * [License](#license) 18 | 19 | ## Intro 20 | 21 | Given a company name, how to find its underline/stock symbol? By hand this does not seem like a very difficult task, but what if we need to match a lof of them? In such case we need to find a simple and effective way to compare company names, match to stock symbols. 22 | 23 | ## Quick Start 24 | 25 | Install the package with ```pip install comp-match``` and check the installation is successful by ```python -c 'import comp_match; print(comp_match.__version__)'```. After successful installation, you should be able to see version printed out. 26 | 27 | The following code snippet is a demo: 28 | 29 | ``` 30 | import comp_match 31 | 32 | comp_match.match(['Apple', 'Google', 'Facebook', 'CitiBank']) 33 | """ 34 | Returned response, takes some time 35 | {'Apple': [['Apple Inc.', 36 | CompanyUnderline: [AAPL@NASDAQ OMX PHLX@US], 37 | {'exch': 'NAS', 38 | 'exch_desc': 'NASDAQ', 39 | 'ric': 'AAPL.OQ', 40 | 'score': 4.9837301}], 41 | ['Apple Hospitality REIT Inc', 42 | CompanyUnderline: [APLE@New York Stock Exchange@US], 43 | {'exch': 'NYQ', 'exch_desc': 'NYSE', 'score': 2.0}], 44 | ['Apple Inc.', 45 | CompanyUnderline: [APC@XETRA@DE], 46 | {'exch': 'FRA', 'exch_desc': 'Frankfurt', 'score': 2.0}], 47 | ... 48 | ['Apple Inc.', 49 | CompanyUnderline: [AAPL@Vienna Stock Exchange@AT], 50 | {'exch': 'VIE', 'exch_desc': 'Vienna', 'score': 1.0}], 51 | ['Apple', 52 | CompanyUnderline: [AAPL.EUR@@UN], 53 | {'exch': 'EBS', 'exch_desc': 'Swiss', 'score': 1.0}]], 54 | 'CitiBank': [['CITIGROUP INC.', 55 | CompanyUnderline: [C@New York Stock Exchange@US], 56 | {'ric': 'C.N', 'score': 3.0}]], 57 | 'Facebook': [['Facebook, Inc. Common Stock', 58 | CompanyUnderline: [FB@NASDAQ OMX PHLX@US], 59 | {'exch': 'NAS', 'exch_desc': 'NASDAQ', 'ric': 'FB.OQ', 'score': 4.9795589}], 60 | ['Facebook, Inc. Common Stock', 61 | CompanyUnderline: [FB2A@XETRA@DE], 62 | {'exch': 'GER', 'exch_desc': 'XETRA', 'score': 4.0}], 63 | ... 64 | ['Facebook', 65 | CompanyUnderline: [FB.USD@@UN], 66 | {'exch': 'EBS', 'exch_desc': 'Swiss', 'score': 1.0}]], 67 | 'Google': [['GOOGLE LLC', None, {'ric': '', 'score': 3.0}], 68 | ['CBOE Equity VIX ON Google', CompanyUnderline: [VXGOG@@UN], {'score': 1.0}], 69 | ['CBOE Equity VIX ON Google', CompanyUnderline: [VXIBM@@UN], {'score': 1.0}], 70 | ['Alphabet Inc.', 71 | CompanyUnderline: [GOOG@@US], 72 | {'exch': 'NGM', 'exch_desc': 'NASDAQ', 'score': 1.0}], 73 | ['Alphabet Inc.', 74 | CompanyUnderline: [GOOGL@@US], 75 | {'exch': 'NAS', 'exch_desc': 'NASDAQ', 'score': 1.0}], 76 | ... 77 | ['Alphabet Inc.', 78 | CompanyUnderline: [GOOGL@Mexico Stock Exchange@MX], 79 | {'exch': 'MEX', 'exch_desc': 'Mexico', 'score': 1.0}]]} 80 | 81 | """ 82 | ``` 83 | 84 | ## Documentation 85 | 86 | TODO 87 | 88 | ## Roadmap 89 | 90 | - [x] Get GoogleFinance, YahooFinance, OpenCalais matchers working 91 | - [x] Add top level function to match company names to underlines directly 92 | - [ ] Add more documentation 93 | - [ ] Double check GoogleFinance and YahooFinance exchange mapping 94 | - [ ] Improve performance with asyncio or threading 95 | - [ ] Add msn finance matching 96 | - [ ] Improve result matching and filtering with similary check, weight adjustment 97 | - [ ] Add command line usage 98 | - [ ] Add in memory caching 99 | - [ ] Add redis / db caching 100 | - [ ] Add Flask web app and json api 101 | 102 | ## Contribution Guide 103 | 104 | TODO 105 | 106 | ## Changelog 107 | 108 | [Changelog](./changelog) 109 | 110 | ## Notes 111 | 112 | 1. Information is gathered from web and inaccuracy is inevitable. In particularly Google Finance and Yahoo Finance exchange mapping relies on some third party website and therefore may not be 100% correct. I am still trying to verify those information. 113 | 2. Tickers do change and currently there is not support for mapping over history yet. 114 | 115 | ### License 116 | 117 | [MIT](./LICENSE) 118 | -------------------------------------------------------------------------------- /comp_match/base.py: -------------------------------------------------------------------------------- 1 | """Base classes for matchers 2 | """ 3 | from abc import ABCMeta 4 | import random 5 | 6 | from ._utils import resource_manager 7 | 8 | 9 | class BaseNameMatcher( # pylint: disable=too-few-public-methods 10 | object, metaclass=ABCMeta): 11 | """Base for name matcher""" 12 | AGENT = 'base' 13 | 14 | def __init__(self, *args, **kwargs): 15 | """ 16 | 17 | TODO: add cache 18 | """ 19 | super(BaseNameMatcher, self).__init__() 20 | self.args = args 21 | self.kwargs = kwargs 22 | self.ua_reprs = [ 23 | ( 24 | 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:46.0)' 25 | ' Gecko/20100101 Firefox/46.0' 26 | ), 27 | ( 28 | 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36' 29 | ' (KHTML, like Gecko) Ubuntu Chromium/37.0.2062.120' 30 | ' Chrome/37.0.2062.120 Safari/537.36' 31 | ), 32 | ] 33 | 34 | def _get_headers(self): 35 | ua_repr = self.ua_reprs[random.randint(0, len(self.ua_reprs) - 1)] 36 | acc = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' 37 | return { 38 | 'User-Agent': ua_repr, 39 | 'Accept': acc, 40 | 'Accept-Language': 'en-US,en;q=0.5', 41 | } 42 | 43 | 44 | def match_by(self, names, **kwargs): 45 | """Match by names 46 | 47 | Params: 48 | names: a company name or a list of company names 49 | 50 | Returns: 51 | dict of orig_name: list of \ 52 | mapped legal name, underline, addon info dict) 53 | """ 54 | if isinstance(names, str): 55 | names = [names] 56 | names = set(names) 57 | return self._match_by(names, **kwargs) 58 | 59 | def _match_by(self, names, **kwargs): 60 | raise NotImplementedError('To be implemented') 61 | 62 | 63 | class CompanyUnderline(object): 64 | """Representation of a company underline""" 65 | def __init__(self, **kwargs): 66 | super(CompanyUnderline, self).__init__() 67 | strict_validate = False 68 | if 'strict_validate' in kwargs: 69 | strict_validate = kwargs.pop('strict_validate') 70 | if kwargs.get('ticker'): 71 | self.ticker = kwargs.pop('ticker') 72 | if kwargs.get('exchange'): 73 | self.exchange = kwargs.pop('exchange') 74 | if kwargs.get('mic'): 75 | self.mic = kwargs.pop('mic') 76 | if kwargs.get('google_exch'): 77 | self.google_exch = kwargs.pop('google_exch') 78 | if kwargs.get('yahoo_exch'): 79 | self.yahoo_exch = kwargs.pop('yahoo_exch') 80 | if kwargs.get('country_code'): 81 | self.country_code = kwargs.pop('country_code') 82 | self.setup_exchange() 83 | self.validate(strict_validate) 84 | 85 | @property 86 | def exch(self): 87 | """Short name for exchange 88 | """ 89 | return getattr(self, 'exchange', None) 90 | 91 | def setup_exchange(self): 92 | """Set exchange based on known information 93 | """ 94 | def set_exchange(self, attr): 95 | """Set exchange for self 96 | """ 97 | if hasattr(self, attr): 98 | cond = {attr: getattr(self, attr, '')} 99 | match = resource_manager.find_exchange_by(**cond) 100 | if match is not None: 101 | self.exchange = match['Exchange Name'] 102 | if match['Country Code']: 103 | self.country_code = match['Country Code'] 104 | 105 | if hasattr(self, 'exchange') and self.exchange is not None: 106 | return 107 | for attr in ['google_exch', 'yahoo_exch', 'mic']: 108 | set_exchange(self, attr) 109 | 110 | def validate(self, strict_validate=False): 111 | """Validate the current presentation of an underline 112 | 113 | Params: 114 | strict_validate: if true, both exchange and ticker should be set; 115 | if false, only ticker is required 116 | Raises: 117 | ValueError 118 | """ 119 | if not hasattr(self, 'ticker') or self.ticker is None: 120 | raise ValueError('Ticker is required') 121 | if not strict_validate: 122 | return 123 | if not hasattr(self, 'exchange') or self.exchange is None: 124 | raise ValueError('Exchange is required') 125 | 126 | def __repr__(self): 127 | return 'CompanyUnderline: [{}@{}@{}]'.format( 128 | getattr(self, 'ticker', ''), 129 | getattr(self, 'exchange', ''), 130 | getattr(self, 'country_code', 'UN') 131 | ) 132 | 133 | def __str__(self): 134 | return '{}@{}'.format( 135 | getattr(self, 'ticker', ''), 136 | getattr(self, 'country_code', 'UN') 137 | ) 138 | 139 | def __eq__(self, other): 140 | if not isinstance(other, self.__class__): 141 | return False 142 | return str(self) == str(other) 143 | 144 | def __hash__(self): 145 | return hash(str(self)) 146 | -------------------------------------------------------------------------------- /comp_match/resources/exchanges.csv: -------------------------------------------------------------------------------- 1 | Exchange Name|Country Name|Country Code|Google Exchange|Yahoo Exchange|MIC|Operating MIC 2 | Botswana Stock Exchange|Botswana|BW|BOT||XBOT|XBOT 3 | Ghana Stock Exchange|Ghana|GH|GHA||XGHA|XGHA 4 | Nairobi Stock Exchange|Kenya|KE|NBO||XNAI|XNAI 5 | Malawi Stock Exchange|Malawi|MW|MAL||XMSW|XMSW 6 | Casablanca Stock Exchange|Morocco|MA|CAS||XCAS|XCAS 7 | Nigerian Stock Exchange|Nigeria|NG|NIG||XNSA|XNSA 8 | JSE Securities Exchange|South Africa|ZA|JSE||XJSE|XJSE 9 | Lusaka Stock Exchange|Zambia|ZM|LUS||XLUS|XLUS 10 | Zimbabwe Stock Exchange|Zimbabwe|ZW|ZIM||XZIM|XZIM 11 | Australian Securities Exchange|Australia|AU|ASX|.AX|XASX|XASX 12 | Dhaka Stock Exchange|Bangladesh|BD|||XDHA|XDHA 13 | Hong Kong Stock Exchange|China|CN|HKG|.HK|XHKG|XHKG 14 | Shanghai Stock Exchange|China|CN|SHA|.SS|XSHG|XSHG 15 | Shenzhen Stock Exchange|China|CN|SHE|.SZ|XSHE|XSHE 16 | National Stock Exchange of India|India|IN|NSE|.NS|XNSE|XNSE 17 | Bombay Stock Exchange|India|IN|BOM|.BO|| 18 | Indonesia Stock Exchange|Indonesia|ID|JAK|.JK|XIDX|XIDX 19 | Fukuoka Stock Exchange|Japan|JP|FUK||XFKA|XFKA 20 | Hercules Stock Exchange|Japan|JP|NJM||| 21 | JASDAQ Securities Exchange|Japan|JP|JSD||XJAS|XJPX 22 | Nagoya Stock Exchange|Japan|JP|NAG||XNGO|XNGO 23 | Osaka Securities Exchange|Japan|JP|OSA||XOSE|XJPX 24 | Sapporo Securities Exchange|Japan|JP|||XSAP|XSAP 25 | Tokyo Stock Exchange|Japan|JP|TYO||XTAM|XJPX 26 | Korea Stock Exchange|Korea, Republic of|KR|KRX|.KS|XKRX|XKRX 27 | KOSDAQ|Korea, Republic of|KR|KDQ|.KQ|XKOS|XKRX 28 | Malaysia Exchange|Malaysia|MY|KUL|.KL|XKLS|XKLS 29 | New Zealand Exchange|New Zealand|NZ|NZE|.NZ|XNZE|XNZE 30 | Karachi Stock Exchange|Pakistan|PK|KAR||| 31 | Lahore Stock Exchange|Pakistan|PK|Lah||| 32 | Philippine Stock Exchange|Philippines|PH|PSE||XPHS|XPHS 33 | Singapore Exchange|Singapore|SG|SGX|.SI|XSES|XSES 34 | Saudi Stock Exchange|Saudi Arabia|SA|TADAWUL||XSAU|XSAU 35 | Colombo Stock Exchange|Sri Lanka|LK|COL||XCOL|XCOL 36 | GreTai Securities Market|Taiwan||||| 37 | Taiwan Stock Exchange|Taiwan||TPE|.TW|XTAI|XTAI 38 | Stock Exchange of Thailand|Thailand|TH|BKK||XBKK|XBKK 39 | Ho Chi Minh Stock Exchange|Vietnam||||HSTC|HSTC 40 | Vienna Stock Exchange|Austria|AT|VIE|.VI|| 41 | Euronext - Brussels|Belgium|BE|EBR|.BR|XBRU|XBRU 42 | Bulgarian Stock Exchange|Bulgaria|BG|BUL||XBUL|XBUL 43 | Zagreb Stock Exchange|Croatia|HR|ZSE||XZAG|XZAG 44 | Cyprus Stock Exchange|Cyprus|CY|CSE||XCYS|XCYS 45 | Prague Stock Exchange|Czech Republic|CZ|PRG||XPRA|XPRA 46 | OMX Nordic Exchange - Copenhagen|Denmark|DK|CPH||| 47 | GXG Markets|Denmark|DK|AMP||GXGR|GXGR 48 | OMX Baltic Exchange - Tallinn|Estonia|EE|TAL||| 49 | OMX Nordic Exchange - Helsinki|Finland|FI|HEL||| 50 | Euronext - Paris|France|FR|EPA|.PA|| 51 | Berlin Stock Exchange|Germany|DE|BER|.BE|| 52 | XETRA|Germany|DE|ETR|.DE|XETR|XETR 53 | Dusseldorf Stock Exchange|Germany|DE|||| 54 | Frankfurt Stock Exchange|Germany|DE|FRA|.F|| 55 | Munich Stock Exchange|Germany|DE|||| 56 | Stuttgart Stock Exchange|Germany|DE|STU|.SG|| 57 | Athens Exchange|Greece|GR|ATH||AAPA|AAPA 58 | Budapest Stock Exchange|Hungary|HU|BDP||XBUD|XBUD 59 | Irish Stock Exchange|Ireland|IE|ISE|.IR|XDUB|XDUB 60 | NASDAQ OMX Iceland|Iceland|IS|ICE||| 61 | Borsa Italiana|Italy|IT|BIT|.MI|XMIL|XMIL 62 | OMX Baltic Exchange - Riga|Latvia|LV|RSE||| 63 | OMX Baltic Exchange - Vilnius|Lithuania|LT|VSE||| 64 | Luxembourg Stock Exchange|Luxembourg|LU|LUX||XLUX|XLUX 65 | Macedonian Stock Exchange|Macedonia||MSE||XMAE|XMAE 66 | Euronext - Amsterdam|Netherlands|NL|AMS|.AS|| 67 | Oslo Stock Exchange|Norway|NO|OSL|.OL|| 68 | Warsaw Stock Exchange|Poland|PL|WAR||XWAR|XWAR 69 | Euronext - Lisbon|Portugal|PT|ELI|.LS|| 70 | Bucharest Stock Exchange|Romania|RO|BSE||| 71 | Sibex-Sibiu Stock Exchange|Romania|RO|SBX||| 72 | Russian Trading System|Russia||RTC||| 73 | Moscow Interbank Currency Exchange|Russia||||| 74 | Warsaw Stock Exchange|Poland|PL|WSE||XWAR|XWAR 75 | Moscow Exchange|Russia||MCX||MISX|MISX 76 | Bratislava Stock Exchange|Slovakia|SK|||XBRA|XBRA 77 | Ljubljana Stock Exchange|Slovenia|SI|LJE||XLJU|XLJU 78 | Barcelona Stock Exchange|Spain|ES|BCN||| 79 | Spanish Stock Exchange|Spain|ES|BME||| 80 | Madrid Stock Exchange|Spain|ES|MCE|.MA|| 81 | OMX Nordic Exchange - Stockholm|Sweden|SE|STO||| 82 | Berne eXchange|Switzerland|CH|BRN||| 83 | SIX Swiss Exchange|Switzerland|CH|SWX|.VX|XSWX|XSWX 84 | Swiss Europe|Switzerland|CH|VTX|.VX|| 85 | Istanbul Stock Exchange|Turkey|TR|IST||| 86 | London Stock Exchange|United Kingdom|GB|LON|.L|ECHO|ECHO 87 | PLUS Markets Group|United Kingdom|GB|OFEX||| 88 | Bahrain Stock Exchange|Bahrain|BH|BSH||| 89 | Egyptian Stock Exchange|Egypt|EG|CAI||| 90 | Cairo & Alexandria Stock Exchange|Egypt|EG|||| 91 | Tel Aviv Stock Exchange|Israel|IL|TLV|.TA|XTAE|XTAE 92 | Amman Stock Exchange|Jordan|JO|AFM||XAMM|XAMM 93 | Beirut Stock Exchange|Lebanon|LB|BEY||XBEY|XBEY 94 | Palestine Securities Exchange|Palestine||PAS||XPAE|XPAE 95 | NASDAQ Dubai|United Arab Emirates|AE|DFM||DIFX|DIFX 96 | Damascus Securities Exchange|Syria||DSE||XDSE|XDSE 97 | Bermuda Stock Exchange|Bermuda|BM|BSX||XBDA|XBDA 98 | Canada National Stock Exchange|Canada|CA|CNSX||| 99 | Toronto Stock Exchange|Canada|CA|TSE|.TO|XTSE|XTSE 100 | TSX Venture Exchange|Canada|CA|CVE|.V|XTSX|XTSX 101 | American Stock Exchange|United States|US|NYSEAMEX||| 102 | NYSE Markets|United States|US|NYSEMKT||| 103 | NASDAQ OMX BX|United States|US|NASDAQ||XBXO|XNAS 104 | Chicago Stock Exchange|United States|US|||XCHI|XCHI 105 | NASDAQ|United States|US|NASDAQ||XARM|XARM 106 | National Stock Exchange|United States|US|||XNEC|XNEC 107 | New York Stock Exchange|United States|US|NYSE||XNYS|XNYS 108 | NYSE Arca Stock Exchange|United States|US|NYSEARCA||ARCX|XNYS 109 | NASDAQ OMX PHLX|United States|US|NASDAQ||XPHL|XNAS 110 | Buenos Aires Stock Exchange|Argentina|AR|BCBA||| 111 | Bovespa Stock Exchange|Brazil|BR|BVMF||| 112 | Mexico Stock Exchange|Mexico|MX||.MX|XMEX|XMEX 113 | -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # Configuration file for the Sphinx documentation builder. 4 | # 5 | # This file does only contain a selection of the most common options. For a 6 | # full list see the documentation: 7 | # http://www.sphinx-doc.org/en/stable/config 8 | 9 | # -- Path setup -------------------------------------------------------------- 10 | 11 | # If extensions (or modules to document with autodoc) are in another directory, 12 | # add these directories to sys.path here. If the directory is relative to the 13 | # documentation root, use os.path.abspath to make it absolute, like shown here. 14 | # 15 | # import os 16 | # import sys 17 | # sys.path.insert(0, os.path.abspath('.')) 18 | 19 | 20 | # -- Project information ----------------------------------------------------- 21 | 22 | project = 'comp-match' 23 | copyright = '2018, franklingu' 24 | author = 'franklingu' 25 | 26 | # The short X.Y version 27 | version = '' 28 | # The full version, including alpha/beta/rc tags 29 | release = '0.0.0.dev' 30 | 31 | 32 | # -- General configuration --------------------------------------------------- 33 | 34 | # If your documentation needs a minimal Sphinx version, state it here. 35 | # 36 | # needs_sphinx = '1.0' 37 | 38 | # Add any Sphinx extension module names here, as strings. They can be 39 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 40 | # ones. 41 | extensions = [ 42 | 'sphinx.ext.autodoc', 43 | 'sphinx.ext.intersphinx', 44 | 'sphinx.ext.todo', 45 | 'sphinx.ext.coverage', 46 | 'sphinx.ext.ifconfig', 47 | 'sphinx.ext.githubpages', 48 | ] 49 | 50 | # Add any paths that contain templates here, relative to this directory. 51 | templates_path = ['_templates'] 52 | 53 | # The suffix(es) of source filenames. 54 | # You can specify multiple suffix as a list of string: 55 | # 56 | # source_suffix = ['.rst', '.md'] 57 | source_suffix = '.rst' 58 | 59 | # The master toctree document. 60 | master_doc = 'index' 61 | 62 | # The language for content autogenerated by Sphinx. Refer to documentation 63 | # for a list of supported languages. 64 | # 65 | # This is also used if you do content translation via gettext catalogs. 66 | # Usually you set "language" from the command line for these cases. 67 | language = None 68 | 69 | # List of patterns, relative to source directory, that match files and 70 | # directories to ignore when looking for source files. 71 | # This pattern also affects html_static_path and html_extra_path . 72 | exclude_patterns = [] 73 | 74 | # The name of the Pygments (syntax highlighting) style to use. 75 | pygments_style = 'sphinx' 76 | 77 | 78 | # -- Options for HTML output ------------------------------------------------- 79 | 80 | # The theme to use for HTML and HTML Help pages. See the documentation for 81 | # a list of builtin themes. 82 | # 83 | html_theme = 'alabaster' 84 | 85 | # Theme options are theme-specific and customize the look and feel of a theme 86 | # further. For a list of options available for each theme, see the 87 | # documentation. 88 | # 89 | # html_theme_options = {} 90 | 91 | # Add any paths that contain custom static files (such as style sheets) here, 92 | # relative to this directory. They are copied after the builtin static files, 93 | # so a file named "default.css" will overwrite the builtin "default.css". 94 | html_static_path = ['_static'] 95 | 96 | # Custom sidebar templates, must be a dictionary that maps document names 97 | # to template names. 98 | # 99 | # The default sidebars (for documents that don't match any pattern) are 100 | # defined by theme itself. Builtin themes are using these templates by 101 | # default: ``['localtoc.html', 'relations.html', 'sourcelink.html', 102 | # 'searchbox.html']``. 103 | # 104 | # html_sidebars = {} 105 | 106 | 107 | # -- Options for HTMLHelp output --------------------------------------------- 108 | 109 | # Output file base name for HTML help builder. 110 | htmlhelp_basename = 'comp-matchdoc' 111 | 112 | 113 | # -- Options for LaTeX output ------------------------------------------------ 114 | 115 | latex_elements = { 116 | # The paper size ('letterpaper' or 'a4paper'). 117 | # 118 | # 'papersize': 'letterpaper', 119 | 120 | # The font size ('10pt', '11pt' or '12pt'). 121 | # 122 | # 'pointsize': '10pt', 123 | 124 | # Additional stuff for the LaTeX preamble. 125 | # 126 | # 'preamble': '', 127 | 128 | # Latex figure (float) alignment 129 | # 130 | # 'figure_align': 'htbp', 131 | } 132 | 133 | # Grouping the document tree into LaTeX files. List of tuples 134 | # (source start file, target name, title, 135 | # author, documentclass [howto, manual, or own class]). 136 | latex_documents = [ 137 | (master_doc, 'comp-match.tex', 'comp-match Documentation', 138 | 'franklingu', 'manual'), 139 | ] 140 | 141 | 142 | # -- Options for manual page output ------------------------------------------ 143 | 144 | # One entry per manual page. List of tuples 145 | # (source start file, name, description, authors, manual section). 146 | man_pages = [ 147 | (master_doc, 'comp-match', 'comp-match Documentation', 148 | [author], 1) 149 | ] 150 | 151 | 152 | # -- Options for Texinfo output ---------------------------------------------- 153 | 154 | # Grouping the document tree into Texinfo files. List of tuples 155 | # (source start file, target name, title, author, 156 | # dir menu entry, description, category) 157 | texinfo_documents = [ 158 | (master_doc, 'comp-match', 'comp-match Documentation', 159 | author, 'comp-match', 'One line description of project.', 160 | 'Miscellaneous'), 161 | ] 162 | 163 | 164 | # -- Options for Epub output ------------------------------------------------- 165 | 166 | # Bibliographic Dublin Core info. 167 | epub_title = project 168 | epub_author = author 169 | epub_publisher = author 170 | epub_copyright = copyright 171 | 172 | # The unique identifier of the text. This can be a ISBN number 173 | # or the project homepage. 174 | # 175 | # epub_identifier = '' 176 | 177 | # A unique identification for the text. 178 | # 179 | # epub_uid = '' 180 | 181 | # A list of files that should not be packed into the epub file. 182 | epub_exclude_files = ['search.html'] 183 | 184 | 185 | # -- Extension configuration ------------------------------------------------- 186 | 187 | # -- Options for intersphinx extension --------------------------------------- 188 | 189 | # Example configuration for intersphinx: refer to the Python standard library. 190 | intersphinx_mapping = {'https://docs.python.org/': None} 191 | 192 | # -- Options for todo extension ---------------------------------------------- 193 | 194 | # If true, `todo` and `todoList` produce output, else they produce nothing. 195 | todo_include_todos = True -------------------------------------------------------------------------------- /comp_match/open_calais.py: -------------------------------------------------------------------------------- 1 | """match company names to tickers 2 | """ 3 | import random 4 | import time 5 | 6 | import requests 7 | from lxml import etree 8 | 9 | from ._utils import get_logger 10 | from .base import BaseNameMatcher, CompanyUnderline 11 | 12 | 13 | class OpenCalaisNameMatcher( # pylint: disable=too-few-public-methods 14 | BaseNameMatcher): 15 | """Match company names to underlines via OpenCalais 16 | """ 17 | AGENT = 'open_calais' 18 | 19 | def __init__(self, access_token=None): 20 | super(OpenCalaisNameMatcher, self).__init__() 21 | if access_token is None: 22 | access_token = '2Uqpdme4VlbUp46wQYxGJoGcw1GpPFpW' 23 | self.access_token = access_token 24 | 25 | def _get_headers(self): 26 | return { 27 | 'X-AG-Access-Token': self.access_token, 28 | 'Content-Type': 'text/raw', 29 | 'outputformat': 'xml/rdf' 30 | } 31 | 32 | def _match_by(self, names, **kwargs): 33 | names = list(names) 34 | retry = int(kwargs.pop('retry', 5)) 35 | sleep = int(kwargs.pop('sleep', 30)) 36 | end, curr, step = len(names), 0, 50 37 | ret = {} 38 | while curr < end: 39 | range_end = curr + step if curr + step < end else end 40 | curr_names = names[curr:range_end] 41 | match_res = self._match_for_names( 42 | curr_names, retry=retry, sleep=sleep 43 | ) 44 | if match_res: 45 | ret.update(match_res) 46 | curr = range_end 47 | return ret 48 | 49 | def _match_for_names(self, names, retry=5, sleep=30): 50 | content = ''.join( 51 | ('{} is a public company\r\n').format(name) for name in names 52 | ).encode('utf-8') 53 | link = 'https://api.thomsonreuters.com/permid/calais' 54 | for retry_num in range(retry): 55 | try: 56 | res = requests.post( 57 | link, data=content, headers=self._get_headers(), 58 | timeout=sleep + 3 59 | ) 60 | res_content = res.content 61 | break 62 | except Exception as err: # pylint: disable=broad-except 63 | get_logger().debug( 64 | 'Exception during requesting opencalais: %s', str(err) 65 | ) 66 | if retry_num == retry - 1: 67 | pass 68 | else: 69 | time.sleep(random.random() * sleep + sleep * retry_num) 70 | raw_matches = self._process_rdf_response(res_content) 71 | ret_data = {} 72 | for _, raw_match in raw_matches.items(): 73 | orig_name, legal_name, ric, ticker, permid, score = raw_match 74 | ret_data[orig_name] = [( 75 | legal_name, 76 | self._match_to_underline( 77 | ticker, permid, retry=retry, sleep=sleep 78 | ), 79 | {'score': score, 'ric': ric} 80 | )] 81 | return ret_data 82 | 83 | def _process_rdf_response(self, res_content): # pylint: disable=no-self-use 84 | """Parse rdf file from open calais 85 | """ 86 | rdf = etree.fromstring(res_content) 87 | match = {} 88 | match_top = {} 89 | top_most_type = ( 90 | 'http://s.opencalais.com/1/type/er/TopmostPublicParentCompany' 91 | ) 92 | raw = {} 93 | raw_top = {} 94 | descs = rdf.xpath('rdf:Description', namespaces=rdf.nsmap) 95 | names = [ 96 | './c:exact', './c:name', './c:primaryric', './c:ticker', 97 | './c:permid', './c:score' 98 | ] 99 | for desc in descs: 100 | subjs = desc.xpath( 101 | './c:subject/@rdf:resource', namespaces=rdf.nsmap 102 | ) 103 | rtype = desc.xpath( 104 | './rdf:type/@rdf:resource', namespaces=rdf.nsmap 105 | ) 106 | if not subjs: 107 | continue 108 | else: 109 | # take only the first subject 110 | subj = subjs[0] 111 | if not subj.startswith('http://d.opencalais.com/comphash'): 112 | continue 113 | if subj not in raw: 114 | raw[subj] = {} 115 | raw_top[subj] = {} 116 | for xpath in names: 117 | elems = desc.xpath(xpath, namespaces=rdf.nsmap) 118 | if elems: 119 | if rtype and rtype[0] == top_most_type: 120 | raw_top[subj][xpath] = elems[0].text 121 | else: 122 | raw[subj][xpath] = elems[0].text 123 | for subj, elem in raw.items(): 124 | if not elem: 125 | continue 126 | row = [elem.get(name, '') for name in names] 127 | match[elem['./c:exact']] = row 128 | for subj, elem in raw_top.items(): 129 | if not elem: 130 | continue 131 | raw_elem = raw.get(subj, {}) 132 | row = [ 133 | elem.get(name, '') 134 | if name != './c:exact' else raw_elem.get(name, '') 135 | for name in names 136 | ] 137 | if not raw_elem: 138 | continue 139 | match_top[raw_elem['./c:exact']] = row 140 | ret = {} 141 | ret.update(match_top) 142 | for exact_name, match_row in match.items(): 143 | if exact_name not in ret: 144 | ret[exact_name] = match_row 145 | continue 146 | # only overwrite if match_row ric is not empty 147 | if match_row[3]: 148 | ret[exact_name] = match_row 149 | return ret 150 | 151 | def _match_to_underline(self, ticker, permid, retry=5, sleep=30): 152 | root_link = 'https://permid.org/1-{}'.format(permid) 153 | link = 'https://permid.org/api/mdaas/getEntityById/{}'.format(permid) 154 | headers = self._get_headers() 155 | del headers['Content-Type'] 156 | del headers['outputformat'] 157 | with requests.Session() as session: 158 | try: 159 | session.get(root_link, timeout=sleep + 3) 160 | except Exception: # pylint: disable=broad-except 161 | pass 162 | for retry_num in range(retry): 163 | try: 164 | res = session.get( 165 | link, headers=headers, timeout=sleep + 3 166 | ) 167 | res_obj = res.json() 168 | for quote in res_obj['mainQuoteId.mdaas']: 169 | mic = quote.get('Primary Mic', [''])[0] 170 | underline = CompanyUnderline(ticker=ticker, mic=mic) 171 | return underline 172 | except Exception as err: # pylint: disable=broad-except 173 | get_logger().debug( 174 | 'Exception during requesting opencalais: %s', str(err) 175 | ) 176 | if retry_num == retry - 1: 177 | pass 178 | else: 179 | time.sleep(random.random() * sleep + sleep * retry_num) 180 | -------------------------------------------------------------------------------- /tests/resources/oc_google.json: -------------------------------------------------------------------------------- 1 | {"IPO date":["2004-08-19T04:00:00Z"],"Domiciled in":["United States"],"Incorporated in":["United States"],"Public":["true"],"Latest Date of Incorporation":["2015-07-23T00:00:00.000Z"],"Organization Name":["Alphabet Inc"],"PERM ID":["5030853586"],"Status":["Active"],"Website":["https:\/\/abc.xyz\/"],"primaryInstrument.mdaas":[{"Main Instrument Name":["Alphabet Ord Shs Class A"],"Main instrument type":["Ordinary Shares"],"Main instrument type URL":["https:\/\/permid.org\/1-300281"],"URL":["https:\/\/permid.org\/1-8590925559"]}],"LEI":["5493006MHB84DD0ZWV18"],"mainQuoteId.mdaas":[{"Primary RIC":["GOOGL.OQ"],"Primary Mic":["XNGS"],"Primary Ticker":["GOOGL"],"Primary Exchange":["NSM"],"URL":["https:\/\/permid.org\/1-55835340529"]}],"entityType":["Organization"],"Additional Info":[{"Person URL":["https:\/\/permid.org\/1-34414328620"],"Honorific prefix":["Mr."],"Given name":["Sundar"],"Family name":["Pichai"],"hasReportedTitle.person":["Director, Chief Executive Officer, Google Inc."],"Position URL":["https:\/\/permid.org\/1-10010134"],"Position Type":["Director"],"Position Rank":[82],"Position Start Date":["2017"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34413413072"],"Honorific prefix":["Dr."],"Given name":["John"],"Middle name":["L."],"Family name":["Hennessy"],"Honorific suffix":["Ph.D."],"hasReportedTitle.person":["Chairman of the Board"],"Position URL":["https:\/\/permid.org\/1-10010076"],"Position Type":["Chairman"],"Position Rank":[1],"Position Start Date":["2018"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34413413072"],"Honorific prefix":["Dr."],"Given name":["John"],"Middle name":["L."],"Family name":["Hennessy"],"Honorific suffix":["Ph.D."],"hasReportedTitle.person":["Chairman of the Board"],"Position URL":["https:\/\/permid.org\/1-10010134"],"Position Type":["Director"],"Position Rank":[82],"Position Start Date":["2018"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34413413065"],"Honorific prefix":["Mr."],"Given name":["Sergey"],"Family name":["Brin"],"hasReportedTitle.person":["President, Director"],"Position URL":["https:\/\/permid.org\/1-10010115"],"Position Type":["President"],"Position Rank":[6],"Position Start Date":["2015"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34414072361"],"Honorific prefix":["Mr."],"Given name":["Lawrence"],"Middle name":["E."],"Family name":["Page"],"Preferred name":["Larry"],"hasReportedTitle.person":["Chief Executive Officer, Director"],"Position URL":["https:\/\/permid.org\/1-10010134"],"Position Type":["Director"],"Position Rank":[82],"Position Start Date":["2015"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34413603348"],"Honorific prefix":["Dr."],"Given name":["Roger"],"Middle name":["W."],"Family name":["Ferguson"],"Honorific suffix":["Jr."],"hasReportedTitle.person":["Independent Director"],"Position URL":["https:\/\/permid.org\/1-10010135"],"Position Type":["Independent Director"],"Position Rank":[84],"Position Start Date":["2016"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34413960665"],"Honorific prefix":["Ms."],"Given name":["Ruth"],"Middle name":["M."],"Family name":["Porat"],"hasReportedTitle.person":["Chief Financial Officer, Senior Vice President"],"Position URL":["https:\/\/permid.org\/1-10010075"],"Position Type":["Chief Financial Officer"],"Position Rank":[23],"Position Start Date":["2015"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34413413065"],"Honorific prefix":["Mr."],"Given name":["Sergey"],"Family name":["Brin"],"hasReportedTitle.person":["President, Director"],"Position URL":["https:\/\/permid.org\/1-10010134"],"Position Type":["Director"],"Position Rank":[82],"Position Start Date":["2015"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34413409783"],"Honorific prefix":["Ms."],"Given name":["Ann"],"Family name":["Mather"],"hasReportedTitle.person":["Independent Director"],"Position URL":["https:\/\/permid.org\/1-10010135"],"Position Type":["Independent Director"],"Position Rank":[84],"Position Start Date":["2005"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34414328620"],"Honorific prefix":["Mr."],"Given name":["Sundar"],"Family name":["Pichai"],"hasReportedTitle.person":["Director, Chief Executive Officer, Google Inc."],"Position URL":["https:\/\/permid.org\/1-10010074"],"Position Type":["Corporate Executive"],"Position Rank":[25],"Position Start Date":["2017"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34413960665"],"Honorific prefix":["Ms."],"Given name":["Ruth"],"Middle name":["M."],"Family name":["Porat"],"hasReportedTitle.person":["Chief Financial Officer, Senior Vice President"],"Position URL":["https:\/\/permid.org\/1-10010122"],"Position Type":["Senior Vice President"],"Position Rank":[31],"Position Start Date":["2015"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34413157809"],"Honorific prefix":["Mr."],"Given name":["Paul"],"Middle name":["S."],"Family name":["Otellini"],"hasReportedTitle.person":["Independent Director"],"Position URL":["https:\/\/permid.org\/1-10010135"],"Position Type":["Independent Director"],"Position Rank":[84],"Position Start Date":["2004"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34413413063"],"Honorific prefix":["Dr."],"Given name":["Eric"],"Middle name":["E."],"Family name":["Schmidt"],"Honorific suffix":["Ph.D."],"hasReportedTitle.person":["Director"],"Position URL":["https:\/\/permid.org\/1-10010134"],"Position Type":["Director"],"Position Rank":[82],"Position Start Date":["2018"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34415682785"],"Honorific prefix":["Mr."],"Given name":["Kavitark"],"Middle name":["Ram"],"Family name":["Shriram"],"hasReportedTitle.person":["Independent Director"],"Position URL":["https:\/\/permid.org\/1-10010135"],"Position Type":["Independent Director"],"Position Rank":[84],"Position Start Date":["1998"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34413213793"],"Honorific prefix":["Mr."],"Given name":["L. John"],"Family name":["Doerr"],"hasReportedTitle.person":["Independent Director"],"Position URL":["https:\/\/permid.org\/1-10010135"],"Position Type":["Independent Director"],"Position Rank":[84],"Position Start Date":["2016"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34413198664"],"Honorific prefix":["Mr."],"Given name":["David"],"Middle name":["C."],"Family name":["Drummond"],"hasReportedTitle.person":["Senior Vice President - Corporate Development, Chief Legal Officer, Secretary"],"Position URL":["https:\/\/permid.org\/1-10010122"],"Position Type":["Senior Vice President"],"Position Rank":[31],"Position Start Date":["2015"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34413485708"],"Honorific prefix":["Ms."],"Given name":["Diane"],"Middle name":["B."],"Family name":["Greene"],"hasReportedTitle.person":["Director"],"Position URL":["https:\/\/permid.org\/1-10010134"],"Position Type":["Director"],"Position Rank":[82],"Position Start Date":["2015"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34413176896"],"Honorific prefix":["Mr."],"Given name":["Alan"],"Middle name":["R."],"Family name":["Mulally"],"hasReportedTitle.person":["Independent Director"],"Position URL":["https:\/\/permid.org\/1-10010135"],"Position Type":["Independent Director"],"Position Rank":[84],"Position Start Date":["2014"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34414072361"],"Honorific prefix":["Mr."],"Given name":["Lawrence"],"Middle name":["E."],"Family name":["Page"],"Preferred name":["Larry"],"hasReportedTitle.person":["Chief Executive Officer, Director"],"Position URL":["https:\/\/permid.org\/1-10010073"],"Position Type":["Chief Executive Officer"],"Position Rank":[8],"Position Start Date":["2015"],"entityType":["Professional"]}]} 2 | -------------------------------------------------------------------------------- /tests/resources/oc_apple.json: -------------------------------------------------------------------------------- 1 | {"IPO date":["1980-12-12T05:00:00Z"],"Domiciled in":["United States"],"Incorporated in":["United States"],"Public":["true"],"Latest Date of Incorporation":["1977-01-03T00:00:00.000Z"],"Organization Name":["Apple Inc"],"PERM ID":["4295905573"],"Status":["Active"],"Website":["https:\/\/www.apple.com\/"],"HQ Address":["1 Apple Park Way\nCUPERTINO\nCALIFORNIA\n95014-0642\nUnited States\n"],"Registered Address":["818 W 7th St Ste 930\nLOS ANGELES\nCALIFORNIA\n90017-3476\nUnited States\n"],"HQ Phone":["14089961010"],"Primary industry":["Computers, Phones & Household Electronics"],"Primary Industry ID":["4294952719"],"Primary Business Sector":["Technology Equipment"],"Primary Business Sector ID":["4294952722"],"Primary Economic Sector":["Technology"],"Primary Economic Sector ID":["4294952723"],"primaryInstrument.mdaas":[{"Main Instrument":["8590932301"],"Main Instrument URL":["https:\/\/permid.org\/1-8590932301"],"Main Instrument Name":["Apple Ord Shs"],"Main instrument type":["Ordinary Shares"],"Main instrument type URL":["https:\/\/permid.org\/1-300281"],"URL":["https:\/\/permid.org\/1-8590932301"]}],"LEI":["HWUPKR0MPOU8FGXBT394"],"mainQuoteId.mdaas":[{"Main Quote":["55835312773"],"Main Quote URL":["https:\/\/permid.org\/1-55835312773"],"Primary RIC":["AAPL.OQ"],"Primary Mic":["XNGS"],"Primary Ticker":["AAPL"],"Primary Exchange":["NSM"],"URL":["https:\/\/permid.org\/1-55835312773"]}],"entityType":["Organization"],"Additional Info":[{"Person URL":["https:\/\/permid.org\/1-34416235455"],"Honorific prefix":["Ms."],"Given name":["Andrea"],"Family name":["Jung"],"hasReportedTitle.person":["Independent Director"],"Position URL":["https:\/\/permid.org\/1-10010135"],"Position Type":["Independent Director"],"Position Rank":[84],"Position Start Date":["2008"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34413343859"],"Honorific prefix":["Mr."],"Given name":["Phil"],"Family name":["Schiller"],"hasReportedTitle.person":["Senior Vice President - Worldwide Marketing"],"Position URL":["https:\/\/permid.org\/1-10010122"],"Position Type":["Senior Vice President"],"Position Rank":[31],"Position Start Date":["2002"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34421597583"],"Honorific prefix":["Mr."],"Given name":["Johny"],"Family name":["Srouji"],"hasReportedTitle.person":["Senior Vice President - Hardware Technologies"],"Position URL":["https:\/\/permid.org\/1-10010122"],"Position Type":["Senior Vice President"],"Position Rank":[31],"Position Start Date":["2015"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34413343859"],"Honorific prefix":["Mr."],"Given name":["Phil"],"Family name":["Schiller"],"hasReportedTitle.person":["Senior Vice President - Worldwide Marketing"],"Position URL":["https:\/\/permid.org\/1-10010096"],"Position Type":["Director of Marketing"],"Position Rank":[69],"Position Start Date":["2002"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34423763407"],"Honorific prefix":["Ms."],"Given name":["Katherine"],"Family name":["Adams"],"Preferred name":["Kate"],"hasReportedTitle.person":["Senior Vice President, General Counsel"],"Position URL":["https:\/\/permid.org\/1-10010104"],"Position Type":["General Counsel"],"Position Rank":[51],"Position Start Date":["2017"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34415690850"],"Honorific prefix":["Mr."],"Given name":["Eddy"],"Family name":["Cue"],"hasReportedTitle.person":["Senior Vice President - Internet Software and Services"],"Position URL":["https:\/\/permid.org\/1-10010122"],"Position Type":["Senior Vice President"],"Position Rank":[31],"Position Start Date":["2011"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34415678026"],"Honorific prefix":["Dr."],"Given name":["Ronald"],"Middle name":["D."],"Family name":["Sugar"],"Honorific suffix":["Ph.D."],"Preferred name":["Ron"],"hasReportedTitle.person":["Independent Director"],"Position URL":["https:\/\/permid.org\/1-10010135"],"Position Type":["Independent Director"],"Position Rank":[84],"Position Start Date":["2010"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34423763407"],"Honorific prefix":["Ms."],"Given name":["Katherine"],"Family name":["Adams"],"Preferred name":["Kate"],"hasReportedTitle.person":["Senior Vice President, General Counsel"],"Position URL":["https:\/\/permid.org\/1-10010122"],"Position Type":["Senior Vice President"],"Position Rank":[31],"Position Start Date":["2017"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34413413073"],"Honorific prefix":["Dr."],"Given name":["Art"],"Middle name":["D."],"Family name":["Levinson"],"Honorific suffix":["Ph.D."],"hasReportedTitle.person":["Independent Chairman of the Board"],"Position URL":["https:\/\/permid.org\/1-10010134"],"Position Type":["Director"],"Position Rank":[82],"Position Start Date":["2011"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34413400240"],"Honorific prefix":["Mr."],"Given name":["Craig"],"Family name":["Federighi"],"hasReportedTitle.person":["Senior Vice President - Software Engineering"],"Position URL":["https:\/\/permid.org\/1-10010122"],"Position Type":["Senior Vice President"],"Position Rank":[31],"Position Start Date":["2012"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34414554748"],"Honorific prefix":["Mr."],"Given name":["Luca"],"Family name":["Maestri"],"hasReportedTitle.person":["Chief Financial Officer, Senior Vice President"],"Position URL":["https:\/\/permid.org\/1-10010075"],"Position Type":["Chief Financial Officer"],"Position Rank":[23],"Position Start Date":["2014"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34413199178"],"Honorific prefix":["Mr."],"Given name":["Timothy"],"Middle name":["D."],"Family name":["Cook"],"Preferred name":["Tim"],"hasReportedTitle.person":["Chief Executive Officer, Director"],"Position URL":["https:\/\/permid.org\/1-10010073"],"Position Type":["Chief Executive Officer"],"Position Rank":[8],"Position Start Date":["2011"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34421511525"],"Honorific prefix":["Mr."],"Given name":["James"],"Middle name":["A."],"Family name":["Bell"],"hasReportedTitle.person":["Independent Director"],"Position URL":["https:\/\/permid.org\/1-10010135"],"Position Type":["Independent Director"],"Position Rank":[84],"Position Start Date":["2015"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34415747009"],"Honorific prefix":["Mr."],"Given name":["Jeffrey"],"Middle name":["E"],"Family name":["Williams"],"hasReportedTitle.person":["Chief Operating Officer, Senior Vice President"],"Position URL":["https:\/\/permid.org\/1-10010122"],"Position Type":["Senior Vice President"],"Position Rank":[31],"Position Start Date":["2015"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34415747009"],"Honorific prefix":["Mr."],"Given name":["Jeffrey"],"Middle name":["E"],"Family name":["Williams"],"hasReportedTitle.person":["Chief Operating Officer, Senior Vice President"],"Position URL":["https:\/\/permid.org\/1-10010082"],"Position Type":["Chief Operating Officer"],"Position Rank":[26],"Position Start Date":["2015"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34413199178"],"Honorific prefix":["Mr."],"Given name":["Timothy"],"Middle name":["D."],"Family name":["Cook"],"Preferred name":["Tim"],"hasReportedTitle.person":["Chief Executive Officer, Director"],"Position URL":["https:\/\/permid.org\/1-10010134"],"Position Type":["Director"],"Position Rank":[82],"Position Start Date":["2011"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34413189969"],"Honorific prefix":["Mr."],"Given name":["Robert"],"Middle name":["A."],"Family name":["Iger"],"Preferred name":["Bob"],"hasReportedTitle.person":["Independent Director"],"Position URL":["https:\/\/permid.org\/1-10010135"],"Position Type":["Independent Director"],"Position Rank":[84],"Position Start Date":["2011"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34414554748"],"Honorific prefix":["Mr."],"Given name":["Luca"],"Family name":["Maestri"],"hasReportedTitle.person":["Chief Financial Officer, Senior Vice President, Principal Accounting Officer"],"Position URL":["https:\/\/permid.org\/1-10010122"],"Position Type":["Senior Vice President"],"Position Rank":[31],"Position Start Date":["2014"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34413413073"],"Honorific prefix":["Dr."],"Given name":["Art"],"Middle name":["D."],"Family name":["Levinson"],"Honorific suffix":["Ph.D."],"hasReportedTitle.person":["Independent Chairman of the Board"],"Position URL":["https:\/\/permid.org\/1-10010134"],"Position Type":["Independent Director"],"Position Rank":[84],"Position Start Date":["2011"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34413413073"],"Honorific prefix":["Dr."],"Given name":["Art"],"Middle name":["D."],"Family name":["Levinson"],"Honorific suffix":["Ph.D."],"hasReportedTitle.person":["Independent Chairman of the Board"],"Position URL":["https:\/\/permid.org\/1-10010076"],"Position Type":["Chairman"],"Position Rank":[1],"Position Start Date":["2011"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34413350616"],"Honorific prefix":["Mr."],"Given name":["AI"],"Middle name":["A."],"Family name":["Gore"],"hasReportedTitle.person":["Independent Director"],"Position URL":["https:\/\/permid.org\/1-10010135"],"Position Type":["Independent Director"],"Position Rank":[84],"Position Start Date":["2003"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34417231543"],"Honorific prefix":["Ms."],"Given name":["Sue"],"Family name":["Wagner"],"hasReportedTitle.person":["Independent Director"],"Position URL":["https:\/\/permid.org\/1-10010135"],"Position Type":["Independent Director"],"Position Rank":[84],"Position Start Date":["2014"],"entityType":["Directorship"]},{"Person URL":["https:\/\/permid.org\/1-34414955340"],"Honorific prefix":["Mr."],"Given name":["Daniel"],"Middle name":["J."],"Family name":["Riccio"],"Honorific suffix":["Jr."],"Preferred name":["Dan"],"hasReportedTitle.person":["Senior Vice President - Hardware Engineering"],"Position URL":["https:\/\/permid.org\/1-10010122"],"Position Type":["Senior Vice President"],"Position Rank":[31],"Position Start Date":["2012"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34414032638"],"Honorific prefix":["Ms."],"Given name":["Angela"],"Middle name":["J."],"Family name":["Ahrendts"],"hasReportedTitle.person":["Senior Vice President - Retail"],"Position URL":["https:\/\/permid.org\/1-10010122"],"Position Type":["Senior Vice President"],"Position Rank":[31],"Position Start Date":["2014"],"entityType":["Professional"]},{"Person URL":["https:\/\/permid.org\/1-34414554748"],"Honorific prefix":["Mr."],"Given name":["Luca"],"Family name":["Maestri"],"hasReportedTitle.person":["Chief Financial Officer, Senior Vice President"],"Position URL":["https:\/\/permid.org\/1-10010122"],"Position Type":["Senior Vice President"],"Position Rank":[31],"Position Start Date":["2014"],"entityType":["Professional"]}]} -------------------------------------------------------------------------------- /tests/resources/oc_apple.rdf: -------------------------------------------------------------------------------- 1 | 2 | 2018-06-09 07:48:45.0770ca6a864-5659-789d-5f32-f365f695e757digestalg-1|5ABIy0w088RJUNmNQzSipNapiJQ=|RVu+bmlOCMKmQd/4IBdGEbHfEwlorzxCVV1CMLHzoZwi2S2FrckNBA==DIY-Categorization-fnr-TRCS-prcng_3:20171117095241:20171117095241DIY-Categorization-fnr-TRCS-curint-News:20180221133342:20180221133342DIY-Categorization-fnr-TRCS-capx:20170627191152:20170627191152DIY-Categorization-fnr-TRCS-abs-News:20180321093043:20180321093043DIY-Categorization-fnr-TRCS-cstcut_new-News:20180301140156:20180301140156DIY-Categorization-fnr-TRCS-margnu:20171117095324:20171117095324DIY-Categorization-fnr-TRCS-pgm___PGM-News:20180508065449:20180508065449Deals Index:201806090650:201806090650DIY-Categorization-fnr-TRCS-cttl___CTTL-News:20180424161004:20180424161004DIY-Categorization-fnr-TRCS-indx_stsale:20170323110805:20170323110805DIY-Categorization-fnr-TRCS-margin_pressure_rsch_joel___MARGND-Research:20180518140643:20180518140643DIY-Categorization-fnr-TRCS-comptn:20170621141739:20170621141739DIY-Categorization-fnr-TRCS-plcy___PLCY-News:20180416161629:20180416161629index-refineries:201806021806:201806021806DIY-Categorization-fnr-TRCS-regs_buyb_new:20170509091609:20170509091609DIY-Categorization-fnr-TRCS-int___INT-News:20180326113056:20180326113056DIY-Categorization-fnr-TRCS-risk_infring_ola___M_1TC-News:20180605101139:20180605101139config-physicalAssets-powerStations:759:759DIY-Categorization-fnr-TRCS-same_store_sales_sai_rch___STSALE-Research:20180508132425:20180508132425DIY-Categorization-fnr-TRCS-revenue_drivers_ram_rch___REVDRV-Research:20180406095446:20180406095446NextTags:OneCalais_11.7-RELEASE:5SpanishIM:OneCalais_11.5-RELEASE:38DIY-Categorization-fnr-TRCS-accounting_issues_rsch_joel___ACCI-Research:20180405085125:20180405085125DIY-Categorization-fnr-TRCS-pltry___PLTRY-News:20180502073135:20180502073135DIY-Categorization-fnr-TRCS-infl-News:20180206095852:20180206095852DIY-Categorization-fnr-TRCS-newjbs:20180124163802:20180124163802DIY-Categorization-fnr-TRCS-dis:20170418132337:20170418132337DIY-Categorization-fnr-TRCS-revdrv2-News:20180202125843:20180202125843DIY-Categorization-fnr-TRCS-splitb_r1:20170329082516:20170329082516DIY-Categorization-fnr-TRCS-alu-News:20180314130406:20180314130406DIY-Categorization-fnr-TRCS-ils___ILS-News:20180419135358:20180419135358DIY-Categorization-fnr-TRCS-esgenv_2-News:20180202131300:20180202131300DIY-Categorization-fnr-TRCS-loa___LOA-News:20180409071645:20180409071645DIY-Categorization-fnr-TRCS-margnd_2:20171117095121:20171117095121DIY-Categorization-fnr-TRCS-soy1___SOY1-News:20180521141509:20180521141509DIY-Categorization-fnr-TRCS-change_of_cfo_joel_res-Research:20180315092841:20180315092841config-sca-DataPackage:50:50DIY-Categorization-fnr-TRCS-tracc___TRACC-News:20180409095318:20180409095318DIY-Categorization-fnr-TRCS-mergers___acquisitions__joel_rch-Research:20180322100020:20180322100020config-companyNe:842:842DIY-Categorization-fnr-TRCS-acb:20170502102348:20170502102348DIY-Categorization-fnr-TRCS-stsale_new-News:20180302131833:20180302131833DIY-Categorization-support-TRCS-test_mike3___JointVenture-News:20180408082242:20180408082242DIY-Categorization-fnr-TRCS-scrp___SCRP-News:20180514114027:20180514114027DIY-Categorization-fnr-TRCS-hosal_jayasimha-News:20180320092027:20180320092027DIY-Categorization-fnr-TRCS-levrge:20170621122109:20170621122109DIY-Categorization-fnr-TRCS-nkl___NKL-News:20180605132818:20180605132818DIY-Categorization-fnr-TRCS-hedge_list1:20170625000000:20170625000000DIY-Categorization-fnr-TRCS-corporate_inventory_rama_rch___INVTRY-Research:20180329065542:20180329065542SECHeaderMetadataIM:OneCalais_11.5-RELEASE:38DIY-Categorization-fnr-TRCS-soil___SOIL-News:20180601140445:20180601140445DIY-Categorization-fnr-TRCS-esggov-News:20180301091656:20180301091656DIY-Categorization-fnr-TRCS-sales1:20171219091829:20171219091829DIY-Categorization-fnr-TRCS-product_launches_rsch_joel___PRDLCH-Research:20180604142910:20180604142910config-refreshableDIY:3:3DIY-Categorization-fnr-TRCS-crycur:20171121113558:20171121113558DIY-Categorization-fnr-TRCS-competition_sai_kiran_rch___COMPTN-Research:20180412104501:20180412104501DIY-Categorization-fnr-TRCS-rmrmrg:20171204112525:20171204112525DIY-Categorization-fnr-TRCS-capital_expenditure_rama_rch2-Research:20180305132538:20180305132538DIY-Categorization-fnr-TRCS-money_laundering_trial___M_1SH-News:20180425112705:20180425112705DIY-Categorization-fnr-TRCS-hjk_sajith___HJK-News:20180427070940:20180427070940DIY-Categorization-fnr-TRCS-frxrte:20171229123536:20171229123536DIY-Categorization-fnr-TRCS-war___WAR-News:20180419081608:20180419081608DIY-Categorization-fnr-TRCS-esgsoc_2-News:20180315093602:20180315093602People Index:201806090520:201806090520DIY-Categorization-fnr-TRCS-mons___MONS-News:20180404103759:20180404103759DIY-Categorization-fnr-TRCS-pall___PALL-News:20180601131312:20180601131312DIY-Categorization-fnr-TRCS-wine1___WINE1-News:20180522120541:20180522120541DIY-Categorization-fnr-TRCS-ocrim___OCRIM-News:20180417114410:20180417114410DIY-Categorization-fnr-TRCS-ceo1_new___CEO1-News:20180515143641:20180515143641DIY-Categorization-fnr-TRCS-gol_new___GOL-News:20180511091509:20180511091509DIY-Categorization-fnr-TRCS-awlq:20170331124441:20170331124441DIY-Categorization-fnr-TRCS-segment_revenue_rsh_sai_2___SEGREV-Research:20180406153631:20180406153631DIY-Categorization-fnr-TRCS-corporate_valuation_rama_rch___CVALU-Research:20180403102035:20180403102035DIY-Categorization-fnr-TRCS-market_share_rsch_joel_new___MKTSHR-Research:20180403070617:20180403070617DIY-Categorization-fnr-TRCS-murd_sajith___MURD-News:20180418122332:20180418122332config-negativeSignature:759:759DIY-Categorization-fnr-TRCS-poil___POIL-News:20180524145900:20180524145900DIY-Categorization-fnr-TRCS-fake1_monop_bnkcap_new:20170405133257:20170405133257DIY-Categorization-fnr-TRCS-nrg___NRG-News:20180515122734:20180515122734Dial4J:OneCalais_11.5-RELEASE:38DIY-Categorization-fnr-TRCS-share_buybacks_repurchase_ram_rh-Research:20180322095215:20180322095215AutocoderRuntimeIM:OneCalais_11.5-RELEASE:38DIY-Categorization-fnr-TRCS-corporate_controversy_rsh_sai2___CVRSY-Research:20180606105315:20180606105315DIY-Categorization-fnr-TRCS-dbtr_new:20170315123740:20170315123740DIY-Categorization-fnr-TRCS-auct___AUCT-News:20180425084455:20180425084455DIY-Categorization-fnr-TRCS-scale_2:20171130072915:20171130072915DIY-Categorization-fnr-TRCS-dbulk___DBULK-News:20180403110302:20180403110302DIY-Categorization-fnr-TRCS-gdp-News:20180321130548:20180321130548OA Override:842:842DIY-Categorization-fnr-TRCS-civ___CIV-News:20180607121523:20180607121523DIY-Categorization-fnr-TRCS-hrgt:20170427081548:20170427081548DIY-Categorization-fnr-TRCS-xpand:20170323144646:20170323144646DIY-Categorization-fnr-TRCS-kycterror-News:20180223164257:20180223164257DIY-Categorization-fnr-TRCS-leverage_ratios_rama_rch-Research:20180305132725:20180305132725DIY-Categorization-fnr-TRCS-same_store_sales_sai_rch-Research:20180320084305:20180320084305DIY-Categorization-fnr-TRCS-bonus_share_issues_sai_rch-Research:20180305132618:20180305132618DIY-Categorization-fnr-TRCS-resass-News:20180208130324:20180208130324DIY-Categorization-fnr-TRCS-allcemrgdvst2:20170424130000:20170424130000DIY-Categorization-fnr-TRCS-lead1-News:20180321121644:20180321121644DIY-Categorization-fnr-TRCS-plat___PLAT-News:20180513085820:20180513085820DIY-Categorization-fnr-TRCS-ordr:20170313151239:20170313151239DIY-Categorization-fnr-TRCS-eqb___EQB-News:20180510082724:20180510082724DIY-Categorization-fnr-TRCS-coc___COC-News:20180423125041:20180423125041DIY-Categorization-fnr-TRCS-coa___COA-News:20180524073631:20180524073631People Override:759:759DIY-Categorization-fnr-TRCS-seasns_kamila-News:20180320120211:20180320120211DIY-Categorization-fnr-TRCS-change_of_ceo_ram_rch___CEO1-Research:20180403103028:20180403103028DIY-Categorization-fnr-TRCS-hrgt_recll:20170522120000:20170522120000DIY-Categorization-fnr-TRCS-fraud1___FRAUD1-News:20180608135213:20180608135213index-company-oa3:201806070155:201806070155DIY-Categorization-fnr-TRCS-hoil___HOIL-News:20180515122702:20180515122702DIY-Categorization-fnr-TRCS-rawm___RAWM-News:20180403083541:20180403083541index-vessels:201806021740:201806021740DIY-Categorization-fnr-TRCS-brib_r1:20170329090629:20170329090629DIY-Categorization-fnr-TRCS-mplt___MPLT-News:20180327111715:20180327111715DIY-Categorization-fnr-TRCS-shareholder_activism_rama_rch-Research:20180320142730:20180320142730DIY-Categorization-fnr-TRCS-cvalu:20171212133524:20171212133524DIY-Categorization-fnr-TRCS-performan_result_earning_ram_rch___RES-Research:20180516103928:20180516103928DIY-Categorization-fnr-TRCS-csent-News:20180314134456:20180314134456DIY-Categorization-fnr-TRCS-disasters___accidents_rsch_joel___DIS-Research:20180412092858:20180412092858DIY-Categorization-fnr-TRCS-kycaas_bribery_and_corruption___M_1S5-News:20180524131445:20180524131445BrokerResearchIM:OneCalais_11.5-RELEASE:38DIY-Categorization-fnr-TRCS-company_cost_reduction_ram_rch2-Research:20180320152742:20180320152742config-forEndUserDisplay:3:3config-refineries:759:759DIY-Categorization-fnr-TRCS-cdo2-News:20180315084530:20180315084530DIY-Categorization-fnr-TRCS-prdlch-News:20180201133354:20180201133354DIY-Categorization-fnr-TRCS-strategic_combinations_joel_rch-Research:20180315092813:20180315092813DIY-Categorization-fnr-TRCS-ipr-News:20180319134217:20180319134217DIY-Categorization-fnr-TRCS-fapm:20170713144316:20170713144316DIY-Categorization-fnr-TRCS-class:20170315123207:20170315123207config-cse:824:824OneCalaisIM:OneCalais_11.5-RELEASE:38DIY-Categorization-fnr-TRCS-isu_dat_r:20170405124144:20170405124144DIY-Categorization-fnr-TRCS-cnsl_sisu:20170321144134:20170321144134DIY-Categorization-fnr-TRCS-customer_loyalty_sai_rch___CLYLTY-Research:20180409122355:20180409122355DIY-Categorization-fnr-TRCS-narc_kairav___NARC-News:20180510113450:20180510113450DIY-Categorization-fnr-TRCS-newjbs-News:20180123114120:20180123114120DIY-Categorization-fnr-TRCS-shract_r1:20170412111808:20170412111808DIY-Categorization-fnr-TRCS-demand_rsch_joel2___SALES1-Research:20180427132317:20180427132317config-vessels:759:759DIY-Categorization-fnr-TRCS-product_shipments_rashmi_rch2-Research:20180313094806:20180313094806OneCalais:OneCalais_11.7-RELEASE:5DIY-Categorization-fnr-TRCS-invtry_09_25_2017:20171120093416:20171120093416DIY-Categorization-fnr-TRCS-organizational_rest_rsch_joel___REORG-Research:20180508125004:20180508125004DIY-Categorization-fnr-TRCS-igd___IGD-News:20180509090349:20180509090349DIY-Categorization-fnr-TRCS-risk_violent_crime___VCRIM-News:20180607141731:20180607141731DIY-Categorization-fnr-TRCS-mktshr2:20170705120412:20170705120412DIY-RCS-fnr-TRCS-cavs:4:4DIY-Categorization-fnr-TRCS-wom___WOM-News:20180508045954:20180508045954DIY-Categorization-fnr-TRCS-divestitures_spin_offs_rash_rch-Research:20180305132659:20180305132659DIY-Categorization-fnr-TRCS-jet___JET-News:20180604151907:20180604151907DIY-Categorization-fnr-TRCS-mtg___MTG-News:20180423093530:20180423093530DIY-Categorization-fnr-TRCS-eub___EUB-News:20180327093517:20180327093517DIY-Categorization-fnr-TRCS-blktrd_r1:20170413063806:20170413063806DIY-Categorization-fnr-TRCS-znc___ZNC-News:20180412130505:20180412130505DIY-Categorization-fnr-TRCS-trd_tax:20170309132522:20170309132522DIY-Categorization-fnr-TRCS-reorg_new___REORG-News:20180601111024:20180601111024DIY-Categorization-fnr-TRCS-product_recalls_rsh_sai2___RECLL-Research:20180425121704:20180425121704DIY-Categorization-fnr-TRCS-expansions_new_markets_sai_rsh2___XPAND-Research:20180605143141:20180605143141DIY-Categorization-fnr-TRCS-sov_2:20170522130956:20170522130956DIY-Categorization-fnr-TRCS-bons:20170406103713:20170406103713DIY-Categorization-fnr-TRCS-fake1___FAKE1-News:20180516150141:20180516150141DIY-Categorization-fnr-TRCS-antitrust_competitive_behaviour2___MONOP-Research:20180430152713:20180430152713DIY-Categorization-fnr-TRCS-racr___RACR-News:20180404134359:20180404134359DIY-Categorization-fnr-TRCS-corruption___bribery___joel_rch-Research:20180319102344:20180319102344DIY-Categorization-fnr-TRCS-commercial_contract_wins_sai_rch___ORDR-Research:20180413122334:20180413122334DIY-Categorization-fnr-TRCS-change_of_chairperson_rsch_joel___CHAIR1-Research:20180430061611:20180430061611DIY-Categorization-fnr-TRCS-exchange_rate_impact_rama_rsh-Research:20180312091507:20180312091507DIY-Categorization-fnr-TRCS-bankruptcy_insolvency_rsch_joel-Research:20180315095938:20180315095938DIY-Categorization-fnr-TRCS-blkchn_4-News:20180123105513:20180123105513DIY-Categorization-fnr-TRCS-bomb___BOMB-News:20180509143515:20180509143515DIY-Categorization-fnr-TRCS-research_regulatory_issues___REGS-Research:20180516142505:20180516142505DIY-Categorization-fnr-TRCS-segrev:20171117133125:20171117133125DIY-Categorization-tms-TRCS-sanity_tms_auto_publish___CEO1-News:20180325093931:20180325093931DIY-Categorization-fnr-TRCS-kyc_embezzlement___M_1SE-News:20180430061642:20180430061642DIY-Categorization-fnr-TRCS-hrgt_namec:20170329090731:20170329090731DIY-Categorization-fnr-TRCS-change_of_president_joel_rch___PRES1-Research:20180402085923:20180402085923DIY-RCS-fnr-TRCS-nd:3:3DIY-Categorization-fnr-TRCS-stx:20170530123138:20170530123138DIY-Categorization-fnr-TRCS-pmi-News:20180214153232:20180214153232config-physicalAssets-mines:759:759SocialTags Index:201806041235:201806041235BlackList:824:824DIY-Categorization-fnr-TRCS-mgs___MGS-News:20180529091421:20180529091421DIY-Categorization-fnr-TRCS-shpmnt_new2:20171116121809:20171116121809DIY-Categorization-fnr-TRCS-gol-News:20180319131232:20180319131232DIY-Categorization-fnr-TRCS-shl___SHL-News:20180420142214:20180420142214DIY-Categorization-fnr-TRCS-crptax:20171117095403:20171117095403DIY-Categorization-fnr-TRCS-cppr-News:20180315144023:20180315144023index-ports:201806021756:201806021756FrenchIM:OneCalais_11.5-RELEASE:38config-physicalAssets-ports:759:759DIY-Categorization-fnr-TRCS-ream:20170529065740:20170529065740DIY-Categorization-fnr-TRCS-rub___RUB-News:20180510113353:20180510113353DIY-Categorization-fnr-TRCS-chld:20170524084254:20170524084254DIY-Categorization-fnr-TRCS-raw_material_cost_rsch_joel___RAWM-Research:20180607121525:20180607121525DIY-Categorization-tms-TRCS-sanity_0104___DDEAL-News:20180408102110:20180408102110DIY-Categorization-fnr-TRCS-allce:20170323145654:20170323145654DIY-Categorization-fnr-TRCS-medreg:20170508120210:20170508120210DIY-Categorization-fnr-TRCS-equity_stakes_rama_rch___STK-Research:20180329064332:20180329064332config-drugs:759:759DIY-Categorization-fnr-TRCS-hyd___HYD-News:20180418120003:20180418120003DIY-Categorization-fnr-TRCS-exrsks:20171129184952:20171129184952falsetrueComputing1ComputingtrueApple Inc.1Apple Inc.trueTechnology1TechnologytrueApple II family2Apple II familytrueApple2Apple (automobile)trueApple Valley Airport2Apple Valley AirporttrueType Allocation Code2Type Allocation Codefalse1.000Business_Financefalse1.000Technology_Internetfalse0.869Law_CrimefalsePhones & Smart PhonesB:176942949512320.800APPLE INC.4295905573AAPL.OQtrueApple0.99451727 6 | 7 | AAPL0.8760.00.994517270.904falseAppleN/A0.904name[]Apple[ is a public company 8 | ]Apple is a public company 9 | 050.80.74 -------------------------------------------------------------------------------- /tests/resources/oc_google.rdf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 2018-06-11 14:39:35.547 16 | 17 | 18 | 19 | 20 | 0ca6a864-5659-789d-5f32-f365f695e757 21 | digestalg-1|jsqBMh2i7GyANOumIbRHVTdrDlI=|ExKTG3Ne9cBZLmNTQTXUpv5nfulKKRABmJDV6o5lzp7fxTUXYpci4Q== 22 | 23 | 24 | 25 | 26 | DIY-Categorization-fnr-TRCS-prcng_3:20171117095241:20171117095241 27 | DIY-Categorization-fnr-TRCS-curint-News:20180221133342:20180221133342 28 | DIY-Categorization-fnr-TRCS-capx:20170627191152:20170627191152 29 | DIY-Categorization-fnr-TRCS-abs-News:20180321093043:20180321093043 30 | DIY-Categorization-fnr-TRCS-cstcut_new-News:20180301140156:20180301140156 31 | DIY-Categorization-fnr-TRCS-margnu:20171117095324:20171117095324 32 | DIY-Categorization-fnr-TRCS-pgm___PGM-News:20180508065449:20180508065449 33 | Deals Index:201806111410:201806111410 34 | DIY-Categorization-fnr-TRCS-cttl___CTTL-News:20180424161004:20180424161004 35 | DIY-Categorization-fnr-TRCS-indx_stsale:20170323110805:20170323110805 36 | DIY-Categorization-fnr-TRCS-margin_pressure_rsch_joel___MARGND-Research:20180518140643:20180518140643 37 | DIY-Categorization-fnr-TRCS-comptn:20170621141739:20170621141739 38 | DIY-Categorization-fnr-TRCS-plcy___PLCY-News:20180416161629:20180416161629 39 | index-refineries:201806091325:201806091325 40 | DIY-Categorization-fnr-TRCS-regs_buyb_new:20170509091609:20170509091609 41 | DIY-Categorization-fnr-TRCS-int___INT-News:20180326113056:20180326113056 42 | DIY-Categorization-fnr-TRCS-risk_infring_ola___M_1TC-News:20180605101139:20180605101139 43 | config-physicalAssets-powerStations:759:759 44 | DIY-Categorization-fnr-TRCS-same_store_sales_sai_rch___STSALE-Research:20180508132425:20180508132425 45 | DIY-Categorization-fnr-TRCS-revenue_drivers_ram_rch___REVDRV-Research:20180406095446:20180406095446 46 | NextTags:OneCalais_11.7-RELEASE:5 47 | SpanishIM:OneCalais_11.5-RELEASE:38 48 | DIY-Categorization-fnr-TRCS-accounting_issues_rsch_joel___ACCI-Research:20180405085125:20180405085125 49 | DIY-Categorization-fnr-TRCS-pltry___PLTRY-News:20180502073135:20180502073135 50 | DIY-Categorization-fnr-TRCS-infl-News:20180206095852:20180206095852 51 | DIY-Categorization-fnr-TRCS-newjbs:20180124163802:20180124163802 52 | DIY-Categorization-fnr-TRCS-dis:20170418132337:20170418132337 53 | DIY-Categorization-fnr-TRCS-revdrv2-News:20180202125843:20180202125843 54 | DIY-Categorization-fnr-TRCS-splitb_r1:20170329082516:20170329082516 55 | DIY-Categorization-fnr-TRCS-alu-News:20180314130406:20180314130406 56 | DIY-Categorization-fnr-TRCS-ils___ILS-News:20180419135358:20180419135358 57 | DIY-Categorization-fnr-TRCS-esgenv_2-News:20180202131300:20180202131300 58 | DIY-Categorization-fnr-TRCS-loa___LOA-News:20180409071645:20180409071645 59 | DIY-Categorization-fnr-TRCS-margnd_2:20171117095121:20171117095121 60 | DIY-Categorization-fnr-TRCS-soy1___SOY1-News:20180521141509:20180521141509 61 | DIY-Categorization-fnr-TRCS-change_of_cfo_joel_res-Research:20180315092841:20180315092841 62 | config-sca-DataPackage:50:50 63 | DIY-Categorization-fnr-TRCS-tracc___TRACC-News:20180409095318:20180409095318 64 | DIY-Categorization-fnr-TRCS-mergers___acquisitions__joel_rch-Research:20180322100020:20180322100020 65 | config-companyNe:844:844 66 | DIY-Categorization-fnr-TRCS-acb:20170502102348:20170502102348 67 | DIY-Categorization-fnr-TRCS-stsale_new-News:20180302131833:20180302131833 68 | DIY-Categorization-support-TRCS-test_mike3___JointVenture-News:20180408082242:20180408082242 69 | DIY-Categorization-fnr-TRCS-scrp___SCRP-News:20180514114027:20180514114027 70 | DIY-Categorization-fnr-TRCS-hosal_jayasimha-News:20180320092027:20180320092027 71 | DIY-Categorization-fnr-TRCS-levrge:20170621122109:20170621122109 72 | DIY-Categorization-fnr-TRCS-nkl___NKL-News:20180605132818:20180605132818 73 | DIY-Categorization-fnr-TRCS-hedge_list1:20170625000000:20170625000000 74 | DIY-Categorization-fnr-TRCS-corporate_inventory_rama_rch___INVTRY-Research:20180329065542:20180329065542 75 | SECHeaderMetadataIM:OneCalais_11.5-RELEASE:38 76 | DIY-Categorization-fnr-TRCS-soil___SOIL-News:20180601140445:20180601140445 77 | DIY-Categorization-fnr-TRCS-esggov-News:20180301091656:20180301091656 78 | DIY-Categorization-fnr-TRCS-sales1:20171219091829:20171219091829 79 | DIY-Categorization-fnr-TRCS-product_launches_rsch_joel___PRDLCH-Research:20180604142910:20180604142910 80 | config-refreshableDIY:3:3 81 | DIY-Categorization-fnr-TRCS-crycur:20171121113558:20171121113558 82 | DIY-Categorization-fnr-TRCS-competition_sai_kiran_rch___COMPTN-Research:20180412104501:20180412104501 83 | DIY-Categorization-fnr-TRCS-rmrmrg:20171204112525:20171204112525 84 | DIY-Categorization-fnr-TRCS-capital_expenditure_rama_rch2-Research:20180305132538:20180305132538 85 | DIY-Categorization-fnr-TRCS-money_laundering_trial___M_1SH-News:20180425112705:20180425112705 86 | DIY-Categorization-fnr-TRCS-hjk_sajith___HJK-News:20180427070940:20180427070940 87 | DIY-Categorization-fnr-TRCS-frxrte:20171229123536:20171229123536 88 | DIY-Categorization-fnr-TRCS-war___WAR-News:20180419081608:20180419081608 89 | DIY-Categorization-fnr-TRCS-esgsoc_2-News:20180315093602:20180315093602 90 | People Index:201806111200:201806111200 91 | DIY-Categorization-fnr-TRCS-mons___MONS-News:20180404103759:20180404103759 92 | DIY-Categorization-fnr-TRCS-pall___PALL-News:20180601131312:20180601131312 93 | DIY-Categorization-fnr-TRCS-wine1___WINE1-News:20180522120541:20180522120541 94 | DIY-Categorization-fnr-TRCS-ocrim___OCRIM-News:20180417114410:20180417114410 95 | DIY-Categorization-fnr-TRCS-ceo1_new___CEO1-News:20180515143641:20180515143641 96 | DIY-Categorization-fnr-TRCS-gol_new___GOL-News:20180511091509:20180511091509 97 | DIY-Categorization-fnr-TRCS-awlq:20170331124441:20170331124441 98 | DIY-Categorization-fnr-TRCS-segment_revenue_rsh_sai_2___SEGREV-Research:20180406153631:20180406153631 99 | DIY-Categorization-fnr-TRCS-corporate_valuation_rama_rch___CVALU-Research:20180403102035:20180403102035 100 | DIY-Categorization-fnr-TRCS-market_share_rsch_joel_new___MKTSHR-Research:20180403070617:20180403070617 101 | DIY-Categorization-fnr-TRCS-murd_sajith___MURD-News:20180418122332:20180418122332 102 | config-negativeSignature:759:759 103 | DIY-Categorization-fnr-TRCS-poil___POIL-News:20180524145900:20180524145900 104 | DIY-Categorization-fnr-TRCS-fake1_monop_bnkcap_new:20170405133257:20170405133257 105 | DIY-Categorization-fnr-TRCS-nrg___NRG-News:20180515122734:20180515122734 106 | Dial4J:OneCalais_11.5-RELEASE:38 107 | DIY-Categorization-fnr-TRCS-share_buybacks_repurchase_ram_rh-Research:20180322095215:20180322095215 108 | AutocoderRuntimeIM:OneCalais_11.5-RELEASE:38 109 | DIY-Categorization-fnr-TRCS-corporate_controversy_rsh_sai2___CVRSY-Research:20180606105315:20180606105315 110 | DIY-Categorization-fnr-TRCS-dbtr_new:20170315123740:20170315123740 111 | DIY-Categorization-fnr-TRCS-auct___AUCT-News:20180425084455:20180425084455 112 | DIY-Categorization-fnr-TRCS-scale_2:20171130072915:20171130072915 113 | DIY-Categorization-fnr-TRCS-dbulk___DBULK-News:20180403110302:20180403110302 114 | DIY-Categorization-fnr-TRCS-gdp-News:20180321130548:20180321130548 115 | OA Override:842:842 116 | DIY-Categorization-fnr-TRCS-civ___CIV-News:20180607121523:20180607121523 117 | DIY-Categorization-fnr-TRCS-hrgt:20170427081548:20170427081548 118 | DIY-Categorization-fnr-TRCS-xpand:20170323144646:20170323144646 119 | DIY-Categorization-fnr-TRCS-kycterror-News:20180223164257:20180223164257 120 | DIY-Categorization-fnr-TRCS-leverage_ratios_rama_rch-Research:20180305132725:20180305132725 121 | DIY-Categorization-fnr-TRCS-same_store_sales_sai_rch-Research:20180320084305:20180320084305 122 | DIY-Categorization-fnr-TRCS-bonus_share_issues_sai_rch-Research:20180305132618:20180305132618 123 | DIY-Categorization-fnr-TRCS-resass-News:20180208130324:20180208130324 124 | DIY-Categorization-fnr-TRCS-allcemrgdvst2:20170424130000:20170424130000 125 | DIY-Categorization-fnr-TRCS-lead1-News:20180321121644:20180321121644 126 | DIY-Categorization-fnr-TRCS-plat___PLAT-News:20180513085820:20180513085820 127 | DIY-Categorization-fnr-TRCS-ordr:20170313151239:20170313151239 128 | DIY-Categorization-fnr-TRCS-eqb___EQB-News:20180510082724:20180510082724 129 | DIY-Categorization-fnr-TRCS-coc___COC-News:20180423125041:20180423125041 130 | DIY-Categorization-fnr-TRCS-coa___COA-News:20180524073631:20180524073631 131 | People Override:759:759 132 | DIY-Categorization-fnr-TRCS-seasns_kamila-News:20180320120211:20180320120211 133 | DIY-Categorization-fnr-TRCS-change_of_ceo_ram_rch___CEO1-Research:20180403103028:20180403103028 134 | DIY-Categorization-fnr-TRCS-hrgt_recll:20170522120000:20170522120000 135 | DIY-Categorization-fnr-TRCS-fraud1___FRAUD1-News:20180608135213:20180608135213 136 | index-company-oa3:201806070155:201806070155 137 | DIY-Categorization-fnr-TRCS-hoil___HOIL-News:20180515122702:20180515122702 138 | DIY-Categorization-fnr-TRCS-rawm___RAWM-News:20180403083541:20180403083541 139 | index-vessels:201806091915:201806091915 140 | DIY-Categorization-fnr-TRCS-brib_r1:20170329090629:20170329090629 141 | DIY-Categorization-fnr-TRCS-mplt___MPLT-News:20180327111715:20180327111715 142 | DIY-Categorization-fnr-TRCS-shareholder_activism_rama_rch-Research:20180320142730:20180320142730 143 | DIY-Categorization-fnr-TRCS-cvalu:20171212133524:20171212133524 144 | DIY-Categorization-fnr-TRCS-performan_result_earning_ram_rch___RES-Research:20180516103928:20180516103928 145 | DIY-Categorization-fnr-TRCS-csent-News:20180314134456:20180314134456 146 | DIY-Categorization-fnr-TRCS-disasters___accidents_rsch_joel___DIS-Research:20180412092858:20180412092858 147 | DIY-Categorization-fnr-TRCS-kycaas_bribery_and_corruption___M_1S5-News:20180524131445:20180524131445 148 | BrokerResearchIM:OneCalais_11.5-RELEASE:38 149 | DIY-Categorization-fnr-TRCS-company_cost_reduction_ram_rch2-Research:20180320152742:20180320152742 150 | config-forEndUserDisplay:3:3 151 | config-refineries:759:759 152 | DIY-Categorization-fnr-TRCS-cdo2-News:20180315084530:20180315084530 153 | DIY-Categorization-fnr-TRCS-prdlch-News:20180201133354:20180201133354 154 | DIY-Categorization-fnr-TRCS-strategic_combinations_joel_rch-Research:20180315092813:20180315092813 155 | DIY-Categorization-fnr-TRCS-ipr-News:20180319134217:20180319134217 156 | DIY-Categorization-fnr-TRCS-fapm:20170713144316:20170713144316 157 | DIY-Categorization-fnr-TRCS-class:20170315123207:20170315123207 158 | config-cse:1:1 159 | OneCalaisIM:OneCalais_11.5-RELEASE:38 160 | DIY-Categorization-fnr-TRCS-isu_dat_r:20170405124144:20170405124144 161 | DIY-Categorization-fnr-TRCS-cnsl_sisu:20170321144134:20170321144134 162 | DIY-Categorization-fnr-TRCS-customer_loyalty_sai_rch___CLYLTY-Research:20180409122355:20180409122355 163 | DIY-Categorization-fnr-TRCS-narc_kairav___NARC-News:20180510113450:20180510113450 164 | DIY-Categorization-fnr-TRCS-newjbs-News:20180123114120:20180123114120 165 | DIY-Categorization-fnr-TRCS-shract_r1:20170412111808:20170412111808 166 | DIY-Categorization-fnr-TRCS-demand_rsch_joel2___SALES1-Research:20180427132317:20180427132317 167 | config-vessels:759:759 168 | DIY-Categorization-fnr-TRCS-product_shipments_rashmi_rch2-Research:20180313094806:20180313094806 169 | OneCalais:OneCalais_11.7-RELEASE:5 170 | DIY-Categorization-fnr-TRCS-invtry_09_25_2017:20171120093416:20171120093416 171 | DIY-Categorization-fnr-TRCS-organizational_rest_rsch_joel___REORG-Research:20180508125004:20180508125004 172 | DIY-Categorization-fnr-TRCS-igd___IGD-News:20180509090349:20180509090349 173 | DIY-Categorization-fnr-TRCS-risk_violent_crime___VCRIM-News:20180607141731:20180607141731 174 | DIY-Categorization-fnr-TRCS-mktshr2:20170705120412:20170705120412 175 | DIY-RCS-fnr-TRCS-cavs:4:4 176 | DIY-Categorization-fnr-TRCS-wom___WOM-News:20180508045954:20180508045954 177 | DIY-Categorization-fnr-TRCS-divestitures_spin_offs_rash_rch-Research:20180305132659:20180305132659 178 | DIY-Categorization-fnr-TRCS-jet___JET-News:20180604151907:20180604151907 179 | DIY-Categorization-fnr-TRCS-mtg___MTG-News:20180423093530:20180423093530 180 | DIY-Categorization-fnr-TRCS-eub___EUB-News:20180327093517:20180327093517 181 | DIY-Categorization-fnr-TRCS-blktrd_r1:20171116075645:20171116075645 182 | DIY-Categorization-fnr-TRCS-znc___ZNC-News:20180412130505:20180412130505 183 | DIY-Categorization-fnr-TRCS-trd_tax:20170309132522:20170309132522 184 | DIY-Categorization-fnr-TRCS-reorg_new___REORG-News:20180601111024:20180601111024 185 | DIY-Categorization-fnr-TRCS-product_recalls_rsh_sai2___RECLL-Research:20180425121704:20180425121704 186 | DIY-Categorization-fnr-TRCS-expansions_new_markets_sai_rsh2___XPAND-Research:20180605143141:20180605143141 187 | DIY-Categorization-fnr-TRCS-sov_2:20170522130956:20170522130956 188 | DIY-Categorization-fnr-TRCS-risk_information_leaked___LKD-News:20180611080047:20180611080047 189 | DIY-Categorization-fnr-TRCS-bons:20170406103713:20170406103713 190 | DIY-Categorization-fnr-TRCS-fake1___FAKE1-News:20180516150141:20180516150141 191 | DIY-Categorization-fnr-TRCS-antitrust_competitive_behaviour2___MONOP-Research:20180430152713:20180430152713 192 | DIY-Categorization-fnr-TRCS-racr___RACR-News:20180404134359:20180404134359 193 | DIY-Categorization-fnr-TRCS-corruption___bribery___joel_rch-Research:20180319102344:20180319102344 194 | DIY-Categorization-fnr-TRCS-commercial_contract_wins_sai_rch___ORDR-Research:20180413122334:20180413122334 195 | DIY-Categorization-fnr-TRCS-change_of_chairperson_rsch_joel___CHAIR1-Research:20180430061611:20180430061611 196 | DIY-Categorization-fnr-TRCS-exchange_rate_impact_rama_rsh-Research:20180312091507:20180312091507 197 | DIY-Categorization-fnr-TRCS-bankruptcy_insolvency_rsch_joel-Research:20180315095938:20180315095938 198 | DIY-Categorization-fnr-TRCS-blkchn_4-News:20180123105513:20180123105513 199 | DIY-Categorization-fnr-TRCS-bomb___BOMB-News:20180509143515:20180509143515 200 | DIY-Categorization-fnr-TRCS-research_regulatory_issues___REGS-Research:20180516142505:20180516142505 201 | DIY-Categorization-fnr-TRCS-segrev:20171117133125:20171117133125 202 | DIY-Categorization-tms-TRCS-sanity_tms_auto_publish___CEO1-News:20180325093931:20180325093931 203 | DIY-Categorization-fnr-TRCS-kyc_embezzlement___M_1SE-News:20180430061642:20180430061642 204 | DIY-Categorization-fnr-TRCS-hrgt_namec:20170329090731:20170329090731 205 | DIY-Categorization-fnr-TRCS-change_of_president_joel_rch___PRES1-Research:20180402085923:20180402085923 206 | DIY-RCS-fnr-TRCS-nd:3:3 207 | DIY-Categorization-fnr-TRCS-stx:20170530123138:20170530123138 208 | DIY-Categorization-fnr-TRCS-pmi-News:20180214153232:20180214153232 209 | config-physicalAssets-mines:759:759 210 | SocialTags Index:201806041235:201806041235 211 | BlackList:828:828 212 | DIY-Categorization-fnr-TRCS-mgs___MGS-News:20180529091421:20180529091421 213 | DIY-Categorization-fnr-TRCS-shpmnt_new2:20171116121809:20171116121809 214 | DIY-Categorization-fnr-TRCS-gol-News:20180319131232:20180319131232 215 | DIY-Categorization-fnr-TRCS-shl___SHL-News:20180420142214:20180420142214 216 | DIY-Categorization-fnr-TRCS-crptax:20171117095403:20171117095403 217 | DIY-Categorization-fnr-TRCS-cppr-News:20180315144023:20180315144023 218 | index-ports:201806091929:201806091929 219 | FrenchIM:OneCalais_11.5-RELEASE:38 220 | config-physicalAssets-ports:759:759 221 | DIY-Categorization-fnr-TRCS-ream:20170529065740:20170529065740 222 | DIY-Categorization-fnr-TRCS-rub___RUB-News:20180510113353:20180510113353 223 | DIY-Categorization-fnr-TRCS-chld:20170524084254:20170524084254 224 | DIY-Categorization-fnr-TRCS-raw_material_cost_rsch_joel___RAWM-Research:20180607121525:20180607121525 225 | DIY-Categorization-tms-TRCS-sanity_0104___DDEAL-News:20180408102110:20180408102110 226 | DIY-Categorization-fnr-TRCS-allce:20170323145654:20170323145654 227 | DIY-Categorization-fnr-TRCS-medreg:20170508120210:20170508120210 228 | DIY-Categorization-fnr-TRCS-equity_stakes_rama_rch___STK-Research:20180329064332:20180329064332 229 | config-drugs:759:759 230 | DIY-Categorization-fnr-TRCS-hyd___HYD-News:20180418120003:20180418120003 231 | DIY-Categorization-fnr-TRCS-exrsks:20171129184952:20171129184952 232 | 233 | 234 | 235 | 236 | 237 | false 238 | 239 | 240 | 241 | 242 | 243 | true 244 | Google 245 | 1 246 | Google 247 | 248 | 249 | 250 | 251 | 252 | true 253 | Digital media 254 | 1 255 | Digital media 256 | 257 | 258 | 259 | 260 | 261 | true 262 | Alphabet Inc. 263 | 1 264 | Alphabet Inc. 265 | 266 | 267 | 268 | 269 | 270 | true 271 | Outline of Google 272 | 2 273 | Outline of Google 274 | 275 | 276 | 277 | 278 | 279 | true 280 | Google+ 281 | 2 282 | Google+ 283 | 284 | 285 | 286 | 287 | false 288 | 1.000 289 | Business_Finance 290 | 291 | 292 | 293 | 294 | false 295 | 1.000 296 | Technology_Internet 297 | 298 | 299 | 300 | 301 | false 302 | 0.869 303 | Law_Crime 304 | 305 | 306 | 307 | 308 | false 309 | Search Engines 310 | B:1805 311 | 5720103011 312 | 4294951196 313 | 0.800 314 | 315 | 316 | 317 | true 318 | Google 319 | N/A 320 | 0.981 321 | name 322 | 323 | 324 | 325 | 326 | 327 | 328 | []Google[ is a public company] 329 | 330 | Google 331 | is a public company 332 | 0 333 | 6 334 | 335 | 336 | 337 | 338 | 339 | 0.8 340 | 0.84 341 | 342 | 343 | 344 | 345 | GOOGLE LLC 346 | 4295899948 347 | false 348 | Google 349 | 1.0 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | ALPHABET INC. 359 | 5030853586 360 | GOOGL.OQ 361 | true 362 | Alphabet 363 | 364 | 365 | 366 | 367 | GOOGL 368 | 369 | 370 | 371 | 372 | 373 | 374 | 0.912 375 | 0.0 376 | 1.0 377 | 0.981 378 | 379 | 380 | -------------------------------------------------------------------------------- /comp_match/resources/iso_countries.json: -------------------------------------------------------------------------------- 1 | { 2 | "3166-1": [ 3 | { 4 | "alpha_2": "AW", 5 | "alpha_3": "ABW", 6 | "name": "Aruba", 7 | "numeric": "533" 8 | }, 9 | { 10 | "alpha_2": "AF", 11 | "alpha_3": "AFG", 12 | "name": "Afghanistan", 13 | "numeric": "004", 14 | "official_name": "Islamic Republic of Afghanistan" 15 | }, 16 | { 17 | "alpha_2": "AO", 18 | "alpha_3": "AGO", 19 | "name": "Angola", 20 | "numeric": "024", 21 | "official_name": "Republic of Angola" 22 | }, 23 | { 24 | "alpha_2": "AI", 25 | "alpha_3": "AIA", 26 | "name": "Anguilla", 27 | "numeric": "660" 28 | }, 29 | { 30 | "alpha_2": "AX", 31 | "alpha_3": "ALA", 32 | "name": "Ã…land Islands", 33 | "numeric": "248" 34 | }, 35 | { 36 | "alpha_2": "AL", 37 | "alpha_3": "ALB", 38 | "name": "Albania", 39 | "numeric": "008", 40 | "official_name": "Republic of Albania" 41 | }, 42 | { 43 | "alpha_2": "AD", 44 | "alpha_3": "AND", 45 | "name": "Andorra", 46 | "numeric": "020", 47 | "official_name": "Principality of Andorra" 48 | }, 49 | { 50 | "alpha_2": "AE", 51 | "alpha_3": "ARE", 52 | "name": "United Arab Emirates", 53 | "numeric": "784" 54 | }, 55 | { 56 | "alpha_2": "AR", 57 | "alpha_3": "ARG", 58 | "name": "Argentina", 59 | "numeric": "032", 60 | "official_name": "Argentine Republic" 61 | }, 62 | { 63 | "alpha_2": "AM", 64 | "alpha_3": "ARM", 65 | "name": "Armenia", 66 | "numeric": "051", 67 | "official_name": "Republic of Armenia" 68 | }, 69 | { 70 | "alpha_2": "AS", 71 | "alpha_3": "ASM", 72 | "name": "American Samoa", 73 | "numeric": "016" 74 | }, 75 | { 76 | "alpha_2": "AQ", 77 | "alpha_3": "ATA", 78 | "name": "Antarctica", 79 | "numeric": "010" 80 | }, 81 | { 82 | "alpha_2": "TF", 83 | "alpha_3": "ATF", 84 | "name": "French Southern Territories", 85 | "numeric": "260" 86 | }, 87 | { 88 | "alpha_2": "AG", 89 | "alpha_3": "ATG", 90 | "name": "Antigua and Barbuda", 91 | "numeric": "028" 92 | }, 93 | { 94 | "alpha_2": "AU", 95 | "alpha_3": "AUS", 96 | "name": "Australia", 97 | "numeric": "036" 98 | }, 99 | { 100 | "alpha_2": "AT", 101 | "alpha_3": "AUT", 102 | "name": "Austria", 103 | "numeric": "040", 104 | "official_name": "Republic of Austria" 105 | }, 106 | { 107 | "alpha_2": "AZ", 108 | "alpha_3": "AZE", 109 | "name": "Azerbaijan", 110 | "numeric": "031", 111 | "official_name": "Republic of Azerbaijan" 112 | }, 113 | { 114 | "alpha_2": "BI", 115 | "alpha_3": "BDI", 116 | "name": "Burundi", 117 | "numeric": "108", 118 | "official_name": "Republic of Burundi" 119 | }, 120 | { 121 | "alpha_2": "BE", 122 | "alpha_3": "BEL", 123 | "name": "Belgium", 124 | "numeric": "056", 125 | "official_name": "Kingdom of Belgium" 126 | }, 127 | { 128 | "alpha_2": "BJ", 129 | "alpha_3": "BEN", 130 | "name": "Benin", 131 | "numeric": "204", 132 | "official_name": "Republic of Benin" 133 | }, 134 | { 135 | "alpha_2": "BQ", 136 | "alpha_3": "BES", 137 | "name": "Bonaire, Sint Eustatius and Saba", 138 | "numeric": "535", 139 | "official_name": "Bonaire, Sint Eustatius and Saba" 140 | }, 141 | { 142 | "alpha_2": "BF", 143 | "alpha_3": "BFA", 144 | "name": "Burkina Faso", 145 | "numeric": "854" 146 | }, 147 | { 148 | "alpha_2": "BD", 149 | "alpha_3": "BGD", 150 | "name": "Bangladesh", 151 | "numeric": "050", 152 | "official_name": "People's Republic of Bangladesh" 153 | }, 154 | { 155 | "alpha_2": "BG", 156 | "alpha_3": "BGR", 157 | "name": "Bulgaria", 158 | "numeric": "100", 159 | "official_name": "Republic of Bulgaria" 160 | }, 161 | { 162 | "alpha_2": "BH", 163 | "alpha_3": "BHR", 164 | "name": "Bahrain", 165 | "numeric": "048", 166 | "official_name": "Kingdom of Bahrain" 167 | }, 168 | { 169 | "alpha_2": "BS", 170 | "alpha_3": "BHS", 171 | "name": "Bahamas", 172 | "numeric": "044", 173 | "official_name": "Commonwealth of the Bahamas" 174 | }, 175 | { 176 | "alpha_2": "BA", 177 | "alpha_3": "BIH", 178 | "name": "Bosnia and Herzegovina", 179 | "numeric": "070", 180 | "official_name": "Republic of Bosnia and Herzegovina" 181 | }, 182 | { 183 | "alpha_2": "BL", 184 | "alpha_3": "BLM", 185 | "name": "Saint Barthélemy", 186 | "numeric": "652" 187 | }, 188 | { 189 | "alpha_2": "BY", 190 | "alpha_3": "BLR", 191 | "name": "Belarus", 192 | "numeric": "112", 193 | "official_name": "Republic of Belarus" 194 | }, 195 | { 196 | "alpha_2": "BZ", 197 | "alpha_3": "BLZ", 198 | "name": "Belize", 199 | "numeric": "084" 200 | }, 201 | { 202 | "alpha_2": "BM", 203 | "alpha_3": "BMU", 204 | "name": "Bermuda", 205 | "numeric": "060" 206 | }, 207 | { 208 | "alpha_2": "BO", 209 | "alpha_3": "BOL", 210 | "common_name": "Bolivia", 211 | "name": "Bolivia, Plurinational State of", 212 | "numeric": "068", 213 | "official_name": "Plurinational State of Bolivia" 214 | }, 215 | { 216 | "alpha_2": "BR", 217 | "alpha_3": "BRA", 218 | "name": "Brazil", 219 | "numeric": "076", 220 | "official_name": "Federative Republic of Brazil" 221 | }, 222 | { 223 | "alpha_2": "BB", 224 | "alpha_3": "BRB", 225 | "name": "Barbados", 226 | "numeric": "052" 227 | }, 228 | { 229 | "alpha_2": "BN", 230 | "alpha_3": "BRN", 231 | "name": "Brunei Darussalam", 232 | "numeric": "096" 233 | }, 234 | { 235 | "alpha_2": "BT", 236 | "alpha_3": "BTN", 237 | "name": "Bhutan", 238 | "numeric": "064", 239 | "official_name": "Kingdom of Bhutan" 240 | }, 241 | { 242 | "alpha_2": "BV", 243 | "alpha_3": "BVT", 244 | "name": "Bouvet Island", 245 | "numeric": "074" 246 | }, 247 | { 248 | "alpha_2": "BW", 249 | "alpha_3": "BWA", 250 | "name": "Botswana", 251 | "numeric": "072", 252 | "official_name": "Republic of Botswana" 253 | }, 254 | { 255 | "alpha_2": "CF", 256 | "alpha_3": "CAF", 257 | "name": "Central African Republic", 258 | "numeric": "140" 259 | }, 260 | { 261 | "alpha_2": "CA", 262 | "alpha_3": "CAN", 263 | "name": "Canada", 264 | "numeric": "124" 265 | }, 266 | { 267 | "alpha_2": "CC", 268 | "alpha_3": "CCK", 269 | "name": "Cocos (Keeling) Islands", 270 | "numeric": "166" 271 | }, 272 | { 273 | "alpha_2": "CH", 274 | "alpha_3": "CHE", 275 | "name": "Switzerland", 276 | "numeric": "756", 277 | "official_name": "Swiss Confederation" 278 | }, 279 | { 280 | "alpha_2": "CL", 281 | "alpha_3": "CHL", 282 | "name": "Chile", 283 | "numeric": "152", 284 | "official_name": "Republic of Chile" 285 | }, 286 | { 287 | "alpha_2": "CN", 288 | "alpha_3": "CHN", 289 | "name": "China", 290 | "numeric": "156", 291 | "official_name": "People's Republic of China" 292 | }, 293 | { 294 | "alpha_2": "CI", 295 | "alpha_3": "CIV", 296 | "name": "Côte d'Ivoire", 297 | "numeric": "384", 298 | "official_name": "Republic of Côte d'Ivoire" 299 | }, 300 | { 301 | "alpha_2": "CM", 302 | "alpha_3": "CMR", 303 | "name": "Cameroon", 304 | "numeric": "120", 305 | "official_name": "Republic of Cameroon" 306 | }, 307 | { 308 | "alpha_2": "CD", 309 | "alpha_3": "COD", 310 | "name": "Congo, The Democratic Republic of the", 311 | "numeric": "180" 312 | }, 313 | { 314 | "alpha_2": "CG", 315 | "alpha_3": "COG", 316 | "name": "Congo", 317 | "numeric": "178", 318 | "official_name": "Republic of the Congo" 319 | }, 320 | { 321 | "alpha_2": "CK", 322 | "alpha_3": "COK", 323 | "name": "Cook Islands", 324 | "numeric": "184" 325 | }, 326 | { 327 | "alpha_2": "CO", 328 | "alpha_3": "COL", 329 | "name": "Colombia", 330 | "numeric": "170", 331 | "official_name": "Republic of Colombia" 332 | }, 333 | { 334 | "alpha_2": "KM", 335 | "alpha_3": "COM", 336 | "name": "Comoros", 337 | "numeric": "174", 338 | "official_name": "Union of the Comoros" 339 | }, 340 | { 341 | "alpha_2": "CV", 342 | "alpha_3": "CPV", 343 | "name": "Cabo Verde", 344 | "numeric": "132", 345 | "official_name": "Republic of Cabo Verde" 346 | }, 347 | { 348 | "alpha_2": "CR", 349 | "alpha_3": "CRI", 350 | "name": "Costa Rica", 351 | "numeric": "188", 352 | "official_name": "Republic of Costa Rica" 353 | }, 354 | { 355 | "alpha_2": "CU", 356 | "alpha_3": "CUB", 357 | "name": "Cuba", 358 | "numeric": "192", 359 | "official_name": "Republic of Cuba" 360 | }, 361 | { 362 | "alpha_2": "CW", 363 | "alpha_3": "CUW", 364 | "name": "Curaçao", 365 | "numeric": "531", 366 | "official_name": "Curaçao" 367 | }, 368 | { 369 | "alpha_2": "CX", 370 | "alpha_3": "CXR", 371 | "name": "Christmas Island", 372 | "numeric": "162" 373 | }, 374 | { 375 | "alpha_2": "KY", 376 | "alpha_3": "CYM", 377 | "name": "Cayman Islands", 378 | "numeric": "136" 379 | }, 380 | { 381 | "alpha_2": "CY", 382 | "alpha_3": "CYP", 383 | "name": "Cyprus", 384 | "numeric": "196", 385 | "official_name": "Republic of Cyprus" 386 | }, 387 | { 388 | "alpha_2": "CZ", 389 | "alpha_3": "CZE", 390 | "name": "Czechia", 391 | "numeric": "203", 392 | "official_name": "Czech Republic" 393 | }, 394 | { 395 | "alpha_2": "DE", 396 | "alpha_3": "DEU", 397 | "name": "Germany", 398 | "numeric": "276", 399 | "official_name": "Federal Republic of Germany" 400 | }, 401 | { 402 | "alpha_2": "DJ", 403 | "alpha_3": "DJI", 404 | "name": "Djibouti", 405 | "numeric": "262", 406 | "official_name": "Republic of Djibouti" 407 | }, 408 | { 409 | "alpha_2": "DM", 410 | "alpha_3": "DMA", 411 | "name": "Dominica", 412 | "numeric": "212", 413 | "official_name": "Commonwealth of Dominica" 414 | }, 415 | { 416 | "alpha_2": "DK", 417 | "alpha_3": "DNK", 418 | "name": "Denmark", 419 | "numeric": "208", 420 | "official_name": "Kingdom of Denmark" 421 | }, 422 | { 423 | "alpha_2": "DO", 424 | "alpha_3": "DOM", 425 | "name": "Dominican Republic", 426 | "numeric": "214" 427 | }, 428 | { 429 | "alpha_2": "DZ", 430 | "alpha_3": "DZA", 431 | "name": "Algeria", 432 | "numeric": "012", 433 | "official_name": "People's Democratic Republic of Algeria" 434 | }, 435 | { 436 | "alpha_2": "EC", 437 | "alpha_3": "ECU", 438 | "name": "Ecuador", 439 | "numeric": "218", 440 | "official_name": "Republic of Ecuador" 441 | }, 442 | { 443 | "alpha_2": "EG", 444 | "alpha_3": "EGY", 445 | "name": "Egypt", 446 | "numeric": "818", 447 | "official_name": "Arab Republic of Egypt" 448 | }, 449 | { 450 | "alpha_2": "ER", 451 | "alpha_3": "ERI", 452 | "name": "Eritrea", 453 | "numeric": "232", 454 | "official_name": "the State of Eritrea" 455 | }, 456 | { 457 | "alpha_2": "EH", 458 | "alpha_3": "ESH", 459 | "name": "Western Sahara", 460 | "numeric": "732" 461 | }, 462 | { 463 | "alpha_2": "ES", 464 | "alpha_3": "ESP", 465 | "name": "Spain", 466 | "numeric": "724", 467 | "official_name": "Kingdom of Spain" 468 | }, 469 | { 470 | "alpha_2": "EE", 471 | "alpha_3": "EST", 472 | "name": "Estonia", 473 | "numeric": "233", 474 | "official_name": "Republic of Estonia" 475 | }, 476 | { 477 | "alpha_2": "ET", 478 | "alpha_3": "ETH", 479 | "name": "Ethiopia", 480 | "numeric": "231", 481 | "official_name": "Federal Democratic Republic of Ethiopia" 482 | }, 483 | { 484 | "alpha_2": "FI", 485 | "alpha_3": "FIN", 486 | "name": "Finland", 487 | "numeric": "246", 488 | "official_name": "Republic of Finland" 489 | }, 490 | { 491 | "alpha_2": "FJ", 492 | "alpha_3": "FJI", 493 | "name": "Fiji", 494 | "numeric": "242", 495 | "official_name": "Republic of Fiji" 496 | }, 497 | { 498 | "alpha_2": "FK", 499 | "alpha_3": "FLK", 500 | "name": "Falkland Islands (Malvinas)", 501 | "numeric": "238" 502 | }, 503 | { 504 | "alpha_2": "FR", 505 | "alpha_3": "FRA", 506 | "name": "France", 507 | "numeric": "250", 508 | "official_name": "French Republic" 509 | }, 510 | { 511 | "alpha_2": "FO", 512 | "alpha_3": "FRO", 513 | "name": "Faroe Islands", 514 | "numeric": "234" 515 | }, 516 | { 517 | "alpha_2": "FM", 518 | "alpha_3": "FSM", 519 | "name": "Micronesia, Federated States of", 520 | "numeric": "583", 521 | "official_name": "Federated States of Micronesia" 522 | }, 523 | { 524 | "alpha_2": "GA", 525 | "alpha_3": "GAB", 526 | "name": "Gabon", 527 | "numeric": "266", 528 | "official_name": "Gabonese Republic" 529 | }, 530 | { 531 | "alpha_2": "GB", 532 | "alpha_3": "GBR", 533 | "name": "United Kingdom", 534 | "numeric": "826", 535 | "official_name": "United Kingdom of Great Britain and Northern Ireland" 536 | }, 537 | { 538 | "alpha_2": "GE", 539 | "alpha_3": "GEO", 540 | "name": "Georgia", 541 | "numeric": "268" 542 | }, 543 | { 544 | "alpha_2": "GG", 545 | "alpha_3": "GGY", 546 | "name": "Guernsey", 547 | "numeric": "831" 548 | }, 549 | { 550 | "alpha_2": "GH", 551 | "alpha_3": "GHA", 552 | "name": "Ghana", 553 | "numeric": "288", 554 | "official_name": "Republic of Ghana" 555 | }, 556 | { 557 | "alpha_2": "GI", 558 | "alpha_3": "GIB", 559 | "name": "Gibraltar", 560 | "numeric": "292" 561 | }, 562 | { 563 | "alpha_2": "GN", 564 | "alpha_3": "GIN", 565 | "name": "Guinea", 566 | "numeric": "324", 567 | "official_name": "Republic of Guinea" 568 | }, 569 | { 570 | "alpha_2": "GP", 571 | "alpha_3": "GLP", 572 | "name": "Guadeloupe", 573 | "numeric": "312" 574 | }, 575 | { 576 | "alpha_2": "GM", 577 | "alpha_3": "GMB", 578 | "name": "Gambia", 579 | "numeric": "270", 580 | "official_name": "Islamic Republic of the Gambia" 581 | }, 582 | { 583 | "alpha_2": "GW", 584 | "alpha_3": "GNB", 585 | "name": "Guinea-Bissau", 586 | "numeric": "624", 587 | "official_name": "Republic of Guinea-Bissau" 588 | }, 589 | { 590 | "alpha_2": "GQ", 591 | "alpha_3": "GNQ", 592 | "name": "Equatorial Guinea", 593 | "numeric": "226", 594 | "official_name": "Republic of Equatorial Guinea" 595 | }, 596 | { 597 | "alpha_2": "GR", 598 | "alpha_3": "GRC", 599 | "name": "Greece", 600 | "numeric": "300", 601 | "official_name": "Hellenic Republic" 602 | }, 603 | { 604 | "alpha_2": "GD", 605 | "alpha_3": "GRD", 606 | "name": "Grenada", 607 | "numeric": "308" 608 | }, 609 | { 610 | "alpha_2": "GL", 611 | "alpha_3": "GRL", 612 | "name": "Greenland", 613 | "numeric": "304" 614 | }, 615 | { 616 | "alpha_2": "GT", 617 | "alpha_3": "GTM", 618 | "name": "Guatemala", 619 | "numeric": "320", 620 | "official_name": "Republic of Guatemala" 621 | }, 622 | { 623 | "alpha_2": "GF", 624 | "alpha_3": "GUF", 625 | "name": "French Guiana", 626 | "numeric": "254" 627 | }, 628 | { 629 | "alpha_2": "GU", 630 | "alpha_3": "GUM", 631 | "name": "Guam", 632 | "numeric": "316" 633 | }, 634 | { 635 | "alpha_2": "GY", 636 | "alpha_3": "GUY", 637 | "name": "Guyana", 638 | "numeric": "328", 639 | "official_name": "Republic of Guyana" 640 | }, 641 | { 642 | "alpha_2": "HK", 643 | "alpha_3": "HKG", 644 | "name": "Hong Kong", 645 | "numeric": "344", 646 | "official_name": "Hong Kong Special Administrative Region of China" 647 | }, 648 | { 649 | "alpha_2": "HM", 650 | "alpha_3": "HMD", 651 | "name": "Heard Island and McDonald Islands", 652 | "numeric": "334" 653 | }, 654 | { 655 | "alpha_2": "HN", 656 | "alpha_3": "HND", 657 | "name": "Honduras", 658 | "numeric": "340", 659 | "official_name": "Republic of Honduras" 660 | }, 661 | { 662 | "alpha_2": "HR", 663 | "alpha_3": "HRV", 664 | "name": "Croatia", 665 | "numeric": "191", 666 | "official_name": "Republic of Croatia" 667 | }, 668 | { 669 | "alpha_2": "HT", 670 | "alpha_3": "HTI", 671 | "name": "Haiti", 672 | "numeric": "332", 673 | "official_name": "Republic of Haiti" 674 | }, 675 | { 676 | "alpha_2": "HU", 677 | "alpha_3": "HUN", 678 | "name": "Hungary", 679 | "numeric": "348", 680 | "official_name": "Hungary" 681 | }, 682 | { 683 | "alpha_2": "ID", 684 | "alpha_3": "IDN", 685 | "name": "Indonesia", 686 | "numeric": "360", 687 | "official_name": "Republic of Indonesia" 688 | }, 689 | { 690 | "alpha_2": "IM", 691 | "alpha_3": "IMN", 692 | "name": "Isle of Man", 693 | "numeric": "833" 694 | }, 695 | { 696 | "alpha_2": "IN", 697 | "alpha_3": "IND", 698 | "name": "India", 699 | "numeric": "356", 700 | "official_name": "Republic of India" 701 | }, 702 | { 703 | "alpha_2": "IO", 704 | "alpha_3": "IOT", 705 | "name": "British Indian Ocean Territory", 706 | "numeric": "086" 707 | }, 708 | { 709 | "alpha_2": "IE", 710 | "alpha_3": "IRL", 711 | "name": "Ireland", 712 | "numeric": "372" 713 | }, 714 | { 715 | "alpha_2": "IR", 716 | "alpha_3": "IRN", 717 | "name": "Iran, Islamic Republic of", 718 | "numeric": "364", 719 | "official_name": "Islamic Republic of Iran" 720 | }, 721 | { 722 | "alpha_2": "IQ", 723 | "alpha_3": "IRQ", 724 | "name": "Iraq", 725 | "numeric": "368", 726 | "official_name": "Republic of Iraq" 727 | }, 728 | { 729 | "alpha_2": "IS", 730 | "alpha_3": "ISL", 731 | "name": "Iceland", 732 | "numeric": "352", 733 | "official_name": "Republic of Iceland" 734 | }, 735 | { 736 | "alpha_2": "IL", 737 | "alpha_3": "ISR", 738 | "name": "Israel", 739 | "numeric": "376", 740 | "official_name": "State of Israel" 741 | }, 742 | { 743 | "alpha_2": "IT", 744 | "alpha_3": "ITA", 745 | "name": "Italy", 746 | "numeric": "380", 747 | "official_name": "Italian Republic" 748 | }, 749 | { 750 | "alpha_2": "JM", 751 | "alpha_3": "JAM", 752 | "name": "Jamaica", 753 | "numeric": "388" 754 | }, 755 | { 756 | "alpha_2": "JE", 757 | "alpha_3": "JEY", 758 | "name": "Jersey", 759 | "numeric": "832" 760 | }, 761 | { 762 | "alpha_2": "JO", 763 | "alpha_3": "JOR", 764 | "name": "Jordan", 765 | "numeric": "400", 766 | "official_name": "Hashemite Kingdom of Jordan" 767 | }, 768 | { 769 | "alpha_2": "JP", 770 | "alpha_3": "JPN", 771 | "name": "Japan", 772 | "numeric": "392" 773 | }, 774 | { 775 | "alpha_2": "KZ", 776 | "alpha_3": "KAZ", 777 | "name": "Kazakhstan", 778 | "numeric": "398", 779 | "official_name": "Republic of Kazakhstan" 780 | }, 781 | { 782 | "alpha_2": "KE", 783 | "alpha_3": "KEN", 784 | "name": "Kenya", 785 | "numeric": "404", 786 | "official_name": "Republic of Kenya" 787 | }, 788 | { 789 | "alpha_2": "KG", 790 | "alpha_3": "KGZ", 791 | "name": "Kyrgyzstan", 792 | "numeric": "417", 793 | "official_name": "Kyrgyz Republic" 794 | }, 795 | { 796 | "alpha_2": "KH", 797 | "alpha_3": "KHM", 798 | "name": "Cambodia", 799 | "numeric": "116", 800 | "official_name": "Kingdom of Cambodia" 801 | }, 802 | { 803 | "alpha_2": "KI", 804 | "alpha_3": "KIR", 805 | "name": "Kiribati", 806 | "numeric": "296", 807 | "official_name": "Republic of Kiribati" 808 | }, 809 | { 810 | "alpha_2": "KN", 811 | "alpha_3": "KNA", 812 | "name": "Saint Kitts and Nevis", 813 | "numeric": "659" 814 | }, 815 | { 816 | "alpha_2": "KR", 817 | "alpha_3": "KOR", 818 | "name": "Korea, Republic of", 819 | "numeric": "410" 820 | }, 821 | { 822 | "alpha_2": "KW", 823 | "alpha_3": "KWT", 824 | "name": "Kuwait", 825 | "numeric": "414", 826 | "official_name": "State of Kuwait" 827 | }, 828 | { 829 | "alpha_2": "LA", 830 | "alpha_3": "LAO", 831 | "name": "Lao People's Democratic Republic", 832 | "numeric": "418" 833 | }, 834 | { 835 | "alpha_2": "LB", 836 | "alpha_3": "LBN", 837 | "name": "Lebanon", 838 | "numeric": "422", 839 | "official_name": "Lebanese Republic" 840 | }, 841 | { 842 | "alpha_2": "LR", 843 | "alpha_3": "LBR", 844 | "name": "Liberia", 845 | "numeric": "430", 846 | "official_name": "Republic of Liberia" 847 | }, 848 | { 849 | "alpha_2": "LY", 850 | "alpha_3": "LBY", 851 | "name": "Libya", 852 | "numeric": "434", 853 | "official_name": "Libya" 854 | }, 855 | { 856 | "alpha_2": "LC", 857 | "alpha_3": "LCA", 858 | "name": "Saint Lucia", 859 | "numeric": "662" 860 | }, 861 | { 862 | "alpha_2": "LI", 863 | "alpha_3": "LIE", 864 | "name": "Liechtenstein", 865 | "numeric": "438", 866 | "official_name": "Principality of Liechtenstein" 867 | }, 868 | { 869 | "alpha_2": "LK", 870 | "alpha_3": "LKA", 871 | "name": "Sri Lanka", 872 | "numeric": "144", 873 | "official_name": "Democratic Socialist Republic of Sri Lanka" 874 | }, 875 | { 876 | "alpha_2": "LS", 877 | "alpha_3": "LSO", 878 | "name": "Lesotho", 879 | "numeric": "426", 880 | "official_name": "Kingdom of Lesotho" 881 | }, 882 | { 883 | "alpha_2": "LT", 884 | "alpha_3": "LTU", 885 | "name": "Lithuania", 886 | "numeric": "440", 887 | "official_name": "Republic of Lithuania" 888 | }, 889 | { 890 | "alpha_2": "LU", 891 | "alpha_3": "LUX", 892 | "name": "Luxembourg", 893 | "numeric": "442", 894 | "official_name": "Grand Duchy of Luxembourg" 895 | }, 896 | { 897 | "alpha_2": "LV", 898 | "alpha_3": "LVA", 899 | "name": "Latvia", 900 | "numeric": "428", 901 | "official_name": "Republic of Latvia" 902 | }, 903 | { 904 | "alpha_2": "MO", 905 | "alpha_3": "MAC", 906 | "name": "Macao", 907 | "numeric": "446", 908 | "official_name": "Macao Special Administrative Region of China" 909 | }, 910 | { 911 | "alpha_2": "MF", 912 | "alpha_3": "MAF", 913 | "name": "Saint Martin (French part)", 914 | "numeric": "663" 915 | }, 916 | { 917 | "alpha_2": "MA", 918 | "alpha_3": "MAR", 919 | "name": "Morocco", 920 | "numeric": "504", 921 | "official_name": "Kingdom of Morocco" 922 | }, 923 | { 924 | "alpha_2": "MC", 925 | "alpha_3": "MCO", 926 | "name": "Monaco", 927 | "numeric": "492", 928 | "official_name": "Principality of Monaco" 929 | }, 930 | { 931 | "alpha_2": "MD", 932 | "alpha_3": "MDA", 933 | "common_name": "Moldova", 934 | "name": "Moldova, Republic of", 935 | "numeric": "498", 936 | "official_name": "Republic of Moldova" 937 | }, 938 | { 939 | "alpha_2": "MG", 940 | "alpha_3": "MDG", 941 | "name": "Madagascar", 942 | "numeric": "450", 943 | "official_name": "Republic of Madagascar" 944 | }, 945 | { 946 | "alpha_2": "MV", 947 | "alpha_3": "MDV", 948 | "name": "Maldives", 949 | "numeric": "462", 950 | "official_name": "Republic of Maldives" 951 | }, 952 | { 953 | "alpha_2": "MX", 954 | "alpha_3": "MEX", 955 | "name": "Mexico", 956 | "numeric": "484", 957 | "official_name": "United Mexican States" 958 | }, 959 | { 960 | "alpha_2": "MH", 961 | "alpha_3": "MHL", 962 | "name": "Marshall Islands", 963 | "numeric": "584", 964 | "official_name": "Republic of the Marshall Islands" 965 | }, 966 | { 967 | "alpha_2": "MK", 968 | "alpha_3": "MKD", 969 | "name": "Macedonia, Republic of", 970 | "numeric": "807", 971 | "official_name": "The Former Yugoslav Republic of Macedonia" 972 | }, 973 | { 974 | "alpha_2": "ML", 975 | "alpha_3": "MLI", 976 | "name": "Mali", 977 | "numeric": "466", 978 | "official_name": "Republic of Mali" 979 | }, 980 | { 981 | "alpha_2": "MT", 982 | "alpha_3": "MLT", 983 | "name": "Malta", 984 | "numeric": "470", 985 | "official_name": "Republic of Malta" 986 | }, 987 | { 988 | "alpha_2": "MM", 989 | "alpha_3": "MMR", 990 | "name": "Myanmar", 991 | "numeric": "104", 992 | "official_name": "Republic of Myanmar" 993 | }, 994 | { 995 | "alpha_2": "ME", 996 | "alpha_3": "MNE", 997 | "name": "Montenegro", 998 | "numeric": "499", 999 | "official_name": "Montenegro" 1000 | }, 1001 | { 1002 | "alpha_2": "MN", 1003 | "alpha_3": "MNG", 1004 | "name": "Mongolia", 1005 | "numeric": "496" 1006 | }, 1007 | { 1008 | "alpha_2": "MP", 1009 | "alpha_3": "MNP", 1010 | "name": "Northern Mariana Islands", 1011 | "numeric": "580", 1012 | "official_name": "Commonwealth of the Northern Mariana Islands" 1013 | }, 1014 | { 1015 | "alpha_2": "MZ", 1016 | "alpha_3": "MOZ", 1017 | "name": "Mozambique", 1018 | "numeric": "508", 1019 | "official_name": "Republic of Mozambique" 1020 | }, 1021 | { 1022 | "alpha_2": "MR", 1023 | "alpha_3": "MRT", 1024 | "name": "Mauritania", 1025 | "numeric": "478", 1026 | "official_name": "Islamic Republic of Mauritania" 1027 | }, 1028 | { 1029 | "alpha_2": "MS", 1030 | "alpha_3": "MSR", 1031 | "name": "Montserrat", 1032 | "numeric": "500" 1033 | }, 1034 | { 1035 | "alpha_2": "MQ", 1036 | "alpha_3": "MTQ", 1037 | "name": "Martinique", 1038 | "numeric": "474" 1039 | }, 1040 | { 1041 | "alpha_2": "MU", 1042 | "alpha_3": "MUS", 1043 | "name": "Mauritius", 1044 | "numeric": "480", 1045 | "official_name": "Republic of Mauritius" 1046 | }, 1047 | { 1048 | "alpha_2": "MW", 1049 | "alpha_3": "MWI", 1050 | "name": "Malawi", 1051 | "numeric": "454", 1052 | "official_name": "Republic of Malawi" 1053 | }, 1054 | { 1055 | "alpha_2": "MY", 1056 | "alpha_3": "MYS", 1057 | "name": "Malaysia", 1058 | "numeric": "458" 1059 | }, 1060 | { 1061 | "alpha_2": "YT", 1062 | "alpha_3": "MYT", 1063 | "name": "Mayotte", 1064 | "numeric": "175" 1065 | }, 1066 | { 1067 | "alpha_2": "NA", 1068 | "alpha_3": "NAM", 1069 | "name": "Namibia", 1070 | "numeric": "516", 1071 | "official_name": "Republic of Namibia" 1072 | }, 1073 | { 1074 | "alpha_2": "NC", 1075 | "alpha_3": "NCL", 1076 | "name": "New Caledonia", 1077 | "numeric": "540" 1078 | }, 1079 | { 1080 | "alpha_2": "NE", 1081 | "alpha_3": "NER", 1082 | "name": "Niger", 1083 | "numeric": "562", 1084 | "official_name": "Republic of the Niger" 1085 | }, 1086 | { 1087 | "alpha_2": "NF", 1088 | "alpha_3": "NFK", 1089 | "name": "Norfolk Island", 1090 | "numeric": "574" 1091 | }, 1092 | { 1093 | "alpha_2": "NG", 1094 | "alpha_3": "NGA", 1095 | "name": "Nigeria", 1096 | "numeric": "566", 1097 | "official_name": "Federal Republic of Nigeria" 1098 | }, 1099 | { 1100 | "alpha_2": "NI", 1101 | "alpha_3": "NIC", 1102 | "name": "Nicaragua", 1103 | "numeric": "558", 1104 | "official_name": "Republic of Nicaragua" 1105 | }, 1106 | { 1107 | "alpha_2": "NU", 1108 | "alpha_3": "NIU", 1109 | "name": "Niue", 1110 | "numeric": "570", 1111 | "official_name": "Niue" 1112 | }, 1113 | { 1114 | "alpha_2": "NL", 1115 | "alpha_3": "NLD", 1116 | "name": "Netherlands", 1117 | "numeric": "528", 1118 | "official_name": "Kingdom of the Netherlands" 1119 | }, 1120 | { 1121 | "alpha_2": "NO", 1122 | "alpha_3": "NOR", 1123 | "name": "Norway", 1124 | "numeric": "578", 1125 | "official_name": "Kingdom of Norway" 1126 | }, 1127 | { 1128 | "alpha_2": "NP", 1129 | "alpha_3": "NPL", 1130 | "name": "Nepal", 1131 | "numeric": "524", 1132 | "official_name": "Federal Democratic Republic of Nepal" 1133 | }, 1134 | { 1135 | "alpha_2": "NR", 1136 | "alpha_3": "NRU", 1137 | "name": "Nauru", 1138 | "numeric": "520", 1139 | "official_name": "Republic of Nauru" 1140 | }, 1141 | { 1142 | "alpha_2": "NZ", 1143 | "alpha_3": "NZL", 1144 | "name": "New Zealand", 1145 | "numeric": "554" 1146 | }, 1147 | { 1148 | "alpha_2": "OM", 1149 | "alpha_3": "OMN", 1150 | "name": "Oman", 1151 | "numeric": "512", 1152 | "official_name": "Sultanate of Oman" 1153 | }, 1154 | { 1155 | "alpha_2": "PK", 1156 | "alpha_3": "PAK", 1157 | "name": "Pakistan", 1158 | "numeric": "586", 1159 | "official_name": "Islamic Republic of Pakistan" 1160 | }, 1161 | { 1162 | "alpha_2": "PA", 1163 | "alpha_3": "PAN", 1164 | "name": "Panama", 1165 | "numeric": "591", 1166 | "official_name": "Republic of Panama" 1167 | }, 1168 | { 1169 | "alpha_2": "PN", 1170 | "alpha_3": "PCN", 1171 | "name": "Pitcairn", 1172 | "numeric": "612" 1173 | }, 1174 | { 1175 | "alpha_2": "PE", 1176 | "alpha_3": "PER", 1177 | "name": "Peru", 1178 | "numeric": "604", 1179 | "official_name": "Republic of Peru" 1180 | }, 1181 | { 1182 | "alpha_2": "PH", 1183 | "alpha_3": "PHL", 1184 | "name": "Philippines", 1185 | "numeric": "608", 1186 | "official_name": "Republic of the Philippines" 1187 | }, 1188 | { 1189 | "alpha_2": "PW", 1190 | "alpha_3": "PLW", 1191 | "name": "Palau", 1192 | "numeric": "585", 1193 | "official_name": "Republic of Palau" 1194 | }, 1195 | { 1196 | "alpha_2": "PG", 1197 | "alpha_3": "PNG", 1198 | "name": "Papua New Guinea", 1199 | "numeric": "598", 1200 | "official_name": "Independent State of Papua New Guinea" 1201 | }, 1202 | { 1203 | "alpha_2": "PL", 1204 | "alpha_3": "POL", 1205 | "name": "Poland", 1206 | "numeric": "616", 1207 | "official_name": "Republic of Poland" 1208 | }, 1209 | { 1210 | "alpha_2": "PR", 1211 | "alpha_3": "PRI", 1212 | "name": "Puerto Rico", 1213 | "numeric": "630" 1214 | }, 1215 | { 1216 | "alpha_2": "KP", 1217 | "alpha_3": "PRK", 1218 | "name": "Korea, Democratic People's Republic of", 1219 | "numeric": "408", 1220 | "official_name": "Democratic People's Republic of Korea" 1221 | }, 1222 | { 1223 | "alpha_2": "PT", 1224 | "alpha_3": "PRT", 1225 | "name": "Portugal", 1226 | "numeric": "620", 1227 | "official_name": "Portuguese Republic" 1228 | }, 1229 | { 1230 | "alpha_2": "PY", 1231 | "alpha_3": "PRY", 1232 | "name": "Paraguay", 1233 | "numeric": "600", 1234 | "official_name": "Republic of Paraguay" 1235 | }, 1236 | { 1237 | "alpha_2": "PS", 1238 | "alpha_3": "PSE", 1239 | "name": "Palestine, State of", 1240 | "numeric": "275", 1241 | "official_name": "the State of Palestine" 1242 | }, 1243 | { 1244 | "alpha_2": "PF", 1245 | "alpha_3": "PYF", 1246 | "name": "French Polynesia", 1247 | "numeric": "258" 1248 | }, 1249 | { 1250 | "alpha_2": "QA", 1251 | "alpha_3": "QAT", 1252 | "name": "Qatar", 1253 | "numeric": "634", 1254 | "official_name": "State of Qatar" 1255 | }, 1256 | { 1257 | "alpha_2": "RE", 1258 | "alpha_3": "REU", 1259 | "name": "Réunion", 1260 | "numeric": "638" 1261 | }, 1262 | { 1263 | "alpha_2": "RO", 1264 | "alpha_3": "ROU", 1265 | "name": "Romania", 1266 | "numeric": "642" 1267 | }, 1268 | { 1269 | "alpha_2": "RU", 1270 | "alpha_3": "RUS", 1271 | "name": "Russian Federation", 1272 | "numeric": "643" 1273 | }, 1274 | { 1275 | "alpha_2": "RW", 1276 | "alpha_3": "RWA", 1277 | "name": "Rwanda", 1278 | "numeric": "646", 1279 | "official_name": "Rwandese Republic" 1280 | }, 1281 | { 1282 | "alpha_2": "SA", 1283 | "alpha_3": "SAU", 1284 | "name": "Saudi Arabia", 1285 | "numeric": "682", 1286 | "official_name": "Kingdom of Saudi Arabia" 1287 | }, 1288 | { 1289 | "alpha_2": "SD", 1290 | "alpha_3": "SDN", 1291 | "name": "Sudan", 1292 | "numeric": "729", 1293 | "official_name": "Republic of the Sudan" 1294 | }, 1295 | { 1296 | "alpha_2": "SN", 1297 | "alpha_3": "SEN", 1298 | "name": "Senegal", 1299 | "numeric": "686", 1300 | "official_name": "Republic of Senegal" 1301 | }, 1302 | { 1303 | "alpha_2": "SG", 1304 | "alpha_3": "SGP", 1305 | "name": "Singapore", 1306 | "numeric": "702", 1307 | "official_name": "Republic of Singapore" 1308 | }, 1309 | { 1310 | "alpha_2": "GS", 1311 | "alpha_3": "SGS", 1312 | "name": "South Georgia and the South Sandwich Islands", 1313 | "numeric": "239" 1314 | }, 1315 | { 1316 | "alpha_2": "SH", 1317 | "alpha_3": "SHN", 1318 | "name": "Saint Helena, Ascension and Tristan da Cunha", 1319 | "numeric": "654" 1320 | }, 1321 | { 1322 | "alpha_2": "SJ", 1323 | "alpha_3": "SJM", 1324 | "name": "Svalbard and Jan Mayen", 1325 | "numeric": "744" 1326 | }, 1327 | { 1328 | "alpha_2": "SB", 1329 | "alpha_3": "SLB", 1330 | "name": "Solomon Islands", 1331 | "numeric": "090" 1332 | }, 1333 | { 1334 | "alpha_2": "SL", 1335 | "alpha_3": "SLE", 1336 | "name": "Sierra Leone", 1337 | "numeric": "694", 1338 | "official_name": "Republic of Sierra Leone" 1339 | }, 1340 | { 1341 | "alpha_2": "SV", 1342 | "alpha_3": "SLV", 1343 | "name": "El Salvador", 1344 | "numeric": "222", 1345 | "official_name": "Republic of El Salvador" 1346 | }, 1347 | { 1348 | "alpha_2": "SM", 1349 | "alpha_3": "SMR", 1350 | "name": "San Marino", 1351 | "numeric": "674", 1352 | "official_name": "Republic of San Marino" 1353 | }, 1354 | { 1355 | "alpha_2": "SO", 1356 | "alpha_3": "SOM", 1357 | "name": "Somalia", 1358 | "numeric": "706", 1359 | "official_name": "Federal Republic of Somalia" 1360 | }, 1361 | { 1362 | "alpha_2": "PM", 1363 | "alpha_3": "SPM", 1364 | "name": "Saint Pierre and Miquelon", 1365 | "numeric": "666" 1366 | }, 1367 | { 1368 | "alpha_2": "RS", 1369 | "alpha_3": "SRB", 1370 | "name": "Serbia", 1371 | "numeric": "688", 1372 | "official_name": "Republic of Serbia" 1373 | }, 1374 | { 1375 | "alpha_2": "SS", 1376 | "alpha_3": "SSD", 1377 | "name": "South Sudan", 1378 | "numeric": "728", 1379 | "official_name": "Republic of South Sudan" 1380 | }, 1381 | { 1382 | "alpha_2": "ST", 1383 | "alpha_3": "STP", 1384 | "name": "Sao Tome and Principe", 1385 | "numeric": "678", 1386 | "official_name": "Democratic Republic of Sao Tome and Principe" 1387 | }, 1388 | { 1389 | "alpha_2": "SR", 1390 | "alpha_3": "SUR", 1391 | "name": "Suriname", 1392 | "numeric": "740", 1393 | "official_name": "Republic of Suriname" 1394 | }, 1395 | { 1396 | "alpha_2": "SK", 1397 | "alpha_3": "SVK", 1398 | "name": "Slovakia", 1399 | "numeric": "703", 1400 | "official_name": "Slovak Republic" 1401 | }, 1402 | { 1403 | "alpha_2": "SI", 1404 | "alpha_3": "SVN", 1405 | "name": "Slovenia", 1406 | "numeric": "705", 1407 | "official_name": "Republic of Slovenia" 1408 | }, 1409 | { 1410 | "alpha_2": "SE", 1411 | "alpha_3": "SWE", 1412 | "name": "Sweden", 1413 | "numeric": "752", 1414 | "official_name": "Kingdom of Sweden" 1415 | }, 1416 | { 1417 | "alpha_2": "SZ", 1418 | "alpha_3": "SWZ", 1419 | "name": "Swaziland", 1420 | "numeric": "748", 1421 | "official_name": "Kingdom of Swaziland" 1422 | }, 1423 | { 1424 | "alpha_2": "SX", 1425 | "alpha_3": "SXM", 1426 | "name": "Sint Maarten (Dutch part)", 1427 | "numeric": "534", 1428 | "official_name": "Sint Maarten (Dutch part)" 1429 | }, 1430 | { 1431 | "alpha_2": "SC", 1432 | "alpha_3": "SYC", 1433 | "name": "Seychelles", 1434 | "numeric": "690", 1435 | "official_name": "Republic of Seychelles" 1436 | }, 1437 | { 1438 | "alpha_2": "SY", 1439 | "alpha_3": "SYR", 1440 | "name": "Syrian Arab Republic", 1441 | "numeric": "760" 1442 | }, 1443 | { 1444 | "alpha_2": "TC", 1445 | "alpha_3": "TCA", 1446 | "name": "Turks and Caicos Islands", 1447 | "numeric": "796" 1448 | }, 1449 | { 1450 | "alpha_2": "TD", 1451 | "alpha_3": "TCD", 1452 | "name": "Chad", 1453 | "numeric": "148", 1454 | "official_name": "Republic of Chad" 1455 | }, 1456 | { 1457 | "alpha_2": "TG", 1458 | "alpha_3": "TGO", 1459 | "name": "Togo", 1460 | "numeric": "768", 1461 | "official_name": "Togolese Republic" 1462 | }, 1463 | { 1464 | "alpha_2": "TH", 1465 | "alpha_3": "THA", 1466 | "name": "Thailand", 1467 | "numeric": "764", 1468 | "official_name": "Kingdom of Thailand" 1469 | }, 1470 | { 1471 | "alpha_2": "TJ", 1472 | "alpha_3": "TJK", 1473 | "name": "Tajikistan", 1474 | "numeric": "762", 1475 | "official_name": "Republic of Tajikistan" 1476 | }, 1477 | { 1478 | "alpha_2": "TK", 1479 | "alpha_3": "TKL", 1480 | "name": "Tokelau", 1481 | "numeric": "772" 1482 | }, 1483 | { 1484 | "alpha_2": "TM", 1485 | "alpha_3": "TKM", 1486 | "name": "Turkmenistan", 1487 | "numeric": "795" 1488 | }, 1489 | { 1490 | "alpha_2": "TL", 1491 | "alpha_3": "TLS", 1492 | "name": "Timor-Leste", 1493 | "numeric": "626", 1494 | "official_name": "Democratic Republic of Timor-Leste" 1495 | }, 1496 | { 1497 | "alpha_2": "TO", 1498 | "alpha_3": "TON", 1499 | "name": "Tonga", 1500 | "numeric": "776", 1501 | "official_name": "Kingdom of Tonga" 1502 | }, 1503 | { 1504 | "alpha_2": "TT", 1505 | "alpha_3": "TTO", 1506 | "name": "Trinidad and Tobago", 1507 | "numeric": "780", 1508 | "official_name": "Republic of Trinidad and Tobago" 1509 | }, 1510 | { 1511 | "alpha_2": "TN", 1512 | "alpha_3": "TUN", 1513 | "name": "Tunisia", 1514 | "numeric": "788", 1515 | "official_name": "Republic of Tunisia" 1516 | }, 1517 | { 1518 | "alpha_2": "TR", 1519 | "alpha_3": "TUR", 1520 | "name": "Turkey", 1521 | "numeric": "792", 1522 | "official_name": "Republic of Turkey" 1523 | }, 1524 | { 1525 | "alpha_2": "TV", 1526 | "alpha_3": "TUV", 1527 | "name": "Tuvalu", 1528 | "numeric": "798" 1529 | }, 1530 | { 1531 | "alpha_2": "TW", 1532 | "alpha_3": "TWN", 1533 | "common_name": "Taiwan", 1534 | "name": "Taiwan, Province of China", 1535 | "numeric": "158", 1536 | "official_name": "Taiwan, Province of China" 1537 | }, 1538 | { 1539 | "alpha_2": "TZ", 1540 | "alpha_3": "TZA", 1541 | "common_name": "Tanzania", 1542 | "name": "Tanzania, United Republic of", 1543 | "numeric": "834", 1544 | "official_name": "United Republic of Tanzania" 1545 | }, 1546 | { 1547 | "alpha_2": "UG", 1548 | "alpha_3": "UGA", 1549 | "name": "Uganda", 1550 | "numeric": "800", 1551 | "official_name": "Republic of Uganda" 1552 | }, 1553 | { 1554 | "alpha_2": "UA", 1555 | "alpha_3": "UKR", 1556 | "name": "Ukraine", 1557 | "numeric": "804" 1558 | }, 1559 | { 1560 | "alpha_2": "UM", 1561 | "alpha_3": "UMI", 1562 | "name": "United States Minor Outlying Islands", 1563 | "numeric": "581" 1564 | }, 1565 | { 1566 | "alpha_2": "UY", 1567 | "alpha_3": "URY", 1568 | "name": "Uruguay", 1569 | "numeric": "858", 1570 | "official_name": "Eastern Republic of Uruguay" 1571 | }, 1572 | { 1573 | "alpha_2": "US", 1574 | "alpha_3": "USA", 1575 | "name": "United States", 1576 | "numeric": "840", 1577 | "official_name": "United States of America" 1578 | }, 1579 | { 1580 | "alpha_2": "UZ", 1581 | "alpha_3": "UZB", 1582 | "name": "Uzbekistan", 1583 | "numeric": "860", 1584 | "official_name": "Republic of Uzbekistan" 1585 | }, 1586 | { 1587 | "alpha_2": "VA", 1588 | "alpha_3": "VAT", 1589 | "name": "Holy See (Vatican City State)", 1590 | "numeric": "336" 1591 | }, 1592 | { 1593 | "alpha_2": "VC", 1594 | "alpha_3": "VCT", 1595 | "name": "Saint Vincent and the Grenadines", 1596 | "numeric": "670" 1597 | }, 1598 | { 1599 | "alpha_2": "VE", 1600 | "alpha_3": "VEN", 1601 | "common_name": "Venezuela", 1602 | "name": "Venezuela, Bolivarian Republic of", 1603 | "numeric": "862", 1604 | "official_name": "Bolivarian Republic of Venezuela" 1605 | }, 1606 | { 1607 | "alpha_2": "VG", 1608 | "alpha_3": "VGB", 1609 | "name": "Virgin Islands, British", 1610 | "numeric": "092", 1611 | "official_name": "British Virgin Islands" 1612 | }, 1613 | { 1614 | "alpha_2": "VI", 1615 | "alpha_3": "VIR", 1616 | "name": "Virgin Islands, U.S.", 1617 | "numeric": "850", 1618 | "official_name": "Virgin Islands of the United States" 1619 | }, 1620 | { 1621 | "alpha_2": "VN", 1622 | "alpha_3": "VNM", 1623 | "common_name": "Vietnam", 1624 | "name": "Viet Nam", 1625 | "numeric": "704", 1626 | "official_name": "Socialist Republic of Viet Nam" 1627 | }, 1628 | { 1629 | "alpha_2": "VU", 1630 | "alpha_3": "VUT", 1631 | "name": "Vanuatu", 1632 | "numeric": "548", 1633 | "official_name": "Republic of Vanuatu" 1634 | }, 1635 | { 1636 | "alpha_2": "WF", 1637 | "alpha_3": "WLF", 1638 | "name": "Wallis and Futuna", 1639 | "numeric": "876" 1640 | }, 1641 | { 1642 | "alpha_2": "WS", 1643 | "alpha_3": "WSM", 1644 | "name": "Samoa", 1645 | "numeric": "882", 1646 | "official_name": "Independent State of Samoa" 1647 | }, 1648 | { 1649 | "alpha_2": "YE", 1650 | "alpha_3": "YEM", 1651 | "name": "Yemen", 1652 | "numeric": "887", 1653 | "official_name": "Republic of Yemen" 1654 | }, 1655 | { 1656 | "alpha_2": "ZA", 1657 | "alpha_3": "ZAF", 1658 | "name": "South Africa", 1659 | "numeric": "710", 1660 | "official_name": "Republic of South Africa" 1661 | }, 1662 | { 1663 | "alpha_2": "ZM", 1664 | "alpha_3": "ZMB", 1665 | "name": "Zambia", 1666 | "numeric": "894", 1667 | "official_name": "Republic of Zambia" 1668 | }, 1669 | { 1670 | "alpha_2": "ZW", 1671 | "alpha_3": "ZWE", 1672 | "name": "Zimbabwe", 1673 | "numeric": "716", 1674 | "official_name": "Republic of Zimbabwe" 1675 | } 1676 | ] 1677 | } 1678 | --------------------------------------------------------------------------------