cryptodatapy 0.2.0__py3-none-any.whl → 0.2.2__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.
@@ -1,504 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "code",
5
- "execution_count": 14,
6
- "id": "e3a0c158",
7
- "metadata": {},
8
- "outputs": [],
9
- "source": [
10
- "from typing import Optional, Any, Union, Dict\n",
11
- "\n",
12
- "import pandas as pd\n",
13
- "\n",
14
- "from cryptodatapy.extract.data_vendors.datavendor import DataVendor\n",
15
- "from cryptodatapy.extract.datarequest import DataRequest\n",
16
- "from cryptodatapy.transform.convertparams import ConvertParams\n",
17
- "from cryptodatapy.transform.wrangle import WrangleData, WrangleInfo\n",
18
- "from cryptodatapy.util.datacredentials import DataCredentials\n",
19
- "\n",
20
- "\n",
21
- "# data credentials\n",
22
- "data_cred = DataCredentials()\n",
23
- "\n",
24
- "# url endpoints\n",
25
- "urls = {'assets_info': 'assets', 'fields_info': 'endpoints'}\n",
26
- "\n",
27
- "\n",
28
- "class Glassnode(DataVendor):\n",
29
- " \"\"\"\n",
30
- " Retrieves data from Glassnode API.\n",
31
- " \"\"\"\n",
32
- "\n",
33
- " def __init__(\n",
34
- " self,\n",
35
- " categories=None,\n",
36
- " exchanges: Optional[list[str]] = None,\n",
37
- " indexes: Optional[list[str]] = None,\n",
38
- " assets: Optional[list[str]] = None,\n",
39
- " markets: Optional[list[str]] = None,\n",
40
- " market_types=None,\n",
41
- " fields: Optional[list[str]] = None,\n",
42
- " frequencies=None,\n",
43
- " base_url: str = data_cred.glassnode_base_url,\n",
44
- " api_key: str = data_cred.glassnode_api_key,\n",
45
- " max_obs_per_call: Optional[int] = None,\n",
46
- " rate_limit: Optional[Any] = None\n",
47
- " ):\n",
48
- " \"\"\"\n",
49
- " Constructor\n",
50
- "\n",
51
- " Parameters\n",
52
- " ----------\n",
53
- " categories: list or str, {'crypto', 'fx', 'rates', 'eqty', 'commodities', 'credit', 'macro', 'alt'}\n",
54
- " List or string of available categories, e.g. ['crypto', 'fx', 'alt'].\n",
55
- " exchanges: list, optional, default None\n",
56
- " List of available exchanges, e.g. ['Binance', 'Coinbase', 'Kraken', 'FTX', ...].\n",
57
- " indexes: list, optional, default None\n",
58
- " List of available indexes, e.g. ['mvda', 'bvin'].\n",
59
- " assets: list, optional, default None\n",
60
- " List of available assets, e.g. ['btc', 'eth'].\n",
61
- " markets: list, optional, default None\n",
62
- " List of available markets as asset/quote currency pairs, e.g. ['btcusdt', 'ethbtc'].\n",
63
- " market_types: list\n",
64
- " List of available market types, e.g. [spot', 'perpetual_future', 'future', 'option'].\n",
65
- " fields: list, optional, default None\n",
66
- " List of available fields, e.g. ['open', 'high', 'low', 'close', 'volume'].\n",
67
- " frequencies: list\n",
68
- " List of available frequencies, e.g. ['tick', '1min', '5min', '10min', '20min', '30min', '1h', '2h', '4h',\n",
69
- " '8h', 'd', 'w', 'm']\n",
70
- " base_url: str\n",
71
- " Base url used for GET requests. If not provided, default is set to base_url stored in DataCredentials.\n",
72
- " api_key: str\n",
73
- " Api key, e.g. 'dcf13983adf7dfa79a0dfa35adf'. If not provided, default is set to\n",
74
- " api_key stored in DataCredentials.\n",
75
- " max_obs_per_call: int, optional, default None\n",
76
- " Maximum number of observations returned per API call. If not provided, default is set to\n",
77
- " api_limit stored in DataCredentials.\n",
78
- " rate_limit: Any, optional, Default None\n",
79
- " Number of API calls made and left, by time frequency.\n",
80
- " \"\"\"\n",
81
- " DataVendor.__init__(self, categories, exchanges, indexes, assets, markets, market_types, fields,\n",
82
- " frequencies, base_url, api_key, max_obs_per_call, rate_limit)\n",
83
- "\n",
84
- " if frequencies is None:\n",
85
- " self.frequencies = ['10min', '15min', '30min', '1h', '2h', '4h', '8h', 'd', 'w', 'm', 'q', 'y']\n",
86
- " if market_types is None:\n",
87
- " self.market_types = ['spot', 'perpetual_future', 'future', 'option']\n",
88
- " if categories is None:\n",
89
- " self.categories = ['crypto']\n",
90
- " if api_key is None:\n",
91
- " raise TypeError(\"Set your api key. We recommend setting your api key in environment variables as\"\n",
92
- " \"'GLASSNODE_API_KEY', will allow DataCredentials to automatically load it.\")\n",
93
- "# if assets is None:\n",
94
- "# self.assets = self.get_assets_info(as_list=True)\n",
95
- "# if fields is None:\n",
96
- "# self.fields = self.get_fields_info(data_type=None, as_list=True)\n",
97
- "\n",
98
- " def get_exchanges_info(self) -> None:\n",
99
- " \"\"\"\n",
100
- " Gets exchanges info.\n",
101
- " \"\"\"\n",
102
- " return None\n",
103
- "\n",
104
- " def get_indexes_info(self) -> None:\n",
105
- " \"\"\"\n",
106
- " Gets indexes info.\n",
107
- " \"\"\"\n",
108
- " return None\n",
109
- "\n",
110
- " def req_assets(self) -> Dict[str, Any]:\n",
111
- " \"\"\"\n",
112
- " Get request for assets info.\n",
113
- "\n",
114
- " Returns\n",
115
- " -------\n",
116
- " dict: dictionary\n",
117
- " Data response with asset info in json format.\n",
118
- " \"\"\"\n",
119
- " return DataRequest().get_req(url=self.base_url + urls['assets_info'], params={'api_key': self.api_key})\n",
120
- "\n",
121
- " def get_assets_info(self, as_list: bool = False) -> Union[list[str], pd.DataFrame]:\n",
122
- " \"\"\"\n",
123
- " Get assets info.\n",
124
- "\n",
125
- " Parameters\n",
126
- " ----------\n",
127
- " as_list: bool, default False\n",
128
- " Returns assets info as list.\n",
129
- "\n",
130
- " Returns\n",
131
- " -------\n",
132
- " assets: list or pd.DataFrame\n",
133
- " List or dataframe with info on available assets.\n",
134
- " \"\"\"\n",
135
- " # data req\n",
136
- " data_resp = self.req_assets()\n",
137
- " # wrangle data resp\n",
138
- " assets = WrangleInfo(data_resp).gn_assets_info(as_list=as_list)\n",
139
- "\n",
140
- " return assets\n",
141
- "\n",
142
- " def get_markets_info(self) -> None:\n",
143
- " \"\"\"\n",
144
- " Get markets info.\n",
145
- " \"\"\"\n",
146
- " return None\n",
147
- "\n",
148
- " def req_fields(self) -> Dict[str, Any]:\n",
149
- " \"\"\"\n",
150
- " Get request for fields info.\n",
151
- "\n",
152
- " Returns\n",
153
- " -------\n",
154
- " dict: dictionary\n",
155
- " Data response with fields info in json format.\n",
156
- " \"\"\"\n",
157
- " return DataRequest().get_req(url=self.base_url.replace('v1', 'v2') + urls['fields_info'],\n",
158
- " params={'api_key': self.api_key})\n",
159
- "\n",
160
- " def get_fields_info(self, data_type: Optional[str] = None, as_list: bool = False) -> Union[list[str], pd.DataFrame]:\n",
161
- " \"\"\"\n",
162
- " Get fields info.\n",
163
- "\n",
164
- " Parameters\n",
165
- " ----------\n",
166
- " data_type: str, {'market', 'on-chain', 'off-chain'}, default None\n",
167
- " Type of data.\n",
168
- " as_list: bool, default False\n",
169
- " Returns available fields info as list.\n",
170
- "\n",
171
- " Returns\n",
172
- " -------\n",
173
- " fields: list or pd.DataFrame\n",
174
- " List or dataframe with info on available fields.\n",
175
- " \"\"\"\n",
176
- " # data req\n",
177
- " data_resp = self.req_fields()\n",
178
- " # wrangle data resp\n",
179
- " fields = WrangleInfo(data_resp).gn_fields_info(data_type=data_type, as_list=as_list)\n",
180
- "\n",
181
- " return fields\n",
182
- "\n",
183
- " def get_rate_limit_info(self) -> None:\n",
184
- " \"\"\"\n",
185
- " Get rate limit info.\n",
186
- " \"\"\"\n",
187
- " return None\n",
188
- "\n",
189
- " def req_data(self, data_req: DataRequest, ticker: str, field: str) -> Dict[str, Any]:\n",
190
- " \"\"\"\n",
191
- " Submits data request to API.\n",
192
- "\n",
193
- " Parameters\n",
194
- " ----------\n",
195
- " data_req: DataRequest\n",
196
- " Data request parameters in CryptoDataPy format.\n",
197
- " ticker: str\n",
198
- " Requested ticker symbol.\n",
199
- " field: str\n",
200
- " Requested field.\n",
201
- "\n",
202
- " Returns\n",
203
- " -------\n",
204
- " data_resp: dict\n",
205
- " Data response in json format.\n",
206
- " \"\"\"\n",
207
- " # convert data request parameters to CryptoCompare format\n",
208
- " gn_data_req = ConvertParams(data_req).to_glassnode()\n",
209
- "\n",
210
- " # set url, params\n",
211
- " url = self.base_url + field\n",
212
- " params = {\n",
213
- " 'api_key': self.api_key,\n",
214
- " 'a': ticker,\n",
215
- " 's': gn_data_req['start_date'],\n",
216
- " 'u': gn_data_req['end_date'],\n",
217
- " 'i': gn_data_req['freq'],\n",
218
- " 'c': gn_data_req['quote_ccy']\n",
219
- " }\n",
220
- " # data req\n",
221
- " data_resp = DataRequest().get_req(url=url, params=params)\n",
222
- "\n",
223
- " return data_resp\n",
224
- "\n",
225
- " @staticmethod\n",
226
- " def wrangle_data_resp(data_req: DataRequest, data_resp: Dict[str, Any], field: str) -> pd.DataFrame:\n",
227
- " \"\"\"\n",
228
- " Wrangle data response into tidy data format.\n",
229
- "\n",
230
- " Parameters\n",
231
- " ----------\n",
232
- " data_req: DataRequest\n",
233
- " Data request parameters in CryptoDataPy format.\n",
234
- " data_resp: dictionary\n",
235
- " Data response in JSON format.\n",
236
- " field: str\n",
237
- " Requested field.\n",
238
- "\n",
239
- " Returns\n",
240
- " -------\n",
241
- " df: pd.DataFrame\n",
242
- " Wrangled dataframe with DatetimeIndex and selected field values (cols), in tidy format.\n",
243
- " \"\"\"\n",
244
- " # wrangle data resp\n",
245
- " if data_resp is None or len(data_resp) == 0:\n",
246
- " df = None\n",
247
- " else:\n",
248
- " df = WrangleData(data_req, data_resp).glassnode(field)\n",
249
- "\n",
250
- " return df\n",
251
- "\n",
252
- " def get_tidy_data(self, data_req: DataRequest, ticker: str, field: str) -> pd.DataFrame:\n",
253
- " \"\"\"\n",
254
- " Submits data request and wrangles the data response into tidy data format.\n",
255
- "\n",
256
- " Parameters\n",
257
- " ----------\n",
258
- " data_req: DataRequest\n",
259
- " Data request parameters in CryptoDataPy format.\n",
260
- " ticker: str\n",
261
- " Requested ticker symbol.\n",
262
- " field: str\n",
263
- " Requested field.\n",
264
- "\n",
265
- " Returns\n",
266
- " -------\n",
267
- " df: pd.DataFrame\n",
268
- " Dataframe with DatetimeIndex and field values (col) wrangled into tidy data format.\n",
269
- " \"\"\"\n",
270
- " # get entire data history\n",
271
- " df = self.req_data(data_req, ticker=ticker, field=field)\n",
272
- " # wrangle df\n",
273
- " df = self.wrangle_data_resp(data_req, df, field)\n",
274
- "\n",
275
- " return df\n",
276
- "\n",
277
- " def get_all_fields(self, data_req: DataRequest, ticker: str) -> pd.DataFrame:\n",
278
- " \"\"\"\n",
279
- " Loops list of tickers, retrieves data in tidy format for each ticker and stores it in a dataframe.\n",
280
- "\n",
281
- " Parameters\n",
282
- " ----------\n",
283
- " data_req: DataRequest\n",
284
- " Data request parameters in CryptoDataPy format.\n",
285
- " ticker: str\n",
286
- " Requested ticker symbol.\n",
287
- "\n",
288
- " Returns\n",
289
- " -------\n",
290
- " df: pd.DataFrame\n",
291
- " Dataframe with DatetimeIndex and values for fields (cols), in tidy data format.\n",
292
- " \"\"\"\n",
293
- " # convert data request parameters to CryptoCompare format\n",
294
- " gn_data_req = ConvertParams(data_req).to_glassnode()\n",
295
- "\n",
296
- " df = pd.DataFrame() # empty fields df\n",
297
- " counter = 0 # ohlc counter to avoid requesting OHLC data multiples times\n",
298
- "\n",
299
- " for field in gn_data_req['fields']: # loop through fields\n",
300
- "\n",
301
- " df0 = None\n",
302
- "\n",
303
- " # get tidy data\n",
304
- " if field == 'market/price_usd_ohlc' and counter == 0:\n",
305
- " df0 = self.get_tidy_data(data_req, ticker, field)\n",
306
- " counter += 1\n",
307
- " elif field != 'market/price_usd_ohlc':\n",
308
- " df0 = self.get_tidy_data(data_req, ticker, field)\n",
309
- "\n",
310
- " # add field to fields df\n",
311
- " if df0 is not None:\n",
312
- " df = pd.concat([df, df0], axis=1)\n",
313
- "\n",
314
- " return df\n",
315
- "\n",
316
- " def check_params(self, data_req: DataRequest) -> None:\n",
317
- " \"\"\"\n",
318
- " Check data request parameters before calling API to improve efficiency.\n",
319
- "\n",
320
- " Parameters\n",
321
- " ----------\n",
322
- " data_req: DataRequest\n",
323
- " Data request parameters in CryptoDataPy format.\n",
324
- " \"\"\"\n",
325
- " # convert data request parameters to CryptoCompare format\n",
326
- " gn_data_req = ConvertParams(data_req).to_glassnode()\n",
327
- "\n",
328
- " # check tickers\n",
329
- " if not all([ticker.upper() in self.assets for ticker in gn_data_req['tickers']]):\n",
330
- " raise ValueError(f\"Some of the selected assets are not available.\"\n",
331
- " \" See assets attribute for a list of available assets.\")\n",
332
- "\n",
333
- " # check fields\n",
334
- " if not all([field in self.fields for field in gn_data_req['fields']]):\n",
335
- " raise ValueError(f\"Some of the selected fields are not available.\"\n",
336
- " \" See fields attribute for a list of available fields.\")\n",
337
- "\n",
338
- " # check freq\n",
339
- " if data_req.freq not in self.frequencies:\n",
340
- " raise ValueError(f\"On-chain data is only available for {self.frequencies} frequencies.\"\n",
341
- " f\" Change data request frequency and try again.\")\n",
342
- "\n",
343
- " return None\n",
344
- "\n",
345
- " def get_data(self, data_req: DataRequest) -> pd.DataFrame:\n",
346
- " \"\"\"\n",
347
- " Get market, on-chain or off-chain data.\n",
348
- "\n",
349
- " Parameters\n",
350
- " ----------\n",
351
- " data_req: DataRequest\n",
352
- " Data request parameters in CryptoDataPy format.\n",
353
- "\n",
354
- " Returns\n",
355
- " -------\n",
356
- " df: pd.DataFrame - MultiIndex\n",
357
- " DataFrame with DatetimeIndex (level 0), ticker (level 1), and values for market, on-chain and/or\n",
358
- " off-chain fields (cols), in tidy data format.\n",
359
- " \"\"\"\n",
360
- " # convert data request parameters to CryptoCompare format\n",
361
- " gn_data_req = ConvertParams(data_req).to_glassnode()\n",
362
- "\n",
363
- " # check params\n",
364
- " self.check_params(data_req)\n",
365
- "\n",
366
- " # empty df to add data\n",
367
- " df = pd.DataFrame()\n",
368
- "\n",
369
- " # loop through tickers and fields\n",
370
- " for ticker in gn_data_req['tickers']: # loop tickers\n",
371
- "\n",
372
- " # get all fields for ticker\n",
373
- " df0 = self.get_all_fields(data_req, ticker)\n",
374
- " # add ticker to index\n",
375
- " df0['ticker'] = ticker.upper()\n",
376
- " df0.set_index(['ticker'], append=True, inplace=True)\n",
377
- " # stack ticker dfs\n",
378
- " df = pd.concat([df, df0])\n",
379
- "\n",
380
- " # filter df for desired fields and typecast\n",
381
- " fields = [field for field in data_req.fields if field in df.columns]\n",
382
- " df = df.loc[:, fields]\n",
383
- "\n",
384
- " return df.sort_index()\n"
385
- ]
386
- },
387
- {
388
- "cell_type": "code",
389
- "execution_count": 15,
390
- "id": "ed941370",
391
- "metadata": {},
392
- "outputs": [],
393
- "source": [
394
- "gn = Glassnode()"
395
- ]
396
- },
397
- {
398
- "cell_type": "code",
399
- "execution_count": 16,
400
- "id": "f999fa1b",
401
- "metadata": {},
402
- "outputs": [],
403
- "source": [
404
- "dr = DataRequest()"
405
- ]
406
- },
407
- {
408
- "cell_type": "code",
409
- "execution_count": 17,
410
- "id": "f9ae10a2",
411
- "metadata": {},
412
- "outputs": [],
413
- "source": [
414
- "url = gn.base_url + 'assets'"
415
- ]
416
- },
417
- {
418
- "cell_type": "code",
419
- "execution_count": 18,
420
- "id": "6baff740",
421
- "metadata": {},
422
- "outputs": [
423
- {
424
- "data": {
425
- "text/plain": [
426
- "'https://api.glassnode.com/v1/metrics/assets'"
427
- ]
428
- },
429
- "execution_count": 18,
430
- "metadata": {},
431
- "output_type": "execute_result"
432
- }
433
- ],
434
- "source": [
435
- "url"
436
- ]
437
- },
438
- {
439
- "cell_type": "code",
440
- "execution_count": 19,
441
- "id": "b3617fe0",
442
- "metadata": {},
443
- "outputs": [],
444
- "source": [
445
- "import json\n",
446
- "import requests\n",
447
- "import pandas as pd\n",
448
- "\n",
449
- "\n",
450
- "# insert your API key here\n",
451
- "API_KEY = gn.api_key\n",
452
- "\n",
453
- "# make API request\n",
454
- "res = requests.get('https://api.glassnode.com/v1/metrics/indicators/sopr',\n",
455
- " params={'a': 'BTC', 'api_key': API_KEY})\n",
456
- "\n",
457
- "# # convert to pandas dataframe\n",
458
- "# df = pd.read_json(res.text, convert_dates=['t'])"
459
- ]
460
- },
461
- {
462
- "cell_type": "code",
463
- "execution_count": 20,
464
- "id": "efd5044c",
465
- "metadata": {},
466
- "outputs": [
467
- {
468
- "data": {
469
- "text/plain": [
470
- "<Response [403]>"
471
- ]
472
- },
473
- "execution_count": 20,
474
- "metadata": {},
475
- "output_type": "execute_result"
476
- }
477
- ],
478
- "source": [
479
- "requests.get(url, params={'api_key': API_KEY})"
480
- ]
481
- }
482
- ],
483
- "metadata": {
484
- "kernelspec": {
485
- "display_name": "cryptodatapy",
486
- "language": "python",
487
- "name": "cryptodatapy"
488
- },
489
- "language_info": {
490
- "codemirror_mode": {
491
- "name": "ipython",
492
- "version": 3
493
- },
494
- "file_extension": ".py",
495
- "mimetype": "text/x-python",
496
- "name": "python",
497
- "nbconvert_exporter": "python",
498
- "pygments_lexer": "ipython3",
499
- "version": "3.9.12"
500
- }
501
- },
502
- "nbformat": 4,
503
- "nbformat_minor": 5
504
- }
@@ -1,2 +0,0 @@
1
- # Created by pytest automatically.
2
- *
@@ -1,4 +0,0 @@
1
- Signature: 8a477f597d28d172789f06886806bc55
2
- # This file is a cache directory tag created by pytest.
3
- # For information about cache directory tags, see:
4
- # https://bford.info/cachedir/spec.html
@@ -1,8 +0,0 @@
1
- # pytest cache directory #
2
-
3
- This directory contains data from the pytest's cache plugin,
4
- which provides the `--lf` and `--ff` options, as well as the `cache` fixture.
5
-
6
- **Do not** commit this to version control.
7
-
8
- See [the docs](https://docs.pytest.org/en/stable/how-to/cache.html) for more information.
@@ -1,6 +0,0 @@
1
- {
2
- "cells": [],
3
- "metadata": {},
4
- "nbformat": 4,
5
- "nbformat_minor": 5
6
- }