crypticorn 1.0.2rc2__py3-none-any.whl → 1.0.2rc4__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.
crypticorn/client.py CHANGED
@@ -1,49 +1,7 @@
1
- import httpx
2
- import pandas as pd
3
- from pandas import DataFrame
4
- from pydantic import BaseModel
5
- from typing import Optional, Union, List
6
- from urllib.parse import urljoin
7
- from datetime import datetime, timedelta
8
-
9
1
  from crypticorn.hive import HiveClient
10
2
  from crypticorn.trade import TradeClient
11
3
  from crypticorn.klines import KlinesClient
12
4
 
13
- class PredictionData(BaseModel):
14
- id: Optional[int] = None
15
- action: Optional[str] = None
16
- course_change: Optional[float]
17
- symbol: str
18
- timestamp: int
19
- version: str
20
- base_price: Optional[float]
21
- p10: list[float]
22
- p30: list[float]
23
- p50: list[float]
24
- p70: list[float]
25
- p90: list[float]
26
-
27
-
28
- class TrendData(BaseModel):
29
- timestamps: Optional[list[int]]
30
- positive_prob: list[float]
31
- symbol: str
32
- version: Optional[str]
33
-
34
-
35
- class TrendQuery(BaseModel):
36
- symbol: str
37
- limit: int
38
- offset: int
39
- sort: str
40
- dir: str
41
- from_ts: int
42
- to_ts: int
43
- version: str = "1"
44
-
45
- default_version = "1.5"
46
-
47
5
  class CrypticornClient:
48
6
  def __init__(
49
7
  self, base_url: str = "https://api.crypticorn.com", api_key: str = None, jwt: str = None
@@ -51,672 +9,8 @@ class CrypticornClient:
51
9
  self.base_url = base_url
52
10
  self.api_key = api_key
53
11
  self.jwt = jwt
54
- self.client = httpx.Client()
55
12
 
56
13
  # Initialize service clients
57
14
  self.hive = HiveClient(base_url, api_key, jwt)
58
15
  self.trade = TradeClient(base_url, api_key, jwt)
59
16
  self.klines = KlinesClient(base_url, api_key, jwt)
60
-
61
- def get_response(
62
- self, endpoint: str, params: dict = None, dict_key: str = None
63
- ) -> Union[DataFrame, dict]:
64
- full_url = urljoin(self.base_url, "/v1/miners" + endpoint)
65
- print(full_url)
66
- print(params)
67
- try:
68
- response = self.client.get(full_url, params=params, timeout=None)
69
- response.raise_for_status()
70
- except httpx.HTTPStatusError as e:
71
- print(f"HTTP error occurred: {e}")
72
- return {}
73
- except httpx.RequestError as e:
74
- print(f"Request error occurred: {e}")
75
- return {}
76
-
77
- formatted_response = response.json()
78
-
79
- if dict_key:
80
- return formatted_response.get(dict_key, {})
81
-
82
- return DataFrame(formatted_response)
83
-
84
- # -------------------- START OF DATA PLATFORM SERVICE ------------------------ #
85
- def get_economics_news(self, entries: int, reverse: bool = False) -> DataFrame:
86
- class NewsData(BaseModel):
87
- timestamp: int
88
- country: Union[str, None]
89
- event: Union[str, None]
90
- currency: Union[str, None]
91
- previous: Union[float, None]
92
- estimate: Union[float, None]
93
- actual: Union[float, None]
94
- change: Union[float, None]
95
- impact: Union[str, None]
96
- changePercentage: Union[float, None]
97
-
98
- res = self.get_response("/ec", {"entries": entries, "reverse": reverse}, "data")
99
- df = DataFrame(res)
100
- df.columns = NewsData.__annotations__
101
- df.sort_values(by="timestamp", ascending=False, inplace=True)
102
- return df
103
-
104
- def get_bc_historical(
105
- self, ticker: str, interval: str, entries: int, reverse: bool = False
106
- ) -> DataFrame:
107
- """
108
-
109
- get: ticker + open_unix + OHLC + Volume data , as pandas dataframe
110
-
111
- --- structure reference: ---
112
-
113
- (column name: data type)
114
-
115
- timestamp: int,
116
- ticker: str
117
- open_interval: float,
118
- high_interval: float,
119
- low_interval: float,
120
- close_interval: float,
121
- volume_interval: float,
122
- """
123
- df = self.get_response(
124
- "/historical",
125
- {"ticker": ticker + "@" + interval, "entries": entries, "reverse": reverse},
126
- )
127
- desired_order = [
128
- "timestamp",
129
- "ticker",
130
- "open",
131
- "high",
132
- "low",
133
- "close",
134
- "volume",
135
- ]
136
- df = df[desired_order]
137
- df.rename(
138
- columns={
139
- "ticker": "coin",
140
- "open": f"open_{interval}",
141
- "high": f"high_{interval}",
142
- "low": f"low_{interval}",
143
- "close": f"close_{interval}",
144
- "volume": f"volume_{interval}",
145
- },
146
- inplace=True,
147
- )
148
- df[["coin", "interval"]] = df["coin"].str.split("@", expand=True)
149
- df.pop("interval")
150
- df.sort_values(by="timestamp", ascending=False, inplace=True)
151
- df["timestamp"] = df["timestamp"] // 1000
152
- return df
153
-
154
- def get_fgi_historical(self, days: int) -> DataFrame:
155
- """
156
-
157
- get: unix_time + value , as pandas dataframe
158
-
159
- --- structure reference: ---
160
-
161
- (column name: data type)
162
-
163
- unix_time: int,
164
- value: int,
165
-
166
- """
167
- df = self.get_response(endpoint="/historical/fgi", params={"days": days})
168
- return df
169
-
170
- def post_prediction(self, data: PredictionData) -> dict:
171
- response = self.client.post(
172
- urljoin(self.base_url, "/v1/predictions"),
173
- json=data.dict(),
174
- headers={"Authorization": f"Bearer {self.api_key}"},
175
- )
176
- return response.json()
177
-
178
- def get_latest_predictions(self, version: str = default_version) -> DataFrame:
179
- response = self.client.get(
180
- urljoin(self.base_url, f"/v1/predictions/latest?version={version}"),
181
- headers={"Authorization": f"Bearer {self.api_key}"},
182
- )
183
- arr = response.json()
184
- flatarr = []
185
- for i in arr:
186
- for index, _ in enumerate(i["p50"]):
187
- interval = 900
188
- ts = i["timestamp"]
189
- ts = ts - (ts % interval)
190
- ts = ts + (index * interval)
191
- pred_dict = {
192
- "id": i["id"],
193
- "action": i["action"],
194
- "course_change": i["course_change"],
195
- "symbol": i["symbol"],
196
- "timestamp": ts,
197
- "version": i["version"],
198
- # "base_price": i["base_price"],
199
- "p10": i["p10"][index],
200
- "p30": i["p30"][index],
201
- "p50": i["p50"][index],
202
- "p70": i["p70"][index],
203
- "p90": i["p90"][index],
204
- }
205
- flatarr.append(pred_dict)
206
- df = DataFrame(flatarr)
207
- df["timestamp"] = pd.to_datetime(df["timestamp"], unit="s")
208
- return df
209
-
210
- def get_prediction(self, pair: str, version: str = default_version, limit: int = 1) -> PredictionData:
211
- response = self.client.get(
212
- urljoin(self.base_url, f"/v1/predictions/symbol/{pair}?version={version}&limit={limit}"),
213
- headers={"Authorization": f"Bearer {self.api_key}"},
214
- )
215
- return response.json()
216
-
217
- def get_prediction_time(self, id) -> DataFrame:
218
- response = self.client.get(
219
- urljoin(self.base_url, f"/v1/predictions/time/{id}"),
220
- headers={"Authorization": f"Bearer {self.api_key}"},
221
- )
222
- arr = response.json()
223
- return DataFrame(arr)
224
-
225
- def get_udf_history(self, symbol: str, entries: int) -> DataFrame:
226
- now = int(pd.Timestamp.now().timestamp())
227
- response = self.client.get(
228
- urljoin(self.base_url, "/v1/udf/history"),
229
- headers={"Authorization": f"Bearer {self.api_key}"},
230
- params={
231
- "from": now - (entries * 900),
232
- "to": now,
233
- "symbol": symbol,
234
- "resolution": "15",
235
- "countback": entries,
236
- },
237
- )
238
- # # {'s': 'ok', 't': [1710982800.0, 1710983700.0], 'c': [67860.61, 67930.01], 'o': [67656.01, 67860.6], 'h': [67944.69, 67951.15], 'l': [67656.0, 67792.06], 'v': [448.61539, 336.9907]}
239
- result = response.json()
240
- # construct dataframe for t, c, o, h, l, v arrays
241
- df = DataFrame(result)
242
- df["t"] = pd.to_datetime(df["t"], unit="s")
243
- df.pop("s")
244
- return df
245
-
246
- def post_trend(self, data: TrendData) -> dict:
247
- response = self.client.post(
248
- urljoin(self.base_url, "/v1/trends"),
249
- json=data.dict(),
250
- headers={"Authorization": f"Bearer {self.api_key}"},
251
- )
252
- return response.json()
253
-
254
- def get_trends(self, query: TrendQuery):
255
- response = self.client.get(
256
- urljoin(self.base_url, "/v1/trends"),
257
- headers={"Authorization": f"Bearer {self.api_key}"},
258
- params=query.dict(),
259
- )
260
- df = DataFrame(response.json())
261
- return df
262
-
263
- # -------------------- END OF DATA PLATFORM SERVICE ------------------------ #
264
-
265
- # -------------------- START OF KLINE SERVICE ------------------------ #
266
- def get_symbols(self, market: str) -> DataFrame:
267
- """
268
- get: symbol for futures or spot, as pandas dataframe
269
- market: futures or spot
270
- """
271
- response = self.klines.symbols.symbols_symbols_market_get(market=market)
272
- if response.status_code == 200:
273
- df = DataFrame(response.json())
274
- return df
275
- else:
276
- raise Exception(f"Failed to get symbols: {response.json()}")
277
-
278
- def get_klines(self, market: str, symbol: str, interval: str, limit: int, start_timestamp: int = None, end_timestamp: int = None, sort: str = "desc") -> DataFrame:
279
- """
280
- get: unix_time + OHLCV data , as pandas dataframe
281
- symbol have to be in capital case e.g. (BTCUSDT)
282
- market: futures or spot
283
- interval: 1m, 3m, 5m, 15m, 30m, 1h, 4h, 1d
284
- """
285
- params = {"limit": limit}
286
- if start_timestamp is not None:
287
- params["start"] = start_timestamp
288
- if end_timestamp is not None:
289
- params["end"] = end_timestamp
290
- if sort is not None:
291
- params["sort_direction"] = sort
292
-
293
- response = self.client.get(
294
- urljoin(self.base_url, f"/v1/klines/{market}/{interval}/{symbol}"),
295
- params=params, timeout=None
296
- )
297
- if response.status_code == 200:
298
- df = DataFrame(response.json())
299
- df['timestamp'] = pd.to_datetime(df['timestamp'])
300
- df['timestamp'] = df['timestamp'].astype("int64") // 10 ** 9 # use int64 instead of int for windows
301
- return df
302
- else:
303
- raise Exception(f"Failed to get klines: {response.json()}")
304
-
305
- def get_funding_rate(self, symbol: str, start_timestamp: int = None, end_timestamp: int = None, limit: int = 2000) -> DataFrame:
306
- """
307
- get: unix_time + funding rate data , as pandas dataframe
308
- symbol have to be in capital case e.g. (BTCUSDT)
309
- start_timestamp and end_timestamp are optional
310
- """
311
- params = {"limit": limit}
312
- if start_timestamp is not None:
313
- params["start"] = start_timestamp
314
- if end_timestamp is not None:
315
- params["end"] = end_timestamp
316
-
317
- response = self.client.get(
318
- urljoin(self.base_url, f"/v1/klines/funding_rates/{symbol}"),
319
- params=params, timeout=None
320
- )
321
- if response.status_code == 200:
322
- df = DataFrame(response.json())
323
- return df
324
- else:
325
- raise Exception(f"Failed to get funding rates: {response.json()}")
326
-
327
- # -------------------- END OF KLINE SERVICE ------------------------ #
328
-
329
- # -------------------- START OF TRADE SERVICE ------------------------ #
330
- def list_orders(self) -> DataFrame:
331
- response = self.client.get(
332
- urljoin(self.base_url, "/v1/trade/orders"),
333
- headers={"Authorization": f"Bearer {self.api_key}"},
334
- )
335
- return DataFrame(response.json())
336
-
337
- def get_enabled_bots(self) -> DataFrame:
338
- response = self.client.get(
339
- urljoin(self.base_url, "/v1/trade/bots/enabled"),
340
- headers={"Authorization": f"Bearer {self.api_key}"},
341
- )
342
- data = response.json()
343
- return {
344
- "bots": DataFrame(data["bots"]),
345
- "api_keys": DataFrame(data["api_keys"])
346
- }
347
-
348
- # -------------------- END OF TRADE SERVICE ------------------------ #
349
-
350
- # -------------------- START OF GOOGLE TRENDS ------------------------ #
351
- # Get all keywords available for Google Trends
352
- def get_google_trend_keywords_available(self) -> DataFrame:
353
- response = self.client.get(
354
- urljoin(self.base_url, "/v1/google/keywords"),
355
- )
356
- if response.status_code == 200:
357
- df = pd.DataFrame(response.json())
358
- return df
359
- else:
360
- raise Exception(f"Failed to get google trends keywords available: {response.json()}")
361
-
362
- # Get Google Trends data for a specific keyword
363
- def get_google_trend_keyword(self, keyword: str, timeframe: str = '8m', limit: int = 100) -> DataFrame:
364
- """
365
- Retrieves Google Trends data for a specific keyword.
366
-
367
- Args:
368
- keyword (str): The keyword to retrieve Google Trends data for.
369
- timeframe (str, optional): The timeframe for the data. Defaults to '8m'.
370
- limit (int, optional): The maximum number of data points to retrieve. Defaults to 100.
371
-
372
- Returns:
373
- DataFrame: A pandas DataFrame containing the Google Trends data.
374
-
375
- """
376
- response = self.client.get(
377
- urljoin(self.base_url, f"/v1/google/trends/{keyword}"),
378
- params={"timeframe": timeframe, "limit": limit}, timeout=None
379
- )
380
- if response.status_code == 200:
381
- df = pd.DataFrame(response.json()['data'])
382
- df.rename(columns={"values": "trend_val", "timestamps": "timestamp"}, inplace=True)
383
- return df
384
- else:
385
- raise Exception(f"Failed to get google trends: {response.json()}")
386
-
387
- # -------------------- END OF GOOGLE TRENDS ------------------------ #
388
-
389
- # -------------------- START OF MARKET SERVICE ------------------------ #
390
- def get_exchange_all_symbols(self, exchange_name: str) -> DataFrame:
391
- """Exchange names to be added as follows:
392
- Binance, KuCoin, Gate.io, Bybit, Bingx, Bitget
393
- """
394
- if exchange_name not in ['Binance', 'KuCoin', 'Gate.io', 'Bybit', 'Bingx', 'Bitget']:
395
- raise ValueError("Invalid exchange name it needs to be one of the following: Binance, KuCoin, Gate.io, Bybit, Bingx, Bitget")
396
- response = self.client.get(
397
- urljoin(self.base_url, f"/v1/market/exchange-data/{exchange_name}"), timeout=None
398
- )
399
- if response.status_code == 200:
400
- df = pd.DataFrame(response.json())
401
- return df
402
- else:
403
- raise Exception(f"Failed to get exchange all symbols: {response.json()}")
404
-
405
- def get_symbol_info_exchange(self, exchange_name: str, symbol: str, market: str = 'spot') -> DataFrame:
406
- """
407
- Exchange names to be added as follows:
408
- Binance, KuCoin, Gate.io, Bybit, Bingx, Bitget
409
-
410
- Exchange symbols to be added as follows:
411
- Spot -> BTC-USDT, ETH-USDT, LTC-USDT
412
- Futures -> BTC-USDT-USDT, ETH-USDT-USDT, LTC-USDT-USDT
413
- """
414
- if market == 'futures':
415
- symbol = symbol + '-USDT'
416
- response = self.client.get(
417
- urljoin(self.base_url, f"/v1/market/exchange-data/{exchange_name}/{symbol}"), timeout=None
418
- )
419
- if response.status_code == 200:
420
- df = pd.DataFrame(response.json())
421
- return df
422
- else:
423
- raise Exception(f"Failed to get symbol info: {response.json()}")
424
-
425
- def get_cnn_sentiment(self, indicator_name: str, start_date: str = None, end_date: str = None, limit: int = None) -> DataFrame:
426
- """
427
- Retrieves Fear and Greed Index data for a specific indicator name.
428
-
429
- Args:
430
- indicator_name (str): The indicator name / keyword to retrieve Fear and Greed Index data for.
431
- start_date (str, optional): The start date for the data. Defaults to None.
432
- end_date (str, optional): The end date for the data. Defaults to None.
433
- limit (int, optional): The maximum number of data points to retrieve. Defaults to None.
434
-
435
- Returns:
436
- DataFrame: A pandas DataFrame containing the Fear and Greed Index data.
437
-
438
- """
439
- response = self.client.get(
440
- urljoin(self.base_url, f"/v1/market/fng-index/{indicator_name}"),
441
- params={"start_date": start_date, "end_date": end_date, "limit": limit}, timeout=None
442
- )
443
- if response.status_code == 200:
444
- df = pd.DataFrame(response.json())
445
- return df
446
- else:
447
- raise Exception(f"Failed to get cnn sentiment: {response.json()}")
448
-
449
- def get_cnn_keywords(self) -> DataFrame:
450
- response = self.client.get(
451
- urljoin(self.base_url, "/v1/market/fng-index/list-indicators"), timeout=None
452
- )
453
- if response.status_code == 200:
454
- df = pd.DataFrame(response.json())
455
- df.columns = ['indicator_name']
456
- return df
457
- else:
458
- raise Exception(f"Failed to get cnn keywords: {response.json()}")
459
-
460
- def get_economic_calendar_events(self, start_timestamp: int = None, end_timestamp: int = None, currency: str = 'EUR', country_code: str = 'DE') -> DataFrame:
461
- """
462
- Function returns a pandas dataframe with the economic calendar events for the specified currency and country code during given time period.
463
- currency: EUR, CNY, NZD, AUD, USD, JPY, UAH, GBP, CHF, CAD
464
- country_code: CA, UA, ES, US, FR, JP, IT, NZ, AU, CN, UK, CH, EMU, DE
465
- """
466
- start_date = None
467
- end_date = None
468
- if isinstance(start_timestamp, int):
469
- start_date = pd.to_datetime(start_timestamp, unit='s').strftime('%Y-%m-%d')
470
- if isinstance(end_timestamp, int):
471
- end_date = pd.to_datetime(end_timestamp, unit='s').strftime('%Y-%m-%d')
472
-
473
- params = {
474
- "start_date": start_date,
475
- "end_date": end_date,
476
- "currency": currency,
477
- "country_code": country_code
478
- }
479
- response = self.client.get(
480
- urljoin(self.base_url, f"/v1/market/ecocal"), timeout=None, params=params
481
- )
482
- if response.status_code == 200:
483
- df = pd.DataFrame(response.json())
484
- return df
485
- else:
486
- raise Exception(f"Failed to get economic calendar events: {response.json()}")
487
-
488
- def get_bitstamp_symbols(self) -> List[str]:
489
- response = self.client.get(
490
- urljoin(self.base_url, f"/v1/market/bitstamp/symbols"), timeout=None
491
- )
492
- if response.status_code == 200:
493
- symbols = response.json()
494
- # convert all symbols to uppercase
495
- symbols = [symbol.upper() for symbol in symbols]
496
- return symbols
497
- else:
498
- raise Exception(f"Failed to get bitstamp symbols: {response.json()}")
499
-
500
- def get_bitstamp_ohlcv_spot(self, symbol: str, interval: str, limit: int, start_timestamp: int = None, end_timestamp: int = None) -> DataFrame:
501
- """
502
- get: unix_time + OHLCV data , as pandas dataframe
503
- symbol have to be in capital case e.g. (BTCUSDT)
504
- interval: 15m, 30m, 1h, 4h, 1d
505
- """
506
- params = {"limit": limit}
507
- if start_timestamp is not None:
508
- params["start"] = start_timestamp
509
- if end_timestamp is not None:
510
- params["end"] = end_timestamp
511
-
512
- response = self.client.get(
513
- urljoin(self.base_url, f"/v1/market/bitstamp/{symbol}/{interval}"),
514
- params=params, timeout=None
515
- )
516
- if response.status_code == 200:
517
- df = DataFrame(response.json())
518
- df['timestamp'] = pd.to_datetime(df['timestamp'])
519
- df['timestamp'] = df['timestamp'].astype("int64") // 10 ** 9 # use int64 instead of int for windows
520
- return df
521
- else:
522
- raise Exception(f"Failed to get bitstamp ohlcv spot: {response.json()}")
523
-
524
- # -------------------- END OF MARKET SERVICE ------------------------ #
525
-
526
- # -------------------- START OF MARKETCAP METRICS SERVICE ------------------------ #
527
- # Get historical marketcap rankings for coins
528
- def get_historical_marketcap_rankings(self, start_timestamp: int = None, end_timestamp: int = None, interval: str = "1d", market: str = None, exchange_name: str = None) -> dict:
529
- """
530
- Get historical marketcap rankings and exchange availability for cryptocurrencies.
531
-
532
- Args:
533
- start_timestamp (int, optional): Start timestamp for the data range
534
- end_timestamp (int, optional): End timestamp for the data range
535
- interval (str, optional): Time interval between data points (e.g. "1d")
536
- market (str, optional): Market type (e.g. "futures")
537
- exchange_name (str, optional): Exchange name (e.g. "binance", "kucoin", "gate.io", "bybit", "bingx", "bitget")
538
-
539
- Returns:
540
- DataFrame: A pandas DataFrame containing the historical marketcap rankings
541
- """
542
- response = self.client.get(
543
- urljoin(self.base_url, f"/v1/metrics/marketcap/symbols"),
544
- timeout=None,
545
- params={
546
- "start_timestamp": start_timestamp,
547
- "end_timestamp": end_timestamp,
548
- "interval": interval,
549
- "market": market,
550
- "exchange": exchange_name
551
- }
552
- )
553
-
554
- data = response.json()
555
- # Process rankings data
556
- rankings_df = pd.DataFrame(response.json())
557
- rankings_df.rename(columns={rankings_df.columns[0]: 'timestamp'}, inplace=True)
558
- rankings_df['timestamp'] = pd.to_datetime(rankings_df['timestamp']).astype("int64") // 10 ** 9
559
- return rankings_df
560
-
561
- def get_historical_marketcap_values_for_rankings(self, start_timestamp: int = None, end_timestamp: int = None) -> DataFrame:
562
- """
563
- Get historical marketcap values for rankings
564
- """
565
- response = self.client.get(
566
- urljoin(self.base_url, f"/v1/metrics/marketcap"), timeout=None, params={"start_timestamp": start_timestamp, "end_timestamp": end_timestamp}
567
- )
568
- if response.status_code == 200:
569
- df = pd.DataFrame(response.json())
570
- df.rename(columns={df.columns[0]: 'timestamp'}, inplace=True)
571
- df['timestamp'] = pd.to_datetime(df['timestamp']).astype("int64") // 10 ** 9
572
- return df
573
- else:
574
- raise Exception(f"Failed to get historical marketcap values for rankings: {response.json()}")
575
-
576
- def get_marketcap_indicator_values(self, symbol: str,market: str, period: int, indicator_name: str, timestamp:int = None):
577
- """
578
- Get marketcap indicator values for a specific indicator name and timestamp
579
- Indicator names to be added as follows:
580
- ker, sma
581
- """
582
- response = self.client.get(
583
- urljoin(self.base_url, f"/v1/metrics/{indicator_name}/{symbol}"), timeout=None, params={"market": market, "period": period, "timestamp": timestamp}
584
- )
585
- if response.status_code == 200:
586
- return response.json()
587
- else:
588
- raise Exception(f"Failed to get marketcap indicator values: {response.json()}")
589
-
590
- def get_exchanges_for_mc_symbol(self, symbol: str, market: str, interval: str = '1d', start_timestamp: int = None, end_timestamp: int = None, status: str = 'ACTIVE', quote_currency: str = 'USDT') -> DataFrame:
591
- """
592
- status: 'ACTIVE', 'RETIRED'
593
- quote_currency: USDT, USDC (can be retrieved from get_unique_quote_currencies())
594
- """
595
-
596
- if start_timestamp is None:
597
- start_timestamp = int((datetime.now() - timedelta(days=7, hours=0, minutes=0, seconds=0)).timestamp())
598
- if end_timestamp is None:
599
- end_timestamp = int((datetime.now() - timedelta(days=0, hours=0, minutes=0, seconds=0)).timestamp())
600
-
601
- params = {
602
- "interval": interval,
603
- "start_timestamp": start_timestamp,
604
- "end_timestamp": end_timestamp,
605
- "status": status,
606
- "quote_currency": quote_currency
607
- }
608
-
609
- response = self.client.get(
610
- urljoin(self.base_url, f"/v1/metrics/available_exchanges/{market}/{symbol}"), timeout=None, params=params
611
- )
612
- if response.status_code == 200:
613
- result = response.json()
614
- processed_results = []
615
- for row in result:
616
- data = {'timestamp': row['timestamp']}
617
- data.update(row['exchanges'])
618
- processed_results.append(data)
619
- df = pd.DataFrame(processed_results)
620
- cols = ['timestamp'] + sorted([col for col in df.columns if col != 'timestamp'])
621
- df = df[cols]
622
- df['timestamp'] = pd.to_datetime(df['timestamp']).astype("int64") // 10 ** 9
623
- df = df.astype(int)
624
- return df
625
- else:
626
- raise Exception(f"Failed to get exchanges for mc symbol: {response.json()}")
627
-
628
- def get_marketcap_ranking_with_ohlcv(self, market: str, timeframe: str, top_n: int, ohlcv_limit: int, timestamp: int = int((datetime.now() - timedelta(days=1, hours=0, minutes=0, seconds=0)).timestamp())) -> DataFrame:
629
- params = {"market": market, "timeframe": timeframe, "top_n": top_n, "ohlcv_limit": ohlcv_limit, "timestamp": timestamp}
630
- print(params)
631
- response = self.client.get(
632
- urljoin(self.base_url, f"/v1/metrics/marketcap/symbols/ohlcv"), timeout=None, params=params
633
- )
634
- if response.status_code == 200:
635
- df = pd.DataFrame(response.json())
636
- return df
637
- else:
638
- raise Exception(f"Failed to get marketcap ranking with ohlcv: {response.json()}")
639
-
640
- def get_stable_or_wrapped_tokens(self, token_type: str = 'stable') -> DataFrame:
641
- """
642
- token_type: stable or wrapped
643
- """
644
- if token_type not in ['stable', 'wrapped']:
645
- raise ValueError("token_type must be either stable or wrapped")
646
- response = self.client.get(
647
- urljoin(self.base_url, f"/v1/metrics/tokens/{token_type}"), timeout=None
648
- )
649
- if response.status_code == 200:
650
- df = pd.DataFrame(response.json())
651
- return df
652
- else:
653
- raise Exception(f"Failed to get stable or wrapped tokens: {response.json()}")
654
-
655
- def get_exchanges_mapping_for_specific_symbol(self, market: str, symbol: str) -> DataFrame:
656
- """
657
- Get the exchanges for a specific symbol and market
658
- """
659
- response = self.client.get(
660
- urljoin(self.base_url, f"/v1/metrics/markets/{market}/{symbol}"), timeout=None
661
- )
662
- if response.status_code == 200:
663
- df = pd.DataFrame(response.json())
664
- return df
665
- else:
666
- raise Exception(f"Failed to get exchange mappings: {response.json()}")
667
-
668
- def get_exchange_mappings_for_specific_exchange(self,market: str, exchange_name: str) -> DataFrame:
669
- """
670
- Get the exchanges for a specific exchange and market
671
- exchange_name: binance, kucoin, gate.io, bybit, bingx, bitget (lowercase)
672
- market: spot, futures
673
- """
674
- params = {
675
- "exchange_name": exchange_name.lower()
676
- }
677
- response = self.client.get(
678
- urljoin(self.base_url, f"/v1/metrics/exchange_mappings/{market}"), timeout=None, params=params
679
- )
680
- if response.status_code == 200:
681
- df = pd.DataFrame(response.json())
682
- return df
683
- else:
684
- raise Exception(f"Failed to get exchange mappings: {response.json()}")
685
-
686
- def get_unique_quote_currencies(self, market: str) -> DataFrame:
687
- response = self.client.get(
688
- urljoin(self.base_url, f"/v1/metrics/quote_currencies/{market}"), timeout=None
689
- )
690
- if response.status_code == 200:
691
- df = pd.DataFrame(response.json())
692
- return df
693
- else:
694
- raise Exception(f"Failed to get unique quote currencies: {response.json()}")
695
-
696
- def get_exchanges_list_for_specific_market(self, market: str) -> List[str]:
697
- """
698
- Get the list of exchanges for a specific market
699
- """
700
- response = self.client.get(
701
- urljoin(self.base_url, f"/v1/metrics/exchange_list/{market}"), timeout=None
702
- )
703
- if response.status_code == 200:
704
- return response.json()
705
- else:
706
- raise Exception(f"Failed to get exchanges list: {response.json()}")
707
-
708
- # -------------------- END OF MARKETCAP METRICS SERVICE ------------------------ #
709
-
710
- def verify(self, token: Union[str, None] = None) -> bool:
711
- if token is None:
712
- token = self.jwt
713
- response = self.client.get(
714
- self.base_url + "/v1/auth/verify",
715
- headers={"Authorization": f"Bearer {token}"},
716
- )
717
- response.raise_for_status()
718
- try:
719
- res = response.json()
720
- return res['result']['data']['json']
721
- except:
722
- return None
crypticorn/trade/main.py CHANGED
@@ -34,6 +34,6 @@ class TradeClient:
34
34
  self.orders = OrdersApi(base_client)
35
35
  self.status = StatusApi(base_client)
36
36
  self.strategies = StrategiesApi(base_client)
37
- self.trading_actions = TradingActionsApi(base_client)
37
+ self.actions = TradingActionsApi(base_client)
38
38
  self.futures = FuturesTradingPanelApi(base_client)
39
39
  self.api_keys = APIKeysApi(base_client)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: crypticorn
3
- Version: 1.0.2rc2
3
+ Version: 1.0.2rc4
4
4
  Summary: Maximise Your Crypto Trading Profits with AI Predictions
5
5
  Author-email: Crypticorn <timon@crypticorn.com>
6
6
  License: MIT License
@@ -16,21 +16,14 @@ Classifier: Typing :: Typed
16
16
  Requires-Python: >=3.10
17
17
  Description-Content-Type: text/markdown
18
18
  License-File: LICENSE.md
19
- Provides-Extra: trade
20
- Requires-Dist: urllib3<3.0.0,>=1.25.3; extra == "trade"
21
- Requires-Dist: python_dateutil>=2.8.2; extra == "trade"
22
- Requires-Dist: pydantic>=2; extra == "trade"
23
- Requires-Dist: typing-extensions>=4.7.1; extra == "trade"
24
- Provides-Extra: klines
25
- Requires-Dist: urllib3<3.0.0,>=1.25.3; extra == "klines"
26
- Requires-Dist: python_dateutil>=2.8.2; extra == "klines"
27
- Requires-Dist: pydantic>=2; extra == "klines"
28
- Requires-Dist: typing-extensions>=4.7.1; extra == "klines"
29
- Provides-Extra: hive
30
- Requires-Dist: pandas<3.0.0,>=2.2.0; extra == "hive"
31
- Requires-Dist: requests<3.0.0,>=2.32.0; extra == "hive"
32
- Requires-Dist: tqdm<5.0.0,>=4.67.0; extra == "hive"
33
- Requires-Dist: pydantic<3.0.0,>=2.0.0; extra == "hive"
19
+ Requires-Dist: urllib3<3.0.0,>=1.25.3
20
+ Requires-Dist: python_dateutil>=2.8.2
21
+ Requires-Dist: pydantic>=2
22
+ Requires-Dist: typing-extensions>=4.7.1
23
+ Requires-Dist: pandas<3.0.0,>=2.2.0
24
+ Requires-Dist: requests<3.0.0,>=2.32.0
25
+ Requires-Dist: tqdm<5.0.0,>=4.67.0
26
+ Requires-Dist: pydantic<3.0.0,>=2.0.0
34
27
  Provides-Extra: dev
35
28
  Requires-Dist: streamlit; extra == "dev"
36
29
  Requires-Dist: httpx; extra == "dev"
@@ -1,12 +1,10 @@
1
1
  crypticorn/__init__.py,sha256=tSmvwtqHKKAzbhWIc8Vt95hffRf8aEYX-8wWX6ZAPaM,147
2
- crypticorn/client.py,sha256=AWM7R7X24QQvOJn-YnJQtwK8G7SVNBrfwpGRGdji2uY,29215
2
+ crypticorn/client.py,sha256=LZ7oovE-9XV5iWbojMSEsGxOQ2EYI1qlg6zH4ZiRrGA,574
3
3
  crypticorn/hive/__init__.py,sha256=1o5DghmXxXFp7cL-RCNg9_EqNAJih7ftEl5gz0Q19Qc,43
4
4
  crypticorn/hive/main.py,sha256=ZdB0mS_x37pGF7r63Ek-RMYTfGkmdKPf2Sj18WGGJKw,4856
5
- crypticorn/hive/requirements.txt,sha256=-eIbxeVF3c8WJ-QKUSHm-16kCHVp-dRP7isN25wbxqw,103
6
5
  crypticorn/hive/utils.py,sha256=UOgdUomUDoX97OylN0_4fsu3mPsJHaUkpHqNmSp-QYE,3126
7
6
  crypticorn/klines/__init__.py,sha256=9UUW013uZ5x4evz5zRUxbNid-6O9WAPPYvPZIHpAwms,87
8
7
  crypticorn/klines/main.py,sha256=_c_lVK2tTdiAz36jkUvdNipEg-h-j3VsiSliBehdNmc,1590
9
- crypticorn/klines/requirements.txt,sha256=n8RhXDEAbEojFhhRCctaYym4TMVetN5A7FZ-tjjgMRA,93
10
8
  crypticorn/klines/client/__init__.py,sha256=yRh5QZclw9iV6gx5VXxkcQLDuIDgqf8n4-NHsfjX4Ps,3732
11
9
  crypticorn/klines/client/api_client.py,sha256=daaHrXxIXfsBxpAf82DFktJRXb5V3Di23oMkQp8HO1E,27818
12
10
  crypticorn/klines/client/api_response.py,sha256=eMxw1mpmJcoGZ3gs9z6jM4oYoZ10Gjk333s9sKxGv7s,652
@@ -78,8 +76,7 @@ crypticorn/klines/test/test_udf_config_response.py,sha256=WCMj8VVWE1tQgIuvRSbuFI
78
76
  crypticorn/klines/test/test_validation_error.py,sha256=6zSVzD_LX5yIGKGZJgsH74tsXQsV6DhJIpXyqPV-fow,1910
79
77
  crypticorn/klines/test/test_validation_error_loc_inner.py,sha256=D4dHw64J4-bTmMd5K-JuwKaKzHfe8bJvHdAcAfX8nsA,1759
80
78
  crypticorn/trade/__init__.py,sha256=QzScH9n-ly3QSaBSpPP7EqYwhdzDqYCZJs0-AhEhrsY,84
81
- crypticorn/trade/main.py,sha256=7CpTb-5JiDCgRJwjb2sohTcO1sbL_ux3d8p1cFOd4pg,1228
82
- crypticorn/trade/requirements.txt,sha256=n8RhXDEAbEojFhhRCctaYym4TMVetN5A7FZ-tjjgMRA,93
79
+ crypticorn/trade/main.py,sha256=mHAYbEGp-SEP56xsmHIaTQnTWVPtWux42AzGuWjwCL8,1220
83
80
  crypticorn/trade/client/__init__.py,sha256=Fq_jmX_KcwTcUKG5SLky3UgeiAuJNwJLkomDXFc_APw,3241
84
81
  crypticorn/trade/client/api_client.py,sha256=QFMMs_EPtc0_kS2uIhGPfBVbabN0nI7hyJ98FfeVa7s,27528
85
82
  crypticorn/trade/client/api_response.py,sha256=eMxw1mpmJcoGZ3gs9z6jM4oYoZ10Gjk333s9sKxGv7s,652
@@ -121,8 +118,8 @@ crypticorn/trade/client/models/trading_action_type.py,sha256=eH7sFKbFojxqMdtmqq_
121
118
  crypticorn/trade/client/models/update_notification.py,sha256=7Aw4z98ANT6D5octUmz5UXe6EC7_Mk8ax679bjjCkXk,2988
122
119
  crypticorn/trade/client/models/validation_error.py,sha256=hMZJHRMZuiByzCvD7zyR5HVzlzJSnLKcMnybUalQvgI,3105
123
120
  crypticorn/trade/client/models/validation_error_loc_inner.py,sha256=wHiW_qKw46E2pUdOnesgpdnuqpTX9IQTaEOVDgph5_E,4885
124
- crypticorn-1.0.2rc2.dist-info/LICENSE.md,sha256=4QRTsg__j9b8qUNkL1jcDlrOMViv5B7wJF3p7khs-M0,1053
125
- crypticorn-1.0.2rc2.dist-info/METADATA,sha256=-JVX691iYZHKknke7psUIAPqoEs0Sy0O-6Hwgdsi23Y,1973
126
- crypticorn-1.0.2rc2.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
127
- crypticorn-1.0.2rc2.dist-info/top_level.txt,sha256=EP3NY216qIBYfmvGl0L2Zc9ItP0DjGSkiYqd9xJwGcM,11
128
- crypticorn-1.0.2rc2.dist-info/RECORD,,
121
+ crypticorn-1.0.2rc4.dist-info/LICENSE.md,sha256=4QRTsg__j9b8qUNkL1jcDlrOMViv5B7wJF3p7khs-M0,1053
122
+ crypticorn-1.0.2rc4.dist-info/METADATA,sha256=KkMiznWldgKDnp_QkgLskM7DRoqI-cjMdL-_duHd2c0,1548
123
+ crypticorn-1.0.2rc4.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
124
+ crypticorn-1.0.2rc4.dist-info/top_level.txt,sha256=EP3NY216qIBYfmvGl0L2Zc9ItP0DjGSkiYqd9xJwGcM,11
125
+ crypticorn-1.0.2rc4.dist-info/RECORD,,
@@ -1,4 +0,0 @@
1
- pandas >= 2.2.0, < 3.0.0
2
- requests >= 2.32.0, < 3.0.0
3
- tqdm >= 4.67.0, < 5.0.0
4
- pydantic >= 2.0.0, < 3.0.0
@@ -1,4 +0,0 @@
1
- urllib3 >= 1.25.3, < 3.0.0
2
- python_dateutil >= 2.8.2
3
- pydantic >= 2
4
- typing-extensions >= 4.7.1
@@ -1,4 +0,0 @@
1
- urllib3 >= 1.25.3, < 3.0.0
2
- python_dateutil >= 2.8.2
3
- pydantic >= 2
4
- typing-extensions >= 4.7.1