From a8d723f7cb6ccf903804292d81a692da115e390e Mon Sep 17 00:00:00 2001 From: Martin Kersner Date: Sat, 20 Jul 2024 14:15:58 +0900 Subject: [PATCH 1/6] feat: add dex trade --- datamaxi/datamaxi/__init__.py | 2 + datamaxi/datamaxi/dex_trade.py | 116 +++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 datamaxi/datamaxi/dex_trade.py diff --git a/datamaxi/datamaxi/__init__.py b/datamaxi/datamaxi/__init__.py index a7f0959..2a6631c 100644 --- a/datamaxi/datamaxi/__init__.py +++ b/datamaxi/datamaxi/__init__.py @@ -2,6 +2,7 @@ from datamaxi.lib.constants import BASE_URL from datamaxi.datamaxi.candle import Candle from datamaxi.datamaxi.funding_rate import FundingRate +from datamaxi.datamaxi.dex_trade import DexTrade class Datamaxi: @@ -19,3 +20,4 @@ def __init__(self, api_key=None, **kwargs: Any): self.candle = Candle(api_key, **kwargs) self.funding_rate = FundingRate(api_key, **kwargs) + self.dex_trade = DexTrade(api_key, **kwargs) diff --git a/datamaxi/datamaxi/dex_trade.py b/datamaxi/datamaxi/dex_trade.py new file mode 100644 index 0000000..3001513 --- /dev/null +++ b/datamaxi/datamaxi/dex_trade.py @@ -0,0 +1,116 @@ +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 datamaxi.datamaxi.utils import convert_data_to_data_frame + + +class DexTrade(API): + """Client to fetch DEX trade data from DataMaxi+ API.""" + + def __init__(self, api_key=None, **kwargs: Any): + """Initialize DEX trade client. + + Args: + api_key (str): The DataMaxi+ API key + **kwargs: Keyword arguments used by `datamaxi.api.API`. + """ + super().__init__(api_key, **kwargs) + + def get( + 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]]: + """Fetch DEX trade data + + `GET /v1/dex/trade` + + + + 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: + DEX trade data 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/dex/trade", params) + if res["data"] is None: + raise ValueError("no data found") + + def next_request(): + return self.get( + exchange, + symbol, + page + 1, + limit, + fromDateTime, + toDateTime, + sort, + pandas, + ) + + if pandas: + df = convert_data_to_data_frame(res["data"]) + return df, next_request + else: + return res, next_request + + def exchanges(self) -> List[str]: + """Fetch supported exchanges accepted by + [datamaxi.DexTrade.get](./#datamaxi.datamaxi.DexTrade.get) + API. + + `GET /v1/dex/trade/exchanges` + + + + Returns: + List of supported exchanges + """ + url_path = "/v1/dex/trade/exchanges" + return self.query(url_path) From cb3edb356360e4619ab7acab4c4cb2ba844904c9 Mon Sep 17 00:00:00 2001 From: Martin Kersner Date: Sat, 20 Jul 2024 14:16:08 +0900 Subject: [PATCH 2/6] fix: consecutive calls with pagination to candle/funding rate --- datamaxi/datamaxi/candle.py | 2 +- datamaxi/datamaxi/funding_rate.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/datamaxi/datamaxi/candle.py b/datamaxi/datamaxi/candle.py index 4ee1291..a1c11a1 100644 --- a/datamaxi/datamaxi/candle.py +++ b/datamaxi/datamaxi/candle.py @@ -95,7 +95,7 @@ def get( raise ValueError("no data found") def next_request(): - return self.candle( + return self.get( exchange, symbol, interval, diff --git a/datamaxi/datamaxi/funding_rate.py b/datamaxi/datamaxi/funding_rate.py index fe4d742..756bc2b 100644 --- a/datamaxi/datamaxi/funding_rate.py +++ b/datamaxi/datamaxi/funding_rate.py @@ -84,7 +84,7 @@ def get( raise ValueError("no data found") def next_request(): - return self.funding_rate( + return self.get( exchange, symbol, page + 1, From f30ed887abae915f2e92783b4aa0ba0ba9244b2b Mon Sep 17 00:00:00 2001 From: Martin Kersner Date: Sat, 20 Jul 2024 14:24:36 +0900 Subject: [PATCH 3/6] feat: define which columns to convert to numbers --- datamaxi/datamaxi/dex_trade.py | 2 +- datamaxi/datamaxi/utils.py | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/datamaxi/datamaxi/dex_trade.py b/datamaxi/datamaxi/dex_trade.py index 3001513..6d7cc0b 100644 --- a/datamaxi/datamaxi/dex_trade.py +++ b/datamaxi/datamaxi/dex_trade.py @@ -95,7 +95,7 @@ def next_request(): ) if pandas: - df = convert_data_to_data_frame(res["data"]) + df = convert_data_to_data_frame(res["data"], ["b", "bq", "qq", "p", "usd"]) return df, next_request else: return res, next_request diff --git a/datamaxi/datamaxi/utils.py b/datamaxi/datamaxi/utils.py index caca32b..7024af2 100644 --- a/datamaxi/datamaxi/utils.py +++ b/datamaxi/datamaxi/utils.py @@ -2,9 +2,21 @@ import pandas as pd -def convert_data_to_data_frame(data: List) -> pd.DataFrame: +def convert_data_to_data_frame( + data: List, + columns_to_replace: List[str] = [], +) -> pd.DataFrame: df = pd.DataFrame(data) df = df.set_index("d") - df.replace("NaN", pd.NA, inplace=True) - df = df.apply(pd.to_numeric, errors="coerce") + + if len(columns_to_replace) == 0: + df.replace("NaN", pd.NA, inplace=True) + df = df.apply(pd.to_numeric, errors="coerce") + return df + + df[columns_to_replace] = df[columns_to_replace].replace("NaN", pd.NA) + df[columns_to_replace] = df[columns_to_replace].apply( + pd.to_numeric, errors="coerce" + ) + return df From 1ce20afc7edc7b4d571f5908307a65a0a3ef93d1 Mon Sep 17 00:00:00 2001 From: Martin Kersner Date: Sat, 20 Jul 2024 14:28:43 +0900 Subject: [PATCH 4/6] feat: add dex trade docs --- docs/dex-trade.md | 6 ++++++ mkdocs.yml | 1 + 2 files changed, 7 insertions(+) create mode 100644 docs/dex-trade.md diff --git a/docs/dex-trade.md b/docs/dex-trade.md new file mode 100644 index 0000000..9b68b99 --- /dev/null +++ b/docs/dex-trade.md @@ -0,0 +1,6 @@ +# DEX Trade + +::: datamaxi.datamaxi.DexTrade + options: + show_submodules: true + show_source: false diff --git a/mkdocs.yml b/mkdocs.yml index 9f1dd45..8cb1c8c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -34,6 +34,7 @@ nav: - Datamaxi: - Candle: candle.md - Funding Rate: funding-rate.md + - DEX Trade: dex-trade.md - Defillama: defillama.md - Trend: - Naver Trend: naver-trend.md From e0523f8c606beb75c6550e91af9f970362677f3e Mon Sep 17 00:00:00 2001 From: Martin Kersner Date: Sat, 20 Jul 2024 14:36:14 +0900 Subject: [PATCH 5/6] feat: remove unused parameter --- datamaxi/datamaxi/dex_trade.py | 1 - 1 file changed, 1 deletion(-) diff --git a/datamaxi/datamaxi/dex_trade.py b/datamaxi/datamaxi/dex_trade.py index 6d7cc0b..e3cedd9 100644 --- a/datamaxi/datamaxi/dex_trade.py +++ b/datamaxi/datamaxi/dex_trade.py @@ -1,7 +1,6 @@ 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 datamaxi.datamaxi.utils import convert_data_to_data_frame From 6e196a31002be25441be356df6d6440222828c54 Mon Sep 17 00:00:00 2001 From: Martin Kersner Date: Sat, 20 Jul 2024 14:39:48 +0900 Subject: [PATCH 6/6] feat: bump up version --- datamaxi/__version__.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/datamaxi/__version__.py b/datamaxi/__version__.py index ea370a8..f23a6b3 100644 --- a/datamaxi/__version__.py +++ b/datamaxi/__version__.py @@ -1 +1 @@ -__version__ = "0.12.0" +__version__ = "0.13.0" diff --git a/pyproject.toml b/pyproject.toml index 1c2ab6e..51b8440 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "datamaxi" -version = "0.12.0" +version = "0.13.0" authors = [ { name="Bisonai", email="business@bisonai.com" }, ]