cryptodatapy 0.2.5__py3-none-any.whl → 0.2.6__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.
- cryptodatapy/conf/tickers.csv +0 -1
- cryptodatapy/extract/data_vendors/CoinMetrics.ipynb +747 -0
- cryptodatapy/extract/data_vendors/coinmetrics_api.py +279 -209
- cryptodatapy/extract/data_vendors/cryptocompare_api.py +3 -5
- cryptodatapy/extract/data_vendors/datavendor.py +32 -12
- cryptodatapy/extract/data_vendors/glassnode_api.py +3 -2
- cryptodatapy/extract/data_vendors/tiingo_api.py +3 -2
- cryptodatapy/extract/datarequest.py +55 -9
- cryptodatapy/extract/libraries/ccxt_api.py +13 -2
- cryptodatapy/transform/cc_onchain_data.csv +118423 -0
- cryptodatapy/transform/clean.py +17 -15
- cryptodatapy/transform/clean_onchain_data.ipynb +4750 -0
- cryptodatapy/transform/clean_perp_futures_ohlcv.ipynb +1597 -1178
- cryptodatapy/transform/convertparams.py +28 -18
- cryptodatapy/transform/credit_data.ipynb +291 -0
- cryptodatapy/transform/eqty_data.ipynb +809 -0
- cryptodatapy/transform/filter.py +13 -10
- cryptodatapy/transform/global_credit_data_daily.parquet +0 -0
- cryptodatapy/transform/od.py +1 -0
- cryptodatapy/transform/rates_data.ipynb +465 -0
- cryptodatapy/transform/us_rates_daily.csv +227752 -0
- cryptodatapy/util/datacredentials.py +28 -7
- {cryptodatapy-0.2.5.dist-info → cryptodatapy-0.2.6.dist-info}/METADATA +2 -2
- {cryptodatapy-0.2.5.dist-info → cryptodatapy-0.2.6.dist-info}/RECORD +26 -28
- cryptodatapy/.DS_Store +0 -0
- cryptodatapy/.idea/.gitignore +0 -3
- cryptodatapy/.idea/cryptodatapy.iml +0 -12
- cryptodatapy/.idea/csv-plugin.xml +0 -16
- cryptodatapy/.idea/inspectionProfiles/Project_Default.xml +0 -6
- cryptodatapy/.idea/inspectionProfiles/profiles_settings.xml +0 -6
- cryptodatapy/.idea/misc.xml +0 -4
- cryptodatapy/.idea/modules.xml +0 -8
- cryptodatapy/.idea/vcs.xml +0 -6
- cryptodatapy/extract/libraries/ccxt.ipynb +0 -873
- {cryptodatapy-0.2.5.dist-info → cryptodatapy-0.2.6.dist-info}/LICENSE +0 -0
- {cryptodatapy-0.2.5.dist-info → cryptodatapy-0.2.6.dist-info}/WHEEL +0 -0
@@ -1,4 +1,5 @@
|
|
1
1
|
import logging
|
2
|
+
from time import sleep
|
2
3
|
from typing import Any, Dict, List, Optional, Union
|
3
4
|
|
4
5
|
import pandas as pd
|
@@ -12,6 +13,7 @@ from cryptodatapy.util.datacredentials import DataCredentials
|
|
12
13
|
|
13
14
|
# data credentials
|
14
15
|
data_cred = DataCredentials()
|
16
|
+
|
15
17
|
# CoinMetrics community API client:
|
16
18
|
client = CoinMetricsClient()
|
17
19
|
|
@@ -23,16 +25,17 @@ class CoinMetrics(DataVendor):
|
|
23
25
|
|
24
26
|
def __init__(
|
25
27
|
self,
|
26
|
-
categories=
|
28
|
+
categories: Union[str, List[str]] = "crypto",
|
27
29
|
exchanges: Optional[List[str]] = None,
|
28
30
|
indexes: Optional[List[str]] = None,
|
29
31
|
assets: Optional[List[str]] = None,
|
30
32
|
markets: Optional[List[str]] = None,
|
31
|
-
market_types=
|
33
|
+
market_types: List[str] = ["spot", "perpetual_future", "future", "option"],
|
32
34
|
fields: Optional[List[str]] = None,
|
33
|
-
frequencies=
|
34
|
-
|
35
|
-
|
35
|
+
frequencies: List[str] = ["tick", "block", "1s", "1min", "5min", "10min", "15min", "30min",
|
36
|
+
"1h", "2h", "4h", "8h", "d", "w", "m", "q"],
|
37
|
+
base_url: Optional[str] = data_cred.coinmetrics_base_url,
|
38
|
+
api_key: Optional[str] = data_cred.coinmetrics_api_key,
|
36
39
|
max_obs_per_call: Optional[int] = None,
|
37
40
|
rate_limit: Optional[Any] = None,
|
38
41
|
):
|
@@ -84,40 +87,6 @@ class CoinMetrics(DataVendor):
|
|
84
87
|
rate_limit,
|
85
88
|
)
|
86
89
|
|
87
|
-
if frequencies is None:
|
88
|
-
self.frequencies = [
|
89
|
-
"tick",
|
90
|
-
"block",
|
91
|
-
"1s",
|
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
|
-
]
|
106
|
-
if market_types is None:
|
107
|
-
self.market_types = ["spot", "perpetual_future", "future", "option"]
|
108
|
-
if categories is None:
|
109
|
-
self.categories = ["crypto"]
|
110
|
-
if exchanges is None:
|
111
|
-
self._exchanges = self.get_exchanges_info(as_list=True)
|
112
|
-
if indexes is None:
|
113
|
-
self._indexes = self.get_indexes_info(as_list=True)
|
114
|
-
if assets is None:
|
115
|
-
self._assets = self.get_assets_info(as_list=True)
|
116
|
-
if markets is None:
|
117
|
-
self._markets = self.get_markets_info(as_list=True)
|
118
|
-
if fields is None:
|
119
|
-
self._fields = self.get_fields_info(data_type=None, as_list=True)
|
120
|
-
|
121
90
|
@staticmethod
|
122
91
|
def req_meta(data_type: str) -> Dict[str, Any]:
|
123
92
|
"""
|
@@ -161,9 +130,9 @@ class CoinMetrics(DataVendor):
|
|
161
130
|
# req data
|
162
131
|
exch = self.req_meta(data_type='catalog_exchanges')
|
163
132
|
# wrangle data resp
|
164
|
-
|
133
|
+
self.exchanges = WrangleInfo(exch).cm_meta_resp(as_list=as_list, index_name='exchange')
|
165
134
|
|
166
|
-
return
|
135
|
+
return self.exchanges
|
167
136
|
|
168
137
|
def get_indexes_info(self, as_list: bool = False) -> Union[List[str], pd.DataFrame]:
|
169
138
|
"""
|
@@ -182,11 +151,11 @@ class CoinMetrics(DataVendor):
|
|
182
151
|
# req data
|
183
152
|
indexes = self.req_meta(data_type='catalog_indexes')
|
184
153
|
# wrangle data resp
|
185
|
-
indexes = WrangleInfo(indexes).cm_meta_resp(as_list=as_list, index_name='ticker')
|
154
|
+
self.indexes = WrangleInfo(indexes).cm_meta_resp(as_list=as_list, index_name='ticker')
|
186
155
|
|
187
|
-
return indexes
|
156
|
+
return self.indexes
|
188
157
|
|
189
|
-
def get_assets_info(self, as_list: bool = False
|
158
|
+
def get_assets_info(self, as_list: bool = False) -> Union[List[str], pd.DataFrame]:
|
190
159
|
"""
|
191
160
|
Get assets info.
|
192
161
|
|
@@ -203,9 +172,9 @@ class CoinMetrics(DataVendor):
|
|
203
172
|
# req data
|
204
173
|
assets = self.req_meta(data_type='catalog_assets')
|
205
174
|
# wrangle data resp
|
206
|
-
assets = WrangleInfo(assets).cm_meta_resp(as_list=as_list, index_name='ticker')
|
175
|
+
self.assets = WrangleInfo(assets).cm_meta_resp(as_list=as_list, index_name='ticker')
|
207
176
|
|
208
|
-
return assets
|
177
|
+
return self.assets
|
209
178
|
|
210
179
|
def get_inst_info(self, as_dict: bool = False) -> Union[Dict[str, List[str]], pd.DataFrame]:
|
211
180
|
"""
|
@@ -243,11 +212,11 @@ class CoinMetrics(DataVendor):
|
|
243
212
|
List or dataframe with info on available markets, by exchange.
|
244
213
|
"""
|
245
214
|
# req data
|
246
|
-
|
215
|
+
markets = self.req_meta(data_type='catalog_markets')
|
247
216
|
# wrangle data resp
|
248
|
-
|
217
|
+
self.markets = WrangleInfo(markets).cm_meta_resp(as_list=as_list)
|
249
218
|
|
250
|
-
return
|
219
|
+
return self.markets
|
251
220
|
|
252
221
|
def get_onchain_fields_info(self, as_list: bool = False) -> Union[List[str], pd.DataFrame]:
|
253
222
|
"""
|
@@ -289,29 +258,29 @@ class CoinMetrics(DataVendor):
|
|
289
258
|
# req data
|
290
259
|
ohlcv_fields = ['price_open', 'price_close', 'price_high', 'price_low', 'vwap', 'volume', 'candle_usd_volume',
|
291
260
|
'candle_trades_count'] # get market fields
|
292
|
-
inst_fields =
|
261
|
+
inst_fields = [v for k, v in self.get_inst_info(as_dict=True).items()][0] # inst fields
|
293
262
|
onchain_fields = self.get_onchain_fields_info() # get onchain fields
|
294
263
|
|
295
264
|
# fields df
|
296
265
|
if data_type == "market":
|
297
|
-
fields = onchain_fields[onchain_fields.category == "Market"]
|
266
|
+
self.fields = onchain_fields[onchain_fields.category == "Market"]
|
298
267
|
elif data_type == "off-chain":
|
299
|
-
fields = inst_fields
|
268
|
+
self.fields = inst_fields
|
300
269
|
else:
|
301
|
-
fields = onchain_fields
|
270
|
+
self.fields = onchain_fields
|
302
271
|
|
303
272
|
# fields list
|
304
273
|
if as_list:
|
305
274
|
if data_type == "market":
|
306
|
-
fields = ohlcv_fields + list(fields.index)
|
275
|
+
self.fields = ohlcv_fields + list(self.fields.index)
|
307
276
|
elif data_type == "on-chain":
|
308
|
-
fields = list(fields.index)
|
277
|
+
self.fields = list(self.fields.index)
|
309
278
|
elif data_type == "off-chain":
|
310
|
-
fields = inst_fields
|
279
|
+
self.fields = inst_fields
|
311
280
|
else:
|
312
|
-
fields = ohlcv_fields + list(fields.index) + inst_fields
|
281
|
+
self.fields = ohlcv_fields + list(self.fields.index) + inst_fields
|
313
282
|
|
314
|
-
return fields
|
283
|
+
return self.fields
|
315
284
|
|
316
285
|
def get_onchain_tickers_list(self, data_req: DataRequest) -> List[str]:
|
317
286
|
"""
|
@@ -332,12 +301,15 @@ class CoinMetrics(DataVendor):
|
|
332
301
|
# fields param
|
333
302
|
fields = cm_data_req["fields"]
|
334
303
|
|
304
|
+
# fields info
|
305
|
+
self.get_fields_info()
|
335
306
|
# fields dict
|
336
307
|
fields_dict = {}
|
337
308
|
for field in fields:
|
338
|
-
|
339
|
-
|
340
|
-
|
309
|
+
if field in self.fields.index:
|
310
|
+
df = self.fields.loc[field] # get fields metadata
|
311
|
+
# add to dict
|
312
|
+
fields_dict[field] = df["frequencies"][0]["assets"]
|
341
313
|
|
342
314
|
# asset list
|
343
315
|
asset_list = list(set.intersection(*(set(val) for val in fields_dict.values())))
|
@@ -354,51 +326,67 @@ class CoinMetrics(DataVendor):
|
|
354
326
|
"""
|
355
327
|
return None
|
356
328
|
|
357
|
-
|
358
|
-
|
329
|
+
def get_metadata(self) -> None:
|
330
|
+
"""
|
331
|
+
Get CoinMetrics metadata.
|
332
|
+
"""
|
333
|
+
if self.exchanges is None:
|
334
|
+
self.get_exchanges_info(as_list=True)
|
335
|
+
if self.indexes is None:
|
336
|
+
self.get_indexes_info(as_list=True)
|
337
|
+
if self.assets is None:
|
338
|
+
self.get_assets_info(as_list=True)
|
339
|
+
if self.markets is None:
|
340
|
+
self.get_markets_info(as_list=True)
|
341
|
+
if self.fields is None:
|
342
|
+
self.get_fields_info(as_list=True)
|
343
|
+
|
344
|
+
def req_data(self, data_type: str, params: Dict[str, Union[str, int]]) -> pd.DataFrame:
|
359
345
|
"""
|
360
346
|
Sends data request to Python client.
|
361
347
|
|
362
348
|
Parameters
|
363
349
|
----------
|
364
|
-
data_type: str
|
365
|
-
'get_market_open_interest', 'get_market_funding_rates', 'get_market_trades',
|
366
|
-
'get_market_quotes'}
|
350
|
+
data_type: str
|
367
351
|
Data type to retrieve.
|
368
|
-
|
369
|
-
|
370
|
-
----------------
|
371
|
-
indexes: list
|
372
|
-
List of indexes.
|
373
|
-
assets: list
|
374
|
-
List of assets.
|
375
|
-
markets: list
|
376
|
-
List of markets.
|
377
|
-
metrics: list
|
378
|
-
List of metrics.
|
379
|
-
frequency: str
|
380
|
-
Frequency of data observations.
|
381
|
-
start_time: str, pd.Timestamp, datetime
|
382
|
-
Start datetime.
|
383
|
-
end_time: str, pd.Timestamp, datetime
|
384
|
-
End datetime.
|
385
|
-
timezone: str
|
386
|
-
Timezone.
|
352
|
+
params: dict
|
353
|
+
Dictionary containing parameter values for get request.
|
387
354
|
|
388
355
|
Returns
|
389
356
|
-------
|
390
357
|
df: pd.DataFrame
|
391
358
|
Dataframe with datetime, ticker/identifier, and field/col values.
|
392
359
|
"""
|
393
|
-
|
394
|
-
|
395
|
-
assert not df.empty
|
360
|
+
# url
|
361
|
+
url = self.base_url + data_type
|
396
362
|
|
397
|
-
|
398
|
-
|
399
|
-
logging.warning(e)
|
363
|
+
# data request
|
364
|
+
data_resp = DataRequest().get_req(url=url, params=params)
|
400
365
|
|
366
|
+
# raise error if data is None
|
367
|
+
if data_resp is None:
|
368
|
+
raise Exception("Failed to fetch data after multiple attempts.")
|
369
|
+
# retrieve data
|
401
370
|
else:
|
371
|
+
# data
|
372
|
+
data, next_page_url = data_resp.get('data', []), data_resp.get('next_page_url')
|
373
|
+
|
374
|
+
# while loop
|
375
|
+
while next_page_url:
|
376
|
+
# wait to avoid exceeding rate limit
|
377
|
+
sleep(0.6)
|
378
|
+
|
379
|
+
# request next page
|
380
|
+
next_page_data_resp = DataRequest(pause=0.6).get_req(url=next_page_url, params=None)
|
381
|
+
next_page_data, next_page_url = next_page_data_resp.get('data', []), next_page_data_resp.get(
|
382
|
+
'next_page_url')
|
383
|
+
|
384
|
+
# add data to list
|
385
|
+
data.extend(next_page_data)
|
386
|
+
|
387
|
+
# convert to df
|
388
|
+
df = pd.DataFrame(data)
|
389
|
+
|
402
390
|
return df
|
403
391
|
|
404
392
|
@staticmethod
|
@@ -424,7 +412,7 @@ class CoinMetrics(DataVendor):
|
|
424
412
|
|
425
413
|
return df
|
426
414
|
|
427
|
-
def get_tidy_data(self, data_req: DataRequest, data_type: str,
|
415
|
+
def get_tidy_data(self, data_req: DataRequest, data_type: str, params: dict) -> pd.DataFrame:
|
428
416
|
"""
|
429
417
|
Gets data and wrangles it into tidy data format.
|
430
418
|
|
@@ -436,7 +424,8 @@ class CoinMetrics(DataVendor):
|
|
436
424
|
'get_market_open_interest', 'get_market_funding_rates', 'get_market_trades',
|
437
425
|
'get_market_quotes'}
|
438
426
|
Data type to retrieve.
|
439
|
-
|
427
|
+
params: dict
|
428
|
+
Dictionary containing parameter values for get request.
|
440
429
|
|
441
430
|
Returns
|
442
431
|
-------
|
@@ -444,15 +433,15 @@ class CoinMetrics(DataVendor):
|
|
444
433
|
Dataframe with DatetimeIndex (level 0), ticker (level 1) and values for fields/col, in tidy data format.
|
445
434
|
"""
|
446
435
|
# get entire data history
|
447
|
-
df = self.req_data(data_type,
|
436
|
+
df = self.req_data(data_type, params)
|
448
437
|
# wrangle df
|
449
438
|
df = self.wrangle_data_resp(data_req, df)
|
450
439
|
|
451
440
|
return df
|
452
441
|
|
453
|
-
def
|
442
|
+
def check_tickers(self, data_req: DataRequest, data_type: str) -> List[str]:
|
454
443
|
"""
|
455
|
-
|
444
|
+
Checks tickers for data availability.
|
456
445
|
|
457
446
|
Parameters
|
458
447
|
----------
|
@@ -465,47 +454,45 @@ class CoinMetrics(DataVendor):
|
|
465
454
|
Returns
|
466
455
|
-------
|
467
456
|
tickers: list
|
468
|
-
List of
|
457
|
+
List of available tickers.
|
469
458
|
"""
|
470
459
|
# convert params
|
471
460
|
cm_data_req = ConvertParams(data_req).to_coinmetrics()
|
472
461
|
# tickers
|
473
462
|
tickers = []
|
474
463
|
|
475
|
-
# check
|
464
|
+
# check indexes
|
476
465
|
if data_type == 'indexes':
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
tickers.append(ticker) # keep only avail tickers
|
466
|
+
self.get_indexes_info(as_list=True)
|
467
|
+
# avail tickers
|
468
|
+
tickers = [ticker for ticker in cm_data_req["tickers"] if ticker.upper() in self.indexes]
|
481
469
|
|
482
|
-
# check
|
470
|
+
# check markets
|
483
471
|
elif data_type == 'market_candles' or data_type == 'open_interest' or \
|
484
472
|
data_type == 'funding_rates' or data_type == 'trades' or data_type == 'quotes':
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
473
|
+
self.get_assets_info(as_list=True)
|
474
|
+
# avail tickers
|
475
|
+
tickers = [ticker for asset, ticker in zip(cm_data_req["tickers"], cm_data_req["mkts"]) if
|
476
|
+
asset in self.assets]
|
489
477
|
|
490
|
-
# check
|
478
|
+
# check assets
|
491
479
|
elif data_type == 'asset_metrics':
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
tickers.append(ticker) # keep only asset tickers
|
480
|
+
self.get_assets_info(as_list=True)
|
481
|
+
# avail tickers
|
482
|
+
tickers = [ticker for ticker in cm_data_req["tickers"] if ticker in self.assets]
|
496
483
|
|
497
|
-
# raise error if no tickers
|
484
|
+
# raise error if no tickers available
|
498
485
|
if len(tickers) == 0:
|
499
486
|
raise ValueError(
|
500
|
-
f"{data_req.tickers} are not valid tickers for requested data type."
|
501
|
-
f" Use
|
487
|
+
f"{data_req.tickers} are not valid tickers for the requested data type."
|
488
|
+
f" Use get_metadata to get a list of available indexes and assets."
|
502
489
|
)
|
503
490
|
|
504
491
|
return tickers
|
505
492
|
|
506
|
-
def
|
493
|
+
def check_fields(self, data_req: DataRequest, data_type: str) -> List[str]:
|
507
494
|
"""
|
508
|
-
|
495
|
+
Checks fields for data availability.
|
509
496
|
|
510
497
|
Parameters
|
511
498
|
----------
|
@@ -518,31 +505,30 @@ class CoinMetrics(DataVendor):
|
|
518
505
|
Returns
|
519
506
|
-------
|
520
507
|
fields: list
|
521
|
-
List of
|
508
|
+
List of avaialble fields.
|
522
509
|
"""
|
523
510
|
# convert params
|
524
511
|
cm_data_req = ConvertParams(data_req).to_coinmetrics()
|
525
512
|
# fields
|
526
513
|
fields = []
|
527
514
|
|
528
|
-
# check
|
515
|
+
# check instution
|
529
516
|
if data_type == 'institutions':
|
530
|
-
|
531
|
-
for
|
532
|
-
|
533
|
-
fields.append(field) # keep only inst fields
|
517
|
+
# avail inst
|
518
|
+
inst_list = [val for key, val in self.get_inst_info(as_dict=True).items()][0]
|
519
|
+
fields = [field for field in cm_data_req["fields"] if field in inst_list]
|
534
520
|
|
521
|
+
# check on-chain metrics
|
535
522
|
elif data_type == 'asset_metrics':
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
fields.append(field) # keep only on-chain fields
|
523
|
+
self.get_fields_info(data_type='on-chain', as_list=True)
|
524
|
+
# avail fields
|
525
|
+
fields = [field for field in cm_data_req["fields"] if field in self.fields]
|
540
526
|
|
541
527
|
# raise error if fields is empty
|
542
528
|
if len(fields) == 0:
|
543
529
|
raise ValueError(
|
544
|
-
f"{data_req.fields} are not valid
|
545
|
-
f" Use the
|
530
|
+
f"{data_req.fields} are not valid fields."
|
531
|
+
f" Use the get_fields_info or get_inst_info methods to get available source fields."
|
546
532
|
)
|
547
533
|
|
548
534
|
return fields
|
@@ -550,7 +536,7 @@ class CoinMetrics(DataVendor):
|
|
550
536
|
@staticmethod
|
551
537
|
def check_params(data_req: DataRequest, data_type: str) -> None:
|
552
538
|
"""
|
553
|
-
Checks
|
539
|
+
Checks data request parameters.
|
554
540
|
|
555
541
|
Parameters
|
556
542
|
----------
|
@@ -611,14 +597,22 @@ class CoinMetrics(DataVendor):
|
|
611
597
|
f" 'option' market types. Change 'mkt_type' in data request and try again."
|
612
598
|
)
|
613
599
|
|
614
|
-
# trades
|
615
|
-
elif data_type == 'trades'
|
616
|
-
if cm_data_req["freq"] != "
|
600
|
+
# trades
|
601
|
+
elif data_type == 'trades':
|
602
|
+
if cm_data_req["freq"] != "raw":
|
617
603
|
raise ValueError(
|
618
604
|
f"{data_type} data is only available at the 'tick' frequency."
|
619
605
|
f" Change data request frequency and try again."
|
620
606
|
)
|
621
607
|
|
608
|
+
# quotes
|
609
|
+
elif data_type == 'quotes':
|
610
|
+
if cm_data_req["freq"] not in ["raw", "1s", "1m", "1h", "1d"]:
|
611
|
+
raise ValueError(
|
612
|
+
f"{data_type} data is only available at the 'tick', '1s', '1m', '1h' and '1d' frequencies."
|
613
|
+
f" Change data request frequency and try again."
|
614
|
+
)
|
615
|
+
|
622
616
|
return None
|
623
617
|
|
624
618
|
def get_indexes(self, data_req: DataRequest) -> pd.DataFrame:
|
@@ -638,20 +632,27 @@ class CoinMetrics(DataVendor):
|
|
638
632
|
# convert data request parameters to Coin Metrics format
|
639
633
|
cm_data_req = ConvertParams(data_req).to_coinmetrics()
|
640
634
|
|
641
|
-
# check
|
635
|
+
# check params
|
642
636
|
self.check_params(data_req, data_type='indexes')
|
643
637
|
|
644
|
-
#
|
645
|
-
tickers = self.
|
638
|
+
# check tickers
|
639
|
+
tickers = self.check_tickers(data_req, data_type='indexes')
|
640
|
+
sleep(0.6)
|
641
|
+
|
642
|
+
# params
|
643
|
+
params = {
|
644
|
+
'indexes': ','.join(tickers),
|
645
|
+
'frequency': cm_data_req['freq'],
|
646
|
+
'start_time': cm_data_req["start_date"],
|
647
|
+
'end_time': cm_data_req["end_date"],
|
648
|
+
'pretty': True,
|
649
|
+
'page_size': 10000,
|
650
|
+
}
|
646
651
|
|
647
|
-
# get
|
652
|
+
# get tidy data
|
648
653
|
df = self.get_tidy_data(data_req,
|
649
|
-
data_type='
|
650
|
-
|
651
|
-
frequency=cm_data_req["freq"],
|
652
|
-
start_time=cm_data_req["start_date"],
|
653
|
-
end_time=cm_data_req["end_date"],
|
654
|
-
)
|
654
|
+
data_type='/timeseries/index-levels',
|
655
|
+
params=params)
|
655
656
|
|
656
657
|
return df
|
657
658
|
|
@@ -672,21 +673,28 @@ class CoinMetrics(DataVendor):
|
|
672
673
|
# convert data request parameters to Coin Metrics format
|
673
674
|
cm_data_req = ConvertParams(data_req).to_coinmetrics()
|
674
675
|
|
675
|
-
# check
|
676
|
+
# check params
|
676
677
|
self.check_params(data_req, data_type='institutions')
|
677
678
|
|
678
|
-
#
|
679
|
-
fields = self.
|
679
|
+
# check fields
|
680
|
+
fields = self.check_fields(data_req, data_type='institutions')
|
681
|
+
sleep(0.6)
|
682
|
+
|
683
|
+
# params
|
684
|
+
params = {
|
685
|
+
'institutions': cm_data_req["inst"],
|
686
|
+
'metrics': ','.join(fields),
|
687
|
+
'frequency': cm_data_req['freq'],
|
688
|
+
'start_time': cm_data_req["start_date"],
|
689
|
+
'end_time': cm_data_req["end_date"],
|
690
|
+
'pretty': True,
|
691
|
+
'page_size': 10000,
|
692
|
+
}
|
680
693
|
|
681
694
|
# get tidy data
|
682
695
|
df = self.get_tidy_data(data_req,
|
683
|
-
data_type='
|
684
|
-
|
685
|
-
metrics=fields,
|
686
|
-
frequency=cm_data_req["freq"],
|
687
|
-
start_time=cm_data_req["start_date"],
|
688
|
-
end_time=cm_data_req["end_date"],
|
689
|
-
)
|
696
|
+
data_type='/timeseries/institution-metrics',
|
697
|
+
params=params)
|
690
698
|
|
691
699
|
return df
|
692
700
|
|
@@ -710,17 +718,24 @@ class CoinMetrics(DataVendor):
|
|
710
718
|
# check freq
|
711
719
|
self.check_params(data_req, data_type='market_candles')
|
712
720
|
|
713
|
-
#
|
714
|
-
tickers = self.
|
721
|
+
# check tickers
|
722
|
+
tickers = self.check_tickers(data_req, data_type='market_candles')
|
723
|
+
sleep(0.6)
|
724
|
+
|
725
|
+
# params
|
726
|
+
params = {
|
727
|
+
'markets': ','.join(tickers),
|
728
|
+
'frequency': cm_data_req['freq'],
|
729
|
+
'start_time': cm_data_req["start_date"],
|
730
|
+
'end_time': cm_data_req["end_date"],
|
731
|
+
'pretty': True,
|
732
|
+
'page_size': 10000,
|
733
|
+
}
|
715
734
|
|
716
735
|
# get tidy data
|
717
736
|
df = self.get_tidy_data(data_req,
|
718
|
-
data_type='
|
719
|
-
|
720
|
-
frequency=cm_data_req["freq"],
|
721
|
-
start_time=cm_data_req["start_date"],
|
722
|
-
end_time=cm_data_req["end_date"],
|
723
|
-
)
|
737
|
+
data_type='/timeseries/market-candles',
|
738
|
+
params=params)
|
724
739
|
|
725
740
|
return df
|
726
741
|
|
@@ -741,22 +756,35 @@ class CoinMetrics(DataVendor):
|
|
741
756
|
# convert data request parameters to Coin Metrics format
|
742
757
|
cm_data_req = ConvertParams(data_req).to_coinmetrics()
|
743
758
|
|
744
|
-
# check
|
759
|
+
# check params
|
745
760
|
self.check_params(data_req, data_type='asset_metrics')
|
746
761
|
|
747
|
-
#
|
748
|
-
tickers = self.
|
749
|
-
|
750
|
-
|
762
|
+
# check tickers
|
763
|
+
tickers = self.check_tickers(data_req, data_type='asset_metrics')
|
764
|
+
sleep(0.6)
|
765
|
+
|
766
|
+
# check fields
|
767
|
+
fields = self.check_fields(data_req, data_type='asset_metrics')
|
768
|
+
sleep(0.6)
|
769
|
+
|
770
|
+
# params
|
771
|
+
params = {
|
772
|
+
'assets': ','.join(tickers),
|
773
|
+
'metrics': ','.join(fields),
|
774
|
+
'frequency': cm_data_req['freq'],
|
775
|
+
'start_time': cm_data_req["start_date"],
|
776
|
+
'end_time': cm_data_req["end_date"],
|
777
|
+
'pretty': True,
|
778
|
+
'page_size': 10000,
|
779
|
+
'ignore_forbidden_errors': True,
|
780
|
+
'ignore_unsupported_errors': True
|
781
|
+
|
782
|
+
}
|
751
783
|
|
752
784
|
# get tidy data
|
753
785
|
df = self.get_tidy_data(data_req,
|
754
|
-
data_type='
|
755
|
-
|
756
|
-
metrics=fields,
|
757
|
-
frequency=cm_data_req["freq"],
|
758
|
-
start_time=cm_data_req["start_date"],
|
759
|
-
end_time=cm_data_req["end_date"],
|
786
|
+
data_type='/timeseries/asset-metrics',
|
787
|
+
params=params
|
760
788
|
)
|
761
789
|
|
762
790
|
return df
|
@@ -778,18 +806,26 @@ class CoinMetrics(DataVendor):
|
|
778
806
|
# convert data request parameters to Coin Metrics format
|
779
807
|
cm_data_req = ConvertParams(data_req).to_coinmetrics()
|
780
808
|
|
781
|
-
# check
|
809
|
+
# check params
|
782
810
|
self.check_params(data_req, data_type='open_interest')
|
783
811
|
|
784
|
-
#
|
785
|
-
tickers = self.
|
812
|
+
# check tickers
|
813
|
+
tickers = self.check_tickers(data_req, data_type='open_interest')
|
814
|
+
sleep(0.6)
|
815
|
+
|
816
|
+
# params
|
817
|
+
params = {
|
818
|
+
'markets': ','.join(tickers),
|
819
|
+
'start_time': cm_data_req["start_date"],
|
820
|
+
'end_time': cm_data_req["end_date"],
|
821
|
+
'pretty': True,
|
822
|
+
'page_size': 10000,
|
823
|
+
}
|
786
824
|
|
787
|
-
# get
|
825
|
+
# get tidy data
|
788
826
|
df = self.get_tidy_data(data_req,
|
789
|
-
data_type='
|
790
|
-
|
791
|
-
start_time=cm_data_req["start_date"],
|
792
|
-
end_time=cm_data_req["end_date"],
|
827
|
+
data_type='/timeseries/market-openinterest',
|
828
|
+
params=params
|
793
829
|
)
|
794
830
|
|
795
831
|
return df
|
@@ -811,18 +847,26 @@ class CoinMetrics(DataVendor):
|
|
811
847
|
# convert data request parameters to Coin Metrics format
|
812
848
|
cm_data_req = ConvertParams(data_req).to_coinmetrics()
|
813
849
|
|
814
|
-
# check
|
850
|
+
# check params
|
815
851
|
self.check_params(data_req, data_type='funding_rates')
|
816
852
|
|
817
|
-
#
|
818
|
-
tickers = self.
|
853
|
+
# check tickers
|
854
|
+
tickers = self.check_tickers(data_req, data_type='funding_rates')
|
855
|
+
sleep(0.6)
|
819
856
|
|
820
|
-
#
|
857
|
+
# params
|
858
|
+
params = {
|
859
|
+
'markets': ','.join(tickers),
|
860
|
+
'start_time': cm_data_req["start_date"],
|
861
|
+
'end_time': cm_data_req["end_date"],
|
862
|
+
'pretty': True,
|
863
|
+
'page_size': 10000,
|
864
|
+
}
|
865
|
+
|
866
|
+
# get tidy data
|
821
867
|
df = self.get_tidy_data(data_req,
|
822
|
-
data_type='
|
823
|
-
|
824
|
-
start_time=cm_data_req["start_date"],
|
825
|
-
end_time=cm_data_req["end_date"],
|
868
|
+
data_type='/timeseries/market-funding-rates',
|
869
|
+
params=params
|
826
870
|
)
|
827
871
|
|
828
872
|
return df
|
@@ -844,17 +888,26 @@ class CoinMetrics(DataVendor):
|
|
844
888
|
# convert data request parameters to Coin Metrics format
|
845
889
|
cm_data_req = ConvertParams(data_req).to_coinmetrics()
|
846
890
|
|
847
|
-
# check
|
891
|
+
# check params
|
848
892
|
self.check_params(data_req, data_type='trades')
|
849
893
|
|
850
|
-
#
|
851
|
-
tickers = self.
|
894
|
+
# check tickers
|
895
|
+
tickers = self.check_tickers(data_req, data_type='trades')
|
896
|
+
sleep(0.6)
|
897
|
+
|
898
|
+
# params
|
899
|
+
params = {
|
900
|
+
'markets': ','.join(tickers),
|
901
|
+
'start_time': cm_data_req["start_date"],
|
902
|
+
'end_time': cm_data_req["end_date"],
|
903
|
+
'pretty': True,
|
904
|
+
'page_size': 10000,
|
905
|
+
}
|
852
906
|
|
853
|
-
# get
|
907
|
+
# get tidy data
|
854
908
|
df = self.get_tidy_data(data_req,
|
855
|
-
data_type='
|
856
|
-
|
857
|
-
start_time=cm_data_req["start_date"]
|
909
|
+
data_type='/timeseries/market-trades',
|
910
|
+
params=params
|
858
911
|
)
|
859
912
|
|
860
913
|
return df
|
@@ -876,17 +929,27 @@ class CoinMetrics(DataVendor):
|
|
876
929
|
# convert data request parameters to Coin Metrics format
|
877
930
|
cm_data_req = ConvertParams(data_req).to_coinmetrics()
|
878
931
|
|
879
|
-
# check
|
932
|
+
# check params
|
880
933
|
self.check_params(data_req, data_type='quotes')
|
881
934
|
|
882
|
-
#
|
883
|
-
tickers = self.
|
935
|
+
# check tickers
|
936
|
+
tickers = self.check_tickers(data_req, data_type='quotes')
|
937
|
+
sleep(0.6)
|
938
|
+
|
939
|
+
# params
|
940
|
+
params = {
|
941
|
+
'markets': ','.join(tickers),
|
942
|
+
'granularity': cm_data_req['freq'],
|
943
|
+
'start_time': cm_data_req["start_date"],
|
944
|
+
'end_time': cm_data_req["end_date"],
|
945
|
+
'pretty': True,
|
946
|
+
'page_size': 10000,
|
947
|
+
}
|
884
948
|
|
885
|
-
# get
|
949
|
+
# get tidy data
|
886
950
|
df = self.get_tidy_data(data_req,
|
887
|
-
data_type='
|
888
|
-
|
889
|
-
start_time=cm_data_req["start_date"]
|
951
|
+
data_type='/timeseries/market-quotes',
|
952
|
+
params=params
|
890
953
|
)
|
891
954
|
|
892
955
|
return df
|
@@ -910,20 +973,25 @@ class CoinMetrics(DataVendor):
|
|
910
973
|
cm_data_req = ConvertParams(data_req).to_coinmetrics()
|
911
974
|
|
912
975
|
# check if fields available
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
#
|
976
|
+
self.get_fields_info(as_list=True)
|
977
|
+
sleep(0.6)
|
978
|
+
# if not all([field in self.fields for field in cm_data_req["fields"]]):
|
979
|
+
# raise ValueError(
|
980
|
+
# "Some selected fields are not available. Check available fields with"
|
981
|
+
# " get_fields_info method and try again."
|
982
|
+
# )
|
983
|
+
|
984
|
+
# field lists
|
920
985
|
ohlcv_list = ['price_open', 'price_close', 'price_high', 'price_low', 'vwap', 'volume',
|
921
986
|
'candle_usd_volume', 'candle_trades_count']
|
922
987
|
oc_list = [field for field in self.fields if field not in ohlcv_list]
|
988
|
+
|
923
989
|
# empty df
|
924
990
|
df = pd.DataFrame()
|
925
991
|
|
926
992
|
# get indexes data
|
993
|
+
self.get_indexes_info(as_list=True)
|
994
|
+
sleep(0.6)
|
927
995
|
if any([ticker.upper() in self.indexes for ticker in cm_data_req["tickers"]]) and any(
|
928
996
|
[field in ohlcv_list for field in cm_data_req["fields"]]
|
929
997
|
):
|
@@ -931,6 +999,8 @@ class CoinMetrics(DataVendor):
|
|
931
999
|
df = pd.concat([df, df0])
|
932
1000
|
|
933
1001
|
# get OHLCV data
|
1002
|
+
self.get_assets_info(as_list=True)
|
1003
|
+
sleep(0.6)
|
934
1004
|
if any([ticker in self.assets for ticker in cm_data_req["tickers"]]) and any(
|
935
1005
|
[field in ohlcv_list for field in cm_data_req["fields"]]
|
936
1006
|
):
|