kensho-kfinance 2.8.0__py3-none-any.whl → 2.9.0__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.8.0.dist-info → kensho_kfinance-2.9.0.dist-info}/METADATA +2 -2
- {kensho_kfinance-2.8.0.dist-info → kensho_kfinance-2.9.0.dist-info}/RECORD +13 -13
- kfinance/CHANGELOG.md +3 -0
- kfinance/kfinance.py +68 -78
- kfinance/tests/test_objects.py +78 -34
- kfinance/tool_calling/get_advisors_for_company_in_transaction_from_identifier.py +9 -6
- kfinance/tool_calling/get_merger_info_from_transaction_id.py +5 -4
- kfinance/tool_calling/get_mergers_from_identifier.py +3 -0
- kfinance/version.py +2 -2
- {kensho_kfinance-2.8.0.dist-info → kensho_kfinance-2.9.0.dist-info}/WHEEL +0 -0
- {kensho_kfinance-2.8.0.dist-info → kensho_kfinance-2.9.0.dist-info}/licenses/AUTHORS.md +0 -0
- {kensho_kfinance-2.8.0.dist-info → kensho_kfinance-2.9.0.dist-info}/licenses/LICENSE +0 -0
- {kensho_kfinance-2.8.0.dist-info → kensho_kfinance-2.9.0.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.
|
|
3
|
+
Version: 2.9.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
|
|
@@ -14,7 +14,7 @@ License-File: LICENSE
|
|
|
14
14
|
License-File: AUTHORS.md
|
|
15
15
|
Requires-Dist: cachetools<6,>=5.5
|
|
16
16
|
Requires-Dist: click<=9,>=8.2.1
|
|
17
|
-
Requires-Dist: fastmcp<
|
|
17
|
+
Requires-Dist: fastmcp<2.10,>=2.9
|
|
18
18
|
Requires-Dist: langchain-core>=0.3.15
|
|
19
19
|
Requires-Dist: langchain-google-genai<3,>=2.1.5
|
|
20
20
|
Requires-Dist: numpy>=1.22.4
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
kensho_kfinance-2.
|
|
2
|
-
kensho_kfinance-2.
|
|
3
|
-
kfinance/CHANGELOG.md,sha256=
|
|
1
|
+
kensho_kfinance-2.9.0.dist-info/licenses/AUTHORS.md,sha256=0h9ClbI0pu1oKj1M28ROUsaxrbZg-6ukQGl6X4y9noI,68
|
|
2
|
+
kensho_kfinance-2.9.0.dist-info/licenses/LICENSE,sha256=bsY4blvSgq6o0FMQ3RXa2NCgco--nHCCchLXzxr6kms,83
|
|
3
|
+
kfinance/CHANGELOG.md,sha256=vwLoxhyrR2AGSJbkfkvWYjjZQ6UBrfjOPSZq4eM9nok,2280
|
|
4
4
|
kfinance/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
kfinance/batch_request_handling.py,sha256=G9rhpgQaCdb5C1dsfuJip8383iszibcOJ5k8gxld-tQ,5001
|
|
6
6
|
kfinance/decimal_with_unit.py,sha256=U1eJSJ-4zPHkdtHcrfaW9CmmaLPE13MiWJy6odRyeXo,2904
|
|
7
7
|
kfinance/fetch.py,sha256=MSdDddZ_1YdmzCuXqCXwY_vfFLdbdQeCJ6YRQrwCUCI,28157
|
|
8
|
-
kfinance/kfinance.py,sha256=
|
|
8
|
+
kfinance/kfinance.py,sha256=ob5jNO5-aTSfBwknsSVCMLQJD5mWZkPTAZlvsBJ_Z2Y,72584
|
|
9
9
|
kfinance/mcp.py,sha256=MbktclVfBOEwfe-eR7kPaTXopMJmn_8RMlf4Jx5CXKU,3689
|
|
10
10
|
kfinance/meta_classes.py,sha256=0wI70PXfQzNbRUW2nYVfxJjqCqqI5EukUIKjaMcrzVA,21804
|
|
11
11
|
kfinance/prompt.py,sha256=PtVB8c_FcSlVdyGgByAnIFGzuUuBaEjciCqnBJl1hSQ,25133
|
|
12
12
|
kfinance/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
kfinance/pydantic_models.py,sha256=avpbPqwrAyLqsCbrmFpK_B8_fj1nPlBHrnPxRcBaSkE,774
|
|
14
14
|
kfinance/server_thread.py,sha256=jUnt1YGoYDkqqz1MbCwd44zJs1T_Z2BCgvj75bdtLgA,2574
|
|
15
|
-
kfinance/version.py,sha256=
|
|
15
|
+
kfinance/version.py,sha256=pqhLPO2SP7VnEU-lJpoO0qS9x0Kgz8BD6Rgr6J_aK-o,511
|
|
16
16
|
kfinance/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
17
|
kfinance/models/business_relationship_models.py,sha256=XlkYI_XUegORH4U4oLXjdFIX9Pr9FvQUnFAc67D2M4s,770
|
|
18
18
|
kfinance/models/capitalization_models.py,sha256=jB0MIZ94UOPfVckuS2asED9ARjisrStC_O4KgfHmoJw,3193
|
|
@@ -34,14 +34,14 @@ kfinance/tests/test_decimal_with_unit.py,sha256=98zZmSLojWq3FS0e5AuNxv9eluqGVEoq
|
|
|
34
34
|
kfinance/tests/test_example_notebook.py,sha256=VFS2W_T0yEtd74YiRxj3KA7eEL_fJuCpWwUAkiFqzkc,6501
|
|
35
35
|
kfinance/tests/test_fetch.py,sha256=s8fSkXDtNjDcK_jWQYUO1stx9ElX1I54qG_48WxfBAc,18558
|
|
36
36
|
kfinance/tests/test_group_objects.py,sha256=SoMEZmkG4RYdgWOAwxLHHtzIQho92KM01YbQXPUg578,1689
|
|
37
|
-
kfinance/tests/test_objects.py,sha256=
|
|
37
|
+
kfinance/tests/test_objects.py,sha256=cpTE22omZATe-2j9jnuchgEiZtNM-wler95ainYoh_o,42471
|
|
38
38
|
kfinance/tests/test_tools.py,sha256=jLrugYTSdK6Cw4SmJxsxdYdJ1S3X7wDcBC7kQAWe75A,31024
|
|
39
39
|
kfinance/tests/test_models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
40
40
|
kfinance/tests/test_models/test_capitalization_models.py,sha256=E-5eZX0ufdFsmcWATt5agyH4Ks-q8TNO-W6cnYIMOcE,3116
|
|
41
41
|
kfinance/tests/test_models/test_price_models.py,sha256=DHBMAFJ8axat1s_C0tElqcCjw6YhmzF9WWKpKmySwv0,2378
|
|
42
42
|
kfinance/tool_calling/README.md,sha256=omJq7Us6r4U45QB7hRpLjRJ5BMalCkZkh4uXBjTbJXc,2022
|
|
43
43
|
kfinance/tool_calling/__init__.py,sha256=UmtbtG6PvQHB1fInEL-K5q0kPHL__zTY9wzaPRSp1wg,2174
|
|
44
|
-
kfinance/tool_calling/get_advisors_for_company_in_transaction_from_identifier.py,sha256=
|
|
44
|
+
kfinance/tool_calling/get_advisors_for_company_in_transaction_from_identifier.py,sha256=IYpImoYfeq7Ep_IrUZgsSHC0oLSmI1mwuTR_1ftTPMY,1789
|
|
45
45
|
kfinance/tool_calling/get_business_relationship_from_identifier.py,sha256=oPlVpDy4AY8nQFZnHRp9DhpL8SecIlyEY6aiklHtVDg,1551
|
|
46
46
|
kfinance/tool_calling/get_capitalization_from_identifier.py,sha256=qciQI9gSJh4gGatnjOkid-GJSlzXkvt7-2VcK2yBfrg,1558
|
|
47
47
|
kfinance/tool_calling/get_competitors_from_identifier.py,sha256=J9TVWNU_6d6ltJLIJTdCtkhbc0MqoCbqdWUxrwBkOUs,1156
|
|
@@ -54,8 +54,8 @@ kfinance/tool_calling/get_info_from_identifier.py,sha256=2-NmGvFpYXASGV_lJaYhhdX
|
|
|
54
54
|
kfinance/tool_calling/get_isin_from_ticker.py,sha256=tp79lowBUdkv7fm-8QX4vJqeDZiq5M_jkkp8XKC1KY4,661
|
|
55
55
|
kfinance/tool_calling/get_latest.py,sha256=m6nBA8Bo51Q85kGbGnP59IUz4-lm_CRo1kSuNM26iXg,857
|
|
56
56
|
kfinance/tool_calling/get_latest_earnings.py,sha256=R98ImaONP3AjVshygkRLwcAHKscvVRkVoPw117O9nuw,1197
|
|
57
|
-
kfinance/tool_calling/get_merger_info_from_transaction_id.py,sha256=
|
|
58
|
-
kfinance/tool_calling/get_mergers_from_identifier.py,sha256=
|
|
57
|
+
kfinance/tool_calling/get_merger_info_from_transaction_id.py,sha256=gB6VUmCAKS0OBclpcdp2gQq7cdxKbWTXt5Z8aMH_-ys,3243
|
|
58
|
+
kfinance/tool_calling/get_mergers_from_identifier.py,sha256=tgpcLQM1CPvyk4_xyUhcZh01kAzwdkQCV6gq-bEsFhA,1935
|
|
59
59
|
kfinance/tool_calling/get_n_quarters_ago.py,sha256=VYUBbQIowHXmNuln1oKoDKeWDbnXLg4p6X0d1HoY_NY,784
|
|
60
60
|
kfinance/tool_calling/get_next_earnings.py,sha256=vL3sCoocPhHDRawVRu9IyQPLXVAgODrZgKSqkP3Scs8,1177
|
|
61
61
|
kfinance/tool_calling/get_prices_from_identifier.py,sha256=uXD9fiLFI0vUM_YY8DI_9ifC0oeeC3KCyaTQQ0IjuSA,1966
|
|
@@ -64,7 +64,7 @@ kfinance/tool_calling/get_transcript.py,sha256=urZgpQXigmahy-vj6OjkGI9O6HJcPIpd-
|
|
|
64
64
|
kfinance/tool_calling/prompts.py,sha256=Yw1DJIMh90cjL-8q6_RMRiSjCtFDXvJAy7QiV5_uAU8,911
|
|
65
65
|
kfinance/tool_calling/resolve_identifier.py,sha256=Rkhwi6m3hffE19qaxRkrsu6slRKyiAXjfLr8L41N2zc,647
|
|
66
66
|
kfinance/tool_calling/shared_models.py,sha256=Sx_zlwk5YLu533406Pmh499NH5oTBWrZf8Ua8zoUSRk,3746
|
|
67
|
-
kensho_kfinance-2.
|
|
68
|
-
kensho_kfinance-2.
|
|
69
|
-
kensho_kfinance-2.
|
|
70
|
-
kensho_kfinance-2.
|
|
67
|
+
kensho_kfinance-2.9.0.dist-info/METADATA,sha256=NhJXLeMBY0A1QP2PaA2BWB7-m-cUxY1wqp7TlDRqPAY,6202
|
|
68
|
+
kensho_kfinance-2.9.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
69
|
+
kensho_kfinance-2.9.0.dist-info/top_level.txt,sha256=kT_kNwVhfQoOAecY8W7uYah5xaHMoHoAdBIvXh6DaKM,9
|
|
70
|
+
kensho_kfinance-2.9.0.dist-info/RECORD,,
|
kfinance/CHANGELOG.md
CHANGED
kfinance/kfinance.py
CHANGED
|
@@ -641,83 +641,77 @@ class Company(CompanyFunctionsMetaClass):
|
|
|
641
641
|
return self._mergers_for_company
|
|
642
642
|
|
|
643
643
|
|
|
644
|
-
class
|
|
644
|
+
class ParticipantInMerger:
|
|
645
645
|
"""A Company that has been involved in a transaction is a company that may have been advised."""
|
|
646
646
|
|
|
647
647
|
def __init__(
|
|
648
|
-
self,
|
|
649
|
-
kfinance_api_client: KFinanceApiClient,
|
|
650
|
-
company_id: int,
|
|
651
|
-
transaction_id: int,
|
|
652
|
-
company_name: str | None = None,
|
|
648
|
+
self, kfinance_api_client: KFinanceApiClient, transaction_id: int, company: Company
|
|
653
649
|
):
|
|
654
650
|
"""Initialize the AdvisedCompany object
|
|
655
651
|
|
|
656
652
|
:param kfinance_api_client: The KFinanceApiClient used to fetch data
|
|
657
653
|
:type kfinance_api_client: KFinanceApiClient
|
|
658
|
-
:param company_id: The S&P Global CIQ Company Id
|
|
659
|
-
:type company_id: int
|
|
660
654
|
:param transaction_id: The S&P Global CIP Transaction Id
|
|
661
655
|
:type transaction_id: int
|
|
656
|
+
:param company: The company object
|
|
657
|
+
:type company: Company
|
|
662
658
|
"""
|
|
663
|
-
|
|
664
|
-
super().__init__(
|
|
665
|
-
kfinance_api_client=kfinance_api_client,
|
|
666
|
-
company_id=company_id,
|
|
667
|
-
company_name=company_name,
|
|
668
|
-
)
|
|
659
|
+
self.kfinance_api_client = kfinance_api_client
|
|
669
660
|
self.transaction_id = transaction_id
|
|
661
|
+
self._company = company
|
|
662
|
+
|
|
663
|
+
@property
|
|
664
|
+
def company(self) -> Company:
|
|
665
|
+
"""Get the specific Company object."""
|
|
666
|
+
return self._company
|
|
670
667
|
|
|
671
668
|
@property
|
|
672
|
-
def advisors(self) ->
|
|
669
|
+
def advisors(self) -> list[Advisor] | None:
|
|
673
670
|
"""Get the companies that advised this company during the current transaction."""
|
|
674
671
|
advisors = self.kfinance_api_client.fetch_advisors_for_company_in_merger(
|
|
675
|
-
transaction_id=self.transaction_id, advised_company_id=self.company_id
|
|
672
|
+
transaction_id=self.transaction_id, advised_company_id=self._company.company_id
|
|
676
673
|
)["advisors"]
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
kfinance_api_client=self.kfinance_api_client,
|
|
680
|
-
company_id=int(advisor["advisor_company_id"]),
|
|
681
|
-
company_name=str(advisor["advisor_company_name"]),
|
|
674
|
+
return [
|
|
675
|
+
Advisor(
|
|
682
676
|
advisor_type_name=str(advisor["advisor_type_name"]),
|
|
677
|
+
company=Company(
|
|
678
|
+
kfinance_api_client=self.kfinance_api_client,
|
|
679
|
+
company_id=int(advisor["advisor_company_id"]),
|
|
680
|
+
company_name=str(advisor["advisor_company_name"]),
|
|
681
|
+
),
|
|
683
682
|
)
|
|
684
683
|
for advisor in advisors
|
|
685
684
|
]
|
|
686
|
-
return Companies(kfinance_api_client=self.kfinance_api_client, companies=companies)
|
|
687
685
|
|
|
688
686
|
|
|
689
|
-
class
|
|
687
|
+
class Advisor:
|
|
690
688
|
"""A company that advised another company during a transaction."""
|
|
691
689
|
|
|
692
690
|
def __init__(
|
|
693
691
|
self,
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
advisor_type_name: str,
|
|
697
|
-
company_name: str | None = None,
|
|
692
|
+
advisor_type_name: str | None,
|
|
693
|
+
company: Company,
|
|
698
694
|
):
|
|
699
695
|
"""Initialize the AdvisorCompany object
|
|
700
696
|
|
|
701
|
-
:param
|
|
702
|
-
:type
|
|
703
|
-
:param company_id: The S&P Global CIQ Company Id
|
|
704
|
-
:type company_id: int
|
|
697
|
+
:param company: The company that advised
|
|
698
|
+
:type company: Company
|
|
705
699
|
:param advisor_type_name: The type of the advisor company
|
|
706
700
|
:type advisor_type_name: str
|
|
707
701
|
"""
|
|
708
|
-
|
|
709
|
-
super().__init__(
|
|
710
|
-
kfinance_api_client=kfinance_api_client,
|
|
711
|
-
company_id=company_id,
|
|
712
|
-
company_name=company_name,
|
|
713
|
-
)
|
|
714
702
|
self._advisor_type_name = advisor_type_name
|
|
703
|
+
self._company = company
|
|
715
704
|
|
|
716
705
|
@property
|
|
717
706
|
def advisor_type_name(self) -> str | None:
|
|
718
707
|
"""When this company advised another during a transaction, get the advisor type name."""
|
|
719
708
|
return self._advisor_type_name
|
|
720
709
|
|
|
710
|
+
@property
|
|
711
|
+
def company(self) -> Company:
|
|
712
|
+
"""Get the Company object."""
|
|
713
|
+
return self._company
|
|
714
|
+
|
|
721
715
|
|
|
722
716
|
class Security:
|
|
723
717
|
"""Security class
|
|
@@ -1253,7 +1247,11 @@ class MergerOrAcquisition:
|
|
|
1253
1247
|
"""An object that represents a merger or an acquisition of a company."""
|
|
1254
1248
|
|
|
1255
1249
|
def __init__(
|
|
1256
|
-
self,
|
|
1250
|
+
self,
|
|
1251
|
+
kfinance_api_client: KFinanceApiClient,
|
|
1252
|
+
transaction_id: int,
|
|
1253
|
+
merger_title: str | None,
|
|
1254
|
+
closed_date: date | None,
|
|
1257
1255
|
) -> None:
|
|
1258
1256
|
"""MergerOrAcqusition initializer.
|
|
1259
1257
|
|
|
@@ -1264,6 +1262,7 @@ class MergerOrAcquisition:
|
|
|
1264
1262
|
self.kfinance_api_client = kfinance_api_client
|
|
1265
1263
|
self.transaction_id = transaction_id
|
|
1266
1264
|
self.merger_title = merger_title
|
|
1265
|
+
self.closed_date = closed_date
|
|
1267
1266
|
self._merger_info: dict | None = None
|
|
1268
1267
|
|
|
1269
1268
|
@property
|
|
@@ -1301,36 +1300,39 @@ class MergerOrAcquisition:
|
|
|
1301
1300
|
Each category is a single Company or a list of Companies.
|
|
1302
1301
|
"""
|
|
1303
1302
|
return {
|
|
1304
|
-
"target":
|
|
1303
|
+
"target": ParticipantInMerger(
|
|
1305
1304
|
kfinance_api_client=self.kfinance_api_client,
|
|
1306
|
-
company_id=self.merger_info["participants"]["target"]["company_id"],
|
|
1307
|
-
company_name=self.merger_info["participants"]["target"]["company_name"],
|
|
1308
1305
|
transaction_id=self.transaction_id,
|
|
1306
|
+
company=Company(
|
|
1307
|
+
kfinance_api_client=self.kfinance_api_client,
|
|
1308
|
+
company_id=self.merger_info["participants"]["target"]["company_id"],
|
|
1309
|
+
company_name=self.merger_info["participants"]["target"]["company_name"],
|
|
1310
|
+
),
|
|
1309
1311
|
),
|
|
1310
|
-
"buyers":
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1312
|
+
"buyers": [
|
|
1313
|
+
ParticipantInMerger(
|
|
1314
|
+
kfinance_api_client=self.kfinance_api_client,
|
|
1315
|
+
transaction_id=self.transaction_id,
|
|
1316
|
+
company=Company(
|
|
1314
1317
|
kfinance_api_client=self.kfinance_api_client,
|
|
1315
1318
|
company_id=company["company_id"],
|
|
1316
1319
|
company_name=company["company_name"],
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1320
|
+
),
|
|
1321
|
+
)
|
|
1322
|
+
for company in self.merger_info["participants"]["buyers"]
|
|
1323
|
+
],
|
|
1324
|
+
"sellers": [
|
|
1325
|
+
ParticipantInMerger(
|
|
1326
|
+
kfinance_api_client=self.kfinance_api_client,
|
|
1327
|
+
transaction_id=self.transaction_id,
|
|
1328
|
+
company=Company(
|
|
1326
1329
|
kfinance_api_client=self.kfinance_api_client,
|
|
1327
1330
|
company_id=company["company_id"],
|
|
1328
1331
|
company_name=company["company_name"],
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
),
|
|
1332
|
+
),
|
|
1333
|
+
)
|
|
1334
|
+
for company in self.merger_info["participants"]["sellers"]
|
|
1335
|
+
],
|
|
1334
1336
|
}
|
|
1335
1337
|
|
|
1336
1338
|
@property
|
|
@@ -1360,7 +1362,6 @@ class Companies(set):
|
|
|
1360
1362
|
self,
|
|
1361
1363
|
kfinance_api_client: KFinanceApiClient,
|
|
1362
1364
|
company_ids: Optional[Iterable[int]] = None,
|
|
1363
|
-
transaction_id: Optional[int] = None,
|
|
1364
1365
|
companies: Optional[Iterable[Company]] = None,
|
|
1365
1366
|
) -> None:
|
|
1366
1367
|
"""Initialize the Companies object
|
|
@@ -1369,8 +1370,6 @@ class Companies(set):
|
|
|
1369
1370
|
:type kfinance_api_client: KFinanceApiClient
|
|
1370
1371
|
:param company_ids: An iterable of S&P CIQ Company ids
|
|
1371
1372
|
:type company_ids: Iterable[int]
|
|
1372
|
-
:param transaction_id: If the companies were party to a transaction, the S&P CIQ Transaction Id
|
|
1373
|
-
:type transaction_id: Optional[int]
|
|
1374
1373
|
:param companies: If there's already an iterable of Company objects
|
|
1375
1374
|
:type companies: Iterable[Company]
|
|
1376
1375
|
"""
|
|
@@ -1378,23 +1377,13 @@ class Companies(set):
|
|
|
1378
1377
|
if companies is not None:
|
|
1379
1378
|
super().__init__(company for company in companies)
|
|
1380
1379
|
elif company_ids is not None:
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
company_id=company_id,
|
|
1386
|
-
transaction_id=transaction_id,
|
|
1387
|
-
)
|
|
1388
|
-
for company_id in company_ids
|
|
1389
|
-
)
|
|
1390
|
-
else:
|
|
1391
|
-
super().__init__(
|
|
1392
|
-
Company(
|
|
1393
|
-
kfinance_api_client=kfinance_api_client,
|
|
1394
|
-
company_id=company_id,
|
|
1395
|
-
)
|
|
1396
|
-
for company_id in company_ids
|
|
1380
|
+
super().__init__(
|
|
1381
|
+
Company(
|
|
1382
|
+
kfinance_api_client=kfinance_api_client,
|
|
1383
|
+
company_id=company_id,
|
|
1397
1384
|
)
|
|
1385
|
+
for company_id in company_ids
|
|
1386
|
+
)
|
|
1398
1387
|
|
|
1399
1388
|
|
|
1400
1389
|
@add_methods_of_singular_class_to_iterable_class(Security)
|
|
@@ -1533,6 +1522,7 @@ class MergersAndAcquisitions(set):
|
|
|
1533
1522
|
kfinance_api_client=kfinance_api_client,
|
|
1534
1523
|
transaction_id=id_and_title["transaction_id"],
|
|
1535
1524
|
merger_title=id_and_title["merger_title"],
|
|
1525
|
+
closed_date=id_and_title["closed_date"],
|
|
1536
1526
|
)
|
|
1537
1527
|
for id_and_title in ids_and_titles
|
|
1538
1528
|
)
|
kfinance/tests/test_objects.py
CHANGED
|
@@ -11,11 +11,11 @@ from PIL.Image import open as image_open
|
|
|
11
11
|
import time_machine
|
|
12
12
|
|
|
13
13
|
from kfinance.kfinance import (
|
|
14
|
-
AdvisedCompany,
|
|
15
14
|
BusinessRelationships,
|
|
16
15
|
Company,
|
|
17
16
|
Earnings,
|
|
18
17
|
MergerOrAcquisition,
|
|
18
|
+
ParticipantInMerger,
|
|
19
19
|
Security,
|
|
20
20
|
Ticker,
|
|
21
21
|
TradingItem,
|
|
@@ -125,16 +125,40 @@ MOCK_COMPANY_DB = {
|
|
|
125
125
|
},
|
|
126
126
|
"mergers": {
|
|
127
127
|
"target": [
|
|
128
|
-
{
|
|
129
|
-
|
|
128
|
+
{
|
|
129
|
+
"transaction_id": 10998717,
|
|
130
|
+
"merger_title": "Closed M/A of Microsoft Corporation",
|
|
131
|
+
"closed_date": "2021-01-01",
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"transaction_id": 28237969,
|
|
135
|
+
"merger_title": "Closed M/A of Microsoft Corporation",
|
|
136
|
+
"closed_date": "2022-01-01",
|
|
137
|
+
},
|
|
130
138
|
],
|
|
131
139
|
"buyer": [
|
|
132
|
-
{
|
|
133
|
-
|
|
140
|
+
{
|
|
141
|
+
"transaction_id": 517414,
|
|
142
|
+
"merger_title": "Closed M/A of MongoMusic, Inc.",
|
|
143
|
+
"closed_date": "2023-01-01",
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"transaction_id": 596722,
|
|
147
|
+
"merger_title": "Closed M/A of Digital Anvil, Inc.",
|
|
148
|
+
"closed_date": "2023-01-01",
|
|
149
|
+
},
|
|
134
150
|
],
|
|
135
151
|
"seller": [
|
|
136
|
-
{
|
|
137
|
-
|
|
152
|
+
{
|
|
153
|
+
"transaction_id": 455551,
|
|
154
|
+
"merger_title": "Closed M/A of VacationSpot.com, Inc.",
|
|
155
|
+
"closed_date": "2024-01-01",
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"transaction_id": 456045,
|
|
159
|
+
"merger_title": "Closed M/A of TransPoint, LLC",
|
|
160
|
+
"closed_date": "2025-01-01",
|
|
161
|
+
},
|
|
138
162
|
],
|
|
139
163
|
},
|
|
140
164
|
"advisors": {
|
|
@@ -380,8 +404,8 @@ class MockKFinanceApiClient:
|
|
|
380
404
|
def fetch_mergers_for_company(self, company_id):
|
|
381
405
|
return copy.deepcopy(MOCK_COMPANY_DB[company_id]["mergers"])
|
|
382
406
|
|
|
383
|
-
def fetch_merger_info(self, transaction_id):
|
|
384
|
-
return copy.deepcopy(MOCK_MERGERS_DB[transaction_id])
|
|
407
|
+
def fetch_merger_info(self, transaction_id: int):
|
|
408
|
+
return copy.deepcopy(MOCK_MERGERS_DB[str(transaction_id)])
|
|
385
409
|
|
|
386
410
|
def fetch_advisors_for_company_in_merger(self, transaction_id, advised_company_id):
|
|
387
411
|
return copy.deepcopy(MOCK_COMPANY_DB[advised_company_id]["advisors"][transaction_id])
|
|
@@ -444,26 +468,31 @@ class TestCompany(TestCase):
|
|
|
444
468
|
def setUp(self):
|
|
445
469
|
"""setup tests"""
|
|
446
470
|
self.kfinance_api_client = MockKFinanceApiClient()
|
|
447
|
-
self.msft_company =
|
|
448
|
-
self.kfinance_api_client,
|
|
471
|
+
self.msft_company = ParticipantInMerger(
|
|
472
|
+
kfinance_api_client=self.kfinance_api_client,
|
|
473
|
+
transaction_id=msft_buys_mongo,
|
|
474
|
+
company=Company(
|
|
475
|
+
kfinance_api_client=self.kfinance_api_client,
|
|
476
|
+
company_id=msft_company_id,
|
|
477
|
+
),
|
|
449
478
|
)
|
|
450
479
|
|
|
451
480
|
def test_company_id(self) -> None:
|
|
452
481
|
"""test company id"""
|
|
453
482
|
expected_company_id = msft_company_id
|
|
454
|
-
company_id = self.msft_company.company_id
|
|
483
|
+
company_id = self.msft_company.company.company_id
|
|
455
484
|
self.assertEqual(expected_company_id, company_id)
|
|
456
485
|
|
|
457
486
|
def test_info(self) -> None:
|
|
458
487
|
"""test info"""
|
|
459
488
|
expected_info = MOCK_COMPANY_DB[msft_company_id]["info"]
|
|
460
|
-
info = self.msft_company.info
|
|
489
|
+
info = self.msft_company.company.info
|
|
461
490
|
self.assertEqual(expected_info, info)
|
|
462
491
|
|
|
463
492
|
def test_name(self) -> None:
|
|
464
493
|
"""test name"""
|
|
465
494
|
expected_name = MOCK_COMPANY_DB[msft_company_id]["info"]["name"]
|
|
466
|
-
name = self.msft_company.name
|
|
495
|
+
name = self.msft_company.company.name
|
|
467
496
|
self.assertEqual(expected_name, name)
|
|
468
497
|
|
|
469
498
|
def test_founding_date(self) -> None:
|
|
@@ -471,7 +500,7 @@ class TestCompany(TestCase):
|
|
|
471
500
|
expected_founding_date = datetime.strptime(
|
|
472
501
|
MOCK_COMPANY_DB[msft_company_id]["info"]["founding_date"], "%Y-%m-%d"
|
|
473
502
|
).date()
|
|
474
|
-
founding_date = self.msft_company.founding_date
|
|
503
|
+
founding_date = self.msft_company.company.founding_date
|
|
475
504
|
self.assertEqual(expected_founding_date, founding_date)
|
|
476
505
|
|
|
477
506
|
def test_earnings_call_datetimes(self) -> None:
|
|
@@ -481,7 +510,7 @@ class TestCompany(TestCase):
|
|
|
481
510
|
MOCK_COMPANY_DB[msft_company_id]["earnings_call_dates"]["earnings"][0]
|
|
482
511
|
).replace(tzinfo=timezone.utc)
|
|
483
512
|
]
|
|
484
|
-
earnings_call_datetimes = self.msft_company.earnings_call_datetimes
|
|
513
|
+
earnings_call_datetimes = self.msft_company.company.earnings_call_datetimes
|
|
485
514
|
self.assertEqual(expected_earnings_call_datetimes, earnings_call_datetimes)
|
|
486
515
|
|
|
487
516
|
def test_income_statement(self) -> None:
|
|
@@ -493,7 +522,7 @@ class TestCompany(TestCase):
|
|
|
493
522
|
.apply(pd.to_numeric)
|
|
494
523
|
.replace(np.nan, None)
|
|
495
524
|
)
|
|
496
|
-
income_statement = self.msft_company.income_statement()
|
|
525
|
+
income_statement = self.msft_company.company.income_statement()
|
|
497
526
|
pd.testing.assert_frame_equal(expected_income_statement, income_statement)
|
|
498
527
|
|
|
499
528
|
def test_revenue(self) -> None:
|
|
@@ -505,14 +534,14 @@ class TestCompany(TestCase):
|
|
|
505
534
|
.replace(np.nan, None)
|
|
506
535
|
.set_index(pd.Index(["revenue"]))
|
|
507
536
|
)
|
|
508
|
-
revenue = self.msft_company.revenue()
|
|
537
|
+
revenue = self.msft_company.company.revenue()
|
|
509
538
|
pd.testing.assert_frame_equal(expected_revenue, revenue)
|
|
510
539
|
|
|
511
540
|
def test_business_segments(self) -> None:
|
|
512
541
|
"""test business statement"""
|
|
513
542
|
expected_segments = MOCK_COMPANY_DB[msft_company_id]["segments"]
|
|
514
543
|
|
|
515
|
-
business_segment = self.msft_company.business_segments()
|
|
544
|
+
business_segment = self.msft_company.company.business_segments()
|
|
516
545
|
self.assertEqual(expected_segments, business_segment)
|
|
517
546
|
|
|
518
547
|
def test_relationships(self) -> None:
|
|
@@ -523,7 +552,9 @@ class TestCompany(TestCase):
|
|
|
523
552
|
|
|
524
553
|
expected_suppliers = MOCK_COMPANY_DB[msft_company_id][BusinessRelationshipType.supplier]
|
|
525
554
|
|
|
526
|
-
suppliers_via_method = self.msft_company.relationships(
|
|
555
|
+
suppliers_via_method = self.msft_company.company.relationships(
|
|
556
|
+
BusinessRelationshipType.supplier
|
|
557
|
+
)
|
|
527
558
|
self.assertIsInstance(suppliers_via_method, BusinessRelationships)
|
|
528
559
|
# Company ids should match
|
|
529
560
|
self.assertEqual(
|
|
@@ -536,23 +567,35 @@ class TestCompany(TestCase):
|
|
|
536
567
|
)
|
|
537
568
|
|
|
538
569
|
# Fetching via property should return the same result
|
|
539
|
-
suppliers_via_property = self.msft_company.supplier
|
|
570
|
+
suppliers_via_property = self.msft_company.company.supplier
|
|
540
571
|
self.assertEqual(suppliers_via_property, suppliers_via_method)
|
|
541
572
|
|
|
542
573
|
def test_mergers(self) -> None:
|
|
543
574
|
expected_mergers = MOCK_COMPANY_DB[msft_company_id]["mergers"]
|
|
544
|
-
mergers = self.msft_company.mergers_and_acquisitions
|
|
575
|
+
mergers = self.msft_company.company.mergers_and_acquisitions
|
|
545
576
|
mergers_json = {
|
|
546
577
|
"target": [
|
|
547
|
-
{
|
|
578
|
+
{
|
|
579
|
+
"transaction_id": merger.transaction_id,
|
|
580
|
+
"merger_title": merger.merger_title,
|
|
581
|
+
"closed_date": merger.closed_date,
|
|
582
|
+
}
|
|
548
583
|
for merger in mergers["target"]
|
|
549
584
|
],
|
|
550
585
|
"buyer": [
|
|
551
|
-
{
|
|
586
|
+
{
|
|
587
|
+
"transaction_id": merger.transaction_id,
|
|
588
|
+
"merger_title": merger.merger_title,
|
|
589
|
+
"closed_date": merger.closed_date,
|
|
590
|
+
}
|
|
552
591
|
for merger in mergers["buyer"]
|
|
553
592
|
],
|
|
554
593
|
"seller": [
|
|
555
|
-
{
|
|
594
|
+
{
|
|
595
|
+
"transaction_id": merger.transaction_id,
|
|
596
|
+
"merger_title": merger.merger_title,
|
|
597
|
+
"closed_date": merger.closed_date,
|
|
598
|
+
}
|
|
556
599
|
for merger in mergers["seller"]
|
|
557
600
|
],
|
|
558
601
|
}
|
|
@@ -571,7 +614,7 @@ class TestCompany(TestCase):
|
|
|
571
614
|
company_ids: list[int] = []
|
|
572
615
|
advisor_type_names: list[str] = []
|
|
573
616
|
for advisor in advisors:
|
|
574
|
-
company_ids.append(advisor.company_id)
|
|
617
|
+
company_ids.append(advisor.company.company_id)
|
|
575
618
|
advisor_type_names.append(advisor.advisor_type_name)
|
|
576
619
|
self.assertListEqual(expected_company_ids, company_ids)
|
|
577
620
|
self.assertListEqual(expected_advisor_type_names, advisor_type_names)
|
|
@@ -970,9 +1013,10 @@ class TestMerger(TestCase):
|
|
|
970
1013
|
def setUp(self):
|
|
971
1014
|
self.kfinance_api_client = MockKFinanceApiClient()
|
|
972
1015
|
self.merger = MergerOrAcquisition(
|
|
973
|
-
self.kfinance_api_client,
|
|
974
|
-
transaction_id=msft_buys_mongo,
|
|
1016
|
+
kfinance_api_client=self.kfinance_api_client,
|
|
1017
|
+
transaction_id=int(msft_buys_mongo),
|
|
975
1018
|
merger_title="Closed M/A of MongoMusic, Inc.",
|
|
1019
|
+
closed_date=date(2021, 1, 1),
|
|
976
1020
|
)
|
|
977
1021
|
|
|
978
1022
|
def test_merger_info(self) -> None:
|
|
@@ -984,16 +1028,16 @@ class TestMerger(TestCase):
|
|
|
984
1028
|
],
|
|
985
1029
|
"participants": {
|
|
986
1030
|
"target": {
|
|
987
|
-
"company_id": self.merger.get_participants["target"].company_id,
|
|
988
|
-
"company_name": self.merger.get_participants["target"].name,
|
|
1031
|
+
"company_id": self.merger.get_participants["target"].company.company_id,
|
|
1032
|
+
"company_name": self.merger.get_participants["target"].company.name,
|
|
989
1033
|
},
|
|
990
1034
|
"buyers": [
|
|
991
|
-
{"company_id": company.company_id, "company_name": company.name}
|
|
992
|
-
for
|
|
1035
|
+
{"company_id": buyer.company.company_id, "company_name": buyer.company.name}
|
|
1036
|
+
for buyer in self.merger.get_participants["buyers"]
|
|
993
1037
|
],
|
|
994
1038
|
"sellers": [
|
|
995
|
-
{"company_id": company.company_id, "company_name": company.name}
|
|
996
|
-
for
|
|
1039
|
+
{"company_id": seller.company.company_id, "company_name": seller.company.name}
|
|
1040
|
+
for seller in self.merger.get_participants["sellers"]
|
|
997
1041
|
],
|
|
998
1042
|
},
|
|
999
1043
|
"consideration": {
|
|
@@ -2,7 +2,7 @@ from typing import Type
|
|
|
2
2
|
|
|
3
3
|
from pydantic import BaseModel, Field
|
|
4
4
|
|
|
5
|
-
from kfinance.kfinance import
|
|
5
|
+
from kfinance.kfinance import Company, ParticipantInMerger
|
|
6
6
|
from kfinance.models.permission_models import Permission
|
|
7
7
|
from kfinance.tool_calling.shared_models import KfinanceTool, ToolArgsWithIdentifier
|
|
8
8
|
|
|
@@ -19,18 +19,21 @@ class GetAdvisorsForCompanyInTransactionFromIdentifier(KfinanceTool):
|
|
|
19
19
|
|
|
20
20
|
def _run(self, identifier: str, transaction_id: int) -> list:
|
|
21
21
|
ticker = self.kfinance_client.ticker(identifier)
|
|
22
|
-
|
|
22
|
+
participant_in_merger = ParticipantInMerger(
|
|
23
23
|
kfinance_api_client=ticker.kfinance_api_client,
|
|
24
|
-
company_id=ticker.company.company_id,
|
|
25
24
|
transaction_id=transaction_id,
|
|
25
|
+
company=Company(
|
|
26
|
+
kfinance_api_client=ticker.kfinance_api_client,
|
|
27
|
+
company_id=ticker.company.company_id,
|
|
28
|
+
),
|
|
26
29
|
)
|
|
27
|
-
advisors =
|
|
30
|
+
advisors = participant_in_merger.advisors
|
|
28
31
|
|
|
29
32
|
if advisors:
|
|
30
33
|
return [
|
|
31
34
|
{
|
|
32
|
-
"advisor_company_id": advisor.company_id,
|
|
33
|
-
"advisor_company_name": advisor.name,
|
|
35
|
+
"advisor_company_id": advisor.company.company_id,
|
|
36
|
+
"advisor_company_name": advisor.company.name,
|
|
34
37
|
"advisor_type_name": advisor.advisor_type_name,
|
|
35
38
|
}
|
|
36
39
|
for advisor in advisors
|
|
@@ -22,6 +22,7 @@ class GetMergerInfoFromTransactionId(KfinanceTool):
|
|
|
22
22
|
kfinance_api_client=self.kfinance_client.kfinance_api_client,
|
|
23
23
|
transaction_id=transaction_id,
|
|
24
24
|
merger_title=None,
|
|
25
|
+
closed_date=None,
|
|
25
26
|
)
|
|
26
27
|
merger_timeline = merger_or_acquisition.get_timeline
|
|
27
28
|
merger_participants = merger_or_acquisition.get_participants
|
|
@@ -36,15 +37,15 @@ class GetMergerInfoFromTransactionId(KfinanceTool):
|
|
|
36
37
|
else None,
|
|
37
38
|
"participants": {
|
|
38
39
|
"target": {
|
|
39
|
-
"company_id": merger_participants["target"].company_id,
|
|
40
|
-
"company_name": merger_participants["target"].name,
|
|
40
|
+
"company_id": merger_participants["target"].company.company_id,
|
|
41
|
+
"company_name": merger_participants["target"].company.name,
|
|
41
42
|
},
|
|
42
43
|
"buyers": [
|
|
43
|
-
{"company_id": buyer.company_id, "company_name": buyer.name}
|
|
44
|
+
{"company_id": buyer.company.company_id, "company_name": buyer.company.name}
|
|
44
45
|
for buyer in merger_participants["buyers"]
|
|
45
46
|
],
|
|
46
47
|
"sellers": [
|
|
47
|
-
{"company_id": seller.company_id, "company_name": seller.name}
|
|
48
|
+
{"company_id": seller.company.company_id, "company_name": seller.company.name}
|
|
48
49
|
for seller in merger_participants["sellers"]
|
|
49
50
|
],
|
|
50
51
|
}
|
|
@@ -21,6 +21,7 @@ class GetMergersFromIdentifier(KfinanceTool):
|
|
|
21
21
|
{
|
|
22
22
|
"transaction_id": merger_or_acquisition.transaction_id,
|
|
23
23
|
"merger_title": merger_or_acquisition.merger_title,
|
|
24
|
+
"closed_date": merger_or_acquisition.closed_date,
|
|
24
25
|
}
|
|
25
26
|
for merger_or_acquisition in mergers_and_acquisitions["target"]
|
|
26
27
|
],
|
|
@@ -28,6 +29,7 @@ class GetMergersFromIdentifier(KfinanceTool):
|
|
|
28
29
|
{
|
|
29
30
|
"transaction_id": merger_or_acquisition.transaction_id,
|
|
30
31
|
"merger_title": merger_or_acquisition.merger_title,
|
|
32
|
+
"closed_date": merger_or_acquisition.closed_date,
|
|
31
33
|
}
|
|
32
34
|
for merger_or_acquisition in mergers_and_acquisitions["buyer"]
|
|
33
35
|
],
|
|
@@ -35,6 +37,7 @@ class GetMergersFromIdentifier(KfinanceTool):
|
|
|
35
37
|
{
|
|
36
38
|
"transaction_id": merger_or_acquisition.transaction_id,
|
|
37
39
|
"merger_title": merger_or_acquisition.merger_title,
|
|
40
|
+
"closed_date": merger_or_acquisition.closed_date,
|
|
38
41
|
}
|
|
39
42
|
for merger_or_acquisition in mergers_and_acquisitions["seller"]
|
|
40
43
|
],
|
kfinance/version.py
CHANGED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|