diff --git a/bfxapi/rest/BfxRestInterface.py b/bfxapi/rest/BfxRestInterface.py index 4994bad..3a02593 100644 --- a/bfxapi/rest/BfxRestInterface.py +++ b/bfxapi/rest/BfxRestInterface.py @@ -247,8 +247,16 @@ class _RestAuthenticatedEndpoints(_Requests): def get_wallets(self) -> List[Wallet]: return [ serializers.Wallet.parse(*subdata) for subdata in self._POST("auth/r/wallets") ] - def get_orders(self, ids: Optional[List[str]] = None) -> List[Order]: - return [ serializers.Order.parse(*subdata) for subdata in self._POST("auth/r/orders", data={ "id": ids }) ] + def get_orders(self, symbol: Optional[str] = None, ids: Optional[List[str]] = None) -> List[Order]: + endpoint = "auth/r/orders" + + if symbol != None: + endpoint += f"/{symbol}" + + return [ serializers.Order.parse(*subdata) for subdata in self._POST(endpoint, data={ "id": ids }) ] + + def get_positions(self) -> List[Position]: + return [ serializers.Position.parse(*subdata) for subdata in self._POST("auth/r/positions") ] def submit_order(self, type: OrderType, symbol: str, amount: Union[Decimal, str], price: Optional[Union[Decimal, str]] = None, lev: Optional[int] = None, @@ -311,8 +319,21 @@ class _RestAuthenticatedEndpoints(_Requests): return [ serializers.Order.parse(*subdata) for subdata in self._POST(endpoint, data=data) ] - def get_trades(self, symbol: str) -> List[Trade]: - return [ serializers.Trade.parse(*subdata) for subdata in self._POST(f"auth/r/trades/{symbol}/hist") ] + def get_trades_history(self, symbol: Optional[str] = None, sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[Trade]: + if symbol == None: + endpoint = "auth/r/trades/hist" + else: endpoint = f"auth/r/trades/{symbol}/hist" + + data = { + "sort": sort, + "start": start, "end": end, + "limit": limit + } + + return [ serializers.Trade.parse(*subdata) for subdata in self._POST(endpoint, data=data) ] + + def get_order_trades(self, symbol: str, id: int) -> List[OrderTrade]: + return [ serializers.OrderTrade.parse(*subdata) for subdata in self._POST(f"auth/r/order/{symbol}:{id}/trades") ] def get_ledgers(self, currency: str, category: Optional[int] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[Ledger]: data = { @@ -323,7 +344,7 @@ class _RestAuthenticatedEndpoints(_Requests): return [ serializers.Ledger.parse(*subdata) for subdata in self._POST(f"auth/r/ledgers/{currency}/hist", data=data) ] - def get_active_funding_offers(self, symbol: Optional[str] = None) -> List[FundingOffer]: + def get_funding_offers(self, symbol: Optional[str] = None) -> List[FundingOffer]: endpoint = "auth/r/funding/offers" if symbol != None: @@ -343,4 +364,35 @@ class _RestAuthenticatedEndpoints(_Requests): return serializers._Notification(serializer=serializers.FundingOffer).parse(*self._POST("auth/w/funding/offer/submit", data=data)) def cancel_funding_offer(self, id: int) -> Notification: - return serializers._Notification(serializer=serializers.FundingOffer).parse(*self._POST("auth/w/funding/offer/cancel", data={ "id": id })) \ No newline at end of file + return serializers._Notification(serializer=serializers.FundingOffer).parse(*self._POST("auth/w/funding/offer/cancel", data={ "id": id })) + + def get_funding_offers_history(self, symbol: Optional[str] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[FundingOffer]: + if symbol == None: + endpoint = "auth/r/funding/offers/hist" + else: endpoint = f"auth/r/funding/offers/{symbol}/hist" + + data = { + "start": start, "end": end, + "limit": limit + } + + return [ serializers.FundingOffer.parse(*subdata) for subdata in self._POST(endpoint, data=data) ] + + def get_funding_credits(self, symbol: Optional[str] = None) -> List[FundingCredit]: + if symbol == None: + endpoint = "auth/r/funding/credits" + else: endpoint = f"auth/r/funding/credits/{symbol}" + + return [ serializers.FundingCredit.parse(*subdata) for subdata in self._POST(endpoint) ] + + def get_funding_credits_history(self, symbol: Optional[str] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[FundingCredit]: + if symbol == None: + endpoint = "auth/r/funding/credits/hist" + else: endpoint = f"auth/r/funding/credits/{symbol}/hist" + + data = { + "start": start, "end": end, + "limit": limit + } + + return [ serializers.FundingCredit.parse(*subdata) for subdata in self._POST(endpoint, data=data) ] \ No newline at end of file diff --git a/bfxapi/rest/serializers.py b/bfxapi/rest/serializers.py index ad0f2d1..9e2612a 100644 --- a/bfxapi/rest/serializers.py +++ b/bfxapi/rest/serializers.py @@ -234,6 +234,29 @@ Order = _Serializer[typings.Order]("Order", labels=[ "META" ]) +Position = _Serializer[typings.Position]("Position", labels=[ + "SYMBOL", + "STATUS", + "AMOUNT", + "BASE_PRICE", + "FUNDING", + "FUNDING_TYPE", + "PL", + "PL_PERC", + "PRICE_LIQ", + "LEVERAGE", + "_PLACEHOLDER", + "POSITION_ID", + "MTS_CREATE", + "MTS_UPDATE", + "_PLACEHOLDER", + "TYPE", + "_PLACEHOLDER", + "COLLATERAL", + "COLLATERAL_MIN", + "META" +]) + FundingOffer = _Serializer[typings.FundingOffer]("FundingOffer", labels=[ "ID", "SYMBOL", @@ -273,6 +296,21 @@ Trade = _Serializer[typings.Trade]("Trade", labels=[ "CID" ]) +OrderTrade = _Serializer[typings.OrderTrade]("OrderTrade", labels=[ + "ID", + "PAIR", + "MTS_CREATE", + "ORDER_ID", + "EXEC_AMOUNT", + "EXEC_PRICE", + "_PLACEHOLDER", + "_PLACEHOLDER", + "MAKER", + "FEE", + "FEE_CURRENCY", + "CID" +]) + Ledger = _Serializer[typings.Ledger]("Ledger", labels=[ "ID", "CURRENCY", @@ -285,4 +323,29 @@ Ledger = _Serializer[typings.Ledger]("Ledger", labels=[ "DESCRIPTION" ]) +FundingCredit = _Serializer[typings.FundingCredit]("FundingCredit", labels=[ + "ID", + "SYMBOL", + "SIDE", + "MTS_CREATE", + "MTS_UPDATE", + "AMOUNT", + "FLAGS", + "STATUS", + "RATE_TYPE", + "_PLACEHOLDER", + "_PLACEHOLDER", + "RATE", + "PERIOD", + "MTS_OPENING", + "MTS_LAST_PAYOUT", + "NOTIFY", + "HIDDEN", + "_PLACEHOLDER", + "RENEW", + "_PLACEHOLDER", + "NO_CLOSE", + "POSITION_PAIR" +]) + #endregion \ No newline at end of file diff --git a/bfxapi/rest/typings.py b/bfxapi/rest/typings.py index 20b2eed..d9d37a7 100644 --- a/bfxapi/rest/typings.py +++ b/bfxapi/rest/typings.py @@ -169,6 +169,25 @@ class Order(TypedDict): ROUTING: str META: JSON +class Position(TypedDict): + SYMBOL: str + STATUS: str + AMOUNT: float + BASE_PRICE: float + MARGIN_FUNDING: float + MARGIN_FUNDING_TYPE: int + PL: float + PL_PERC: float + PRICE_LIQ: float + LEVERAGE: float + POSITION_ID: int + MTS_CREATE: int + MTS_UPDATE: int + TYPE: int + COLLATERAL: float + COLLATERAL_MIN: float + META: JSON + class FundingOffer(TypedDict): ID: int SYMBOL: str @@ -199,6 +218,18 @@ class Trade(TypedDict): FEE_CURRENCY: str CID: int +class OrderTrade(TypedDict): + ID: int + SYMBOL: str + MTS_CREATE: int + ORDER_ID: int + EXEC_AMOUNT: float + EXEC_PRICE: float + MAKER:int + FEE: float + FEE_CURRENCY: str + CID: int + class Ledger(TypedDict): ID: int CURRENCY: str @@ -207,4 +238,24 @@ class Ledger(TypedDict): BALANCE: float description: str +class FundingCredit(TypedDict): + ID: int + SYMBOL: str + SIDE: int + MTS_CREATE: int + MTS_UPDATE: int + AMOUNT: float + FLAGS: int + STATUS: str + RATE: float + PERIOD: int + MTS_OPENING: int + MTS_LAST_PAYOUT: int + NOTIFY: int + HIDDEN: int + RENEW: int + RATE_REAL: float + NO_CLOSE: int + POSITION_PAIR: str + #endregion \ No newline at end of file diff --git a/examples/rest/get_authenticated_data.py b/examples/rest/get_authenticated_data.py new file mode 100644 index 0000000..881cbf6 --- /dev/null +++ b/examples/rest/get_authenticated_data.py @@ -0,0 +1,101 @@ +# python -c "from examples.rest.get_authenticated_data import *" + +import os +import time + +from bfxapi.client import Client, Constants + +bfx = Client( + REST_HOST=Constants.REST_HOST, + API_KEY=os.getenv("BFX_API_KEY"), + API_SECRET=os.getenv("BFX_API_SECRET") +) + +now = int(round(time.time() * 1000)) + +def log_wallets(): + wallets = bfx.rest.auth.get_wallets() + print("Wallets:") + [print(w) for w in wallets] + + +def log_orders(): + orders = bfx.rest.auth.get_orders(symbol='tBTCUSD') + print("Orders:") + [print(o) for o in orders] + + +def log_orders_history(): + orders = bfx.rest.auth.get_orders_history(symbol='tBTCUSD', start=0, end=now) + print("Orders:") + [print(o) for o in orders] + + +def log_positions(): + positions = bfx.rest.auth.get_positions() + print("Positions:") + [print(p) for p in positions] + + +def log_trades(): + trades = bfx.rest.auth.get_trades(symbol='tBTCUSD', start=0, end=now) + print("Trades:") + [print(t) for t in trades] + + +def log_order_trades(): + order_id = 82406909127 + trades = bfx.rest.auth.get_order_trades(symbol='tBTCUSD', order_id=order_id) + print("Trade orders:") + [print(t) for t in trades] + + +def log_funding_offers(): + offers = bfx.rest.auth.get_funding_offers(symbol='fUSD') + print("Offers:") + [print(o) for o in offers] + + +def log_funding_offer_history(): + offers = bfx.rest.auth.get_funding_offers_history(symbol='fUSD', start=0, end=now) + print("Offers history:") + [print(o) for o in offers] + + +def log_funding_loans(): + loans = bfx.rest.auth.get_funding_loans(symbol='fUSD') + print("Funding loans:") + [print(l) for l in loans] + + +def log_funding_loans_history(): + loans = bfx.rest.auth.get_funding_loan_history(symbol='fUSD', start=0, end=now) + print("Funding loan history:") + [print(l) for l in loans] + + +def log_funding_credits(): + credits = bfx.rest.auth.get_funding_credits(symbol='fUSD') + print("Funding credits:") + [print(c) for c in credits] + + +def log_funding_credits_history(): + credit = bfx.rest.auth.get_funding_credits_history(symbol='fUSD', start=0, end=now) + print("Funding credit history:") + [print(c) for c in credit] + + +def run(): + log_wallets() + log_orders() + log_orders_history() + log_positions() + log_trades() + log_order_trades() + log_funding_offers() + log_funding_offer_history() + log_funding_credits() + log_funding_credits_history() + +run() \ No newline at end of file