kensho-kfinance 2.2.2__py3-none-any.whl → 2.2.4__py3-none-any.whl
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-2.2.2.dist-info → kensho_kfinance-2.2.4.dist-info}/METADATA +1 -1
- {kensho_kfinance-2.2.2.dist-info → kensho_kfinance-2.2.4.dist-info}/RECORD +14 -13
- {kensho_kfinance-2.2.2.dist-info → kensho_kfinance-2.2.4.dist-info}/WHEEL +1 -1
- kfinance/CHANGELOG.md +6 -0
- kfinance/constants.py +1 -0
- kfinance/meta_classes.py +10 -24
- kfinance/tests/test_objects.py +2 -9
- kfinance/tests/test_tools.py +43 -1
- kfinance/tool_calling/__init__.py +4 -0
- kfinance/tool_calling/get_segments_from_identifier.py +42 -0
- kfinance/version.py +2 -2
- {kensho_kfinance-2.2.2.dist-info → kensho_kfinance-2.2.4.dist-info}/licenses/AUTHORS.md +0 -0
- {kensho_kfinance-2.2.2.dist-info → kensho_kfinance-2.2.4.dist-info}/licenses/LICENSE +0 -0
- {kensho_kfinance-2.2.2.dist-info → kensho_kfinance-2.2.4.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kensho-kfinance
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.4
|
|
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
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
kensho_kfinance-2.2.
|
|
2
|
-
kensho_kfinance-2.2.
|
|
3
|
-
kfinance/CHANGELOG.md,sha256=
|
|
1
|
+
kensho_kfinance-2.2.4.dist-info/licenses/AUTHORS.md,sha256=0h9ClbI0pu1oKj1M28ROUsaxrbZg-6ukQGl6X4y9noI,68
|
|
2
|
+
kensho_kfinance-2.2.4.dist-info/licenses/LICENSE,sha256=bsY4blvSgq6o0FMQ3RXa2NCgco--nHCCchLXzxr6kms,83
|
|
3
|
+
kfinance/CHANGELOG.md,sha256=rBjrg8H9eODymBNuLyOWIRrA5FAVR92WgxswFMkGI9E,1241
|
|
4
4
|
kfinance/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
kfinance/batch_request_handling.py,sha256=p6p_G4_BL06GgeKlh7P1k9CUqOMahWCLEw1NoBwbLvU,5698
|
|
6
|
-
kfinance/constants.py,sha256=
|
|
6
|
+
kfinance/constants.py,sha256=UuFzqL253-2tRQfma785K9tfaZGv-o821tO2tVLwc5Q,48813
|
|
7
7
|
kfinance/fetch.py,sha256=fguxYy5rjLQKNkmP7gsvZUJtmt9uDNxg6LN9FRJTAVQ,22936
|
|
8
8
|
kfinance/kfinance.py,sha256=_U69k0Dcwkw1B_lzaUZy8N2-c-v93ZKoUAVVZb6wBUM,52758
|
|
9
|
-
kfinance/meta_classes.py,sha256=
|
|
9
|
+
kfinance/meta_classes.py,sha256=1qYkj2L7jcBfdkye6TG2nuRhwzhAbmtxay6rSVY3DsA,19883
|
|
10
10
|
kfinance/prompt.py,sha256=PtVB8c_FcSlVdyGgByAnIFGzuUuBaEjciCqnBJl1hSQ,25133
|
|
11
11
|
kfinance/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
kfinance/server_thread.py,sha256=jUnt1YGoYDkqqz1MbCwd44zJs1T_Z2BCgvj75bdtLgA,2574
|
|
13
|
-
kfinance/version.py,sha256=
|
|
13
|
+
kfinance/version.py,sha256=Ath1yNFbHtPzluPba0J7EfQTfLH_byRzLfGjqAUl6cY,511
|
|
14
14
|
kfinance/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
kfinance/tests/conftest.py,sha256=voB-w8P_6L3Nel3rdgylXKe5WWaS1q7nCFt1O04uqoY,948
|
|
16
16
|
kfinance/tests/test_batch_requests.py,sha256=uXJF2IcRdyBm5SthwIUHMKtkGZ21MY84pg_k1JeSNOY,11430
|
|
@@ -18,10 +18,10 @@ kfinance/tests/test_client.py,sha256=O7icZCSDhlQ9WGhzoXlpiSvbuA-mQNJHBYVsilyP_dE
|
|
|
18
18
|
kfinance/tests/test_example_notebook.py,sha256=XhDAJp3H5Y6usLAt3k4Ug4W3H6gLyh68nzmoWgOOLn4,6441
|
|
19
19
|
kfinance/tests/test_fetch.py,sha256=O9qOsffQYJPSAR1X_P6CNoA0Buyq2kx4vfS0FOc2Goc,13564
|
|
20
20
|
kfinance/tests/test_group_objects.py,sha256=SoMEZmkG4RYdgWOAwxLHHtzIQho92KM01YbQXPUg578,1689
|
|
21
|
-
kfinance/tests/test_objects.py,sha256=
|
|
22
|
-
kfinance/tests/test_tools.py,sha256=
|
|
21
|
+
kfinance/tests/test_objects.py,sha256=CSk3iN-uDt-E6gaOX4jExuYPT8Up-YNC3hafpenadcA,23614
|
|
22
|
+
kfinance/tests/test_tools.py,sha256=ne4XhebhoxDHFl4kRLl10j4K-SXLrxS6jv6Ypt0Gv_E,16846
|
|
23
23
|
kfinance/tool_calling/README.md,sha256=omJq7Us6r4U45QB7hRpLjRJ5BMalCkZkh4uXBjTbJXc,2022
|
|
24
|
-
kfinance/tool_calling/__init__.py,sha256=
|
|
24
|
+
kfinance/tool_calling/__init__.py,sha256=Fb30Snu09B63NscSUJGGnFAdlXSDrTAOJlzjYvMyZXk,1873
|
|
25
25
|
kfinance/tool_calling/get_business_relationship_from_identifier.py,sha256=CipXvyqEjPm6BXYP0CA9Kp1BIyiIEm7abp85x1zXRV4,1472
|
|
26
26
|
kfinance/tool_calling/get_capitalization_from_identifier.py,sha256=TdWdJDeI-jSL-1YfhnnwIA9D1SXobidvoHrjK42QmqQ,1521
|
|
27
27
|
kfinance/tool_calling/get_cusip_from_ticker.py,sha256=houhGCYXoSzaaTtCvOBf3pPsYiSbcV1Ej5nAyGuMWcU,644
|
|
@@ -34,9 +34,10 @@ kfinance/tool_calling/get_isin_from_ticker.py,sha256=2fJBcA-rNGbVOQmQ7qJEYxqejQw
|
|
|
34
34
|
kfinance/tool_calling/get_latest.py,sha256=btGeVBmvX5QJutzrKfE6spatGGejDuHxtq53NoAaGNk,786
|
|
35
35
|
kfinance/tool_calling/get_n_quarters_ago.py,sha256=A0ilwPKUqU0YYQSz3gNsVF0Jy4YttXrSaDhYj7y8GHA,713
|
|
36
36
|
kfinance/tool_calling/get_prices_from_identifier.py,sha256=ViJkwLDvStB7grc8RuoKSDXQM399Wru4-OY3E8k1l_U,1882
|
|
37
|
+
kfinance/tool_calling/get_segments_from_identifier.py,sha256=WIqJ1wWE6Z87VBREGu42nRc6_eJqUbGKcE9elzqBQJE,1867
|
|
37
38
|
kfinance/tool_calling/resolve_identifier.py,sha256=npslr6bBCu0qEDV1-8d24F5OC3nQ1KBMphuMbHVC1AU,626
|
|
38
39
|
kfinance/tool_calling/shared_models.py,sha256=K-NPQyE_7Ew6Cs0zxG1xO2O47gp5uDHdHtWD7wUDZX4,2132
|
|
39
|
-
kensho_kfinance-2.2.
|
|
40
|
-
kensho_kfinance-2.2.
|
|
41
|
-
kensho_kfinance-2.2.
|
|
42
|
-
kensho_kfinance-2.2.
|
|
40
|
+
kensho_kfinance-2.2.4.dist-info/METADATA,sha256=sx_SF7gbkLwRfyTRUw2WHaqkoSyqQfUoBUS5majgF7w,3436
|
|
41
|
+
kensho_kfinance-2.2.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
42
|
+
kensho_kfinance-2.2.4.dist-info/top_level.txt,sha256=kT_kNwVhfQoOAecY8W7uYah5xaHMoHoAdBIvXh6DaKM,9
|
|
43
|
+
kensho_kfinance-2.2.4.dist-info/RECORD,,
|
kfinance/CHANGELOG.md
CHANGED
kfinance/constants.py
CHANGED
|
@@ -102,6 +102,7 @@ class Permission(StrEnum):
|
|
|
102
102
|
PricingPermission = "PricingPermission"
|
|
103
103
|
RelationshipPermission = "RelationshipPermission"
|
|
104
104
|
StatementsPermission = "StatementsPermission"
|
|
105
|
+
SegmentsPermission = "SegmentsPermission"
|
|
105
106
|
|
|
106
107
|
|
|
107
108
|
class YearAndQuarter(TypedDict):
|
kfinance/meta_classes.py
CHANGED
|
@@ -312,7 +312,7 @@ class CompanyFunctionsMetaClass:
|
|
|
312
312
|
end_year: Optional[int] = None,
|
|
313
313
|
start_quarter: Optional[int] = None,
|
|
314
314
|
end_quarter: Optional[int] = None,
|
|
315
|
-
) ->
|
|
315
|
+
) -> dict:
|
|
316
316
|
"""Get the company's segments"""
|
|
317
317
|
try:
|
|
318
318
|
self.validate_inputs(
|
|
@@ -322,9 +322,9 @@ class CompanyFunctionsMetaClass:
|
|
|
322
322
|
end_quarter=end_quarter,
|
|
323
323
|
)
|
|
324
324
|
except ValueError:
|
|
325
|
-
return
|
|
325
|
+
return {}
|
|
326
326
|
|
|
327
|
-
|
|
327
|
+
return self.kfinance_api_client.fetch_segments(
|
|
328
328
|
company_id=self.company_id,
|
|
329
329
|
segment_type=segment_type,
|
|
330
330
|
period_type=period_type,
|
|
@@ -334,20 +334,6 @@ class CompanyFunctionsMetaClass:
|
|
|
334
334
|
end_quarter=end_quarter,
|
|
335
335
|
)["segments"]
|
|
336
336
|
|
|
337
|
-
period_name = (
|
|
338
|
-
"Year" if (period_type == PeriodType.annual or period_type is None) else "Period"
|
|
339
|
-
)
|
|
340
|
-
|
|
341
|
-
# flatten the nested dictionary and return as a DataFrame
|
|
342
|
-
rows = []
|
|
343
|
-
for period, segments in results.items():
|
|
344
|
-
for segment_name, line_items in segments.items():
|
|
345
|
-
for line_item, value in line_items.items():
|
|
346
|
-
rows.append([period, segment_name, line_item, value])
|
|
347
|
-
return pd.DataFrame(
|
|
348
|
-
rows, columns=[period_name, "Segment Name", "Line Item", "Value"]
|
|
349
|
-
).replace(np.nan, None)
|
|
350
|
-
|
|
351
337
|
def business_segments(
|
|
352
338
|
self,
|
|
353
339
|
period_type: Optional[PeriodType] = None,
|
|
@@ -355,7 +341,7 @@ class CompanyFunctionsMetaClass:
|
|
|
355
341
|
end_year: Optional[int] = None,
|
|
356
342
|
start_quarter: Optional[int] = None,
|
|
357
343
|
end_quarter: Optional[int] = None,
|
|
358
|
-
) ->
|
|
344
|
+
) -> dict:
|
|
359
345
|
"""Retrieves the templated line of business segments for a given period_type, start_year, start_quarter, end_year and end_quarter.
|
|
360
346
|
|
|
361
347
|
:param period_type: The period_type requested for. Can be “annual”, “quarterly”, "ytd". Defaults to “annual” when start_quarter and end_quarter are None.
|
|
@@ -368,8 +354,8 @@ class CompanyFunctionsMetaClass:
|
|
|
368
354
|
:type start_quarter: int, optional
|
|
369
355
|
:param end_quarter: The ending calendar quarter, defaults to None
|
|
370
356
|
:type end_quarter: int, optional
|
|
371
|
-
:return: A
|
|
372
|
-
:rtype:
|
|
357
|
+
:return: A dictionary containing the templated line of business segments for each time period, segment name, line item, and value.
|
|
358
|
+
:rtype: dict
|
|
373
359
|
"""
|
|
374
360
|
return self._segments(
|
|
375
361
|
segment_type=SegmentType.business,
|
|
@@ -387,8 +373,8 @@ class CompanyFunctionsMetaClass:
|
|
|
387
373
|
end_year: Optional[int] = None,
|
|
388
374
|
start_quarter: Optional[int] = None,
|
|
389
375
|
end_quarter: Optional[int] = None,
|
|
390
|
-
) ->
|
|
391
|
-
"""Retrieves the templated geographic segments for a given
|
|
376
|
+
) -> dict:
|
|
377
|
+
"""Retrieves the templated geographic segments for a given period_type, start_year, start_quarter, end_year and end_quarter.
|
|
392
378
|
|
|
393
379
|
:param period_type: The period_type requested for. Can be “annual”, “quarterly”, "ytd". Defaults to “annual” when start_quarter and end_quarter are None.
|
|
394
380
|
:type start_year: PeriodType, optional
|
|
@@ -400,8 +386,8 @@ class CompanyFunctionsMetaClass:
|
|
|
400
386
|
:type start_quarter: int, optional
|
|
401
387
|
:param end_quarter: The ending calendar quarter, defaults to None
|
|
402
388
|
:type end_quarter: int, optional
|
|
403
|
-
:return: A
|
|
404
|
-
:rtype:
|
|
389
|
+
:return: A dictionary containing the templated geographic segments for each time period, segment name, line item, and value.
|
|
390
|
+
:rtype: dict
|
|
405
391
|
"""
|
|
406
392
|
return self._segments(
|
|
407
393
|
segment_type=SegmentType.geographic,
|
kfinance/tests/test_objects.py
CHANGED
|
@@ -337,17 +337,10 @@ class TestCompany(TestCase):
|
|
|
337
337
|
|
|
338
338
|
def test_business_segments(self) -> None:
|
|
339
339
|
"""test business statement"""
|
|
340
|
-
|
|
341
|
-
for period, segments in MOCK_COMPANY_DB[msft_company_id]["segments"].items():
|
|
342
|
-
for segment_name, line_items in segments.items():
|
|
343
|
-
for line_item, value in line_items.items():
|
|
344
|
-
rows.append([period, segment_name, line_item, value])
|
|
345
|
-
expected_segments = pd.DataFrame(
|
|
346
|
-
rows, columns=["Year", "Segment Name", "Line Item", "Value"]
|
|
347
|
-
).replace(np.nan, None)
|
|
340
|
+
expected_segments = MOCK_COMPANY_DB[msft_company_id]["segments"]
|
|
348
341
|
|
|
349
342
|
business_segment = self.msft_company.business_segments()
|
|
350
|
-
|
|
343
|
+
self.assertEqual(expected_segments, business_segment)
|
|
351
344
|
|
|
352
345
|
|
|
353
346
|
class TestSecurity(TestCase):
|
kfinance/tests/test_tools.py
CHANGED
|
@@ -4,7 +4,7 @@ from langchain_core.utils.function_calling import convert_to_openai_tool
|
|
|
4
4
|
from requests_mock import Mocker
|
|
5
5
|
import time_machine
|
|
6
6
|
|
|
7
|
-
from kfinance.constants import BusinessRelationshipType, Capitalization, StatementType
|
|
7
|
+
from kfinance.constants import BusinessRelationshipType, Capitalization, SegmentType, StatementType
|
|
8
8
|
from kfinance.kfinance import Client
|
|
9
9
|
from kfinance.tests.conftest import SPGI_COMPANY_ID, SPGI_SECURITY_ID, SPGI_TRADING_ITEM_ID
|
|
10
10
|
from kfinance.tool_calling import (
|
|
@@ -38,6 +38,10 @@ from kfinance.tool_calling.get_isin_from_ticker import GetIsinFromTickerArgs
|
|
|
38
38
|
from kfinance.tool_calling.get_latest import GetLatestArgs
|
|
39
39
|
from kfinance.tool_calling.get_n_quarters_ago import GetNQuartersAgoArgs
|
|
40
40
|
from kfinance.tool_calling.get_prices_from_identifier import GetPricesFromIdentifierArgs
|
|
41
|
+
from kfinance.tool_calling.get_segments_from_identifier import (
|
|
42
|
+
GetSegmentsFromIdentifier,
|
|
43
|
+
GetSegmentsFromIdentifierArgs,
|
|
44
|
+
)
|
|
41
45
|
from kfinance.tool_calling.shared_models import ToolArgsWithIdentifier
|
|
42
46
|
|
|
43
47
|
|
|
@@ -217,6 +221,44 @@ class TestGetFinancialStatementFromIdentifier:
|
|
|
217
221
|
assert response == expected_response
|
|
218
222
|
|
|
219
223
|
|
|
224
|
+
class TestGetSegmentsFromIdentifier:
|
|
225
|
+
def test_get_segments_from_identifier(self, mock_client: Client, requests_mock: Mocker):
|
|
226
|
+
"""
|
|
227
|
+
GIVEN the GetSegmentsFromIdentifier tool
|
|
228
|
+
WHEN we request the SPGI business segment
|
|
229
|
+
THEN we get back the SPGI business segment
|
|
230
|
+
"""
|
|
231
|
+
|
|
232
|
+
segments_response = {
|
|
233
|
+
"segments": {
|
|
234
|
+
"2020": {
|
|
235
|
+
"Commodity Insights": {
|
|
236
|
+
"CAPEX": -7000000.0,
|
|
237
|
+
"D&A": 17000000.0,
|
|
238
|
+
},
|
|
239
|
+
"Unallocated Assets Held for Sale": None,
|
|
240
|
+
},
|
|
241
|
+
"2021": {
|
|
242
|
+
"Commodity Insights": {
|
|
243
|
+
"CAPEX": -2000000.0,
|
|
244
|
+
"D&A": 12000000.0,
|
|
245
|
+
},
|
|
246
|
+
"Unallocated Assets Held for Sale": {"Total Assets": 321000000.0},
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
}
|
|
250
|
+
requests_mock.get(
|
|
251
|
+
url=f"https://kfinance.kensho.com/api/v1/segments/{SPGI_COMPANY_ID}/business/none/none/none/none/none",
|
|
252
|
+
# truncated from the original API response
|
|
253
|
+
json=segments_response,
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
tool = GetSegmentsFromIdentifier(kfinance_client=mock_client)
|
|
257
|
+
args = GetSegmentsFromIdentifierArgs(identifier="SPGI", segment_type=SegmentType.business)
|
|
258
|
+
response = tool.run(args.model_dump(mode="json"))
|
|
259
|
+
assert response == segments_response["segments"]
|
|
260
|
+
|
|
261
|
+
|
|
220
262
|
class TestGetHistoryMetadataFromIdentifier:
|
|
221
263
|
def test_get_history_metadata_from_identifier(self, mock_client: Client, requests_mock: Mocker):
|
|
222
264
|
"""
|
|
@@ -22,6 +22,9 @@ from kfinance.tool_calling.get_isin_from_ticker import GetIsinFromTicker
|
|
|
22
22
|
from kfinance.tool_calling.get_latest import GetLatest
|
|
23
23
|
from kfinance.tool_calling.get_n_quarters_ago import GetNQuartersAgo
|
|
24
24
|
from kfinance.tool_calling.get_prices_from_identifier import GetPricesFromIdentifier
|
|
25
|
+
from kfinance.tool_calling.get_segments_from_identifier import (
|
|
26
|
+
GetSegmentsFromIdentifier,
|
|
27
|
+
)
|
|
25
28
|
from kfinance.tool_calling.resolve_identifier import ResolveIdentifier
|
|
26
29
|
from kfinance.tool_calling.shared_models import KfinanceTool
|
|
27
30
|
|
|
@@ -40,4 +43,5 @@ ALL_TOOLS: list[Type[KfinanceTool]] = [
|
|
|
40
43
|
GetFinancialLineItemFromIdentifier,
|
|
41
44
|
GetBusinessRelationshipFromIdentifier,
|
|
42
45
|
ResolveIdentifier,
|
|
46
|
+
GetSegmentsFromIdentifier,
|
|
43
47
|
]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
from typing import Literal, Type
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
from kfinance.constants import PeriodType, Permission, SegmentType
|
|
6
|
+
from kfinance.tool_calling.shared_models import KfinanceTool, ToolArgsWithIdentifier
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class GetSegmentsFromIdentifierArgs(ToolArgsWithIdentifier):
|
|
10
|
+
# no description because the description for enum fields comes from the enum docstring.
|
|
11
|
+
segment_type: SegmentType
|
|
12
|
+
period_type: PeriodType | None = Field(default=None, description="The period type")
|
|
13
|
+
start_year: int | None = Field(default=None, description="The starting year for the data range")
|
|
14
|
+
end_year: int | None = Field(default=None, description="The ending year for the data range")
|
|
15
|
+
start_quarter: Literal[1, 2, 3, 4] | None = Field(default=None, description="Starting quarter")
|
|
16
|
+
end_quarter: Literal[1, 2, 3, 4] | None = Field(default=None, description="Ending quarter")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class GetSegmentsFromIdentifier(KfinanceTool):
|
|
20
|
+
name: str = "get_segments_from_identifier"
|
|
21
|
+
description: str = "Get the templated segments associated with an identifier."
|
|
22
|
+
args_schema: Type[BaseModel] = GetSegmentsFromIdentifierArgs
|
|
23
|
+
required_permission: Permission | None = Permission.StatementsPermission
|
|
24
|
+
|
|
25
|
+
def _run(
|
|
26
|
+
self,
|
|
27
|
+
identifier: str,
|
|
28
|
+
segment_type: SegmentType,
|
|
29
|
+
period_type: PeriodType | None = None,
|
|
30
|
+
start_year: int | None = None,
|
|
31
|
+
end_year: int | None = None,
|
|
32
|
+
start_quarter: Literal[1, 2, 3, 4] | None = None,
|
|
33
|
+
end_quarter: Literal[1, 2, 3, 4] | None = None,
|
|
34
|
+
) -> str:
|
|
35
|
+
ticker = self.kfinance_client.ticker(identifier)
|
|
36
|
+
return getattr(ticker, segment_type.value + "_segments")(
|
|
37
|
+
period_type=period_type,
|
|
38
|
+
start_year=start_year,
|
|
39
|
+
end_year=end_year,
|
|
40
|
+
start_quarter=start_quarter,
|
|
41
|
+
end_quarter=end_quarter,
|
|
42
|
+
)
|
kfinance/version.py
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|