kensho-kfinance 1.0.3__tar.gz → 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of kensho-kfinance might be problematic. Click here for more details.
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/.gitignore +2 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/PKG-INFO +9 -3
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/README.md +6 -1
- kensho_kfinance-1.1.0/justfile +31 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kensho_kfinance.egg-info/PKG-INFO +9 -3
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kensho_kfinance.egg-info/SOURCES.txt +1 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kfinance/CHANGELOG.md +3 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kfinance/fetch.py +22 -1
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kfinance/llm_tools.py +56 -1
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kfinance/meta_classes.py +74 -4
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kfinance/tests/test_fetch.py +32 -2
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kfinance/tests/test_objects.py +37 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kfinance/tool_schemas.py +14 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kfinance/version.py +2 -2
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/scripts/lint.sh +4 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/.coveragerc +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/.github/workflows/ci-lint.yml +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/.github/workflows/ci-test.yml +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/.github/workflows/python-publish.yml +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/AUTHORS.md +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/CODE_OF_CONDUCT.md +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/CONTRIBUTING.md +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/LICENSE +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/docs/index.rst +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/docs/kfinance.rst +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/docs/llm_tools.rst +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kensho_kfinance.egg-info/dependency_links.txt +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kensho_kfinance.egg-info/requires.txt +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kensho_kfinance.egg-info/top_level.txt +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kfinance/__init__.py +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kfinance/constants.py +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kfinance/kfinance.py +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kfinance/prompt.py +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kfinance/py.typed +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kfinance/server_thread.py +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kfinance/tests/__init__.py +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/pyproject.toml +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/scripts/copyright_line_check.sh +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/scripts/docs/make_rst.py +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/scripts/test.sh +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/setup.cfg +0 -0
- {kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: kensho-kfinance
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: Python CLI for kFinance
|
|
5
5
|
Author-email: Luke Brown <luke.brown@kensho.com>, Michelle Keoy <michelle.keoy@kensho.com>, Keith Page <keith.page@kensho.com>, Matthew Rosen <matthew.rosen@kensho.com>, Nick Roshdieh <nick.roshdieh@kensho.com>
|
|
6
6
|
Project-URL: source, https://github.com/kensho-technologies/kfinance
|
|
@@ -28,6 +28,7 @@ Requires-Dist: mypy<2,>=1.15.0; extra == "dev"
|
|
|
28
28
|
Requires-Dist: pytest<7,>=6.1.2; extra == "dev"
|
|
29
29
|
Requires-Dist: pytest-cov<7,>=6.0.0; extra == "dev"
|
|
30
30
|
Requires-Dist: ruff<1,>=0.9.4; extra == "dev"
|
|
31
|
+
Dynamic: license-file
|
|
31
32
|
|
|
32
33
|
# kFinance
|
|
33
34
|
|
|
@@ -39,7 +40,7 @@ Any questions or suggestions can be sent to the [kFinance Maintainers](kfinance-
|
|
|
39
40
|
|
|
40
41
|
# Setup
|
|
41
42
|
|
|
42
|
-
You can install kFinance on [PyPI](https://pypi.org/project/kfinance/) via
|
|
43
|
+
You can install kFinance on [PyPI](https://pypi.org/project/kensho-kfinance/) via
|
|
43
44
|
|
|
44
45
|
`pip install kensho-kfinance`
|
|
45
46
|
|
|
@@ -49,6 +50,11 @@ To receive access, please email [S&P Global Market Intelligence](market.intellig
|
|
|
49
50
|
|
|
50
51
|
Once access is obtained, get started using the [Authentication Guide](https://docs.kensho.com/llmreadyapi/kf-authentication) and [Usage Guide](https://docs.kensho.com/llmreadyapi/usage).
|
|
51
52
|
|
|
53
|
+
# Versioning
|
|
54
|
+
The kFinance uses semantic versioning (major, minor, patch).
|
|
55
|
+
To bump the version, add a new entry in [CHANGELOG.md](kfinance%2FCHANGELOG.md).
|
|
56
|
+
This will generate a new version of the library as part of the release process.
|
|
57
|
+
|
|
52
58
|
# License
|
|
53
59
|
|
|
54
60
|
Use is solely in accordance with the signed agreement between your entity and S&P.
|
|
@@ -8,7 +8,7 @@ Any questions or suggestions can be sent to the [kFinance Maintainers](kfinance-
|
|
|
8
8
|
|
|
9
9
|
# Setup
|
|
10
10
|
|
|
11
|
-
You can install kFinance on [PyPI](https://pypi.org/project/kfinance/) via
|
|
11
|
+
You can install kFinance on [PyPI](https://pypi.org/project/kensho-kfinance/) via
|
|
12
12
|
|
|
13
13
|
`pip install kensho-kfinance`
|
|
14
14
|
|
|
@@ -18,6 +18,11 @@ To receive access, please email [S&P Global Market Intelligence](market.intellig
|
|
|
18
18
|
|
|
19
19
|
Once access is obtained, get started using the [Authentication Guide](https://docs.kensho.com/llmreadyapi/kf-authentication) and [Usage Guide](https://docs.kensho.com/llmreadyapi/usage).
|
|
20
20
|
|
|
21
|
+
# Versioning
|
|
22
|
+
The kFinance uses semantic versioning (major, minor, patch).
|
|
23
|
+
To bump the version, add a new entry in [CHANGELOG.md](kfinance%2FCHANGELOG.md).
|
|
24
|
+
This will generate a new version of the library as part of the release process.
|
|
25
|
+
|
|
21
26
|
# License
|
|
22
27
|
|
|
23
28
|
Use is solely in accordance with the signed agreement between your entity and S&P.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
set dotenv-load
|
|
2
|
+
|
|
3
|
+
# Just is a command runner. It can be used to provide a shorthand to run
|
|
4
|
+
# complex commands, for example `just lint` for `python -m kensho_lint.lint...`
|
|
5
|
+
|
|
6
|
+
# Here are some installation instructions:
|
|
7
|
+
# https://github.com/casey/just?tab=readme-ov-file#installation
|
|
8
|
+
# Once installed, you can run any of the commands in this file by
|
|
9
|
+
# prepending them with `just`, for example `just lint` to run the linter.
|
|
10
|
+
# Run `just` shows a list of all available commands
|
|
11
|
+
|
|
12
|
+
# If there are commands that you believe can be useful to other contributors,
|
|
13
|
+
# feel free to add them.
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
default:
|
|
17
|
+
just --list
|
|
18
|
+
|
|
19
|
+
alias l := lint
|
|
20
|
+
# Lint the app directory (both lint and l work). For verbose, use `just lint --verbose`
|
|
21
|
+
lint *args:
|
|
22
|
+
python -m mypy --config-file pyproject.toml kfinance {{args}}
|
|
23
|
+
# The ruff linters (check) and formatters (format) are separate.
|
|
24
|
+
# See https://docs.astral.sh/ruff/formatter/#sorting-imports
|
|
25
|
+
python -m ruff --config pyproject.toml check kfinance --fix {{args}}
|
|
26
|
+
python -m ruff --config pyproject.toml format kfinance {{args}}
|
|
27
|
+
|
|
28
|
+
alias t := unit-test
|
|
29
|
+
# Run unit tests. Use args for optional settings
|
|
30
|
+
unit-test *args:
|
|
31
|
+
python -m pytest {{args}}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: kensho-kfinance
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.1.0
|
|
4
4
|
Summary: Python CLI for kFinance
|
|
5
5
|
Author-email: Luke Brown <luke.brown@kensho.com>, Michelle Keoy <michelle.keoy@kensho.com>, Keith Page <keith.page@kensho.com>, Matthew Rosen <matthew.rosen@kensho.com>, Nick Roshdieh <nick.roshdieh@kensho.com>
|
|
6
6
|
Project-URL: source, https://github.com/kensho-technologies/kfinance
|
|
@@ -28,6 +28,7 @@ Requires-Dist: mypy<2,>=1.15.0; extra == "dev"
|
|
|
28
28
|
Requires-Dist: pytest<7,>=6.1.2; extra == "dev"
|
|
29
29
|
Requires-Dist: pytest-cov<7,>=6.0.0; extra == "dev"
|
|
30
30
|
Requires-Dist: ruff<1,>=0.9.4; extra == "dev"
|
|
31
|
+
Dynamic: license-file
|
|
31
32
|
|
|
32
33
|
# kFinance
|
|
33
34
|
|
|
@@ -39,7 +40,7 @@ Any questions or suggestions can be sent to the [kFinance Maintainers](kfinance-
|
|
|
39
40
|
|
|
40
41
|
# Setup
|
|
41
42
|
|
|
42
|
-
You can install kFinance on [PyPI](https://pypi.org/project/kfinance/) via
|
|
43
|
+
You can install kFinance on [PyPI](https://pypi.org/project/kensho-kfinance/) via
|
|
43
44
|
|
|
44
45
|
`pip install kensho-kfinance`
|
|
45
46
|
|
|
@@ -49,6 +50,11 @@ To receive access, please email [S&P Global Market Intelligence](market.intellig
|
|
|
49
50
|
|
|
50
51
|
Once access is obtained, get started using the [Authentication Guide](https://docs.kensho.com/llmreadyapi/kf-authentication) and [Usage Guide](https://docs.kensho.com/llmreadyapi/usage).
|
|
51
52
|
|
|
53
|
+
# Versioning
|
|
54
|
+
The kFinance uses semantic versioning (major, minor, patch).
|
|
55
|
+
To bump the version, add a new entry in [CHANGELOG.md](kfinance%2FCHANGELOG.md).
|
|
56
|
+
This will generate a new version of the library as part of the release process.
|
|
57
|
+
|
|
52
58
|
# License
|
|
53
59
|
|
|
54
60
|
Use is solely in accordance with the signed agreement between your entity and S&P.
|
|
@@ -5,7 +5,14 @@ import jwt
|
|
|
5
5
|
import requests
|
|
6
6
|
|
|
7
7
|
from .constants import BusinessRelationshipType, IdentificationTriple
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# version.py gets autogenerated by setuptools-scm and is not available
|
|
11
|
+
# during local development.
|
|
12
|
+
try:
|
|
13
|
+
from .version import __version__ as kfinance_version
|
|
14
|
+
except ImportError:
|
|
15
|
+
kfinance_version = "dev"
|
|
9
16
|
|
|
10
17
|
|
|
11
18
|
DEFAULT_API_HOST: str = "https://kfinance.kensho.com"
|
|
@@ -175,6 +182,20 @@ class KFinanceApiClient:
|
|
|
175
182
|
url = f"{self.url_base}pricing/{trading_item_id}/metadata"
|
|
176
183
|
return self.fetch(url)
|
|
177
184
|
|
|
185
|
+
def fetch_market_caps_tevs_and_shares_outstanding(
|
|
186
|
+
self,
|
|
187
|
+
company_id: int,
|
|
188
|
+
start_date: Optional[str] = None,
|
|
189
|
+
end_date: Optional[str] = None,
|
|
190
|
+
) -> dict:
|
|
191
|
+
"""Get the market cap, TEV, and shares outstanding for a company."""
|
|
192
|
+
url = (
|
|
193
|
+
f"{self.url_base}market_cap/{company_id}/"
|
|
194
|
+
f"{start_date if start_date is not None else 'none'}/"
|
|
195
|
+
f"{end_date if end_date is not None else 'none'}"
|
|
196
|
+
)
|
|
197
|
+
return self.fetch(url)
|
|
198
|
+
|
|
178
199
|
def fetch_price_chart(
|
|
179
200
|
self,
|
|
180
201
|
trading_item_id: int,
|
|
@@ -4,7 +4,7 @@ import copy
|
|
|
4
4
|
import datetime
|
|
5
5
|
from enum import Enum
|
|
6
6
|
from functools import partial
|
|
7
|
-
from typing import TYPE_CHECKING, Callable
|
|
7
|
+
from typing import TYPE_CHECKING, Callable, Literal
|
|
8
8
|
|
|
9
9
|
from langchain_core.tools import StructuredTool
|
|
10
10
|
|
|
@@ -210,6 +210,31 @@ def get_prices_from_identifier(
|
|
|
210
210
|
)
|
|
211
211
|
|
|
212
212
|
|
|
213
|
+
def get_capitalization_from_identifier(
|
|
214
|
+
self: Client,
|
|
215
|
+
identifier: str,
|
|
216
|
+
capitalization: Literal["market_cap", "tev", "shares_outstanding"],
|
|
217
|
+
start_date: str | None = None,
|
|
218
|
+
end_date: str | None = None,
|
|
219
|
+
) -> str:
|
|
220
|
+
"""Get the historical market cap, tev (Total Enterprise Value), or shares outstanding of an identifier, where the identifier can be a ticker, ISIN or CUSIP, between inclusive start_date and inclusive end date.
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
identifier: A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.
|
|
224
|
+
capitalization: The capitalization to retrieve (market_cap, tev, or shares_outstanding)
|
|
225
|
+
start_date: The start date for historical price retrieval in format YYYY-MM-DD
|
|
226
|
+
end_date: The end date for historical price retrieval in format YYYY-MM-DD
|
|
227
|
+
"""
|
|
228
|
+
ticker = self.ticker(identifier)
|
|
229
|
+
capitalization_to_func: dict[Literal["market_cap", "tev", "shares_outstanding"], Callable] = {
|
|
230
|
+
"market_cap": ticker.market_cap,
|
|
231
|
+
"tev": ticker.tev,
|
|
232
|
+
"shares_outstanding": ticker.shares_outstanding,
|
|
233
|
+
}
|
|
234
|
+
func = capitalization_to_func[capitalization]
|
|
235
|
+
return func(start_date=start_date, end_date=end_date).to_markdown()
|
|
236
|
+
|
|
237
|
+
|
|
213
238
|
def get_financial_statement_from_identifier(
|
|
214
239
|
self: Client,
|
|
215
240
|
identifier: str,
|
|
@@ -297,6 +322,7 @@ def _llm_tools(self: Client) -> dict[str, Callable]:
|
|
|
297
322
|
),
|
|
298
323
|
"get_history_metadata_from_identifier": partial(get_history_metadata_from_identifier, self),
|
|
299
324
|
"get_prices_from_identifier": partial(get_prices_from_identifier, self),
|
|
325
|
+
"get_capitalization_from_identifier": partial(get_capitalization_from_identifier, self),
|
|
300
326
|
"get_financial_statement_from_identifier": partial(
|
|
301
327
|
get_financial_statement_from_identifier, self
|
|
302
328
|
),
|
|
@@ -323,6 +349,7 @@ def _llm_tool_metadata() -> dict:
|
|
|
323
349
|
"get_earnings_call_datetimes_from_identifier": tool_schemas.GetEarningsCallDatetimesFromIdentifier,
|
|
324
350
|
"get_history_metadata_from_identifier": tool_schemas.GetHistoryMetadataFromIdentifier,
|
|
325
351
|
"get_prices_from_identifier": tool_schemas.GetPricesFromIdentifier,
|
|
352
|
+
"get_capitalization_from_identifier": tool_schemas.GetCapitalizationFromIdentifier,
|
|
326
353
|
"get_financial_statement_from_identifier": tool_schemas.GetFinancialStatementFromIdentifier,
|
|
327
354
|
"get_financial_line_item_from_identifier": tool_schemas.GetFinancialLineItemFromIdentifier,
|
|
328
355
|
"get_business_relationship_from_identifier": tool_schemas.GetBusinessRelationshipFromIdentifier,
|
|
@@ -516,6 +543,34 @@ _base_tool_descriptions = [
|
|
|
516
543
|
"additionalProperties": False,
|
|
517
544
|
},
|
|
518
545
|
},
|
|
546
|
+
{
|
|
547
|
+
"name": "get_capitalization_from_identifier",
|
|
548
|
+
"description": "Get the historical market cap, tev (Total Enterprise Value), or shares outstanding of an identifier, where the identifier can be a ticker, ISIN or CUSIP, between inclusive start_date and inclusive end date.",
|
|
549
|
+
"input_schema": {
|
|
550
|
+
"type": "object",
|
|
551
|
+
"properties": {
|
|
552
|
+
"identifier": {
|
|
553
|
+
"type": "string",
|
|
554
|
+
"description": "A unique identifier, which can be a ticker symbol, ISIN, or CUSIP.",
|
|
555
|
+
},
|
|
556
|
+
"capitalization": {
|
|
557
|
+
"type": "string",
|
|
558
|
+
"description": "The capitalization to retrieve (market_cap, tev, or shares_outstanding).",
|
|
559
|
+
"enum": ["market_cap", "tev", "shares_outstanding"],
|
|
560
|
+
},
|
|
561
|
+
"start_date": {
|
|
562
|
+
"type": "string",
|
|
563
|
+
"description": "The start date for historical price retrieval in format YYYY-MM-DD",
|
|
564
|
+
},
|
|
565
|
+
"end_date": {
|
|
566
|
+
"type": "string",
|
|
567
|
+
"description": "The end date for historical price retrieval in format YYYY-MM-DD",
|
|
568
|
+
},
|
|
569
|
+
},
|
|
570
|
+
"required": ["identifier", "capitalization"],
|
|
571
|
+
"additionalProperties": False,
|
|
572
|
+
},
|
|
573
|
+
},
|
|
519
574
|
{
|
|
520
575
|
"name": "get_financial_statement_from_identifier",
|
|
521
576
|
"description": "Get the financial statement associated with an identifier",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from datetime import datetime
|
|
2
2
|
from functools import cache, cached_property
|
|
3
3
|
import logging
|
|
4
|
-
from typing import TYPE_CHECKING, Any, Callable, Optional
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Callable, Literal, Optional
|
|
5
5
|
|
|
6
6
|
import numpy as np
|
|
7
7
|
import pandas as pd
|
|
@@ -18,9 +18,7 @@ logger = logging.getLogger(__name__)
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class CompanyFunctionsMetaClass:
|
|
21
|
-
|
|
22
|
-
"""Init company functions"""
|
|
23
|
-
self.kfinance_api_client: KFinanceApiClient
|
|
21
|
+
kfinance_api_client: KFinanceApiClient
|
|
24
22
|
|
|
25
23
|
@cached_property
|
|
26
24
|
def company_id(self) -> Any:
|
|
@@ -239,6 +237,78 @@ class CompanyFunctionsMetaClass:
|
|
|
239
237
|
Companies(self.kfinance_api_client, companies["previous"]),
|
|
240
238
|
)
|
|
241
239
|
|
|
240
|
+
def market_cap(
|
|
241
|
+
self,
|
|
242
|
+
start_date: Optional[str] = None,
|
|
243
|
+
end_date: Optional[str] = None,
|
|
244
|
+
) -> pd.DataFrame:
|
|
245
|
+
"""Retrieves market caps for a company between start and end date.
|
|
246
|
+
|
|
247
|
+
:param start_date: The start date in format "YYYY-MM-DD", default to None
|
|
248
|
+
:type start_date: str, optional
|
|
249
|
+
:param end_date: The end date in format "YYYY-MM-DD", default to None
|
|
250
|
+
:type end_date: str, optional
|
|
251
|
+
:return: A DataFrame with a `market_cap` column. The dates are the index.
|
|
252
|
+
:rtype: pd.DataFrame
|
|
253
|
+
"""
|
|
254
|
+
|
|
255
|
+
return self._fetch_market_cap_tev_or_shares_outstanding(
|
|
256
|
+
column_to_extract="market_cap", start_date=start_date, end_date=end_date
|
|
257
|
+
)
|
|
258
|
+
|
|
259
|
+
def tev(
|
|
260
|
+
self,
|
|
261
|
+
start_date: Optional[str] = None,
|
|
262
|
+
end_date: Optional[str] = None,
|
|
263
|
+
) -> pd.DataFrame:
|
|
264
|
+
"""Retrieves TEV (total enterprise value) for a company between start and end date.
|
|
265
|
+
|
|
266
|
+
:param start_date: The start date in format "YYYY-MM-DD", default to None
|
|
267
|
+
:type start_date: str, optional
|
|
268
|
+
:param end_date: The end date in format "YYYY-MM-DD", default to None
|
|
269
|
+
:type end_date: str, optional
|
|
270
|
+
:return: A DataFrame with a `tev` column. The dates are the index.
|
|
271
|
+
:rtype: pd.DataFrame
|
|
272
|
+
"""
|
|
273
|
+
|
|
274
|
+
return self._fetch_market_cap_tev_or_shares_outstanding(
|
|
275
|
+
column_to_extract="tev", start_date=start_date, end_date=end_date
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
def shares_outstanding(
|
|
279
|
+
self,
|
|
280
|
+
start_date: Optional[str] = None,
|
|
281
|
+
end_date: Optional[str] = None,
|
|
282
|
+
) -> pd.DataFrame:
|
|
283
|
+
"""Retrieves shares outstanding for a company between start and end date.
|
|
284
|
+
|
|
285
|
+
:param start_date: The start date in format "YYYY-MM-DD", default to None
|
|
286
|
+
:type start_date: str, optional
|
|
287
|
+
:param end_date: The end date in format "YYYY-MM-DD", default to None
|
|
288
|
+
:type end_date: str, optional
|
|
289
|
+
:return: A DataFrame with a `shares_outstanding` column. The dates are the index.
|
|
290
|
+
:rtype: pd.DataFrame
|
|
291
|
+
"""
|
|
292
|
+
|
|
293
|
+
return self._fetch_market_cap_tev_or_shares_outstanding(
|
|
294
|
+
column_to_extract="shares_outstanding", start_date=start_date, end_date=end_date
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
def _fetch_market_cap_tev_or_shares_outstanding(
|
|
298
|
+
self,
|
|
299
|
+
column_to_extract: Literal["market_cap", "tev", "shares_outstanding"],
|
|
300
|
+
start_date: str | None,
|
|
301
|
+
end_date: str | None,
|
|
302
|
+
) -> pd.DataFrame:
|
|
303
|
+
"""Helper function to fetch market cap, TEV, and shares outstanding."""
|
|
304
|
+
|
|
305
|
+
df = pd.DataFrame(
|
|
306
|
+
self.kfinance_api_client.fetch_market_caps_tevs_and_shares_outstanding(
|
|
307
|
+
company_id=self.company_id, start_date=start_date, end_date=end_date
|
|
308
|
+
)["market_caps"]
|
|
309
|
+
)
|
|
310
|
+
return df.set_index("date")[[column_to_extract]].apply(pd.to_numeric).replace(np.nan, None)
|
|
311
|
+
|
|
242
312
|
|
|
243
313
|
for line_item in LINE_ITEMS:
|
|
244
314
|
line_item_name = line_item["name"]
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
from unittest import TestCase
|
|
2
2
|
from unittest.mock import Mock
|
|
3
3
|
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
4
6
|
from kfinance.fetch import KFinanceApiClient
|
|
5
7
|
|
|
6
8
|
|
|
9
|
+
def build_mock_api_client() -> KFinanceApiClient:
|
|
10
|
+
"""Create a KFinanceApiClient with mocked-out fetch function."""
|
|
11
|
+
kfinance_api_client = KFinanceApiClient(refresh_token="fake_refresh_token")
|
|
12
|
+
kfinance_api_client.fetch = Mock()
|
|
13
|
+
return kfinance_api_client
|
|
14
|
+
|
|
15
|
+
|
|
7
16
|
class TestFetchItem(TestCase):
|
|
8
17
|
def setUp(self):
|
|
9
18
|
"""Create a KFinanceApiClient with mocked-out fetch function."""
|
|
10
|
-
self.kfinance_api_client =
|
|
11
|
-
self.kfinance_api_client.fetch = Mock()
|
|
19
|
+
self.kfinance_api_client = build_mock_api_client()
|
|
12
20
|
|
|
13
21
|
def test_fetch_id_triple(self) -> None:
|
|
14
22
|
identifier = "SPGI"
|
|
@@ -239,3 +247,25 @@ class TestFetchItem(TestCase):
|
|
|
239
247
|
exchange_code=exchange_code,
|
|
240
248
|
)
|
|
241
249
|
self.kfinance_api_client.fetch.assert_called_once_with(expected_fetch_url)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
class TestMarketCap:
|
|
253
|
+
@pytest.mark.parametrize(
|
|
254
|
+
"start_date, start_date_url", [(None, "none"), ("2025-01-01", "2025-01-01")]
|
|
255
|
+
)
|
|
256
|
+
@pytest.mark.parametrize(
|
|
257
|
+
"end_date, end_date_url", [(None, "none"), ("2025-01-02", "2025-01-02")]
|
|
258
|
+
)
|
|
259
|
+
def test_fetch_market_cap(
|
|
260
|
+
self, start_date: str | None, start_date_url: str, end_date: str | None, end_date_url: str
|
|
261
|
+
) -> None:
|
|
262
|
+
company_id = 12345
|
|
263
|
+
client = build_mock_api_client()
|
|
264
|
+
|
|
265
|
+
expected_fetch_url = (
|
|
266
|
+
f"{client.url_base}market_cap/{company_id}/{start_date_url}/{end_date_url}"
|
|
267
|
+
)
|
|
268
|
+
client.fetch_market_caps_tevs_and_shares_outstanding(
|
|
269
|
+
company_id=company_id, start_date=start_date, end_date=end_date
|
|
270
|
+
)
|
|
271
|
+
client.fetch.assert_called_with(expected_fetch_url)
|
|
@@ -166,6 +166,29 @@ class MockKFinanceApiClient:
|
|
|
166
166
|
"""Get a statement"""
|
|
167
167
|
return MOCK_COMPANY_DB[company_id]["line_items"][line_item]
|
|
168
168
|
|
|
169
|
+
def fetch_market_caps_tevs_and_shares_outstanding(
|
|
170
|
+
self,
|
|
171
|
+
company_id: int,
|
|
172
|
+
start_date: Optional[str] = None,
|
|
173
|
+
end_date: Optional[str] = None,
|
|
174
|
+
) -> dict:
|
|
175
|
+
return {
|
|
176
|
+
"market_caps": [
|
|
177
|
+
{
|
|
178
|
+
"date": "2025-01-01",
|
|
179
|
+
"market_cap": "3133802247084.000000",
|
|
180
|
+
"tev": "3152211247084.000000",
|
|
181
|
+
"shares_outstanding": 7434880776,
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
"date": "2025-01-02",
|
|
185
|
+
"market_cap": "3112092395218.000000",
|
|
186
|
+
"tev": "3130501395218.000000",
|
|
187
|
+
"shares_outstanding": 7434880776,
|
|
188
|
+
},
|
|
189
|
+
]
|
|
190
|
+
}
|
|
191
|
+
|
|
169
192
|
|
|
170
193
|
class TestTradingItem(TestCase):
|
|
171
194
|
def setUp(self):
|
|
@@ -549,3 +572,17 @@ class TestTicker(TestCase):
|
|
|
549
572
|
self.assertEqual(expected_ticker_symbol, self.msft_ticker_from_isin.ticker)
|
|
550
573
|
self.assertEqual(expected_ticker_symbol, self.msft_ticker_from_cusip.ticker)
|
|
551
574
|
self.assertEqual(expected_ticker_symbol, self.msft_ticker_from_id_triple.ticker)
|
|
575
|
+
|
|
576
|
+
def test_market_cap(self):
|
|
577
|
+
"""
|
|
578
|
+
GIVEN a mock client
|
|
579
|
+
WHEN the mock client receives a mock market cap response dict
|
|
580
|
+
THEN the Ticker object can correctly extract market caps from the dict.
|
|
581
|
+
"""
|
|
582
|
+
|
|
583
|
+
expected_dataframe = pd.DataFrame(
|
|
584
|
+
{"market_cap": {"2025-01-01": 3133802247084.0, "2025-01-02": 3112092395218.0}}
|
|
585
|
+
)
|
|
586
|
+
expected_dataframe.index.name = "date"
|
|
587
|
+
market_caps = self.msft_ticker_from_ticker.market_cap()
|
|
588
|
+
pd.testing.assert_frame_equal(expected_dataframe, market_caps)
|
|
@@ -77,6 +77,20 @@ class GetPricesFromIdentifier(BaseModel):
|
|
|
77
77
|
)
|
|
78
78
|
|
|
79
79
|
|
|
80
|
+
class GetCapitalizationFromIdentifier(BaseModel):
|
|
81
|
+
identifier: str = Field(
|
|
82
|
+
description="The identifier, which can be a ticker symbol, ISIN, or CUSIP"
|
|
83
|
+
)
|
|
84
|
+
capitalization: Literal["market_cap", "tev", "shares_outstanding"] = Field(
|
|
85
|
+
description="The capitalization to retrieve"
|
|
86
|
+
)
|
|
87
|
+
start_date: str | None = Field(
|
|
88
|
+
default=None,
|
|
89
|
+
description="The start date in format YYYY-MM-DD",
|
|
90
|
+
)
|
|
91
|
+
end_date: str | None = Field(default=None, description="The end date in format YYYY-MM-DD")
|
|
92
|
+
|
|
93
|
+
|
|
80
94
|
class GetFinancialStatementFromIdentifier(BaseModel):
|
|
81
95
|
identifier: str = Field(
|
|
82
96
|
description="The identifier, which can be a ticker symbol, ISIN, or CUSIP"
|
|
@@ -13,7 +13,11 @@ done
|
|
|
13
13
|
python -m mypy --config-file pyproject.toml kfinance
|
|
14
14
|
|
|
15
15
|
if [ "$fix" = "--fix" ]; then
|
|
16
|
+
# The ruff linters (check) and formatters (format) are separate.
|
|
17
|
+
# See https://docs.astral.sh/ruff/formatter/#sorting-imports
|
|
16
18
|
python -m ruff --config pyproject.toml check kfinance --fix
|
|
19
|
+
python -m ruff --config pyproject.toml format kfinance
|
|
17
20
|
else
|
|
18
21
|
python -m ruff --config pyproject.toml check kfinance
|
|
22
|
+
python -m ruff --config pyproject.toml format kfinance --check
|
|
19
23
|
fi
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kensho_kfinance-1.0.3 → kensho_kfinance-1.1.0}/kensho_kfinance.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|