Skip to content

Commit

Permalink
Reorganize data api endpoints (#45)
Browse files Browse the repository at this point in the history
* feat: update candle client

* feat: update funding rate client

* fix: black

* feat: update docs

* feat: bump up version

* feat: unify conversion from list to df

* feat: define default timeout to 10 seconds

* feat: add missing import

* feat: change order of functions and reflect in docs

* fix: timeout test
  • Loading branch information
martinkersner authored Jul 18, 2024
1 parent 7707da2 commit 4950aee
Show file tree
Hide file tree
Showing 13 changed files with 370 additions and 240 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ All clients accept the same parameters that are described at [Configuration](#co
First, import the clients,

```python
# Main client
# Main client to access crypto trading data
from datamaxi.datamaxi import Datamaxi

# DeFi
Expand Down
2 changes: 1 addition & 1 deletion datamaxi/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.11.0"
__version__ = "0.12.0"
2 changes: 1 addition & 1 deletion datamaxi/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def __init__(
self,
api_key=None,
base_url=None,
timeout=None,
timeout=10,
proxies=None,
show_limit_usage=False,
show_header=False,
Expand Down
234 changes: 6 additions & 228 deletions datamaxi/datamaxi/__init__.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
from typing import Any, Callable, Tuple, List, Dict, Union
import pandas as pd
from datamaxi.api import API
from datamaxi.lib.utils import check_required_parameter
from datamaxi.lib.utils import check_required_parameters
from typing import Any
from datamaxi.lib.constants import BASE_URL
from datamaxi.datamaxi.candle import Candle
from datamaxi.datamaxi.funding_rate import FundingRate


class Datamaxi(API):
class Datamaxi:
"""Client to fetch unified data from DataMaxi+ API."""

def __init__(self, api_key=None, **kwargs: Any):
Expand All @@ -19,225 +17,5 @@ def __init__(self, api_key=None, **kwargs: Any):
if "base_url" not in kwargs:
kwargs["base_url"] = BASE_URL

super().__init__(api_key, **kwargs)

def symbols(self, exchange: str) -> List[str]:
"""Supported symbols by given exchange
`GET /v1/symbols`
<https://docs.datamaxiplus.com/api/datasets/cex/symbols>
Args:
exchange (str): Exchange name
Returns:
List of supported symbols
"""
check_required_parameter(exchange, "exchange")
params = {"exchange": exchange}
url_path = "/v1/symbols"
return self.query(url_path, params)

def intervals(self, exchange: str) -> List[str]:
"""Supported intervals by given exchange
`GET /v1/intervals`
<https://docs.datamaxiplus.com/api/datasets/cex/intervals>
Args:
exchange (str): Exchange name
Returns:
List of supported intervals
"""
check_required_parameter(exchange, "exchange")
params = {"exchange": exchange}
url_path = "/v1/intervals"
return self.query(url_path, params)

def candle(
self,
exchange: str,
symbol: str,
interval: str = "1d",
market: str = "spot",
page: int = 1,
limit: int = 1000,
fromDateTime: str = None,
toDateTime: str = None,
sort: str = "desc",
pandas: bool = True,
) -> Union[Tuple[Dict, Callable], Tuple[pd.DataFrame, Callable]]:
"""Get candle data
`GET /v1/candle`
<https://docs.datamaxiplus.com/api/datasets/cex/candle>
Args:
exchange (str): Exchange name
symbol (str): Symbol name
interval (str): Candle interval
market (str): Market type (spot/futures)
page (int): Page number
limit (int): Limit of data
fromDateTime (str): Start date and time (accepts format "2006-01-02 15:04:05" or "2006-01-02")
toDateTime (str): End date and time (accepts format "2006-01-02 15:04:05" or "2006-01-02")
sort (str): Sort order
pandas (bool): Return data as pandas DataFrame
Returns:
Candle data for a given symbol, interval and market in pandas DataFrame and next request function
"""
check_required_parameters(
[
[exchange, "exchange"],
[symbol, "symbol"],
[interval, "interval"],
[market, "market"],
]
)

if market not in ["spot", "futures"]:
raise ValueError("market must be either spot or futures")

if page < 1:
raise ValueError("page must be greater than 0")

if limit < 1:
raise ValueError("limit must be greater than 0")

if fromDateTime is not None and toDateTime is not None:
raise ValueError(
"fromDateTime and toDateTime cannot be set at the same time"
)

if sort not in ["asc", "desc"]:
raise ValueError("sort must be either asc or desc")

params = {
"exchange": exchange,
"symbol": symbol,
"interval": interval,
"market": market,
"page": page,
"limit": limit,
"fromDateTime": fromDateTime,
"toDateTime": toDateTime,
"sort": sort,
}

res = self.query("/v1/candle", params)
if res["data"] is None:
raise ValueError("no data found")

def next_request():
return self.candle(
exchange,
symbol,
interval,
market,
page + 1,
limit,
fromDateTime,
toDateTime,
sort,
pandas,
)

if pandas:
df = pd.DataFrame(res["data"])
df = df.set_index("d")
df.replace("NaN", pd.NA, inplace=True)
df = df.apply(pd.to_numeric, errors="coerce")
return df, next_request
else:
return res, next_request

def funding_rate(
self,
exchange: str,
symbol: str,
page: int = 1,
limit: int = 1000,
fromDateTime: str = None,
toDateTime: str = None,
sort: str = "desc",
pandas: bool = True,
) -> Union[Tuple[Dict, Callable], Tuple[pd.DataFrame, Callable]]:
"""Get funding rate data
`GET /v1/funding-rate`
<https://docs.datamaxiplus.com/api/datasets/cex/funding-rate>
Args:
exchange (str): Exchange name
symbol (str): Symbol name
page (int): Page number
limit (int): Limit of data
fromDateTime (str): Start date and time (accepts format "2006-01-02 15:04:05" or "2006-01-02")
toDateTime (str): End date and time (accepts format "2006-01-02 15:04:05" or "2006-01-02")
sort (str): Sort order
pandas (bool): Return data as pandas DataFrame
Returns:
Funding rate data for a given symbol and exchange in pandas DataFrame and next request function
"""
check_required_parameters(
[
[exchange, "exchange"],
[symbol, "symbol"],
]
)

if page < 1:
raise ValueError("page must be greater than 0")

if limit < 1:
raise ValueError("limit must be greater than 0")

if fromDateTime is not None and toDateTime is not None:
raise ValueError(
"fromDateTime and toDateTime cannot be set at the same time"
)

if sort not in ["asc", "desc"]:
raise ValueError("sort must be either asc or desc")

params = {
"exchange": exchange,
"symbol": symbol,
"page": page,
"limit": limit,
"fromDateTime": fromDateTime,
"toDateTime": toDateTime,
"sort": sort,
}

res = self.query("/v1/funding-rate", params)
if res["data"] is None:
raise ValueError("no data found")

def next_request():
return self.funding_rate(
exchange,
symbol,
page + 1,
limit,
fromDateTime,
toDateTime,
sort,
pandas,
)

if pandas:
df = pd.DataFrame(res["data"])
df = df.set_index("d")
df.replace("NaN", pd.NA, inplace=True)
df = df.apply(pd.to_numeric, errors="coerce")
return df, next_request
else:
return res, next_request
self.candle = Candle(api_key, **kwargs)
self.funding_rate = FundingRate(api_key, **kwargs)
Loading

0 comments on commit 4950aee

Please sign in to comment.