cryptodatapy 0.2.11__tar.gz → 0.2.13__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.
Files changed (62) hide show
  1. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/PKG-INFO +1 -1
  2. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/pyproject.toml +1 -1
  3. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/data_vendors/tiingo_api.py +99 -135
  4. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/libraries/ccxt_api.py +4 -0
  5. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/transform/convertparams.py +55 -70
  6. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/transform/wrangle.py +10 -3
  7. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/LICENSE +0 -0
  8. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/README.md +0 -0
  9. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/__init__.py +0 -0
  10. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/conf/__init__.py +0 -0
  11. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/conf/fields.csv +0 -0
  12. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/conf/tickers.csv +0 -0
  13. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/__init__.py +0 -0
  14. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/br_econ_calendar.csv +0 -0
  15. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/ca_econ_calendar.csv +0 -0
  16. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/cn_econ_calendar.csv +0 -0
  17. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/de_econ_calendar.csv +0 -0
  18. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/ez_econ_calendar.csv +0 -0
  19. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/fr_econ_calendar.csv +0 -0
  20. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/gb_econ_calendar.csv +0 -0
  21. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/get_econ_calendars.py +0 -0
  22. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/id_econ_calendar.csv +0 -0
  23. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/in_econ_calendar.csv +0 -0
  24. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/it_econ_calendar.csv +0 -0
  25. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/jp_econ_calendar.csv +0 -0
  26. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/kr_econ_calendar.csv +0 -0
  27. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/mx_econ_calendar.csv +0 -0
  28. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/ru_econ_calendar.csv +0 -0
  29. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/tr_econ_calendar.csv +0 -0
  30. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/datasets/us_econ_calendar.csv +0 -0
  31. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/__init__.py +0 -0
  32. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/data_vendors/.ipynb_checkpoints/CCXT-checkpoint.ipynb +0 -0
  33. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/data_vendors/.ipynb_checkpoints/DBNomics-checkpoint.ipynb +0 -0
  34. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/data_vendors/.ipynb_checkpoints/InvestPy-checkpoint.ipynb +0 -0
  35. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/data_vendors/.ipynb_checkpoints/NasdaqDataLink-checkpoint.ipynb +0 -0
  36. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/data_vendors/.ipynb_checkpoints/PandasDataReader-checkpoint.ipynb +0 -0
  37. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/data_vendors/__init__.py +0 -0
  38. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/data_vendors/coinmetrics_api.py +0 -0
  39. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/data_vendors/cryptocompare_api.py +0 -0
  40. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/data_vendors/datavendor.py +0 -0
  41. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/data_vendors/glassnode_api.py +0 -0
  42. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/datarequest.py +0 -0
  43. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/exchanges/__init__.py +0 -0
  44. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/exchanges/dydx.py +0 -0
  45. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/exchanges/exchange.py +0 -0
  46. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/getdata.py +0 -0
  47. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/libraries/__init__.py +0 -0
  48. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/libraries/dbnomics_api.py +0 -0
  49. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/libraries/investpy_api.py +0 -0
  50. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/libraries/library.py +0 -0
  51. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/libraries/pandasdr_api.py +0 -0
  52. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/web/__init__.py +0 -0
  53. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/web/aqr.py +0 -0
  54. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/extract/web/web.py +0 -0
  55. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/transform/__init__.py +0 -0
  56. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/transform/clean.py +0 -0
  57. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/transform/filter.py +0 -0
  58. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/transform/impute.py +0 -0
  59. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/transform/od.py +0 -0
  60. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/util/__init__.py +0 -0
  61. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/util/datacatalog.py +0 -0
  62. {cryptodatapy-0.2.11 → cryptodatapy-0.2.13}/src/cryptodatapy/util/datacredentials.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: cryptodatapy
3
- Version: 0.2.11
3
+ Version: 0.2.13
4
4
  Summary: Cryptoasset data library
5
5
  License: Apache-2.0
6
6
  Author: Systamental
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "cryptodatapy"
3
- version = "0.2.11"
3
+ version = "0.2.13"
4
4
  description = "Cryptoasset data library"
5
5
  authors = ["Systamental"]
6
6
  license = "Apache License 2.0"
@@ -20,14 +20,15 @@ class Tiingo(DataVendor):
20
20
 
21
21
  def __init__(
22
22
  self,
23
- categories=None,
23
+ categories: List[str] = ["crypto", "fx", "eqty"],
24
24
  exchanges: Optional[Dict[str, List[str]]] = None,
25
25
  indexes: Optional[Dict[str, List[str]]] = None,
26
26
  assets: Optional[Dict[str, List[str]]] = None,
27
27
  markets: Optional[Dict[str, List[str]]] = None,
28
- market_types=None,
28
+ market_types: List[str] = ["spot"],
29
29
  fields: Dict[str, List[str]] = None,
30
- frequencies=None,
30
+ frequencies: List[str] = ["1min", "5min", "10min", "15min", "30min", "1h",
31
+ "2h", "4h", "8h", "d", "w", "m", "q", "y"],
31
32
  base_url: str = data_cred.tiingo_base_url,
32
33
  api_key: str = data_cred.tiingo_api_key,
33
34
  max_obs_per_call: Optional[int] = None,
@@ -71,53 +72,18 @@ class Tiingo(DataVendor):
71
72
  rate_limit: pd.DataFrame, optional, Default None
72
73
  Number of API calls made and left, by time frequency.
73
74
  """
74
- DataVendor.__init__(
75
- self,
76
- categories,
77
- exchanges,
78
- indexes,
79
- assets,
80
- markets,
81
- market_types,
82
- fields,
83
- frequencies,
84
- base_url,
85
- api_key,
86
- max_obs_per_call,
87
- rate_limit,
75
+ super().__init__(
76
+ categories, exchanges, indexes, assets, markets, market_types,
77
+ fields, frequencies, base_url, api_key, max_obs_per_call, rate_limit
88
78
  )
89
79
 
90
- if frequencies is None:
91
- self.frequencies = [
92
- "1min",
93
- "5min",
94
- "10min",
95
- "15min",
96
- "30min",
97
- "1h",
98
- "2h",
99
- "4h",
100
- "8h",
101
- "d",
102
- "w",
103
- "m",
104
- "q",
105
- "y",
106
- ]
107
- if market_types is None:
108
- self.market_types = ["spot"]
109
- if categories is None:
110
- self.categories = ["crypto", "fx", "eqty"]
111
80
  if api_key is None:
112
81
  raise TypeError("Set your Tiingo api key in environment variables as 'TIINGO_API_KEY' or "
113
82
  "add it as an argument when instantiating the class. To get an api key, visit: "
114
83
  "https://www.tiingo.com/")
115
- if exchanges is None:
116
- self.exchanges = self.get_exchanges_info()
117
- if assets is None:
118
- self.assets = self.get_assets_info(as_list=True)
119
- if fields is None:
120
- self.fields = self.get_fields_info()
84
+
85
+ self.data_req = None
86
+ self.data = pd.DataFrame()
121
87
 
122
88
  def get_exchanges_info(
123
89
  self, cat: Optional[str] = None
@@ -266,8 +232,10 @@ class Tiingo(DataVendor):
266
232
  """
267
233
  # data req
268
234
  data_resp = self.req_crypto()
235
+
269
236
  # wrangle data resp
270
237
  crypto = pd.DataFrame(data_resp).set_index('ticker')
238
+
271
239
  # as list
272
240
  if as_list:
273
241
  crypto = crypto.index.to_list()
@@ -302,15 +270,15 @@ class Tiingo(DataVendor):
302
270
  crypto = crypto.index.to_list()
303
271
 
304
272
  # add to dict
305
- assets_info = {'eqty': eqty,
273
+ self.assets = {'eqty': eqty,
306
274
  'crypto': crypto,
307
275
  'fx': f"For more information, see FX documentation: {fx_url}."}
308
276
 
309
277
  # filter cat
310
278
  if cat is not None:
311
- assets_info = assets_info[cat]
279
+ self.assets = self.assets[cat]
312
280
 
313
- return assets_info
281
+ return self.assets
314
282
 
315
283
  def get_markets_info(self) -> None:
316
284
  """
@@ -357,16 +325,17 @@ class Tiingo(DataVendor):
357
325
  fx_fields_list = ["open", "high", "low", "close"]
358
326
 
359
327
  # fields dict
360
- fields = {
328
+ self.fields = {
361
329
  "crypto": crypto_fields_list,
362
330
  "fx": fx_fields_list,
363
331
  "eqty": equities_fields_list,
364
332
  }
333
+
365
334
  # fields obj
366
335
  if cat is not None:
367
- fields = fields[cat]
336
+ self.fields = self.fields[cat]
368
337
 
369
- return fields
338
+ return self.fields
370
339
 
371
340
  def get_rate_limit_info(self) -> None:
372
341
  """
@@ -394,21 +363,20 @@ class Tiingo(DataVendor):
394
363
 
395
364
  """
396
365
  # convert data req params
397
- tg_data_req = ConvertParams(data_req).to_tiingo()
366
+ self.data_req = ConvertParams(data_req).to_tiingo()
398
367
 
399
368
  url, params, headers = None, {}, {}
400
369
 
401
370
  # eqty daily
402
371
  if data_type == 'eqty':
403
- url = self.base_url + f"daily/prices"
372
+ url = self.base_url + f"daily/{ticker}/prices"
404
373
  headers = {
405
374
  "Content-Type": "application/json",
406
375
  "Authorization": f"Token {self.api_key}",
407
376
  }
408
377
  params = {
409
- "tickers": ticker,
410
- "startDate": tg_data_req["start_date"],
411
- "endDate": tg_data_req["end_date"],
378
+ "startDate": self.data_req.source_start_date,
379
+ "endDate": self.data_req.source_end_date
412
380
  }
413
381
 
414
382
  # eqty intraday
@@ -419,9 +387,9 @@ class Tiingo(DataVendor):
419
387
  "Authorization": f"Token {self.api_key}",
420
388
  }
421
389
  params = {
422
- "startDate": tg_data_req["start_date"],
423
- "endDate": tg_data_req["end_date"],
424
- "resampleFreq": tg_data_req["freq"],
390
+ "startDate": self.data_req.source_start_date,
391
+ "endDate": self.data_req.source_end_date,
392
+ "resampleFreq": self.data_req.source_freq
425
393
  }
426
394
 
427
395
  # crypto
@@ -433,14 +401,13 @@ class Tiingo(DataVendor):
433
401
  }
434
402
  params = {
435
403
  "tickers": ticker,
436
- "startDate": tg_data_req["start_date"],
437
- "endDate": tg_data_req["end_date"],
438
- "resampleFreq": tg_data_req["freq"],
404
+ "startDate": self.data_req.source_start_date,
405
+ "endDate": self.data_req.source_end_date,
406
+ "resampleFreq": self.data_req.source_freq
439
407
  }
440
408
 
441
409
  # fx
442
410
  elif data_type == 'fx':
443
- # url = f"https://api.tiingo.com/tiingo/fx/{ticker}/prices"
444
411
  url = self.base_url + f"fx/prices"
445
412
  headers = {
446
413
  "Content-Type": "application/json",
@@ -448,9 +415,9 @@ class Tiingo(DataVendor):
448
415
  }
449
416
  params = {
450
417
  "tickers": ticker,
451
- "startDate": tg_data_req["start_date"],
452
- "endDate": tg_data_req["end_date"],
453
- "resampleFreq": tg_data_req["freq"],
418
+ "startDate": self.data_req.source_start_date,
419
+ "endDate": self.data_req.source_end_date,
420
+ "resampleFreq": self.data_req.source_freq
454
421
  }
455
422
 
456
423
  return {'url': url, 'params': params, 'headers': headers}
@@ -526,6 +493,7 @@ class Tiingo(DataVendor):
526
493
  """
527
494
  # get entire data history
528
495
  df = self.req_data(data_req, data_type, ticker)
496
+
529
497
  # wrangle df
530
498
  df = self.wrangle_data_resp(data_req, df, data_type)
531
499
 
@@ -549,19 +517,17 @@ class Tiingo(DataVendor):
549
517
  Dataframe with DatetimeIndex (level 0), ticker (level 1) and values for fields (cols), in tidy data format.
550
518
  """
551
519
  # convert data request parameters to CryptoCompare format
552
- tg_data_req = ConvertParams(data_req).to_tiingo()
520
+ self.data_req = ConvertParams(data_req).to_tiingo()
553
521
 
554
522
  # empty df to add data
555
523
  df = pd.DataFrame()
556
524
 
557
525
  if data_type == 'crypto':
558
- # loop through mkts
559
- for mkt, ticker in zip(tg_data_req['mkts'], data_req.tickers):
526
+ for market, ticker in zip(self.data_req.source_markets, self.data_req.tickers):
560
527
  try:
561
- df0 = self.get_tidy_data(data_req, data_type, mkt)
562
- print(df0)
563
- except Exception:
564
- logging.info(f"Failed to get {data_type} data for {ticker} after many attempts.")
528
+ df0 = self.get_tidy_data(self.data_req, data_type, market)
529
+ except Exception as e:
530
+ logging.info(f"Failed to get {data_type} data for {ticker} after many attempts: {e}.")
565
531
  else:
566
532
  # add ticker to index
567
533
  df0['ticker'] = ticker.upper()
@@ -570,29 +536,27 @@ class Tiingo(DataVendor):
570
536
  df = pd.concat([df, df0])
571
537
 
572
538
  elif data_type == 'fx':
573
- # loop through mkts
574
- for mkt, ticker in zip(tg_data_req['mkts'], data_req.tickers):
539
+ for market, ticker in zip(self.data_req.source_markets, self.data_req.tickers):
575
540
  try:
576
- df0 = self.get_tidy_data(data_req, data_type, mkt)
577
- except Exception:
578
- logging.info(f"Failed to get {data_type} data for {mkt} after many attempts.")
541
+ df0 = self.get_tidy_data(self.data_req, data_type, market)
542
+ except Exception as e:
543
+ logging.info(f"Failed to get {data_type} data for {market} after many attempts: {e}.")
579
544
  else:
580
545
  # add ticker to index
581
- df0['ticker'] = mkt.upper()
546
+ df0['ticker'] = market.upper()
582
547
  df0.set_index(['ticker'], append=True, inplace=True)
583
548
  # concat df and df1
584
549
  df = pd.concat([df, df0])
585
550
 
586
551
  else:
587
- # loop through mkts
588
- for tg_ticker, dr_ticker in zip(tg_data_req['tickers'], data_req.tickers):
552
+ for ticker in self.data_req.source_tickers:
589
553
  try:
590
- df0 = self.get_tidy_data(data_req, data_type, tg_ticker)
591
- except Exception:
592
- logging.info(f"Failed to get {data_type} data for {dr_ticker} after many attempts.")
554
+ df0 = self.get_tidy_data(self.data_req, data_type, ticker)
555
+ except Exception as e:
556
+ logging.info(f"Failed to get {data_type} data for {ticker} after many attempts: {e}.")
593
557
  else:
594
558
  # add ticker to index
595
- df0['ticker'] = dr_ticker.upper()
559
+ df0['ticker'] = ticker.upper()
596
560
  df0.set_index(['ticker'], append=True, inplace=True)
597
561
  # concat df and df1
598
562
  df = pd.concat([df, df0])
@@ -614,19 +578,17 @@ class Tiingo(DataVendor):
614
578
  DataFrame with DatetimeIndex (level 0), ticker (level 1) and equities OHLCV values (cols).
615
579
  """
616
580
  # convert data request parameters to CryptoCompare format
617
- tg_data_req = ConvertParams(data_req).to_tiingo()
581
+ self.data_req = ConvertParams(data_req).to_tiingo()
618
582
 
619
- # check tickers
620
- if any([ticker.upper() in self.assets['eqty'] for ticker in tg_data_req['tickers']]) and \
621
- any([field in self.fields['eqty'] for field in data_req.fields]):
622
- try:
623
- df = self.get_all_tickers(data_req, data_type='eqty')
583
+ # get eqty data
584
+ try:
585
+ df = self.get_all_tickers(self.data_req, data_type='eqty')
624
586
 
625
- except Exception as e:
626
- logging.warning(e)
587
+ except Exception as e:
588
+ logging.warning(e)
627
589
 
628
- else:
629
- return df
590
+ else:
591
+ return df
630
592
 
631
593
  def get_eqty_iex(self, data_req: DataRequest) -> pd.DataFrame:
632
594
  """
@@ -643,19 +605,17 @@ class Tiingo(DataVendor):
643
605
  DataFrame with DatetimeIndex (level 0), ticker (level 1) and equities OHLCV values (cols).
644
606
  """
645
607
  # convert data request parameters to CryptoCompare format
646
- tg_data_req = ConvertParams(data_req).to_tiingo()
608
+ self.data_req = ConvertParams(data_req).to_tiingo()
647
609
 
648
- # check tickers
649
- if any([ticker.upper() in self.assets['eqty'] for ticker in tg_data_req['tickers']]) and \
650
- any([field in self.fields['eqty'] for field in data_req.fields]):
651
- try:
652
- df = self.get_all_tickers(data_req, data_type='iex')
610
+ # get iex data
611
+ try:
612
+ df = self.get_all_tickers(self.data_req, data_type='iex')
653
613
 
654
- except Exception as e:
655
- logging.warning(e)
614
+ except Exception as e:
615
+ logging.warning(e)
656
616
 
657
- else:
658
- return df
617
+ else:
618
+ return df
659
619
 
660
620
  def get_crypto(self, data_req: DataRequest) -> pd.DataFrame:
661
621
  """
@@ -672,20 +632,17 @@ class Tiingo(DataVendor):
672
632
  DataFrame with DatetimeIndex (level 0), ticker (level 1) and crypto OHLCV values (cols).
673
633
  """
674
634
  # convert data request parameters to CryptoCompare format
675
- tg_data_req = ConvertParams(data_req).to_tiingo()
676
-
677
- # check tickers
678
- if any([ticker in self.assets['crypto'] for ticker in tg_data_req['mkts']]) and \
679
- any([field in self.fields['crypto'] for field in data_req.fields]):
635
+ self.data_req = ConvertParams(data_req).to_tiingo()
680
636
 
681
- try:
682
- df = self.get_all_tickers(data_req, data_type='crypto')
637
+ # get crypto data
638
+ try:
639
+ df = self.get_all_tickers(self.data_req, data_type='crypto')
683
640
 
684
- except Exception as e:
685
- logging.warning(e)
641
+ except Exception as e:
642
+ logging.warning(e)
686
643
 
687
- else:
688
- return df
644
+ else:
645
+ return df
689
646
 
690
647
  def get_fx(self, data_req: DataRequest) -> pd.DataFrame:
691
648
  """
@@ -702,19 +659,17 @@ class Tiingo(DataVendor):
702
659
  DataFrame with DatetimeIndex (level 0), ticker (level 1) and FX OHLC values (cols).
703
660
  """
704
661
  # convert data request parameters to CryptoCompare format
705
- tg_data_req = ConvertParams(data_req).to_tiingo()
662
+ self.data_req = ConvertParams(data_req).to_tiingo()
706
663
 
707
- # check tickers
708
- if any([field in self.fields['fx'] for field in data_req.fields]):
709
-
710
- try:
711
- df = self.get_all_tickers(data_req, data_type='fx')
664
+ # get fx data
665
+ try:
666
+ df = self.get_all_tickers(self.data_req, data_type='fx')
712
667
 
713
- except Exception as e:
714
- logging.warning(e)
668
+ except Exception as e:
669
+ logging.warning(e)
715
670
 
716
- else:
717
- return df
671
+ else:
672
+ return df
718
673
 
719
674
  def check_params(self, data_req: DataRequest) -> None:
720
675
  """
@@ -722,23 +677,32 @@ class Tiingo(DataVendor):
722
677
  and improve efficiency.
723
678
 
724
679
  """
725
- tg_data_req = ConvertParams(data_req).to_tiingo()
680
+ self.data_req = ConvertParams(data_req).to_tiingo()
681
+
682
+ # get metadata
683
+ self.get_assets_info(as_list=True)
684
+ self.get_fields_info()
726
685
 
727
686
  # check cat
728
- if data_req.cat is None:
687
+ if self.data_req.cat is None:
729
688
  raise ValueError(
730
689
  f"Cat cannot be None. Please provide category. Categories include: {self.categories}."
731
690
  )
732
691
 
733
692
  # check assets
734
- if not any([ticker.upper() in self.assets[data_req.cat] for ticker in tg_data_req['tickers']]) and \
735
- data_req.cat != 'fx':
736
- raise ValueError(
737
- f"Selected tickers are not available. Use assets attribute to see available tickers."
738
- )
739
-
740
- # check fields
741
- if not any([field in self.fields[data_req.cat] for field in data_req.fields]):
693
+ if self.data_req.cat == 'eqty':
694
+ if not any([ticker.upper() in self.assets[self.data_req.cat] for ticker in self.data_req.source_tickers]):
695
+ raise ValueError(
696
+ f"Selected eqty tickers are not available. Use assets attribute to see available eqty tickers."
697
+ )
698
+ elif self.data_req.cat == 'crypto':
699
+ if not any([ticker in self.assets[self.data_req.cat] for ticker in self.data_req.source_markets]):
700
+ raise ValueError(
701
+ f"Selected crypto tickers are not available. Use assets attribute to see available crypto tickers."
702
+ )
703
+
704
+ # check fields
705
+ if not any([field in self.fields[data_req.cat] for field in self.data_req.fields]):
742
706
  raise ValueError(
743
707
  f"Selected fields are not available. Use fields attribute to see available fields."
744
708
  )
@@ -1483,6 +1483,8 @@ class CCXT(Library):
1483
1483
  df: pd.DataFrame - MultiIndex
1484
1484
  DataFrame with DatetimeIndex (level 0), ticker (level 1), and values for selected fields (cols).
1485
1485
  """
1486
+ logging.info("Retrieving data request from CCXT...")
1487
+
1486
1488
  # get OHLCV
1487
1489
  if any([field in ["open", "high", "low", "close", "volume"] for field in data_req.fields]):
1488
1490
  df = await self.fetch_tidy_ohlcv_async(data_req)
@@ -1523,6 +1525,8 @@ class CCXT(Library):
1523
1525
  df: pd.DataFrame - MultiIndex
1524
1526
  DataFrame with DatetimeIndex (level 0), ticker (level 1), and values for selected fields (cols).
1525
1527
  """
1528
+ logging.info("Retrieving data request from CCXT...")
1529
+
1526
1530
  # get OHLCV
1527
1531
  if any([field in ["open", "high", "low", "close", "volume"] for field in data_req.fields]):
1528
1532
  df = self.fetch_tidy_ohlcv(data_req)
@@ -339,34 +339,43 @@ class ConvertParams:
339
339
  "source_fields": self.data_req.source_fields,
340
340
  }
341
341
 
342
- def to_tiingo(self) -> Dict[str, Union[list, str, int, float, datetime, None]]:
342
+ def to_tiingo(self) -> DataRequest:
343
343
  """
344
344
  Convert tickers from CryptoDataPy to Tiingo format.
345
345
  """
346
- # convert tickers
347
- if self.data_req.source_tickers is not None:
348
- tickers = self.data_req.source_tickers
349
- self.data_req.tickers = self.data_req.source_tickers
350
- else:
351
- tickers = [ticker.lower() for ticker in self.data_req.tickers]
352
- # convert freq
353
- if self.data_req.source_freq is not None:
354
- freq = self.data_req.source_freq
355
- self.data_req.freq = self.data_req.source_freq
356
- else:
346
+ # tickers
347
+ with resources.path("cryptodatapy.conf", "tickers.csv") as f:
348
+ tickers_path = f
349
+ tickers_df = pd.read_csv(tickers_path, index_col=0, encoding="latin1")
350
+
351
+ if self.data_req.source_tickers is None and self.data_req.cat == 'eqty':
352
+ self.data_req.source_tickers = []
353
+ for ticker in self.data_req.tickers:
354
+ try:
355
+ self.data_req.source_tickers.append(tickers_df.loc[ticker, "tiingo_id"])
356
+ except KeyError:
357
+ logging.warning(
358
+ f"{ticker} not found for Tiingo source. Check tickers in"
359
+ f" data catalog and try again."
360
+ )
361
+
362
+ # freq
363
+ if self.data_req.source_freq is None:
357
364
  if self.data_req.freq is None:
358
- freq = "1day"
365
+ self.data_req.source_freq = "1day"
359
366
  elif self.data_req.freq[-3:] == "min":
360
- freq = self.data_req.freq
367
+ self.data_req.source_freq = self.data_req.freq
361
368
  elif self.data_req.freq[-1] == "h":
362
- freq = "1hour"
369
+ self.data_req.source_freq = "1hour"
363
370
  else:
364
- freq = "1day"
365
- # convert quote ccy
371
+ self.data_req.source_freq = "1day"
372
+
373
+ # quote ccy
366
374
  if self.data_req.quote_ccy is None:
367
- quote_ccy = "usd"
375
+ self.data_req.quote_ccy = "usd"
368
376
  else:
369
- quote_ccy = self.data_req.quote_ccy.lower()
377
+ self.data_req.quote_ccy = self.data_req.quote_ccy.lower()
378
+
370
379
  # convert exch
371
380
  if (
372
381
  self.data_req.exch is None
@@ -374,64 +383,40 @@ class ConvertParams:
374
383
  and self.data_req.freq
375
384
  in ["1min", "5min", "10min", "15min", "30min", "1h", "2h", "4h", "8h"]
376
385
  ):
377
- exch = "iex"
378
- else:
379
- exch = self.data_req.exch
380
- # convert tickers to mkts
381
- mkts_list = []
382
- if self.data_req.source_tickers is not None:
383
- mkts_list = self.data_req.source_tickers
384
- self.data_req.tickers = self.data_req.source_tickers
385
- else:
386
- if self.data_req.cat == "fx":
387
- fx_list = self.convert_fx_tickers(quote_ccy=quote_ccy)
388
- mkts_list = [ticker.lower().replace("/", "") for ticker in fx_list]
389
- elif self.data_req.cat == "crypto":
390
- mkts_list = [
391
- ticker.lower() + quote_ccy for ticker in self.data_req.tickers
392
- ]
393
- # convert start date
394
- if self.data_req.start_date is None and self.data_req.cat == 'crypto':
395
- start_date = datetime(2010, 1, 1, 0, 0)
386
+ self.data_req.exch = "iex"
387
+
388
+ # markets
389
+ if self.data_req.source_markets is None:
390
+ if self.data_req.cat == 'fx':
391
+ fx_list = self.convert_fx_tickers(quote_ccy=self.data_req.quote_ccy)
392
+ self.data_req.source_markets = [ticker.lower().replace("/", "") for ticker in fx_list]
393
+ elif self.data_req.cat == 'crypto':
394
+ self.data_req.source_markets = [ticker.lower() +
395
+ self.data_req.quote_ccy for ticker in self.data_req.tickers]
396
+
397
+ # start date
398
+ if self.data_req.start_date is None:
399
+ self.data_req.source_start_date = '1990-01-01'
396
400
  else:
397
- start_date = self.data_req.start_date
398
- # convert end date
401
+ self.data_req.source_start_date = self.data_req.start_date
402
+
403
+ # end date
399
404
  if self.data_req.end_date is None:
400
- end_date = pd.Timestamp.utcnow()
405
+ self.data_req.source_end_date = str(pd.Timestamp.utcnow().date())
401
406
  else:
402
- end_date = self.data_req.end_date
403
- # convert fields
404
- if self.data_req.source_fields is not None:
405
- fields = self.data_req.source_fields
406
- self.data_req.fields = self.data_req.source_fields
407
- else:
408
- fields = self.convert_fields(data_source='tiingo')
407
+ self.data_req.source_end_date = self.data_req.end_date
408
+
409
+ # fields
410
+ if self.data_req.source_fields is None:
411
+ self.data_req.source_fields = self.convert_fields(data_source='tiingo')
412
+
409
413
  # tz
410
414
  if self.data_req.cat == 'eqty' or self.data_req.cat == 'fx':
411
- tz = "America/New_York"
415
+ self.data_req.tz = "America/New_York"
412
416
  else:
413
- tz = "UTC"
417
+ self.data_req.tz = "UTC"
414
418
 
415
- return {
416
- "tickers": tickers,
417
- "freq": freq,
418
- "quote_ccy": quote_ccy,
419
- "exch": exch,
420
- "ctys": None,
421
- "mkt_type": self.data_req.mkt_type,
422
- "mkts": mkts_list,
423
- "start_date": start_date,
424
- "end_date": end_date,
425
- "fields": fields,
426
- "tz": tz,
427
- "inst": None,
428
- "cat": self.data_req.cat,
429
- "trials": self.data_req.trials,
430
- "pause": self.data_req.pause,
431
- "source_tickers": self.data_req.source_tickers,
432
- "source_freq": self.data_req.source_freq,
433
- "source_fields": self.data_req.source_fields,
434
- }
419
+ return self.data_req
435
420
 
436
421
  def to_ccxt(self) -> DataRequest:
437
422
  """
@@ -640,27 +640,34 @@ class WrangleData:
640
640
 
641
641
  """
642
642
  # create df
643
- if data_type == 'eqty' or data_type == 'crypto':
643
+ if data_type == 'crypto':
644
644
  self.data_resp = pd.DataFrame(self.data_resp[0]['priceData'])
645
645
  else:
646
646
  self.data_resp = pd.DataFrame(self.data_resp)
647
+
647
648
  # convert fields to lib
648
649
  self.convert_fields_to_lib(data_source='tiingo')
650
+
649
651
  # convert to datetime
650
652
  self.data_resp['date'] = pd.to_datetime(self.data_resp['date'])
653
+
651
654
  # set index
652
655
  self.data_resp = self.data_resp.set_index('date').sort_index()
653
656
  self.data_resp.index = self.data_resp.index.tz_localize(None)
657
+
654
658
  # resample
655
659
  self.data_resp = self.data_resp.resample(self.data_req.freq).last()
660
+
656
661
  # reformat index
657
662
  if self.data_req.freq in ['d', 'w', 'm', 'q']:
658
663
  self.data_resp.reset_index(inplace=True)
659
664
  self.data_resp.date = pd.to_datetime(self.data_resp.date.dt.date)
660
665
  # reset index
661
666
  self.data_resp.set_index('date', inplace=True)
667
+
662
668
  # type conversion
663
- self.data_resp = self.data_resp.apply(pd.to_numeric, errors='coerce').convert_dtypes()
669
+ self.data_resp = self.data_resp.convert_dtypes()
670
+
664
671
  # remove bad data
665
672
  self.data_resp = self.data_resp[~self.data_resp.index.duplicated()] # duplicate rows
666
673
  self.data_resp = self.data_resp.dropna(how='all').dropna(how='all', axis=1) # entire row or col NaNs
@@ -930,7 +937,7 @@ class WrangleData:
930
937
  last().swaplevel('ticker', 'date').sort_index()
931
938
 
932
939
  # type conversion
933
- self.data_resp = self.data_resp.apply(pd.to_numeric, errors='coerce').convert_dtypes()
940
+ self.data_resp = self.data_resp.convert_dtypes()
934
941
 
935
942
  # remove bad data
936
943
  self.data_resp = self.data_resp[self.data_resp != 0] # 0 values
File without changes
File without changes