kensho-kfinance 1.0.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.

@@ -0,0 +1,551 @@
1
+ from datetime import datetime, timezone
2
+ from io import BytesIO
3
+ import re
4
+ from typing import Optional
5
+ from unittest import TestCase
6
+
7
+ import numpy as np
8
+ import pandas as pd
9
+ from PIL.Image import open as image_open
10
+
11
+ from kfinance.kfinance import Company, Security, Ticker, TradingItem
12
+
13
+
14
+ msft_company_id = "21835"
15
+ msft_security_id = "2630412"
16
+ msft_isin = "US5949181045"
17
+ msft_cusip = "594918104"
18
+ msft_trading_item_id = "2630413"
19
+
20
+
21
+ MOCK_TRADING_ITEM_DB = {
22
+ msft_trading_item_id: {
23
+ "metadata": {
24
+ "currency": "USD",
25
+ "symbol": "MSFT",
26
+ "exchange_name": "NasdaqGS",
27
+ "instrument_type": "Equity",
28
+ "first_trade_date": "1986-03-13",
29
+ },
30
+ "price_chart": {
31
+ "2020-01-01": {
32
+ "2021-01-01": b"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x02\x00\x00\x00\x90wS\xde\x00\x00\x00\x0cIDATx\x9cc\xf8\xcf\xc0\x00\x00\x03"
33
+ }
34
+ },
35
+ }
36
+ }
37
+
38
+
39
+ MOCK_COMPANY_DB = {
40
+ msft_company_id: {
41
+ "info": {
42
+ "name": "Microsoft Corporation",
43
+ "status": "Operating",
44
+ "type": "Public Company",
45
+ "simple_industry": "Software",
46
+ "number_of_employees": "228000.0000",
47
+ "founding_date": "1975-01-01",
48
+ "webpage": "www.microsoft.com",
49
+ "address": "One Microsoft Way",
50
+ "city": "Redmond",
51
+ "zip_code": "98052-6399",
52
+ "state": "Washington",
53
+ "country": "United States",
54
+ "iso_country": "USA",
55
+ },
56
+ "earnings_call_dates": {"earnings": ["2004-07-22T21:30:00"]},
57
+ "statements": {
58
+ "income_statement": {
59
+ "statements": {
60
+ "2019": {
61
+ "Revenues": "125843000000.000000",
62
+ "Total Revenues": "125843000000.000000",
63
+ }
64
+ }
65
+ }
66
+ },
67
+ "line_items": {
68
+ "revenue": {
69
+ "line_item": {
70
+ "2019": "125843000000.000000",
71
+ "2020": "143015000000.000000",
72
+ "2021": "168088000000.000000",
73
+ "2022": "198270000000.000000",
74
+ "2023": "211915000000.000000",
75
+ }
76
+ }
77
+ },
78
+ }
79
+ }
80
+
81
+
82
+ MOCK_SECURITY_DB = {msft_security_id: {"isin": msft_isin, "cusip": msft_cusip}}
83
+
84
+
85
+ MOCK_TICKER_DB = {
86
+ "MSFT": {
87
+ "company_id": msft_company_id,
88
+ "security_id": msft_security_id,
89
+ "trading_item_id": msft_trading_item_id,
90
+ }
91
+ }
92
+
93
+ MOCK_ISIN_DB = {
94
+ msft_isin: {
95
+ "company_id": msft_company_id,
96
+ "security_id": msft_security_id,
97
+ "trading_item_id": msft_trading_item_id,
98
+ }
99
+ }
100
+
101
+ MOCK_CUSIP_DB = {
102
+ msft_cusip: {
103
+ "company_id": msft_company_id,
104
+ "security_id": msft_security_id,
105
+ "trading_item_id": msft_trading_item_id,
106
+ }
107
+ }
108
+
109
+
110
+ class MockKFinanceApiClient:
111
+ def __init__(self):
112
+ """Create a mock kfinance api client"""
113
+ pass
114
+
115
+ def fetch_id_triple(self, identifier: int | str, exchange_code: Optional[str] = None) -> dict:
116
+ """Get the ID triple from ticker."""
117
+ if re.match("^[a-zA-Z]{2}[a-zA-Z0-9]{9}[0-9]{1}$", str(identifier)):
118
+ return MOCK_ISIN_DB[identifier]
119
+ elif re.match("^[a-zA-Z0-9]{9}$", str(identifier)):
120
+ return MOCK_CUSIP_DB[identifier]
121
+ else:
122
+ return MOCK_TICKER_DB[identifier]
123
+
124
+ def fetch_isin(self, security_id: int) -> dict:
125
+ """Get the ISIN."""
126
+ return {"isin": MOCK_SECURITY_DB[security_id]["isin"]}
127
+
128
+ def fetch_cusip(self, security_id: int) -> dict:
129
+ """Get the CUSIP."""
130
+ return {"cusip": MOCK_SECURITY_DB[security_id]["cusip"]}
131
+
132
+ def fetch_history_metadata(self, trading_item_id):
133
+ """Get history metadata"""
134
+ return MOCK_TRADING_ITEM_DB[trading_item_id]["metadata"].copy()
135
+
136
+ def fetch_price_chart(
137
+ self, trading_item_id, is_adjusted, start_date, end_date, periodicity
138
+ ) -> bytes:
139
+ """Get price chart"""
140
+ return MOCK_TRADING_ITEM_DB[trading_item_id]["price_chart"][start_date][end_date]
141
+
142
+ def fetch_info(self, company_id: int) -> dict:
143
+ """Get info"""
144
+ return MOCK_COMPANY_DB[company_id]["info"]
145
+
146
+ def fetch_earnings_dates(self, company_id: int):
147
+ """Get the earnings dates"""
148
+ return MOCK_COMPANY_DB[company_id]["earnings_call_dates"]
149
+
150
+ def fetch_statement(
151
+ self,
152
+ company_id,
153
+ statement_type,
154
+ period_type,
155
+ start_year,
156
+ end_year,
157
+ start_quarter,
158
+ end_quarter,
159
+ ):
160
+ """Get a statement"""
161
+ return MOCK_COMPANY_DB[company_id]["statements"][statement_type]
162
+
163
+ def fetch_line_item(
164
+ self, company_id, line_item, period_type, start_year, end_year, start_quarter, end_quarter
165
+ ):
166
+ """Get a statement"""
167
+ return MOCK_COMPANY_DB[company_id]["line_items"][line_item]
168
+
169
+
170
+ class TestTradingItem(TestCase):
171
+ def setUp(self):
172
+ """setup tests"""
173
+ self.kfinance_api_client = MockKFinanceApiClient()
174
+ self.msft_trading_item_from_id = TradingItem(self.kfinance_api_client, msft_trading_item_id)
175
+ self.msft_trading_item_from_ticker = TradingItem.from_ticker(
176
+ self.kfinance_api_client, "MSFT"
177
+ )
178
+
179
+ def test_trading_item_id(self) -> None:
180
+ """test trading item id"""
181
+ expected_trading_item_id = MOCK_TICKER_DB["MSFT"]["trading_item_id"]
182
+ trading_item_id = self.msft_trading_item_from_id.trading_item_id
183
+ self.assertEqual(expected_trading_item_id, trading_item_id)
184
+
185
+ trading_item_id = self.msft_trading_item_from_ticker.trading_item_id
186
+ self.assertEqual(expected_trading_item_id, trading_item_id)
187
+
188
+ def test_history_metadata(self) -> None:
189
+ """test history metadata"""
190
+ expected_history_metadata = MOCK_TRADING_ITEM_DB[msft_trading_item_id]["metadata"].copy()
191
+ expected_history_metadata["first_trade_date"] = datetime.strptime(
192
+ expected_history_metadata["first_trade_date"], "%Y-%m-%d"
193
+ ).date()
194
+ expected_exchange_code = "NasdaqGS"
195
+ history_metadata = self.msft_trading_item_from_id.history_metadata
196
+ self.assertEqual(expected_history_metadata, history_metadata)
197
+ self.assertEqual(expected_exchange_code, self.msft_trading_item_from_id.exchange_code)
198
+
199
+ history_metadata = self.msft_trading_item_from_ticker.history_metadata
200
+ self.assertEqual(expected_history_metadata, history_metadata)
201
+ self.assertEqual(expected_exchange_code, self.msft_trading_item_from_ticker.exchange_code)
202
+
203
+ def test_price_chart(self):
204
+ """test price chart"""
205
+ expected_price_chart = image_open(
206
+ BytesIO(
207
+ MOCK_TRADING_ITEM_DB[msft_trading_item_id]["price_chart"]["2020-01-01"][
208
+ "2021-01-01"
209
+ ]
210
+ )
211
+ )
212
+ price_chart = self.msft_trading_item_from_id.price_chart(
213
+ start_date="2020-01-01", end_date="2021-01-01"
214
+ )
215
+ self.assertEqual(expected_price_chart, price_chart)
216
+
217
+ price_chart = self.msft_trading_item_from_ticker.price_chart(
218
+ start_date="2020-01-01", end_date="2021-01-01"
219
+ )
220
+ self.assertEqual(expected_price_chart, price_chart)
221
+
222
+
223
+ class TestCompany(TestCase):
224
+ def setUp(self):
225
+ """setup tests"""
226
+ self.kfinance_api_client = MockKFinanceApiClient()
227
+ self.msft_company = Company(self.kfinance_api_client, msft_company_id)
228
+
229
+ def test_company_id(self) -> None:
230
+ """test company id"""
231
+ expected_company_id = msft_company_id
232
+ company_id = self.msft_company.company_id
233
+ self.assertEqual(expected_company_id, company_id)
234
+
235
+ def test_info(self) -> None:
236
+ """test info"""
237
+ expected_info = MOCK_COMPANY_DB[msft_company_id]["info"]
238
+ info = self.msft_company.info
239
+ self.assertEqual(expected_info, info)
240
+
241
+ def test_name(self) -> None:
242
+ """test name"""
243
+ expected_name = MOCK_COMPANY_DB[msft_company_id]["info"]["name"]
244
+ name = self.msft_company.name
245
+ self.assertEqual(expected_name, name)
246
+
247
+ def test_founding_date(self) -> None:
248
+ """test founding date"""
249
+ expected_founding_date = datetime.strptime(
250
+ MOCK_COMPANY_DB[msft_company_id]["info"]["founding_date"], "%Y-%m-%d"
251
+ ).date()
252
+ founding_date = self.msft_company.founding_date
253
+ self.assertEqual(expected_founding_date, founding_date)
254
+
255
+ def test_earnings_call_datetimes(self) -> None:
256
+ """test earnings call datetimes"""
257
+ expected_earnings_call_datetimes = [
258
+ datetime.fromisoformat(
259
+ MOCK_COMPANY_DB[msft_company_id]["earnings_call_dates"]["earnings"][0]
260
+ ).replace(tzinfo=timezone.utc)
261
+ ]
262
+ earnings_call_datetimes = self.msft_company.earnings_call_datetimes
263
+ self.assertEqual(expected_earnings_call_datetimes, earnings_call_datetimes)
264
+
265
+ def test_income_statement(self) -> None:
266
+ """test income statement"""
267
+ expected_income_statement = (
268
+ pd.DataFrame(
269
+ MOCK_COMPANY_DB[msft_company_id]["statements"]["income_statement"]["statements"]
270
+ )
271
+ .apply(pd.to_numeric)
272
+ .replace(np.nan, None)
273
+ )
274
+ income_statement = self.msft_company.income_statement()
275
+ pd.testing.assert_frame_equal(expected_income_statement, income_statement)
276
+
277
+ def test_revenue(self) -> None:
278
+ """test revenue"""
279
+ expected_revenue = (
280
+ pd.DataFrame(MOCK_COMPANY_DB[msft_company_id]["line_items"]["revenue"])
281
+ .transpose()
282
+ .apply(pd.to_numeric)
283
+ .replace(np.nan, None)
284
+ .set_index(pd.Index(["revenue"]))
285
+ )
286
+ revenue = self.msft_company.revenue()
287
+ pd.testing.assert_frame_equal(expected_revenue, revenue)
288
+
289
+
290
+ class TestSecurity(TestCase):
291
+ def setUp(self):
292
+ """setup tests"""
293
+ self.kfinance_api_client = MockKFinanceApiClient()
294
+ self.msft_security = Security(self.kfinance_api_client, msft_security_id)
295
+
296
+ def test_security_id(self) -> None:
297
+ """test security id"""
298
+ expected_security_id = msft_security_id
299
+ security_id = self.msft_security.security_id
300
+ self.assertEqual(expected_security_id, security_id)
301
+
302
+ def test_isin(self) -> None:
303
+ """test isin"""
304
+ expected_isin = MOCK_SECURITY_DB[self.msft_security.security_id]["isin"]
305
+ isin = self.msft_security.isin
306
+ self.assertEqual(expected_isin, isin)
307
+
308
+
309
+ class TestTicker(TestCase):
310
+ def setUp(self):
311
+ """setup tests"""
312
+ self.kfinance_api_client = MockKFinanceApiClient()
313
+ self.msft_ticker_from_ticker = Ticker(self.kfinance_api_client, "MSFT")
314
+ self.msft_ticker_from_isin = Ticker(self.kfinance_api_client, msft_isin)
315
+ self.msft_ticker_from_cusip = Ticker(self.kfinance_api_client, msft_cusip)
316
+ self.msft_ticker_from_id_triple = Ticker(
317
+ self.kfinance_api_client,
318
+ company_id=msft_company_id,
319
+ security_id=msft_security_id,
320
+ trading_item_id=msft_trading_item_id,
321
+ )
322
+
323
+ def test_company_id(self) -> None:
324
+ """test company id"""
325
+ expected_company_id = MOCK_TICKER_DB[self.msft_ticker_from_ticker.ticker]["company_id"]
326
+ company_id = self.msft_ticker_from_ticker.company_id
327
+ self.assertEqual(expected_company_id, company_id)
328
+
329
+ company_id = self.msft_ticker_from_isin.company_id
330
+ self.assertEqual(expected_company_id, company_id)
331
+
332
+ company_id = self.msft_ticker_from_cusip.company_id
333
+ self.assertEqual(expected_company_id, company_id)
334
+
335
+ company_id = self.msft_ticker_from_id_triple.company_id
336
+ self.assertEqual(expected_company_id, company_id)
337
+
338
+ def test_security_id(self) -> None:
339
+ """test security id"""
340
+ expected_security_id = MOCK_TICKER_DB[self.msft_ticker_from_ticker.ticker]["security_id"]
341
+ security_id = self.msft_ticker_from_ticker.security_id
342
+ self.assertEqual(expected_security_id, security_id)
343
+
344
+ security_id = self.msft_ticker_from_isin.security_id
345
+ self.assertEqual(expected_security_id, security_id)
346
+
347
+ security_id = self.msft_ticker_from_cusip.security_id
348
+ self.assertEqual(expected_security_id, security_id)
349
+
350
+ security_id = self.msft_ticker_from_id_triple.security_id
351
+ self.assertEqual(expected_security_id, security_id)
352
+
353
+ def test_trading_item_id(self) -> None:
354
+ """test trading item id"""
355
+ expected_trading_item_id = MOCK_TICKER_DB[self.msft_ticker_from_ticker.ticker][
356
+ "trading_item_id"
357
+ ]
358
+ trading_item_id = self.msft_ticker_from_ticker.trading_item_id
359
+ self.assertEqual(expected_trading_item_id, trading_item_id)
360
+
361
+ trading_item_id = self.msft_ticker_from_isin.trading_item_id
362
+ self.assertEqual(expected_trading_item_id, trading_item_id)
363
+
364
+ trading_item_id = self.msft_ticker_from_cusip.trading_item_id
365
+ self.assertEqual(expected_trading_item_id, trading_item_id)
366
+
367
+ trading_item_id = self.msft_ticker_from_id_triple.trading_item_id
368
+ self.assertEqual(expected_trading_item_id, trading_item_id)
369
+
370
+ def test_cusip(self) -> None:
371
+ """test cusip"""
372
+ expected_cusip = msft_cusip
373
+ cusip = self.msft_ticker_from_ticker.cusip
374
+ self.assertEqual(expected_cusip, cusip)
375
+
376
+ cusip = self.msft_ticker_from_isin.cusip
377
+ self.assertEqual(expected_cusip, cusip)
378
+
379
+ cusip = self.msft_ticker_from_cusip.cusip
380
+ self.assertEqual(expected_cusip, cusip)
381
+
382
+ cusip = self.msft_ticker_from_id_triple.cusip
383
+ self.assertEqual(expected_cusip, cusip)
384
+
385
+ def test_history_metadata(self) -> None:
386
+ """test history metadata"""
387
+ expected_history_metadata = MOCK_TRADING_ITEM_DB[msft_trading_item_id]["metadata"].copy()
388
+ expected_history_metadata["first_trade_date"] = datetime.strptime(
389
+ expected_history_metadata["first_trade_date"], "%Y-%m-%d"
390
+ ).date()
391
+ history_metadata = self.msft_ticker_from_ticker.history_metadata
392
+ expected_exchange_code = "NasdaqGS"
393
+ self.assertEqual(expected_history_metadata, history_metadata)
394
+ self.assertEqual(expected_exchange_code, self.msft_ticker_from_ticker.exchange_code)
395
+
396
+ history_metadata = self.msft_ticker_from_isin.history_metadata
397
+ self.assertEqual(expected_history_metadata, history_metadata)
398
+ self.assertEqual(expected_exchange_code, self.msft_ticker_from_isin.exchange_code)
399
+
400
+ history_metadata = self.msft_ticker_from_cusip.history_metadata
401
+ self.assertEqual(expected_history_metadata, history_metadata)
402
+ self.assertEqual(expected_exchange_code, self.msft_ticker_from_cusip.exchange_code)
403
+
404
+ history_metadata = self.msft_ticker_from_id_triple.history_metadata
405
+ self.assertEqual(expected_history_metadata, history_metadata)
406
+ self.assertEqual(expected_exchange_code, self.msft_ticker_from_id_triple.exchange_code)
407
+
408
+ def test_price_chart(self) -> None:
409
+ """test price chart"""
410
+ expected_price_chart = image_open(
411
+ BytesIO(
412
+ MOCK_TRADING_ITEM_DB[msft_trading_item_id]["price_chart"]["2020-01-01"][
413
+ "2021-01-01"
414
+ ]
415
+ )
416
+ )
417
+ price_chart = self.msft_ticker_from_ticker.price_chart(
418
+ start_date="2020-01-01", end_date="2021-01-01"
419
+ )
420
+ self.assertEqual(expected_price_chart, price_chart)
421
+
422
+ price_chart = self.msft_ticker_from_isin.price_chart(
423
+ start_date="2020-01-01", end_date="2021-01-01"
424
+ )
425
+ self.assertEqual(expected_price_chart, price_chart)
426
+
427
+ price_chart = self.msft_ticker_from_cusip.price_chart(
428
+ start_date="2020-01-01", end_date="2021-01-01"
429
+ )
430
+ self.assertEqual(expected_price_chart, price_chart)
431
+
432
+ price_chart = self.msft_ticker_from_id_triple.price_chart(
433
+ start_date="2020-01-01", end_date="2021-01-01"
434
+ )
435
+ self.assertEqual(expected_price_chart, price_chart)
436
+
437
+ def test_info(self) -> None:
438
+ """test info"""
439
+ expected_info = MOCK_COMPANY_DB[msft_company_id]["info"]
440
+ info = self.msft_ticker_from_ticker.info
441
+ self.assertEqual(expected_info, info)
442
+
443
+ info = self.msft_ticker_from_isin.info
444
+ self.assertEqual(expected_info, info)
445
+
446
+ info = self.msft_ticker_from_cusip.info
447
+ self.assertEqual(expected_info, info)
448
+
449
+ info = self.msft_ticker_from_id_triple.info
450
+ self.assertEqual(expected_info, info)
451
+
452
+ def test_name(self) -> None:
453
+ """test name"""
454
+ expected_name = MOCK_COMPANY_DB[msft_company_id]["info"]["name"]
455
+ name = self.msft_ticker_from_ticker.name
456
+ self.assertEqual(expected_name, name)
457
+
458
+ name = self.msft_ticker_from_isin.name
459
+ self.assertEqual(expected_name, name)
460
+
461
+ name = self.msft_ticker_from_cusip.name
462
+ self.assertEqual(expected_name, name)
463
+
464
+ name = self.msft_ticker_from_id_triple.name
465
+ self.assertEqual(expected_name, name)
466
+
467
+ def test_founding_date(self) -> None:
468
+ """test founding date"""
469
+ expected_founding_date = datetime.strptime(
470
+ MOCK_COMPANY_DB[msft_company_id]["info"]["founding_date"], "%Y-%m-%d"
471
+ ).date()
472
+ founding_date = self.msft_ticker_from_ticker.founding_date
473
+ self.assertEqual(expected_founding_date, founding_date)
474
+
475
+ founding_date = self.msft_ticker_from_cusip.founding_date
476
+ self.assertEqual(expected_founding_date, founding_date)
477
+
478
+ founding_date = self.msft_ticker_from_isin.founding_date
479
+ self.assertEqual(expected_founding_date, founding_date)
480
+
481
+ founding_date = self.msft_ticker_from_id_triple.founding_date
482
+ self.assertEqual(expected_founding_date, founding_date)
483
+
484
+ def test_earnings_call_datetimes(self) -> None:
485
+ """test earnings call datetimes"""
486
+ expected_earnings_call_datetimes = [
487
+ datetime.fromisoformat(
488
+ MOCK_COMPANY_DB[msft_company_id]["earnings_call_dates"]["earnings"][0]
489
+ ).replace(tzinfo=timezone.utc)
490
+ ]
491
+ earnings_call_datetimes = self.msft_ticker_from_ticker.earnings_call_datetimes
492
+ self.assertEqual(expected_earnings_call_datetimes, earnings_call_datetimes)
493
+
494
+ earnings_call_datetimes = self.msft_ticker_from_isin.earnings_call_datetimes
495
+ self.assertEqual(expected_earnings_call_datetimes, earnings_call_datetimes)
496
+
497
+ earnings_call_datetimes = self.msft_ticker_from_cusip.earnings_call_datetimes
498
+ self.assertEqual(expected_earnings_call_datetimes, earnings_call_datetimes)
499
+
500
+ earnings_call_datetimes = self.msft_ticker_from_id_triple.earnings_call_datetimes
501
+ self.assertEqual(expected_earnings_call_datetimes, earnings_call_datetimes)
502
+
503
+ def test_income_statement(self) -> None:
504
+ """test income statement"""
505
+ expected_income_statement = (
506
+ pd.DataFrame(
507
+ MOCK_COMPANY_DB[msft_company_id]["statements"]["income_statement"]["statements"]
508
+ )
509
+ .apply(pd.to_numeric)
510
+ .replace(np.nan, None)
511
+ )
512
+ income_statement = self.msft_ticker_from_ticker.income_statement()
513
+ pd.testing.assert_frame_equal(expected_income_statement, income_statement)
514
+
515
+ income_statement = self.msft_ticker_from_isin.income_statement()
516
+ pd.testing.assert_frame_equal(expected_income_statement, income_statement)
517
+
518
+ income_statement = self.msft_ticker_from_cusip.income_statement()
519
+ pd.testing.assert_frame_equal(expected_income_statement, income_statement)
520
+
521
+ income_statement = self.msft_ticker_from_id_triple.income_statement()
522
+ pd.testing.assert_frame_equal(expected_income_statement, income_statement)
523
+
524
+ def test_revenue(self) -> None:
525
+ """test revenue"""
526
+ expected_revenue = (
527
+ pd.DataFrame(MOCK_COMPANY_DB[msft_company_id]["line_items"]["revenue"])
528
+ .transpose()
529
+ .apply(pd.to_numeric)
530
+ .replace(np.nan, None)
531
+ .set_index(pd.Index(["revenue"]))
532
+ )
533
+ revenue = self.msft_ticker_from_ticker.revenue()
534
+ pd.testing.assert_frame_equal(expected_revenue, revenue)
535
+
536
+ revenue = self.msft_ticker_from_isin.revenue()
537
+ pd.testing.assert_frame_equal(expected_revenue, revenue)
538
+
539
+ revenue = self.msft_ticker_from_cusip.revenue()
540
+ pd.testing.assert_frame_equal(expected_revenue, revenue)
541
+
542
+ revenue = self.msft_ticker_from_id_triple.revenue()
543
+ pd.testing.assert_frame_equal(expected_revenue, revenue)
544
+
545
+ def test_ticker_symbol(self):
546
+ """test ticker symbol"""
547
+ expected_ticker_symbol = "MSFT"
548
+ self.assertEqual(expected_ticker_symbol, self.msft_ticker_from_ticker.ticker)
549
+ self.assertEqual(expected_ticker_symbol, self.msft_ticker_from_isin.ticker)
550
+ self.assertEqual(expected_ticker_symbol, self.msft_ticker_from_cusip.ticker)
551
+ self.assertEqual(expected_ticker_symbol, self.msft_ticker_from_id_triple.ticker)
@@ -0,0 +1,132 @@
1
+ from typing import Literal
2
+
3
+ from pydantic import BaseModel, Field
4
+
5
+ from .constants import LINE_ITEM_NAMES_AND_ALIASES, BusinessRelationshipType
6
+
7
+
8
+ class GetLatestInput(BaseModel):
9
+ use_local_timezone: bool = Field(
10
+ default=True, description="whether to use the local timezone of the user"
11
+ )
12
+
13
+
14
+ class GetNQuartersAgoInput(BaseModel):
15
+ n: int = Field(description="number of quarters before the current quarter")
16
+
17
+
18
+ class GetCompanyIdFromIdentifier(BaseModel):
19
+ ticker_str: str = Field(description="The ticker")
20
+
21
+
22
+ class GetSecurityIdFromIdentifier(BaseModel):
23
+ identifier: str = Field(
24
+ description="The identifier, which can be a ticker symbol, ISIN, or CUSIP"
25
+ )
26
+
27
+
28
+ class GetTradingItemIdFromIdentifier(BaseModel):
29
+ identifier: str = Field(
30
+ description="The identifier, which can be a ticker symbol, ISIN, or CUSIP"
31
+ )
32
+
33
+
34
+ class GetIsinFromTicker(BaseModel):
35
+ ticker_str: str = Field(description="The ticker")
36
+
37
+
38
+ class GetCusipFromTicker(BaseModel):
39
+ ticker_str: str = Field(description="The ticker")
40
+
41
+
42
+ class GetInfoFromIdentifier(BaseModel):
43
+ identifier: str = Field(
44
+ description="The identifier, which can be a ticker symbol, ISIN, or CUSIP"
45
+ )
46
+
47
+
48
+ class GetEarningsCallDatetimesFromIdentifier(BaseModel):
49
+ identifier: str = Field(
50
+ description="The identifier, which can be a ticker symbol, ISIN, or CUSIP"
51
+ )
52
+
53
+
54
+ class GetHistoryMetadataFromIdentifier(BaseModel):
55
+ identifier: str = Field(
56
+ description="The identifier, which can be a ticker symbol, ISIN, or CUSIP"
57
+ )
58
+
59
+
60
+ class GetPricesFromIdentifier(BaseModel):
61
+ identifier: str = Field(
62
+ description="The identifier, which can be a ticker symbol, ISIN, or CUSIP"
63
+ )
64
+ periodicity: Literal["day", "week", "month", "year"] = Field(
65
+ default="day",
66
+ description="The frequency or interval at which the historical data points are sampled or aggregated. Periodicity is not the same as the date range. The date range specifies the time span over which the data is retrieved, while periodicity determines how the data within that date range is aggregated, valid inputs are ['day', 'week', 'month', 'year'].",
67
+ )
68
+ adjusted: bool = Field(
69
+ description="Whether to retrieve adjusted prices that account for corporate actions such as dividends and splits."
70
+ )
71
+ start_date: str | None = Field(
72
+ default=None,
73
+ description="The start date for historical price retrieval in format YYYY-MM-DD",
74
+ )
75
+ end_date: str | None = Field(
76
+ default=None, description="The end date for historical price retrieval in format YYYY-MM-DD"
77
+ )
78
+
79
+
80
+ class GetFinancialStatementFromIdentifier(BaseModel):
81
+ identifier: str = Field(
82
+ description="The identifier, which can be a ticker symbol, ISIN, or CUSIP"
83
+ )
84
+ statement: Literal["balance_sheet", "income_statement", "cashflow"] = Field(
85
+ description="The type of financial statement, valid inputs are ['balance_sheet', 'income_statement', 'cashflow']"
86
+ )
87
+ period_type: Literal["annual", "quarterly", "ltm", "ytd"] | None = Field(
88
+ default=None,
89
+ description="time period type, valid inputs are ['annual', 'quarterly', 'ltm', 'ytd'].",
90
+ )
91
+ start_year: int | None = Field(
92
+ default=None, description="The starting year for the data range."
93
+ )
94
+ end_year: int | None = Field(default=None, description="The ending year for the data range.")
95
+ start_quarter: Literal[1, 2, 3, 4] | None = Field(
96
+ default=None, description="starting quarter, valid inputs are [1, 2, 3, 4]"
97
+ )
98
+ end_quarter: Literal[1, 2, 3, 4] | None = Field(
99
+ default=None, description="ending quarter, valid inputs are [1, 2, 3, 4]"
100
+ )
101
+
102
+
103
+ class GetFinancialLineItemFromIdentifier(BaseModel):
104
+ identifier: str = Field(
105
+ description="The identifier, which can be a ticker symbol, ISIN, or CUSIP"
106
+ )
107
+ line_item: Literal[tuple(LINE_ITEM_NAMES_AND_ALIASES)] = Field( # type: ignore
108
+ description="The type of financial line_item requested"
109
+ )
110
+ period_type: Literal["annual", "quarterly", "ltm", "ytd"] | None = Field(
111
+ default=None,
112
+ description="time period type, valid inputs are ['annual', 'quarterly', 'ltm', 'ytd']",
113
+ )
114
+ start_year: int | None = Field(
115
+ default=None, description="The starting year for the data range."
116
+ )
117
+ end_year: int | None = Field(default=None, description="The ending year for the data range.")
118
+ start_quarter: Literal[1, 2, 3, 4] | None = Field(
119
+ default=None, description="starting quarter, valid inputs are [1, 2, 3, 4]"
120
+ )
121
+ end_quarter: Literal[1, 2, 3, 4] | None = Field(
122
+ default=None, description="ending quarter, valid inputs are [1, 2, 3, 4]"
123
+ )
124
+
125
+
126
+ class GetBusinessRelationshipFromIdentifier(BaseModel):
127
+ identifier: str = Field(
128
+ description="The identifier, which can be a ticker symbol, ISIN, or CUSIP"
129
+ )
130
+ business_relationship: BusinessRelationshipType = Field(
131
+ description="The type of business relationship requested"
132
+ )