cryptodatapy 0.2.6__tar.gz → 0.2.8__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 (75) hide show
  1. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/PKG-INFO +9 -6
  2. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/pyproject.toml +9 -2
  3. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/conf/fields.csv +1 -1
  4. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/datarequest.py +169 -28
  5. cryptodatapy-0.2.8/src/cryptodatapy/extract/libraries/Untitled.ipynb +199 -0
  6. cryptodatapy-0.2.8/src/cryptodatapy/extract/libraries/ccxt.ipynb +747 -0
  7. cryptodatapy-0.2.8/src/cryptodatapy/extract/libraries/ccxt_api.py +995 -0
  8. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/libraries/pandasdr_api.py +153 -138
  9. cryptodatapy-0.2.8/src/cryptodatapy/extract/libraries/yfinance_api.py +511 -0
  10. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/transform/clean_perp_futures_ohlcv.ipynb +226 -30
  11. cryptodatapy-0.2.8/src/cryptodatapy/transform/cmdty_data.ipynb +402 -0
  12. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/transform/convertparams.py +160 -303
  13. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/transform/eqty_data.ipynb +126 -99
  14. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/transform/wrangle.py +152 -43
  15. cryptodatapy-0.2.6/setup.py +0 -89
  16. cryptodatapy-0.2.6/src/cryptodatapy/extract/libraries/ccxt_api.py +0 -722
  17. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/LICENSE +0 -0
  18. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/README.md +0 -0
  19. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/__init__.py +0 -0
  20. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/conf/__init__.py +0 -0
  21. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/conf/fx_tickers.csv +0 -0
  22. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/conf/tickers.csv +0 -0
  23. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/__init__.py +0 -0
  24. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/br_econ_calendar.csv +0 -0
  25. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/ca_econ_calendar.csv +0 -0
  26. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/cn_econ_calendar.csv +0 -0
  27. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/de_econ_calendar.csv +0 -0
  28. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/ez_econ_calendar.csv +0 -0
  29. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/fr_econ_calendar.csv +0 -0
  30. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/gb_econ_calendar.csv +0 -0
  31. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/get_econ_calendars.py +0 -0
  32. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/id_econ_calendar.csv +0 -0
  33. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/in_econ_calendar.csv +0 -0
  34. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/it_econ_calendar.csv +0 -0
  35. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/jp_econ_calendar.csv +0 -0
  36. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/kr_econ_calendar.csv +0 -0
  37. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/mx_econ_calendar.csv +0 -0
  38. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/ru_econ_calendar.csv +0 -0
  39. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/tr_econ_calendar.csv +0 -0
  40. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/datasets/us_econ_calendar.csv +0 -0
  41. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/__init__.py +0 -0
  42. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/data_vendors/.ipynb_checkpoints/CCXT-checkpoint.ipynb +0 -0
  43. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/data_vendors/.ipynb_checkpoints/DBNomics-checkpoint.ipynb +0 -0
  44. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/data_vendors/.ipynb_checkpoints/InvestPy-checkpoint.ipynb +0 -0
  45. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/data_vendors/.ipynb_checkpoints/NasdaqDataLink-checkpoint.ipynb +0 -0
  46. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/data_vendors/.ipynb_checkpoints/PandasDataReader-checkpoint.ipynb +0 -0
  47. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/data_vendors/CoinMetrics.ipynb +0 -0
  48. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/data_vendors/__init__.py +0 -0
  49. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/data_vendors/coinmetrics_api.py +0 -0
  50. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/data_vendors/cryptocompare_api.py +0 -0
  51. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/data_vendors/datavendor.py +0 -0
  52. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/data_vendors/glassnode_api.py +0 -0
  53. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/data_vendors/tiingo_api.py +0 -0
  54. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/getdata.py +0 -0
  55. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/libraries/__init__.py +0 -0
  56. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/libraries/dbnomics_api.py +0 -0
  57. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/libraries/investpy_api.py +0 -0
  58. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/libraries/library.py +0 -0
  59. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/web/__init__.py +0 -0
  60. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/web/aqr.py +0 -0
  61. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/extract/web/web.py +0 -0
  62. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/transform/__init__.py +0 -0
  63. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/transform/cc_onchain_data.csv +0 -0
  64. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/transform/clean.py +0 -0
  65. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/transform/clean_onchain_data.ipynb +0 -0
  66. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/transform/credit_data.ipynb +0 -0
  67. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/transform/filter.py +0 -0
  68. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/transform/global_credit_data_daily.parquet +0 -0
  69. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/transform/impute.py +0 -0
  70. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/transform/od.py +0 -0
  71. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/transform/rates_data.ipynb +0 -0
  72. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/transform/us_rates_daily.csv +0 -0
  73. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/util/__init__.py +0 -0
  74. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/util/datacatalog.py +0 -0
  75. {cryptodatapy-0.2.6 → cryptodatapy-0.2.8}/src/cryptodatapy/util/datacredentials.py +0 -0
@@ -1,18 +1,20 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cryptodatapy
3
- Version: 0.2.6
3
+ Version: 0.2.8
4
4
  Summary: Cryptoasset data library
5
5
  License: Apache-2.0
6
6
  Author: Systamental
7
7
  Requires-Python: >=3.8,<4.0
8
8
  Classifier: License :: OSI Approved :: Apache Software License
9
9
  Classifier: Programming Language :: Python :: 3
10
- Classifier: Programming Language :: Python :: 3.10
11
10
  Classifier: Programming Language :: Python :: 3.8
12
11
  Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
13
15
  Requires-Dist: DBnomics (>=1.2.3)
14
16
  Requires-Dist: ccxt (>=1.91.52)
15
- Requires-Dist: coinmetrics-api-client (>=2022.6.17); python_version >= "3.7"
17
+ Requires-Dist: coinmetrics-api-client (>=2022.6.17) ; python_version >= "3.7"
16
18
  Requires-Dist: fsspec (>=2024.6.1)
17
19
  Requires-Dist: investpy (>=1.0.8)
18
20
  Requires-Dist: matplotlib (>=3.5.2)
@@ -20,13 +22,14 @@ Requires-Dist: numpy (>=1.23.2)
20
22
  Requires-Dist: openpyxl (>=3.1.2)
21
23
  Requires-Dist: pandas (>=1.4.4)
22
24
  Requires-Dist: pandas-datareader (>=0.10.0)
23
- Requires-Dist: prophet (>=1.1); python_version >= "3.7"
25
+ Requires-Dist: prophet (>=1.1) ; python_version >= "3.7"
24
26
  Requires-Dist: pyarrow (>=17.0.0)
25
- Requires-Dist: requests (>=2.28.0); python_version >= "3.7"
27
+ Requires-Dist: requests (>=2.28.0) ; python_version >= "3.7"
26
28
  Requires-Dist: responses (>=0.21.0)
27
- Requires-Dist: s3fs (>=2024.6.1,<2025.0.0)
29
+ Requires-Dist: s3fs (>=2024.6.1)
28
30
  Requires-Dist: selenium (>=4.4.3)
29
31
  Requires-Dist: statsmodels (>=0.13.2)
32
+ Requires-Dist: tdqm (>=0.0.1)
30
33
  Requires-Dist: webdriver-manager (>=3.8.3)
31
34
  Requires-Dist: xlrd (>=2.0.1)
32
35
  Requires-Dist: yfinance (>=0.2.14)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "cryptodatapy"
3
- version = "0.2.6"
3
+ version = "0.2.8"
4
4
  description = "Cryptoasset data library"
5
5
  authors = ["Systamental"]
6
6
  license = "Apache License 2.0"
@@ -27,7 +27,8 @@ openpyxl = ">=3.1.2"
27
27
  xlrd = ">=2.0.1"
28
28
  fsspec = ">=2024.6.1"
29
29
  pyarrow = ">=17.0.0"
30
- s3fs = "^2024.6.1"
30
+ s3fs = ">=2024.6.1"
31
+ tdqm = ">=0.0.1"
31
32
 
32
33
  [tool.poetry.dev-dependencies]
33
34
  pytest = ">=7.1.2"
@@ -39,6 +40,12 @@ myst-nb = {version = ">=0.16.0", python = ">=3.8, <4.0"}
39
40
  sphinx-autoapi = ">=1.9.0"
40
41
  sphinx-rtd-theme = ">=1.0.0"
41
42
 
43
+ [tool.poetry.group.dev.dependencies]
44
+ pytest-asyncio = ">=0.24.0"
45
+
46
+ [tool.pytest.ini_options]
47
+ asyncio_default_fixture_loop_scope = "function"
48
+
42
49
  [build-system]
43
50
  requires = ["poetry-core>=1.0.0"]
44
51
  build-backend = "poetry.core.masonry.api"
@@ -27,7 +27,7 @@ vwap,volume-weighted avg price,average volume-weighted price of quote asset with
27
27
  dividend,dividend,dividend paid out on ex-ante date,market,ohlc_bars,d ,quote currency units,Float64,,,,,,divCash,,,,,,
28
28
  split,split,"factor used to adjust prices when a company splits, reverse splits, or pays a distribution",market,ohlc_bars,d ,factor ,Float64,,,,,,splitFactor,,,,,,
29
29
  ref_rate_usd,reference rate in USD,price of asset in USD using an aggregation methodology,market,ohlc_bars,d ,quote currency units,Float64,,ReferenceRateUSD,,,,,,,,,,
30
- oi,open interest,number of outstanding futures contracts that are open and have yet to be settled,market,derivatives,"1min, 5min, 10min, 15min, 30min, 1h, 2h, 4h, 8h, d, w, m, q",number of contracts,Float64,,contract_count,,,,,,,,,,
30
+ oi,open interest,number of outstanding futures contracts that are open and have yet to be settled,market,derivatives,"1min, 5min, 10min, 15min, 30min, 1h, 2h, 4h, 8h, d, w, m, q",number of contracts,Float64,,contract_count,openInterestAmount,,,,,,,,,
31
31
  funding_rate,funding rate,interest rate for holding derivative contract within time interval,market,derivatives,"1h, 2h, 4h, 8h, d, w, m, q",interest rate over time interval,Float64,,rate,fundingRate,derivatives/futures_funding_rate_perpetual,,,,,,,,
32
32
  mkt_cap,market capitalization,usd value of circulating supply,market,market capitalization,"d, w, m, q",usd,Float64,,CapMrktCurUSD,,market/marketcap_usd,,,,,,,,
33
33
  mkt_cap_real,"market capitalization, reaized","The sum USD value based on the USD closing price on the day that a native unit last moved (i.e., last transacted) for all native units",market,market capitalization,"d, w, m, q",usd,Float64,,CapRealUSD,,,,,,,,,,
@@ -17,9 +17,11 @@ class DataRequest:
17
17
  self,
18
18
  source: str = "ccxt",
19
19
  tickers: Union[str, List[str]] = "btc",
20
- freq: str = "d",
21
20
  quote_ccy: Optional[str] = None,
21
+ markets: Optional[Union[str, List[str]]] = None,
22
+ freq: str = "d",
22
23
  exch: Optional[str] = None,
24
+ countries: Optional[Union[str, List[str]]] = None,
23
25
  mkt_type: Optional[str] = "spot",
24
26
  start_date: Optional[Union[str, datetime, pd.Timestamp]] = None,
25
27
  end_date: Optional[Union[str, datetime, pd.Timestamp]] = None,
@@ -30,8 +32,11 @@ class DataRequest:
30
32
  trials: Optional[int] = 3,
31
33
  pause: Optional[float] = 0.1,
32
34
  source_tickers: Optional[Union[str, List[str]]] = None,
35
+ source_markets: Optional[Union[str, List[str]]] = None,
33
36
  source_freq: Optional[str] = None,
34
- source_fields: Optional[Union[str, List[str]]] = None,
37
+ source_start_date: Optional[Union[str, int, datetime, pd.Timestamp]] = None,
38
+ source_end_date: Optional[Union[str, int, datetime, pd.Timestamp]] = None,
39
+ source_fields: Optional[Union[str, List[str]]] = None
35
40
  ):
36
41
  """
37
42
  Constructor
@@ -41,14 +46,18 @@ class DataRequest:
41
46
  source: str, default 'ccxt'
42
47
  Name of data source.
43
48
  tickers: list or str, default 'btc'
44
- Ticker symbols for assets or time series.
45
- e.g. 'BTC', 'EURUSD', 'SPY', 'US_Manuf_PMI', 'EZ_Rates_10Y', etc.
49
+ Ticker symbols for base assets.
50
+ e.g. 'BTC', 'EUR', 'SPY', 'US_Manuf_PMI', 'EZ_Rates_10Y', etc.
51
+ quote_ccy: str, optional, default None
52
+ Ticker symbol for quote asset, e.g. 'USDT' for BTCUSDT (bitcoin in Tether USD), 'GBP' for EURGBP, etc.
53
+ markets: list or str, optional, default None
54
+ Markets/traded pairs of base assets vs quote assets, e.g. 'BTC/USDT', 'EUR/USD', 'SPY/USD', etc.
46
55
  freq: str, default 'd'
47
56
  Frequency of data observations. Defaults to daily 'd' which includes weekends for cryptoassets.
48
- quote_ccy: str, optional, default None
49
- Quote currency for base asset, e.g. 'GBP' for EURGBP, 'USD' for BTCUSD (bitcoin in dollars), etc.
50
57
  exch: str, optional, default None
51
58
  Name of asset exchange, e.g. 'Binance', 'FTX', 'IEX', 'Nasdaq', etc.
59
+ countries: list or str, optional, default None
60
+ Country codes for which to pull data, e.g. 'US', 'GB', 'CN', 'JP', etc.
52
61
  mkt_type: str, optional, default 'spot'
53
62
  Market type, e.g. 'spot ', 'future', 'perpetual_future', 'option'.
54
63
  start_date: str, datetime or pd.Timestamp, optional, default None
@@ -72,19 +81,28 @@ class DataRequest:
72
81
  source_tickers: list or str, optional, default None
73
82
  List or string of ticker symbols for assets or time series in the format used by the
74
83
  data source. If None, tickers will be converted from CryptoDataPy to data source format.
84
+ source_markets: list or str, optional, default None
85
+ List or string of markets/traded pairs of base assets vs quote assets in the format used by the
86
+ data source. If None, markets will be converted from CryptoDataPy to data source format.
75
87
  source_freq: str, optional, default None
76
88
  Frequency of observations for assets or time series in format used by data source. If None,
77
89
  frequency will be converted from CryptoDataPy to data source format.
90
+ source_start_date: str, int, datetime or pd.Timestamp, optional, default None
91
+ Start date for data request in format used by data source.
92
+ source_end_date: str, int, datetime or pd.Timestamp, optional, default None
93
+ End date for data request in format used by data source.
78
94
  source_fields: list or str, optional, default None
79
95
  List or string of fields for assets or time series in format used by data source. If None,
80
96
  fields will be converted from CryptoDataPy to data source format.
81
97
  """
82
98
  # params
83
- self.source = source # specific data source
99
+ self.source = source # name of data source
84
100
  self.tickers = tickers # tickers
85
- self.freq = freq # frequency
86
101
  self.quote_ccy = quote_ccy # quote ccy
102
+ self.markets = markets # markets
103
+ self.freq = freq # frequency
87
104
  self.exch = exch # exchange
105
+ self.countries = countries # country codes
88
106
  self.mkt_type = mkt_type # market type
89
107
  self.start_date = start_date # start date
90
108
  self.end_date = end_date # end date
@@ -95,7 +113,10 @@ class DataRequest:
95
113
  self.trials = trials # number of times to try query request
96
114
  self.pause = pause # number of seconds to pause between query request trials
97
115
  self.source_tickers = source_tickers # tickers used by data source
116
+ self.source_markets = source_markets
98
117
  self.source_freq = source_freq # frequency used by data source
118
+ self.source_start_date = source_start_date # start date used by data source
119
+ self.source_end_date = source_end_date # end date used by data source
99
120
  self.source_fields = source_fields # fields used by data source
100
121
 
101
122
  @property
@@ -151,6 +172,46 @@ class DataRequest:
151
172
  else:
152
173
  raise TypeError("Tickers must be a string or list of strings (tickers).")
153
174
 
175
+ @property
176
+ def quote_ccy(self):
177
+ """
178
+ Returns quote currency for data request.
179
+ """
180
+ return self._quote_ccy
181
+
182
+ @quote_ccy.setter
183
+ def quote_ccy(self, quote):
184
+ """
185
+ Sets quote currency for data request.
186
+ """
187
+ if quote is None:
188
+ self._quote_ccy = quote
189
+ elif isinstance(quote, str):
190
+ self._quote_ccy = quote
191
+ else:
192
+ raise TypeError("Quote currency must be a string.")
193
+
194
+ @property
195
+ def markets(self):
196
+ """
197
+ Returns markets for data request.
198
+ """
199
+ return self._markets
200
+
201
+ @markets.setter
202
+ def markets(self, markets):
203
+ """
204
+ Sets markets for data request.
205
+ """
206
+ if markets is None:
207
+ self._markets = markets
208
+ elif isinstance(markets, str):
209
+ self._markets = [markets]
210
+ elif isinstance(markets, list):
211
+ self._markets = markets
212
+ else:
213
+ raise TypeError("Markets must be a string or list of strings (markets).")
214
+
154
215
  @property
155
216
  def freq(self):
156
217
  """
@@ -206,25 +267,6 @@ class DataRequest:
206
267
  else:
207
268
  self._frequency = frequency
208
269
 
209
- @property
210
- def quote_ccy(self):
211
- """
212
- Returns quote currency for data request.
213
- """
214
- return self._quote_ccy
215
-
216
- @quote_ccy.setter
217
- def quote_ccy(self, quote):
218
- """
219
- Sets quote currency for data request.
220
- """
221
- if quote is None:
222
- self._quote_ccy = quote
223
- elif isinstance(quote, str):
224
- self._quote_ccy = quote
225
- else:
226
- raise TypeError("Quote currency must be a string.")
227
-
228
270
  @property
229
271
  def exch(self):
230
272
  """
@@ -244,6 +286,27 @@ class DataRequest:
244
286
  else:
245
287
  raise TypeError("Exchange must be a string.")
246
288
 
289
+ @property
290
+ def countries(self):
291
+ """
292
+ Returns country codes for data request.
293
+ """
294
+ return self._countries
295
+
296
+ @countries.setter
297
+ def countries(self, countries):
298
+ """
299
+ Sets country codes for data request.
300
+ """
301
+ if countries is None:
302
+ self._countries = countries
303
+ elif isinstance(countries, str):
304
+ self._countries = [countries]
305
+ elif isinstance(countries, list):
306
+ self._countries = countries
307
+ else:
308
+ raise TypeError("Country codes must be a string or list of strings.")
309
+
247
310
  @property
248
311
  def mkt_type(self):
249
312
  """
@@ -486,6 +549,29 @@ class DataRequest:
486
549
  "Source tickers must be a string or list of strings (tickers) in data source's format."
487
550
  )
488
551
 
552
+ @property
553
+ def source_markets(self):
554
+ """
555
+ Returns markets for data request in data source format.
556
+ """
557
+ return self._source_markets
558
+
559
+ @source_markets.setter
560
+ def source_markets(self, markets):
561
+ """
562
+ Sets markets for data request in data source format.
563
+ """
564
+ if markets is None:
565
+ self._source_markets = markets
566
+ elif isinstance(markets, str):
567
+ self._source_markets = [markets]
568
+ elif isinstance(markets, list):
569
+ self._source_markets = markets
570
+ else:
571
+ raise TypeError(
572
+ "Source markets must be a string or list of strings (markets) in data source's format."
573
+ )
574
+
489
575
  @property
490
576
  def source_freq(self):
491
577
  """
@@ -507,6 +593,60 @@ class DataRequest:
507
593
  "Source data frequency must be a string in data source's format."
508
594
  )
509
595
 
596
+ @property
597
+ def source_start_date(self):
598
+ """
599
+ Returns start date for data request in data source format.
600
+ """
601
+ return self._source_start_date
602
+
603
+ @source_start_date.setter
604
+ def source_start_date(self, start_date):
605
+ """
606
+ Sets start date for data request in data source format.
607
+ """
608
+ if start_date is None:
609
+ self._source_start_date = start_date
610
+ elif isinstance(start_date, str):
611
+ self._source_start_date = start_date
612
+ elif isinstance(start_date, int):
613
+ self._source_start_date = start_date
614
+ elif isinstance(start_date, datetime):
615
+ self._source_start_date = start_date
616
+ elif isinstance(start_date, pd.Timestamp):
617
+ self._source_start_date = start_date
618
+ else:
619
+ raise ValueError(
620
+ 'Start date must be in "YYYY-MM-DD" string, integer, datetime or pd.Timestamp format.'
621
+ )
622
+
623
+ @property
624
+ def source_end_date(self):
625
+ """
626
+ Returns end date for data request in data source format.
627
+ """
628
+ return self._source_end_date
629
+
630
+ @source_end_date.setter
631
+ def source_end_date(self, end_date):
632
+ """
633
+ Sets end date for data request in data source format.
634
+ """
635
+ if end_date is None:
636
+ self._source_end_date = end_date
637
+ elif isinstance(end_date, str):
638
+ self._source_end_date = end_date
639
+ elif isinstance(end_date, int):
640
+ self._source_end_date = end_date
641
+ elif isinstance(end_date, datetime):
642
+ self._source_end_date = end_date
643
+ elif isinstance(end_date, pd.Timestamp):
644
+ self._source_end_date = end_date
645
+ else:
646
+ raise ValueError(
647
+ 'End date must be in "YYYY-MM-DD" string, integer, datetime or pd.Timestamp format.'
648
+ )
649
+
510
650
  @property
511
651
  def source_fields(self):
512
652
  """
@@ -550,7 +690,8 @@ class DataRequest:
550
690
  Data response in JSON format.
551
691
  """
552
692
  # set number of attempts
553
- attempts = 0
693
+ attempts, resp = 0, None
694
+
554
695
  # run a while loop in case the attempt fails
555
696
  while attempts < self.trials:
556
697