Merge pull request #24 from Davi0kProgramsThings/fix/refactoring

Merge branch `fix/refactoring` into branch `feature/rest`.
This commit is contained in:
Davide Casale
2023-01-27 17:24:43 +01:00
committed by Davide Casale
19 changed files with 1645 additions and 1580 deletions

View File

@@ -8,16 +8,16 @@ T = TypeVar("T")
@dataclass
class Notification(_Type, Generic[T]):
MTS: int
TYPE: str
MESSAGE_ID: Optional[int]
NOTIFY_INFO: T
CODE: Optional[int]
STATUS: str
TEXT: str
mts: int
type: str
message_id: Optional[int]
notify_info: T
code: Optional[int]
status: str
text: str
class _Notification(_Serializer, Generic[T]):
__LABELS = [ "MTS", "TYPE", "MESSAGE_ID", "_PLACEHOLDER", "NOTIFY_INFO", "CODE", "STATUS", "TEXT" ]
__LABELS = [ "mts", "type", "message_id", "_PLACEHOLDER", "notify_info", "code", "status", "text" ]
def __init__(self, serializer: Optional[_Serializer] = None, iterate: bool = False):
super().__init__("Notification", Notification, _Notification.__LABELS, IGNORE = [ "_PLACEHOLDER" ])
@@ -28,13 +28,13 @@ class _Notification(_Serializer, Generic[T]):
notification = cast(Notification[T], Notification(**dict(self._serialize(*values))))
if isinstance(self.serializer, _Serializer):
NOTIFY_INFO = cast(List[Any], notification.NOTIFY_INFO)
NOTIFY_INFO = cast(List[Any], notification.notify_info)
if self.iterate == False:
if len(NOTIFY_INFO) == 1 and isinstance(NOTIFY_INFO[0], list):
NOTIFY_INFO = NOTIFY_INFO[0]
notification.NOTIFY_INFO = cast(T, self.serializer.klass(**dict(self.serializer._serialize(*NOTIFY_INFO, skip=skip))))
else: notification.NOTIFY_INFO = cast(T, [ self.serializer.klass(**dict(self.serializer._serialize(*data, skip=skip))) for data in NOTIFY_INFO ])
notification.notify_info = cast(T, self.serializer.klass(**dict(self.serializer._serialize(*NOTIFY_INFO, skip=skip))))
else: notification.notify_info = cast(T, [ self.serializer.klass(**dict(self.serializer._serialize(*data, skip=skip))) for data in NOTIFY_INFO ])
return notification

View File

@@ -1,527 +1,13 @@
import time, hmac, hashlib, json, requests
from typing import Optional
from decimal import Decimal
from datetime import datetime
from http import HTTPStatus
from ._RestPublicEndpoints import _RestPublicEndpoints
from typing import List, Union, Literal, Optional, Any, cast
from . import serializers
from .types import *
from .enums import Config, Sort, OrderType, FundingOfferType, Error
from .exceptions import ResourceNotFound, RequestParametersError, InvalidAuthenticationCredentials, UnknownGenericError
from .. utils.encoder import JSONEncoder
from ._RestAuthenticatedEndpoints import _RestAuthenticatedEndpoints
class BfxRestInterface(object):
def __init__(self, host, API_KEY = None, API_SECRET = None):
VERSION = 2
def __init__(self, host: str, API_KEY: Optional[str] = None, API_SECRET: Optional[str] = None):
self.public = _RestPublicEndpoints(host=host)
self.auth = _RestAuthenticatedEndpoints(host=host, API_KEY=API_KEY, API_SECRET=API_SECRET)
class _Requests(object):
def __init__(self, host, API_KEY = None, API_SECRET = None):
self.host, self.API_KEY, self.API_SECRET = host, API_KEY, API_SECRET
def __build_authentication_headers(self, endpoint, data):
nonce = str(int(time.time()) * 1000)
path = f"/api/v2/{endpoint}{nonce}"
if data != None: path += data
signature = hmac.new(
self.API_SECRET.encode("utf8"),
path.encode("utf8"),
hashlib.sha384
).hexdigest()
return {
"bfx-nonce": nonce,
"bfx-signature": signature,
"bfx-apikey": self.API_KEY
}
def _GET(self, endpoint, params = None):
response = requests.get(f"{self.host}/{endpoint}", params=params)
if response.status_code == HTTPStatus.NOT_FOUND:
raise ResourceNotFound(f"No resources found at endpoint <{endpoint}>.")
data = response.json()
if len(data) and data[0] == "error":
if data[1] == Error.ERR_PARAMS:
raise RequestParametersError(f"The request was rejected with the following parameter error: <{data[2]}>")
if data[1] == None or data[1] == Error.ERR_UNK or data[1] == Error.ERR_GENERIC:
raise UnknownGenericError(f"The server replied to the request with a generic error with message: <{data[2]}>.")
return data
def _POST(self, endpoint, params = None, data = None):
headers = { "Content-Type": "application/json" }
if isinstance(data, dict):
data = json.dumps({ key: value for key, value in data.items() if value != None}, cls=JSONEncoder)
if self.API_KEY and self.API_SECRET:
headers = { **headers, **self.__build_authentication_headers(endpoint, data) }
response = requests.post(f"{self.host}/{endpoint}", params=params, data=data, headers=headers)
if response.status_code == HTTPStatus.NOT_FOUND:
raise ResourceNotFound(f"No resources found at endpoint <{endpoint}>.")
data = response.json()
if len(data) and data[0] == "error":
if data[1] == Error.ERR_PARAMS:
raise RequestParametersError(f"The request was rejected with the following parameter error: <{data[2]}>")
if data[1] == Error.ERR_AUTH_FAIL:
raise InvalidAuthenticationCredentials("Cannot authenticate with given API-KEY and API-SECRET.")
if data[1] == None or data[1] == Error.ERR_UNK or data[1] == Error.ERR_GENERIC:
raise UnknownGenericError(f"The server replied to the request with a generic error with message: <{data[2]}>.")
return data
class _RestPublicEndpoints(_Requests):
def get_platform_status(self) -> PlatformStatus:
return serializers.PlatformStatus.parse(*self._GET("platform/status"))
def get_tickers(self, symbols: List[str]) -> List[Union[TradingPairTicker, FundingCurrencyTicker]]:
data = self._GET("tickers", params={ "symbols": ",".join(symbols) })
parsers = { "t": serializers.TradingPairTicker.parse, "f": serializers.FundingCurrencyTicker.parse }
return [ cast(Union[TradingPairTicker, FundingCurrencyTicker], parsers[sub_data[0][0]](*sub_data)) for sub_data in data ]
def get_t_tickers(self, pairs: Union[List[str], Literal["ALL"]]) -> List[TradingPairTicker]:
if isinstance(pairs, str) and pairs == "ALL":
return [ cast(TradingPairTicker, sub_data) for sub_data in self.get_tickers([ "ALL" ]) if cast(str, sub_data.SYMBOL).startswith("t") ]
data = self.get_tickers([ "t" + pair for pair in pairs ])
return cast(List[TradingPairTicker], data)
def get_f_tickers(self, currencies: Union[List[str], Literal["ALL"]]) -> List[FundingCurrencyTicker]:
if isinstance(currencies, str) and currencies == "ALL":
return [ cast(FundingCurrencyTicker, sub_data) for sub_data in self.get_tickers([ "ALL" ]) if cast(str, sub_data.SYMBOL).startswith("f") ]
data = self.get_tickers([ "f" + currency for currency in currencies ])
return cast(List[FundingCurrencyTicker], data)
def get_t_ticker(self, pair: str) -> TradingPairTicker:
return serializers.TradingPairTicker.parse(*self._GET(f"ticker/t{pair}"), skip=["SYMBOL"])
def get_f_ticker(self, currency: str) -> FundingCurrencyTicker:
return serializers.FundingCurrencyTicker.parse(*self._GET(f"ticker/f{currency}"), skip=["SYMBOL"])
def get_tickers_history(self, symbols: List[str], start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[TickersHistory]:
params = {
"symbols": ",".join(symbols),
"start": start, "end": end,
"limit": limit
}
data = self._GET("tickers/hist", params=params)
return [ serializers.TickersHistory.parse(*sub_data) for sub_data in data ]
def get_t_trades(self, pair: str, limit: Optional[int] = None, start: Optional[str] = None, end: Optional[str] = None, sort: Optional[Sort] = None) -> List[TradingPairTrade]:
params = { "limit": limit, "start": start, "end": end, "sort": sort }
data = self._GET(f"trades/{'t' + pair}/hist", params=params)
return [ serializers.TradingPairTrade.parse(*sub_data) for sub_data in data ]
def get_f_trades(self, currency: str, limit: Optional[int] = None, start: Optional[str] = None, end: Optional[str] = None, sort: Optional[Sort] = None) -> List[FundingCurrencyTrade]:
params = { "limit": limit, "start": start, "end": end, "sort": sort }
data = self._GET(f"trades/{'f' + currency}/hist", params=params)
return [ serializers.FundingCurrencyTrade.parse(*sub_data) for sub_data in data ]
def get_t_book(self, pair: str, precision: Literal["P0", "P1", "P2", "P3", "P4"], len: Optional[Literal[1, 25, 100]] = None) -> List[TradingPairBook]:
return [ serializers.TradingPairBook.parse(*sub_data) for sub_data in self._GET(f"book/{'t' + pair}/{precision}", params={ "len": len }) ]
def get_f_book(self, currency: str, precision: Literal["P0", "P1", "P2", "P3", "P4"], len: Optional[Literal[1, 25, 100]] = None) -> List[FundingCurrencyBook]:
return [ serializers.FundingCurrencyBook.parse(*sub_data) for sub_data in self._GET(f"book/{'f' + currency}/{precision}", params={ "len": len }) ]
def get_t_raw_book(self, pair: str, len: Optional[Literal[1, 25, 100]] = None) -> List[TradingPairRawBook]:
return [ serializers.TradingPairRawBook.parse(*sub_data) for sub_data in self._GET(f"book/{'t' + pair}/R0", params={ "len": len }) ]
def get_f_raw_book(self, currency: str, len: Optional[Literal[1, 25, 100]] = None) -> List[FundingCurrencyRawBook]:
return [ serializers.FundingCurrencyRawBook.parse(*sub_data) for sub_data in self._GET(f"book/{'f' + currency}/R0", params={ "len": len }) ]
def get_stats_hist(
self,
resource: str,
sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None
) -> List[Statistic]:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET(f"stats1/{resource}/hist", params=params)
return [ serializers.Statistic.parse(*sub_data) for sub_data in data ]
def get_stats_last(
self,
resource: str,
sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None
) -> Statistic:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET(f"stats1/{resource}/last", params=params)
return serializers.Statistic.parse(*data)
def get_candles_hist(
self,
symbol: str, tf: str = "1m",
sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None
) -> List[Candle]:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET(f"candles/trade:{tf}:{symbol}/hist", params=params)
return [ serializers.Candle.parse(*sub_data) for sub_data in data ]
def get_candles_last(
self,
symbol: str, tf: str = "1m",
sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None
) -> Candle:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET(f"candles/trade:{tf}:{symbol}/last", params=params)
return serializers.Candle.parse(*data)
def get_derivatives_status(self, keys: Union[List[str], Literal["ALL"]]) -> List[DerivativesStatus]:
if keys == "ALL":
params = { "keys": "ALL" }
else: params = { "keys": ",".join(keys) }
data = self._GET(f"status/deriv", params=params)
return [ serializers.DerivativesStatus.parse(*sub_data) for sub_data in data ]
def get_derivatives_status_history(
self,
type: str, symbol: str,
sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None
) -> List[DerivativesStatus]:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET(f"status/{type}/{symbol}/hist", params=params)
return [ serializers.DerivativesStatus.parse(*sub_data, skip=[ "KEY" ]) for sub_data in data ]
def get_liquidations(self, sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[Liquidation]:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET("liquidations/hist", params=params)
return [ serializers.Liquidation.parse(*sub_data[0]) for sub_data in data ]
def get_seed_candles(self, symbol: str, tf: str = '1m', sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[Candle]:
params = {"sort": sort, "start": start, "end": end, "limit": limit}
data = self._GET(f"candles/trade:{tf}:{symbol}/hist?limit={limit}&start={start}&end={end}&sort={sort}", params=params)
return [ serializers.Candle.parse(*sub_data) for sub_data in data ]
def get_leaderboards_hist(
self,
resource: str,
sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None
) -> List[Leaderboard]:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET(f"rankings/{resource}/hist", params=params)
return [ serializers.Leaderboard.parse(*sub_data) for sub_data in data ]
def get_leaderboards_last(
self,
resource: str,
sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None
) -> Leaderboard:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET(f"rankings/{resource}/last", params=params)
return serializers.Leaderboard.parse(*data)
def get_funding_stats(self, symbol: str, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[FundingStatistic]:
params = { "start": start, "end": end, "limit": limit }
data = self._GET(f"funding/stats/{symbol}/hist", params=params)
return [ serializers.FundingStatistic.parse(*sub_data) for sub_data in data ]
def conf(self, config: Config) -> Any:
return self._GET(f"conf/{config}")[0]
def get_pulse_profile(self, nickname: str) -> PulseProfile:
return serializers.PulseProfile.parse(*self._GET(f"pulse/profile/{nickname}"))
def get_pulse_history(self, end: Optional[str] = None, limit: Optional[int] = None) -> List[PulseMessage]:
messages = list()
for subdata in self._GET("pulse/hist", params={ "end": end, "limit": limit }):
subdata[18] = subdata[18][0]
message = serializers.PulseMessage.parse(*subdata)
messages.append(message)
return messages
def get_trading_market_average_price(self, symbol: str, amount: Union[Decimal, float, str], price_limit: Optional[Union[Decimal, float, str]] = None) -> TradingMarketAveragePrice:
data = {
"symbol": symbol, "amount": amount, "price_limit": price_limit
}
return serializers.TradingMarketAveragePrice.parse(*self._POST("calc/trade/avg", data=data))
def get_funding_market_average_price(self, symbol: str, amount: Union[Decimal, float, str], period: int, rate_limit: Optional[Union[Decimal, float, str]] = None) -> FundingMarketAveragePrice:
data = {
"symbol": symbol, "amount": amount, "period": period,
"rate_limit": rate_limit
}
return serializers.FundingMarketAveragePrice.parse(*self._POST("calc/trade/avg", data=data))
def get_fx_rate(self, ccy1: str, ccy2: str) -> FxRate:
return serializers.FxRate.parse(*self._POST("calc/fx", data={ "ccy1": ccy1, "ccy2": ccy2 }))
class _RestAuthenticatedEndpoints(_Requests):
def get_wallets(self) -> List[Wallet]:
return [ serializers.Wallet.parse(*sub_data) for sub_data in self._POST("auth/r/wallets") ]
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(*sub_data) for sub_data in self._POST(endpoint, data={ "id": ids }) ]
def get_positions(self) -> List[Position]:
return [ serializers.Position.parse(*sub_data) for sub_data in self._POST("auth/r/positions") ]
def submit_order(self, type: OrderType, symbol: str, amount: Union[Decimal, float, str],
price: Optional[Union[Decimal, float, str]] = None, lev: Optional[int] = None,
price_trailing: Optional[Union[Decimal, float, str]] = None, price_aux_limit: Optional[Union[Decimal, float, str]] = None, price_oco_stop: Optional[Union[Decimal, float, str]] = None,
gid: Optional[int] = None, cid: Optional[int] = None,
flags: Optional[int] = 0, tif: Optional[Union[datetime, str]] = None, meta: Optional[JSON] = None) -> Notification[Order]:
data = {
"type": type, "symbol": symbol, "amount": amount,
"price": price, "lev": lev,
"price_trailing": price_trailing, "price_aux_limit": price_aux_limit, "price_oco_stop": price_oco_stop,
"gid": gid, "cid": cid,
"flags": flags, "tif": tif, "meta": meta
}
return serializers._Notification[Order](serializer=serializers.Order).parse(*self._POST("auth/w/order/submit", data=data))
def update_order(self, id: int, amount: Optional[Union[Decimal, float, str]] = None, price: Optional[Union[Decimal, float, str]] = None,
cid: Optional[int] = None, cid_date: Optional[str] = None, gid: Optional[int] = None,
flags: Optional[int] = 0, lev: Optional[int] = None, delta: Optional[Union[Decimal, float, str]] = None,
price_aux_limit: Optional[Union[Decimal, float, str]] = None, price_trailing: Optional[Union[Decimal, float, str]] = None, tif: Optional[Union[datetime, str]] = None) -> Notification[Order]:
data = {
"id": id, "amount": amount, "price": price,
"cid": cid, "cid_date": cid_date, "gid": gid,
"flags": flags, "lev": lev, "delta": delta,
"price_aux_limit": price_aux_limit, "price_trailing": price_trailing, "tif": tif
}
return serializers._Notification[Order](serializer=serializers.Order).parse(*self._POST("auth/w/order/update", data=data))
def cancel_order(self, id: Optional[int] = None, cid: Optional[int] = None, cid_date: Optional[str] = None) -> Notification[Order]:
data = {
"id": id,
"cid": cid,
"cid_date": cid_date
}
return serializers._Notification[Order](serializer=serializers.Order).parse(*self._POST("auth/w/order/cancel", data=data))
def cancel_order_multi(self, ids: Optional[List[int]] = None, cids: Optional[List[Tuple[int, str]]] = None, gids: Optional[List[int]] = None, all: bool = False) -> Notification[List[Order]]:
data = {
"ids": ids,
"cids": cids,
"gids": gids,
"all": int(all)
}
return serializers._Notification[List[Order]](serializer=serializers.Order, iterate=True).parse(*self._POST("auth/w/order/cancel/multi", data=data))
def get_orders_history(self, symbol: Optional[str] = None, ids: Optional[List[int]] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[Order]:
if symbol == None:
endpoint = "auth/r/orders/hist"
else: endpoint = f"auth/r/orders/{symbol}/hist"
data = {
"id": ids,
"start": start, "end": end,
"limit": limit
}
return [ serializers.Order.parse(*sub_data) for sub_data in self._POST(endpoint, data=data) ]
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(*sub_data) for sub_data in self._POST(endpoint, data=data) ]
def get_order_trades(self, symbol: str, id: int) -> List[OrderTrade]:
return [ serializers.OrderTrade.parse(*sub_data) for sub_data 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 = {
"category": category,
"start": start, "end": end,
"limit": limit
}
return [ serializers.Ledger.parse(*sub_data) for sub_data in self._POST(f"auth/r/ledgers/{currency}/hist", data=data) ]
def get_funding_offers(self, symbol: Optional[str] = None) -> List[FundingOffer]:
endpoint = "auth/r/funding/offers"
if symbol != None:
endpoint += f"/{symbol}"
return [ serializers.FundingOffer.parse(*sub_data) for sub_data in self._POST(endpoint) ]
def submit_funding_offer(self, type: FundingOfferType, symbol: str, amount: Union[Decimal, float, str],
rate: Union[Decimal, float, str], period: int,
flags: Optional[int] = 0) -> Notification[FundingOffer]:
data = {
"type": type, "symbol": symbol, "amount": amount,
"rate": rate, "period": period,
"flags": flags
}
return serializers._Notification[FundingOffer](serializer=serializers.FundingOffer).parse(*self._POST("auth/w/funding/offer/submit", data=data))
def cancel_funding_offer(self, id: int) -> Notification[FundingOffer]:
return serializers._Notification[FundingOffer](serializer=serializers.FundingOffer).parse(*self._POST("auth/w/funding/offer/cancel", data={ "id": id }))
def cancel_all_funding_offers(self, currency: str) -> Notification:
return serializers._Notification().parse(*self._POST("auth/w/funding/offer/cancel/all", data={ "currency": currency }))
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(*sub_data) for sub_data 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(*sub_data) for sub_data 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(*sub_data) for sub_data in self._POST(endpoint, data=data) ]
def submit_wallet_transfer(self, from_wallet: str, to_wallet: str, currency: str, currency_to: str, amount: Union[Decimal, float, str]) -> Notification[Transfer]:
data = {
"from": from_wallet, "to": to_wallet,
"currency": currency, "currency_to": currency_to,
"amount": amount
}
return serializers._Notification[Transfer](serializer=serializers.Transfer).parse(*self._POST("auth/w/transfer", data=data))
def submit_wallet_withdraw(self, wallet: str, method: str, address: str, amount: Union[Decimal, float, str]) -> Notification[Withdrawal]:
data = {
"wallet": wallet, "method": method,
"address": address, "amount": amount,
}
return serializers._Notification[Withdrawal](serializer=serializers.Withdrawal).parse(*self._POST("auth/w/withdraw", data=data))
def get_deposit_address(self, wallet: str, method: str, renew: bool = False) -> Notification[DepositAddress]:
data = {
"wallet": wallet,
"method": method,
"renew": int(renew)
}
return serializers._Notification[DepositAddress](serializer=serializers.DepositAddress).parse(*self._POST("auth/w/deposit/address", data=data))
def get_deposit_invoice(self, wallet: str, currency: str, amount: Union[Decimal, float, str]) -> Invoice:
data = {
"wallet": wallet, "currency": currency,
"amount": amount
}
return serializers.Invoice.parse(*self._POST("auth/w/deposit/invoice", data=data))
def get_movements(self, currency: Optional[str] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[Movement]:
if currency == None:
endpoint = "auth/r/movements/hist"
else: endpoint = f"auth/r/movements/{currency}/hist"
data = {
"start": start, "end": end,
"limit": limit
}
return [ serializers.Movement.parse(*sub_data) for sub_data in self._POST(endpoint, data=data) ]
def get_symbol_margin_info(self, symbol: str) -> SymbolMarginInfo:
response = self._POST(f"auth/r/info/margin/{symbol}")
return serializers.SymbolMarginInfo.parse(*([response[1]] + response[2]))
def get_all_symbols_margin_info(self) -> List[SymbolMarginInfo]:
return [ serializers.SymbolMarginInfo.parse(*([sub_data[1]] + sub_data[2])) for sub_data in self._POST(f"auth/r/info/margin/sym_all") ]
def get_base_margin_info(self) -> BaseMarginInfo:
return serializers.BaseMarginInfo.parse(*(self._POST(f"auth/r/info/margin/base")[1]))
def claim_position(self, id: int, amount: Optional[Union[Decimal, float, str]] = None) -> Notification[Claim]:
return serializers._Notification[Claim](serializer=serializers.Claim).parse(*self._POST("auth/w/position/claim", data={ "id": id, "amount": amount }))
def get_increase_position_info(self, symbol: str, amount: Union[Decimal, float, str]) -> IncreaseInfo:
response = self._POST(f"auth/r/position/increase/info", data={ "symbol": symbol, "amount": amount })
return serializers.IncreaseInfo.parse(*(
response[0] + [response[1][0]] + response[1][1] + [response[1][2]] + response[4] + response[5]
))
def increase_position(self, symbol: str, amount: Union[Decimal, float, str]) -> Notification[Increase]:
return serializers._Notification[Increase](serializer=serializers.Increase).parse(*self._POST("auth/w/position/increase", data={ "symbol": symbol, "amount": amount }))
def get_positions_history(self, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[PositionHistory]:
return [ serializers.PositionHistory.parse(*sub_data) for sub_data in self._POST("auth/r/positions/hist", data={ "start": start, "end": end, "limit": limit }) ]
def get_positions_snapshot(self, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[PositionSnapshot]:
return [ serializers.PositionSnapshot.parse(*sub_data) for sub_data in self._POST("auth/r/positions/snap", data={ "start": start, "end": end, "limit": limit }) ]
def get_positions_audit(self, ids: Optional[List[int]] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[PositionAudit]:
return [ serializers.PositionAudit.parse(*sub_data) for sub_data in self._POST("auth/r/positions/audit", data={ "ids": ids, "start": start, "end": end, "limit": limit }) ]
def set_derivative_position_collateral(self, symbol: str, collateral: Union[Decimal, float, str]) -> DerivativePositionCollateral:
return serializers.DerivativePositionCollateral.parse(*(self._POST("auth/w/deriv/collateral/set", data={ "symbol": symbol, "collateral": collateral })[0]))
def get_derivative_position_collateral_limits(self, symbol: str) -> DerivativePositionCollateralLimits:
return serializers.DerivativePositionCollateralLimits.parse(*self._POST("auth/calc/deriv/collateral/limits", data={ "symbol": symbol }))
self.auth = _RestAuthenticatedEndpoints(host=host, API_KEY=API_KEY, API_SECRET=API_SECRET)

75
bfxapi/rest/_Requests.py Normal file
View File

@@ -0,0 +1,75 @@
import time, hmac, hashlib, json, requests
from http import HTTPStatus
from .enums import Error
from .exceptions import ResourceNotFound, RequestParametersError, InvalidAuthenticationCredentials, UnknownGenericError
from .. utils.encoder import JSONEncoder
class _Requests(object):
def __init__(self, host, API_KEY = None, API_SECRET = None):
self.host, self.API_KEY, self.API_SECRET = host, API_KEY, API_SECRET
def __build_authentication_headers(self, endpoint, data):
nonce = str(int(time.time()) * 1000)
path = f"/api/v2/{endpoint}{nonce}"
if data != None: path += data
signature = hmac.new(
self.API_SECRET.encode("utf8"),
path.encode("utf8"),
hashlib.sha384
).hexdigest()
return {
"bfx-nonce": nonce,
"bfx-signature": signature,
"bfx-apikey": self.API_KEY
}
def _GET(self, endpoint, params = None):
response = requests.get(f"{self.host}/{endpoint}", params=params)
if response.status_code == HTTPStatus.NOT_FOUND:
raise ResourceNotFound(f"No resources found at endpoint <{endpoint}>.")
data = response.json()
if len(data) and data[0] == "error":
if data[1] == Error.ERR_PARAMS:
raise RequestParametersError(f"The request was rejected with the following parameter error: <{data[2]}>")
if data[1] == None or data[1] == Error.ERR_UNK or data[1] == Error.ERR_GENERIC:
raise UnknownGenericError(f"The server replied to the request with a generic error with message: <{data[2]}>.")
return data
def _POST(self, endpoint, params = None, data = None, _ignore_authentication_headers = False):
headers = { "Content-Type": "application/json" }
if isinstance(data, dict):
data = json.dumps({ key: value for key, value in data.items() if value != None}, cls=JSONEncoder)
if self.API_KEY and self.API_SECRET and _ignore_authentication_headers == False:
headers = { **headers, **self.__build_authentication_headers(endpoint, data) }
response = requests.post(f"{self.host}/{endpoint}", params=params, data=data, headers=headers)
if response.status_code == HTTPStatus.NOT_FOUND:
raise ResourceNotFound(f"No resources found at endpoint <{endpoint}>.")
data = response.json()
if len(data) and data[0] == "error":
if data[1] == Error.ERR_PARAMS:
raise RequestParametersError(f"The request was rejected with the following parameter error: <{data[2]}>")
if data[1] == Error.ERR_AUTH_FAIL:
raise InvalidAuthenticationCredentials("Cannot authenticate with given API-KEY and API-SECRET.")
if data[1] == None or data[1] == Error.ERR_UNK or data[1] == Error.ERR_GENERIC:
raise UnknownGenericError(f"The server replied to the request with a generic error with message: <{data[2]}>.")
return data

View File

@@ -0,0 +1,272 @@
from typing import List, Union, Literal, Optional, Any, cast
from .types import *
from . import serializers
from .enums import Config, Sort, OrderType, FundingOfferType
from decimal import Decimal
from datetime import datetime
from ._Requests import _Requests
class _RestAuthenticatedEndpoints(_Requests):
def get_wallets(self) -> List[Wallet]:
return [ serializers.Wallet.parse(*sub_data) for sub_data in self._POST("auth/r/wallets") ]
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(*sub_data) for sub_data in self._POST(endpoint, data={ "id": ids }) ]
def get_positions(self) -> List[Position]:
return [ serializers.Position.parse(*sub_data) for sub_data in self._POST("auth/r/positions") ]
def submit_order(self, type: OrderType, symbol: str, amount: Union[Decimal, float, str],
price: Optional[Union[Decimal, float, str]] = None, lev: Optional[int] = None,
price_trailing: Optional[Union[Decimal, float, str]] = None, price_aux_limit: Optional[Union[Decimal, float, str]] = None, price_oco_stop: Optional[Union[Decimal, float, str]] = None,
gid: Optional[int] = None, cid: Optional[int] = None,
flags: Optional[int] = 0, tif: Optional[Union[datetime, str]] = None, meta: Optional[JSON] = None) -> Notification[Order]:
data = {
"type": type, "symbol": symbol, "amount": amount,
"price": price, "lev": lev,
"price_trailing": price_trailing, "price_aux_limit": price_aux_limit, "price_oco_stop": price_oco_stop,
"gid": gid, "cid": cid,
"flags": flags, "tif": tif, "meta": meta
}
return serializers._Notification[Order](serializer=serializers.Order).parse(*self._POST("auth/w/order/submit", data=data))
def update_order(self, id: int, amount: Optional[Union[Decimal, float, str]] = None, price: Optional[Union[Decimal, float, str]] = None,
cid: Optional[int] = None, cid_date: Optional[str] = None, gid: Optional[int] = None,
flags: Optional[int] = 0, lev: Optional[int] = None, delta: Optional[Union[Decimal, float, str]] = None,
price_aux_limit: Optional[Union[Decimal, float, str]] = None, price_trailing: Optional[Union[Decimal, float, str]] = None, tif: Optional[Union[datetime, str]] = None) -> Notification[Order]:
data = {
"id": id, "amount": amount, "price": price,
"cid": cid, "cid_date": cid_date, "gid": gid,
"flags": flags, "lev": lev, "delta": delta,
"price_aux_limit": price_aux_limit, "price_trailing": price_trailing, "tif": tif
}
return serializers._Notification[Order](serializer=serializers.Order).parse(*self._POST("auth/w/order/update", data=data))
def cancel_order(self, id: Optional[int] = None, cid: Optional[int] = None, cid_date: Optional[str] = None) -> Notification[Order]:
data = {
"id": id,
"cid": cid,
"cid_date": cid_date
}
return serializers._Notification[Order](serializer=serializers.Order).parse(*self._POST("auth/w/order/cancel", data=data))
def cancel_order_multi(self, ids: Optional[List[int]] = None, cids: Optional[List[Tuple[int, str]]] = None, gids: Optional[List[int]] = None, all: bool = False) -> Notification[List[Order]]:
data = {
"ids": ids,
"cids": cids,
"gids": gids,
"all": int(all)
}
return serializers._Notification[List[Order]](serializer=serializers.Order, iterate=True).parse(*self._POST("auth/w/order/cancel/multi", data=data))
def get_orders_history(self, symbol: Optional[str] = None, ids: Optional[List[int]] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[Order]:
if symbol == None:
endpoint = "auth/r/orders/hist"
else: endpoint = f"auth/r/orders/{symbol}/hist"
data = {
"id": ids,
"start": start, "end": end,
"limit": limit
}
return [ serializers.Order.parse(*sub_data) for sub_data in self._POST(endpoint, data=data) ]
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(*sub_data) for sub_data in self._POST(endpoint, data=data) ]
def get_order_trades(self, symbol: str, id: int) -> List[OrderTrade]:
return [ serializers.OrderTrade.parse(*sub_data) for sub_data 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 = {
"category": category,
"start": start, "end": end,
"limit": limit
}
return [ serializers.Ledger.parse(*sub_data) for sub_data in self._POST(f"auth/r/ledgers/{currency}/hist", data=data) ]
def get_funding_offers(self, symbol: Optional[str] = None) -> List[FundingOffer]:
endpoint = "auth/r/funding/offers"
if symbol != None:
endpoint += f"/{symbol}"
return [ serializers.FundingOffer.parse(*sub_data) for sub_data in self._POST(endpoint) ]
def submit_funding_offer(self, type: FundingOfferType, symbol: str, amount: Union[Decimal, float, str],
rate: Union[Decimal, float, str], period: int,
flags: Optional[int] = 0) -> Notification[FundingOffer]:
data = {
"type": type, "symbol": symbol, "amount": amount,
"rate": rate, "period": period,
"flags": flags
}
return serializers._Notification[FundingOffer](serializer=serializers.FundingOffer).parse(*self._POST("auth/w/funding/offer/submit", data=data))
def cancel_funding_offer(self, id: int) -> Notification[FundingOffer]:
return serializers._Notification[FundingOffer](serializer=serializers.FundingOffer).parse(*self._POST("auth/w/funding/offer/cancel", data={ "id": id }))
def cancel_all_funding_offers(self, currency: str) -> Notification:
return serializers._Notification().parse(*self._POST("auth/w/funding/offer/cancel/all", data={ "currency": currency }))
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(*sub_data) for sub_data in self._POST(endpoint, data=data) ]
def get_funding_loans(self, symbol: Optional[str] = None) -> List[FundingLoan]:
if symbol == None:
endpoint = "auth/r/funding/loans"
else: endpoint = f"auth/r/funding/loans/{symbol}"
return [ serializers.FundingLoan.parse(*sub_data) for sub_data in self._POST(endpoint) ]
def get_funding_loans_history(self, symbol: Optional[str] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[FundingLoan]:
if symbol == None:
endpoint = "auth/r/funding/loans/hist"
else: endpoint = f"auth/r/funding/loans/{symbol}/hist"
data = {
"start": start, "end": end,
"limit": limit
}
return [ serializers.FundingLoan.parse(*sub_data) for sub_data 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(*sub_data) for sub_data 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(*sub_data) for sub_data in self._POST(endpoint, data=data) ]
def submit_wallet_transfer(self, from_wallet: str, to_wallet: str, currency: str, currency_to: str, amount: Union[Decimal, float, str]) -> Notification[Transfer]:
data = {
"from": from_wallet, "to": to_wallet,
"currency": currency, "currency_to": currency_to,
"amount": amount
}
return serializers._Notification[Transfer](serializer=serializers.Transfer).parse(*self._POST("auth/w/transfer", data=data))
def submit_wallet_withdraw(self, wallet: str, method: str, address: str, amount: Union[Decimal, float, str]) -> Notification[Withdrawal]:
data = {
"wallet": wallet, "method": method,
"address": address, "amount": amount,
}
return serializers._Notification[Withdrawal](serializer=serializers.Withdrawal).parse(*self._POST("auth/w/withdraw", data=data))
def get_deposit_address(self, wallet: str, method: str, renew: bool = False) -> Notification[DepositAddress]:
data = {
"wallet": wallet,
"method": method,
"renew": int(renew)
}
return serializers._Notification[DepositAddress](serializer=serializers.DepositAddress).parse(*self._POST("auth/w/deposit/address", data=data))
def get_deposit_invoice(self, wallet: str, currency: str, amount: Union[Decimal, float, str]) -> Invoice:
data = {
"wallet": wallet, "currency": currency,
"amount": amount
}
return serializers.Invoice.parse(*self._POST("auth/w/deposit/invoice", data=data))
def get_movements(self, currency: Optional[str] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[Movement]:
if currency == None:
endpoint = "auth/r/movements/hist"
else: endpoint = f"auth/r/movements/{currency}/hist"
data = {
"start": start, "end": end,
"limit": limit
}
return [ serializers.Movement.parse(*sub_data) for sub_data in self._POST(endpoint, data=data) ]
def get_symbol_margin_info(self, symbol: str) -> SymbolMarginInfo:
response = self._POST(f"auth/r/info/margin/{symbol}")
return serializers.SymbolMarginInfo.parse(*([response[1]] + response[2]))
def get_all_symbols_margin_info(self) -> List[SymbolMarginInfo]:
return [ serializers.SymbolMarginInfo.parse(*([sub_data[1]] + sub_data[2])) for sub_data in self._POST(f"auth/r/info/margin/sym_all") ]
def get_base_margin_info(self) -> BaseMarginInfo:
return serializers.BaseMarginInfo.parse(*(self._POST(f"auth/r/info/margin/base")[1]))
def claim_position(self, id: int, amount: Optional[Union[Decimal, float, str]] = None) -> Notification[Claim]:
return serializers._Notification[Claim](serializer=serializers.Claim).parse(*self._POST("auth/w/position/claim", data={ "id": id, "amount": amount }))
def get_increase_position_info(self, symbol: str, amount: Union[Decimal, float, str]) -> IncreaseInfo:
response = self._POST(f"auth/r/position/increase/info", data={ "symbol": symbol, "amount": amount })
return serializers.IncreaseInfo.parse(*(
response[0] + [response[1][0]] + response[1][1] + [response[1][2]] + response[4] + response[5]
))
def increase_position(self, symbol: str, amount: Union[Decimal, float, str]) -> Notification[Increase]:
return serializers._Notification[Increase](serializer=serializers.Increase).parse(*self._POST("auth/w/position/increase", data={ "symbol": symbol, "amount": amount }))
def get_positions_history(self, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[PositionHistory]:
return [ serializers.PositionHistory.parse(*sub_data) for sub_data in self._POST("auth/r/positions/hist", data={ "start": start, "end": end, "limit": limit }) ]
def get_positions_snapshot(self, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[PositionSnapshot]:
return [ serializers.PositionSnapshot.parse(*sub_data) for sub_data in self._POST("auth/r/positions/snap", data={ "start": start, "end": end, "limit": limit }) ]
def get_positions_audit(self, ids: Optional[List[int]] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[PositionAudit]:
return [ serializers.PositionAudit.parse(*sub_data) for sub_data in self._POST("auth/r/positions/audit", data={ "ids": ids, "start": start, "end": end, "limit": limit }) ]
def set_derivative_position_collateral(self, symbol: str, collateral: Union[Decimal, float, str]) -> DerivativePositionCollateral:
return serializers.DerivativePositionCollateral.parse(*(self._POST("auth/w/deriv/collateral/set", data={ "symbol": symbol, "collateral": collateral })[0]))
def get_derivative_position_collateral_limits(self, symbol: str) -> DerivativePositionCollateralLimits:
return serializers.DerivativePositionCollateralLimits.parse(*self._POST("auth/calc/deriv/collateral/limits", data={ "symbol": symbol }))

View File

@@ -0,0 +1,188 @@
from typing import List, Union, Literal, Optional, Any, cast
from .types import *
from . import serializers
from .enums import Config, Sort
from decimal import Decimal
from ._Requests import _Requests
class _RestPublicEndpoints(_Requests):
def conf(self, config: Config) -> Any:
return self._GET(f"conf/{config}")[0]
def get_platform_status(self) -> PlatformStatus:
return serializers.PlatformStatus.parse(*self._GET("platform/status"))
def get_tickers(self, symbols: List[str]) -> List[Union[TradingPairTicker, FundingCurrencyTicker]]:
data = self._GET("tickers", params={ "symbols": ",".join(symbols) })
parsers = { "t": serializers.TradingPairTicker.parse, "f": serializers.FundingCurrencyTicker.parse }
return [ cast(Union[TradingPairTicker, FundingCurrencyTicker], parsers[sub_data[0][0]](*sub_data)) for sub_data in data ]
def get_t_tickers(self, pairs: Union[List[str], Literal["ALL"]]) -> List[TradingPairTicker]:
if isinstance(pairs, str) and pairs == "ALL":
return [ cast(TradingPairTicker, sub_data) for sub_data in self.get_tickers([ "ALL" ]) if cast(str, sub_data.symbol).startswith("t") ]
data = self.get_tickers([ "t" + pair for pair in pairs ])
return cast(List[TradingPairTicker], data)
def get_f_tickers(self, currencies: Union[List[str], Literal["ALL"]]) -> List[FundingCurrencyTicker]:
if isinstance(currencies, str) and currencies == "ALL":
return [ cast(FundingCurrencyTicker, sub_data) for sub_data in self.get_tickers([ "ALL" ]) if cast(str, sub_data.symbol).startswith("f") ]
data = self.get_tickers([ "f" + currency for currency in currencies ])
return cast(List[FundingCurrencyTicker], data)
def get_t_ticker(self, pair: str) -> TradingPairTicker:
return serializers.TradingPairTicker.parse(*self._GET(f"ticker/t{pair}"), skip=["SYMBOL"])
def get_f_ticker(self, currency: str) -> FundingCurrencyTicker:
return serializers.FundingCurrencyTicker.parse(*self._GET(f"ticker/f{currency}"), skip=["SYMBOL"])
def get_tickers_history(self, symbols: List[str], start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[TickersHistory]:
return [ serializers.TickersHistory.parse(*sub_data) for sub_data in self._GET("tickers/hist", params={
"symbols": ",".join(symbols),
"start": start, "end": end,
"limit": limit
}) ]
def get_t_trades(self, pair: str, limit: Optional[int] = None, start: Optional[str] = None, end: Optional[str] = None, sort: Optional[Sort] = None) -> List[TradingPairTrade]:
params = { "limit": limit, "start": start, "end": end, "sort": sort }
data = self._GET(f"trades/{'t' + pair}/hist", params=params)
return [ serializers.TradingPairTrade.parse(*sub_data) for sub_data in data ]
def get_f_trades(self, currency: str, limit: Optional[int] = None, start: Optional[str] = None, end: Optional[str] = None, sort: Optional[Sort] = None) -> List[FundingCurrencyTrade]:
params = { "limit": limit, "start": start, "end": end, "sort": sort }
data = self._GET(f"trades/{'f' + currency}/hist", params=params)
return [ serializers.FundingCurrencyTrade.parse(*sub_data) for sub_data in data ]
def get_t_book(self, pair: str, precision: Literal["P0", "P1", "P2", "P3", "P4"], len: Optional[Literal[1, 25, 100]] = None) -> List[TradingPairBook]:
return [ serializers.TradingPairBook.parse(*sub_data) for sub_data in self._GET(f"book/{'t' + pair}/{precision}", params={ "len": len }) ]
def get_f_book(self, currency: str, precision: Literal["P0", "P1", "P2", "P3", "P4"], len: Optional[Literal[1, 25, 100]] = None) -> List[FundingCurrencyBook]:
return [ serializers.FundingCurrencyBook.parse(*sub_data) for sub_data in self._GET(f"book/{'f' + currency}/{precision}", params={ "len": len }) ]
def get_t_raw_book(self, pair: str, len: Optional[Literal[1, 25, 100]] = None) -> List[TradingPairRawBook]:
return [ serializers.TradingPairRawBook.parse(*sub_data) for sub_data in self._GET(f"book/{'t' + pair}/R0", params={ "len": len }) ]
def get_f_raw_book(self, currency: str, len: Optional[Literal[1, 25, 100]] = None) -> List[FundingCurrencyRawBook]:
return [ serializers.FundingCurrencyRawBook.parse(*sub_data) for sub_data in self._GET(f"book/{'f' + currency}/R0", params={ "len": len }) ]
def get_stats_hist(
self,
resource: str,
sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None
) -> List[Statistic]:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET(f"stats1/{resource}/hist", params=params)
return [ serializers.Statistic.parse(*sub_data) for sub_data in data ]
def get_stats_last(
self,
resource: str,
sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None
) -> Statistic:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET(f"stats1/{resource}/last", params=params)
return serializers.Statistic.parse(*data)
def get_candles_hist(
self,
symbol: str, tf: str = "1m",
sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None
) -> List[Candle]:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET(f"candles/trade:{tf}:{symbol}/hist", params=params)
return [ serializers.Candle.parse(*sub_data) for sub_data in data ]
def get_candles_last(
self,
symbol: str, tf: str = "1m",
sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None
) -> Candle:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET(f"candles/trade:{tf}:{symbol}/last", params=params)
return serializers.Candle.parse(*data)
def get_derivatives_status(self, keys: Union[List[str], Literal["ALL"]]) -> List[DerivativesStatus]:
if keys == "ALL":
params = { "keys": "ALL" }
else: params = { "keys": ",".join(keys) }
data = self._GET(f"status/deriv", params=params)
return [ serializers.DerivativesStatus.parse(*sub_data) for sub_data in data ]
def get_derivatives_status_history(
self,
type: str, symbol: str,
sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None
) -> List[DerivativesStatus]:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET(f"status/{type}/{symbol}/hist", params=params)
return [ serializers.DerivativesStatus.parse(*sub_data, skip=[ "KEY" ]) for sub_data in data ]
def get_liquidations(self, sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[Liquidation]:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET("liquidations/hist", params=params)
return [ serializers.Liquidation.parse(*sub_data[0]) for sub_data in data ]
def get_seed_candles(self, symbol: str, tf: str = '1m', sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[Candle]:
params = {"sort": sort, "start": start, "end": end, "limit": limit}
data = self._GET(f"candles/trade:{tf}:{symbol}/hist?limit={limit}&start={start}&end={end}&sort={sort}", params=params)
return [ serializers.Candle.parse(*sub_data) for sub_data in data ]
def get_leaderboards_hist(
self,
resource: str,
sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None
) -> List[Leaderboard]:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET(f"rankings/{resource}/hist", params=params)
return [ serializers.Leaderboard.parse(*sub_data) for sub_data in data ]
def get_leaderboards_last(
self,
resource: str,
sort: Optional[Sort] = None, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None
) -> Leaderboard:
params = { "sort": sort, "start": start, "end": end, "limit": limit }
data = self._GET(f"rankings/{resource}/last", params=params)
return serializers.Leaderboard.parse(*data)
def get_funding_stats(self, symbol: str, start: Optional[str] = None, end: Optional[str] = None, limit: Optional[int] = None) -> List[FundingStatistic]:
params = { "start": start, "end": end, "limit": limit }
data = self._GET(f"funding/stats/{symbol}/hist", params=params)
return [ serializers.FundingStatistic.parse(*sub_data) for sub_data in data ]
def get_pulse_profile(self, nickname: str) -> PulseProfile:
return serializers.PulseProfile.parse(*self._GET(f"pulse/profile/{nickname}"))
def get_pulse_history(self, end: Optional[str] = None, limit: Optional[int] = None) -> List[PulseMessage]:
messages = list()
for subdata in self._GET("pulse/hist", params={ "end": end, "limit": limit }):
subdata[18] = subdata[18][0]
message = serializers.PulseMessage.parse(*subdata)
messages.append(message)
return messages
def get_trading_market_average_price(self, symbol: str, amount: Union[Decimal, float, str], price_limit: Optional[Union[Decimal, float, str]] = None) -> TradingMarketAveragePrice:
return serializers.TradingMarketAveragePrice.parse(*self._POST("calc/trade/avg", data={
"symbol": symbol, "amount": amount, "price_limit": price_limit
}))
def get_funding_market_average_price(self, symbol: str, amount: Union[Decimal, float, str], period: int, rate_limit: Optional[Union[Decimal, float, str]] = None) -> FundingMarketAveragePrice:
return serializers.FundingMarketAveragePrice.parse(*self._POST("calc/trade/avg", data={
"symbol": symbol, "amount": amount, "period": period, "rate_limit": rate_limit
}))
def get_fx_rate(self, ccy1: str, ccy2: str) -> FxRate:
return serializers.FxRate.parse(*self._POST("calc/fx", data={ "ccy1": ccy1, "ccy2": ccy2 }))

View File

@@ -7,48 +7,48 @@ from .. notification import _Notification
#region Serializers definition for Rest Public Endpoints
PlatformStatus = generate_labeler_serializer("PlatformStatus", klass=types.PlatformStatus, labels=[
"STATUS"
"status"
])
TradingPairTicker = generate_labeler_serializer("TradingPairTicker", klass=types.TradingPairTicker, labels=[
"SYMBOL",
"BID",
"BID_SIZE",
"ASK",
"ASK_SIZE",
"DAILY_CHANGE",
"DAILY_CHANGE_RELATIVE",
"LAST_PRICE",
"VOLUME",
"HIGH",
"LOW"
"symbol",
"bid",
"bid_size",
"ask",
"ask_size",
"daily_change",
"daily_change_relative",
"last_price",
"volume",
"high",
"low"
])
FundingCurrencyTicker = generate_labeler_serializer("FundingCurrencyTicker", klass=types.FundingCurrencyTicker, labels=[
"SYMBOL",
"FRR",
"BID",
"BID_PERIOD",
"BID_SIZE",
"ASK",
"ASK_PERIOD",
"ASK_SIZE",
"DAILY_CHANGE",
"DAILY_CHANGE_RELATIVE",
"LAST_PRICE",
"VOLUME",
"HIGH",
"LOW",
"symbol",
"frr",
"bid",
"bid_period",
"bid_size",
"ask",
"ask_period",
"ask_size",
"daily_change",
"daily_change_relative",
"last_price",
"volume",
"high",
"low",
"_PLACEHOLDER",
"_PLACEHOLDER",
"FRR_AMOUNT_AVAILABLE"
"frr_amount_available"
])
TickersHistory = generate_labeler_serializer("TickersHistory", klass=types.TickersHistory, labels=[
"SYMBOL",
"BID",
"symbol",
"bid",
"_PLACEHOLDER",
"ASK",
"ask",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
@@ -57,191 +57,191 @@ TickersHistory = generate_labeler_serializer("TickersHistory", klass=types.Ticke
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"MTS"
"mts"
])
TradingPairTrade = generate_labeler_serializer("TradingPairTrade", klass=types.TradingPairTrade, labels=[
"ID",
"MTS",
"AMOUNT",
"PRICE"
"id",
"mts",
"amount",
"price"
])
FundingCurrencyTrade = generate_labeler_serializer("FundingCurrencyTrade", klass=types.FundingCurrencyTrade, labels=[
"ID",
"MTS",
"AMOUNT",
"RATE",
"PERIOD"
"id",
"mts",
"amount",
"rate",
"period"
])
TradingPairBook = generate_labeler_serializer("TradingPairBook", klass=types.TradingPairBook, labels=[
"PRICE",
"COUNT",
"AMOUNT"
"price",
"count",
"amount"
])
FundingCurrencyBook = generate_labeler_serializer("FundingCurrencyBook", klass=types.FundingCurrencyBook, labels=[
"RATE",
"PERIOD",
"COUNT",
"AMOUNT"
"rate",
"period",
"count",
"amount"
])
TradingPairRawBook = generate_labeler_serializer("TradingPairRawBook", klass=types.TradingPairRawBook, labels=[
"ORDER_ID",
"PRICE",
"AMOUNT"
"order_id",
"price",
"amount"
])
FundingCurrencyRawBook = generate_labeler_serializer("FundingCurrencyRawBook", klass=types.FundingCurrencyRawBook, labels=[
"OFFER_ID",
"PERIOD",
"RATE",
"AMOUNT"
"offer_id",
"period",
"rate",
"amount"
])
Statistic = generate_labeler_serializer("Statistic", klass=types.Statistic, labels=[
"MTS",
"VALUE"
"mts",
"value"
])
Candle = generate_labeler_serializer("Candle", klass=types.Candle, labels=[
"MTS",
"OPEN",
"CLOSE",
"HIGH",
"LOW",
"VOLUME"
"mts",
"open",
"close",
"high",
"low",
"volume"
])
DerivativesStatus = generate_labeler_serializer("DerivativesStatus", klass=types.DerivativesStatus, labels=[
"KEY",
"MTS",
"key",
"mts",
"_PLACEHOLDER",
"DERIV_PRICE",
"SPOT_PRICE",
"deriv_price",
"spot_price",
"_PLACEHOLDER",
"INSURANCE_FUND_BALANCE",
"insurance_fund_balance",
"_PLACEHOLDER",
"NEXT_FUNDING_EVT_TIMESTAMP_MS",
"NEXT_FUNDING_ACCRUED",
"NEXT_FUNDING_STEP",
"next_funding_evt_timestamp_ms",
"next_funding_accrued",
"next_funding_step",
"_PLACEHOLDER",
"CURRENT_FUNDING",
"current_funding",
"_PLACEHOLDER",
"_PLACEHOLDER",
"MARK_PRICE",
"mark_price",
"_PLACEHOLDER",
"_PLACEHOLDER",
"OPEN_INTEREST",
"open_interest",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"CLAMP_MIN",
"CLAMP_MAX"
"clamp_min",
"clamp_max"
])
Liquidation = generate_labeler_serializer("Liquidation", klass=types.Liquidation, labels=[
"_PLACEHOLDER",
"POS_ID",
"MTS",
"pos_id",
"mts",
"_PLACEHOLDER",
"SYMBOL",
"AMOUNT",
"BASE_PRICE",
"symbol",
"amount",
"base_price",
"_PLACEHOLDER",
"IS_MATCH",
"IS_MARKET_SOLD",
"is_match",
"is_market_sold",
"_PLACEHOLDER",
"PRICE_ACQUIRED"
"price_acquired"
])
Leaderboard = generate_labeler_serializer("Leaderboard", klass=types.Leaderboard, labels=[
"MTS",
"mts",
"_PLACEHOLDER",
"USERNAME",
"RANKING",
"username",
"ranking",
"_PLACEHOLDER",
"_PLACEHOLDER",
"VALUE",
"value",
"_PLACEHOLDER",
"_PLACEHOLDER",
"TWITTER_HANDLE"
"twitter_handle"
])
FundingStatistic = generate_labeler_serializer("FundingStatistic", klass=types.FundingStatistic, labels=[
"TIMESTAMP",
"timestamp",
"_PLACEHOLDER",
"_PLACEHOLDER",
"FRR",
"AVG_PERIOD",
"frr",
"avg_period",
"_PLACEHOLDER",
"_PLACEHOLDER",
"FUNDING_AMOUNT",
"FUNDING_AMOUNT_USED",
"funding_amount",
"funding_amount_used",
"_PLACEHOLDER",
"_PLACEHOLDER",
"FUNDING_BELOW_THRESHOLD"
"funding_below_threshold"
])
PulseProfile = generate_labeler_serializer("PulseProfile", klass=types.PulseProfile, labels=[
"PUID",
"MTS",
"puid",
"mts",
"_PLACEHOLDER",
"NICKNAME",
"nickname",
"_PLACEHOLDER",
"PICTURE",
"TEXT",
"picture",
"text",
"_PLACEHOLDER",
"_PLACEHOLDER",
"TWITTER_HANDLE",
"twitter_handle",
"_PLACEHOLDER",
"FOLLOWERS",
"FOLLOWING",
"followers",
"following",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"TIPPING_STATUS"
"tipping_status"
])
PulseMessage = generate_recursive_serializer("PulseMessage", klass=types.PulseMessage, serializers={ "PROFILE": PulseProfile }, labels=[
"PID",
"MTS",
PulseMessage = generate_recursive_serializer("PulseMessage", klass=types.PulseMessage, serializers={ "profile": PulseProfile }, labels=[
"pid",
"mts",
"_PLACEHOLDER",
"PUID",
"puid",
"_PLACEHOLDER",
"TITLE",
"CONTENT",
"title",
"content",
"_PLACEHOLDER",
"_PLACEHOLDER",
"IS_PIN",
"IS_PUBLIC",
"COMMENTS_DISABLED",
"TAGS",
"ATTACHMENTS",
"META",
"LIKES",
"is_pin",
"is_public",
"comments_disabled",
"tags",
"attachments",
"meta",
"likes",
"_PLACEHOLDER",
"_PLACEHOLDER",
"PROFILE",
"COMMENTS",
"profile",
"comments",
"_PLACEHOLDER",
"_PLACEHOLDER"
])
TradingMarketAveragePrice = generate_labeler_serializer("TradingMarketAveragePrice", klass=types.TradingMarketAveragePrice, labels=[
"PRICE_AVG",
"AMOUNT"
"price_avg",
"amount"
])
FundingMarketAveragePrice = generate_labeler_serializer("FundingMarketAveragePrice", klass=types.FundingMarketAveragePrice, labels=[
"RATE_AVG",
"AMOUNT"
"rate_avg",
"amount"
])
FxRate = generate_labeler_serializer("FxRate", klass=types.FxRate, labels=[
"CURRENT_RATE"
"current_rate"
])
#endregion
@@ -249,358 +249,382 @@ FxRate = generate_labeler_serializer("FxRate", klass=types.FxRate, labels=[
#region Serializers definition for Rest Authenticated Endpoints
Wallet = generate_labeler_serializer("Wallet", klass=types.Wallet, labels=[
"WALLET_TYPE",
"CURRENCY",
"BALANCE",
"UNSETTLED_INTEREST",
"AVAILABLE_BALANCE",
"LAST_CHANGE",
"TRADE_DETAILS"
"wallet_type",
"currency",
"balance",
"unsettled_interest",
"available_balance",
"last_change",
"trade_details"
])
Order = generate_labeler_serializer("Order", klass=types.Order, labels=[
"ID",
"GID",
"CID",
"SYMBOL",
"MTS_CREATE",
"MTS_UPDATE",
"AMOUNT",
"AMOUNT_ORIG",
"ORDER_TYPE",
"TYPE_PREV",
"MTS_TIF",
"id",
"gid",
"cid",
"symbol",
"mts_create",
"mts_update",
"amount",
"amount_orig",
"order_type",
"type_prev",
"mts_tif",
"_PLACEHOLDER",
"FLAGS",
"ORDER_STATUS",
"flags",
"order_status",
"_PLACEHOLDER",
"_PLACEHOLDER",
"PRICE",
"PRICE_AVG",
"PRICE_TRAILING",
"PRICE_AUX_LIMIT",
"price",
"price_avg",
"price_trailing",
"price_aux_limit",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"NOTIFY",
"HIDDEN",
"PLACED_ID",
"notify",
"hidden",
"placed_id",
"_PLACEHOLDER",
"_PLACEHOLDER",
"ROUTING",
"routing",
"_PLACEHOLDER",
"_PLACEHOLDER",
"META"
"meta"
])
Position = generate_labeler_serializer("Position", klass=types.Position, labels=[
"SYMBOL",
"STATUS",
"AMOUNT",
"BASE_PRICE",
"MARGIN_FUNDING",
"MARGIN_FUNDING_TYPE",
"PL",
"PL_PERC",
"PRICE_LIQ",
"LEVERAGE",
"symbol",
"status",
"amount",
"base_price",
"margin_funding",
"margin_funding_type",
"pl",
"pl_perc",
"price_liq",
"leverage",
"_PLACEHOLDER",
"POSITION_ID",
"MTS_CREATE",
"MTS_UPDATE",
"position_id",
"mts_create",
"mts_update",
"_PLACEHOLDER",
"TYPE",
"type",
"_PLACEHOLDER",
"COLLATERAL",
"COLLATERAL_MIN",
"META"
"collateral",
"collateral_min",
"meta"
])
FundingOffer = generate_labeler_serializer("FundingOffer", klass=types.FundingOffer, labels=[
"ID",
"SYMBOL",
"MTS_CREATED",
"MTS_UPDATED",
"AMOUNT",
"AMOUNT_ORIG",
"OFFER_TYPE",
"id",
"symbol",
"mts_created",
"mts_updated",
"amount",
"amount_orig",
"offer_type",
"_PLACEHOLDER",
"_PLACEHOLDER",
"FLAGS",
"OFFER_STATUS",
"flags",
"offer_status",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"RATE",
"PERIOD",
"NOTIFY",
"HIDDEN",
"rate",
"period",
"notify",
"hidden",
"_PLACEHOLDER",
"RENEW",
"renew",
"_PLACEHOLDER"
])
Trade = generate_labeler_serializer("Trade", klass=types.Trade, labels=[
"ID",
"PAIR",
"MTS_CREATE",
"ORDER_ID",
"EXEC_AMOUNT",
"EXEC_PRICE",
"ORDER_TYPE",
"ORDER_PRICE",
"MAKER",
"FEE",
"FEE_CURRENCY",
"CID"
"id",
"pair",
"mts_create",
"order_id",
"exec_amount",
"exec_price",
"order_type",
"order_price",
"maker",
"fee",
"fee_currency",
"cid"
])
OrderTrade = generate_labeler_serializer("OrderTrade", klass=types.OrderTrade, labels=[
"ID",
"PAIR",
"MTS_CREATE",
"ORDER_ID",
"EXEC_AMOUNT",
"EXEC_PRICE",
"id",
"pair",
"mts_create",
"order_id",
"exec_amount",
"exec_price",
"_PLACEHOLDER",
"_PLACEHOLDER",
"MAKER",
"FEE",
"FEE_CURRENCY",
"CID"
"maker",
"fee",
"fee_currency",
"cid"
])
Ledger = generate_labeler_serializer("Ledger", klass=types.Ledger, labels=[
"ID",
"CURRENCY",
"id",
"currency",
"_PLACEHOLDER",
"MTS",
"mts",
"_PLACEHOLDER",
"AMOUNT",
"BALANCE",
"amount",
"balance",
"_PLACEHOLDER",
"DESCRIPTION"
"description"
])
FundingLoan = generate_labeler_serializer("FundingLoan", klass=types.FundingLoan, labels=[
"id",
"symbol",
"side",
"mts_create",
"mts_update",
"amount",
"flags",
"status",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"rate",
"period",
"mts_opening",
"mts_last_payout",
"notify",
"hidden",
"_PLACEHOLDER",
"renew",
"rate_real",
"no_close"
])
FundingCredit = generate_labeler_serializer("FundingCredit", klass=types.FundingCredit, labels=[
"ID",
"SYMBOL",
"SIDE",
"MTS_CREATE",
"MTS_UPDATE",
"AMOUNT",
"FLAGS",
"STATUS",
"RATE_TYPE",
"id",
"symbol",
"side",
"mts_create",
"mts_update",
"amount",
"flags",
"status",
"rate_type",
"_PLACEHOLDER",
"_PLACEHOLDER",
"RATE",
"PERIOD",
"MTS_OPENING",
"MTS_LAST_PAYOUT",
"NOTIFY",
"HIDDEN",
"rate",
"period",
"mts_opening",
"mts_last_payout",
"notify",
"hidden",
"_PLACEHOLDER",
"RENEW",
"renew",
"_PLACEHOLDER",
"NO_CLOSE",
"POSITION_PAIR"
"no_close",
"position_pair"
])
Transfer = generate_labeler_serializer("Transfer", klass=types.Transfer, labels=[
"MTS",
"WALLET_FROM",
"WALLET_TO",
"mts",
"wallet_from",
"wallet_to",
"_PLACEHOLDER",
"CURRENCY",
"CURRENCY_TO",
"currency",
"currency_to",
"_PLACEHOLDER",
"AMOUNT"
"amount"
])
Withdrawal = generate_labeler_serializer("Withdrawal", klass=types.Withdrawal, labels=[
"WITHDRAWAL_ID",
"withdrawal_id",
"_PLACEHOLDER",
"METHOD",
"PAYMENT_ID",
"WALLET",
"AMOUNT",
"method",
"payment_id",
"wallet",
"amount",
"_PLACEHOLDER",
"_PLACEHOLDER",
"WITHDRAWAL_FEE"
"withdrawal_fee"
])
DepositAddress = generate_labeler_serializer("DepositAddress", klass=types.DepositAddress, labels=[
"_PLACEHOLDER",
"METHOD",
"CURRENCY_CODE",
"method",
"currency_code",
"_PLACEHOLDER",
"ADDRESS",
"POOL_ADDRESS"
"address",
"pool_address"
])
Invoice = generate_labeler_serializer("Invoice", klass=types.Invoice, labels=[
"INVOICE_HASH",
"INVOICE",
"invoice_hash",
"invoice",
"_PLACEHOLDER",
"_PLACEHOLDER",
"AMOUNT"
"amount"
])
Movement = generate_labeler_serializer("Movement", klass=types.Movement, labels=[
"ID",
"CURRENCY",
"CURRENCY_NAME",
"id",
"currency",
"currency_name",
"_PLACEHOLDER",
"_PLACEHOLDER",
"MTS_STARTED",
"MTS_UPDATED",
"mts_started",
"mts_updated",
"_PLACEHOLDER",
"_PLACEHOLDER",
"STATUS",
"status",
"_PLACEHOLDER",
"_PLACEHOLDER",
"AMOUNT",
"FEES",
"amount",
"fees",
"_PLACEHOLDER",
"_PLACEHOLDER",
"DESTINATION_ADDRESS",
"destination_address",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"TRANSACTION_ID",
"WITHDRAW_TRANSACTION_NOTE"
"transaction_id",
"withdraw_transaction_note"
])
SymbolMarginInfo = generate_labeler_serializer("SymbolMarginInfo", klass=types.SymbolMarginInfo, labels=[
"SYMBOL",
"TRADABLE_BALANCE",
"GROSS_BALANCE",
"BUY",
"SELL"
"symbol",
"tradable_balance",
"gross_balance",
"buy",
"sell"
])
BaseMarginInfo = generate_labeler_serializer("BaseMarginInfo", klass=types.BaseMarginInfo, labels=[
"USER_PL",
"USER_SWAPS",
"MARGIN_BALANCE",
"MARGIN_NET",
"MARGIN_MIN"
"user_pl",
"user_swaps",
"margin_balance",
"margin_net",
"margin_min"
])
Claim = generate_labeler_serializer("Claim", klass=types.Claim, labels=[
"SYMBOL",
"POSITION_STATUS",
"AMOUNT",
"BASE_PRICE",
"MARGIN_FUNDING",
"MARGIN_FUNDING_TYPE",
"symbol",
"position_status",
"amount",
"base_price",
"margin_funding",
"margin_funding_type",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"POSITION_ID",
"MTS_CREATE",
"MTS_UPDATE",
"position_id",
"mts_create",
"mts_update",
"_PLACEHOLDER",
"POS_TYPE",
"pos_type",
"_PLACEHOLDER",
"COLLATERAL",
"MIN_COLLATERAL",
"META"
"collateral",
"min_collateral",
"meta"
])
IncreaseInfo = generate_labeler_serializer("IncreaseInfo", klass=types.IncreaseInfo, labels=[
"MAX_POS",
"CURRENT_POS",
"BASE_CURRENCY_BALANCE",
"TRADABLE_BALANCE_QUOTE_CURRENCY",
"TRADABLE_BALANCE_QUOTE_TOTAL",
"TRADABLE_BALANCE_BASE_CURRENCY",
"TRADABLE_BALANCE_BASE_TOTAL",
"max_pos",
"current_pos",
"base_currency_balance",
"tradable_balance_quote_currency",
"tradable_balance_quote_total",
"tradable_balance_base_currency",
"tradable_balance_base_total",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"FUNDING_AVAIL",
"FUNDING_VALUE",
"FUNDING_REQUIRED",
"FUNDING_VALUE_CURRENCY",
"FUNDING_REQUIRED_CURRENCY"
"funding_avail",
"funding_value",
"funding_required",
"funding_value_currency",
"funding_required_currency"
])
Increase = generate_labeler_serializer("Increase", klass=types.Increase, labels=[
"SYMBOL",
"symbol",
"_PLACEHOLDER",
"AMOUNT",
"BASE_PRICE"
"amount",
"base_price"
])
PositionHistory = generate_labeler_serializer("PositionHistory", klass=types.PositionHistory, labels=[
"SYMBOL",
"STATUS",
"AMOUNT",
"BASE_PRICE",
"FUNDING",
"FUNDING_TYPE",
"symbol",
"status",
"amount",
"base_price",
"funding",
"funding_type",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"POSITION_ID",
"MTS_CREATE",
"MTS_UPDATE"
"position_id",
"mts_create",
"mts_update"
])
PositionSnapshot = generate_labeler_serializer("PositionSnapshot", klass=types.PositionSnapshot, labels=[
"SYMBOL",
"STATUS",
"AMOUNT",
"BASE_PRICE",
"FUNDING",
"FUNDING_TYPE",
"symbol",
"status",
"amount",
"base_price",
"funding",
"funding_type",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"POSITION_ID",
"MTS_CREATE",
"MTS_UPDATE"
"position_id",
"mts_create",
"mts_update"
])
PositionAudit = generate_labeler_serializer("PositionAudit", klass=types.PositionAudit, labels=[
"SYMBOL",
"STATUS",
"AMOUNT",
"BASE_PRICE",
"FUNDING",
"FUNDING_TYPE",
"symbol",
"status",
"amount",
"base_price",
"funding",
"funding_type",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"POSITION_ID",
"MTS_CREATE",
"MTS_UPDATE",
"position_id",
"mts_create",
"mts_update",
"_PLACEHOLDER",
"TYPE",
"type",
"_PLACEHOLDER",
"COLLATERAL",
"COLLATERAL_MIN",
"META"
"collateral",
"collateral_min",
"meta"
])
DerivativePositionCollateral = generate_labeler_serializer("DerivativePositionCollateral", klass=types.DerivativePositionCollateral, labels=[
"STATUS"
"status"
])
DerivativePositionCollateralLimits = generate_labeler_serializer("DerivativePositionCollateralLimits", klass=types.DerivativePositionCollateralLimits, labels=[
"MIN_COLLATERAL",
"MAX_COLLATERAL"
"min_collateral",
"max_collateral"
])
#endregion

View File

@@ -10,188 +10,188 @@ from .. utils.encoder import JSON
@dataclass
class PlatformStatus(_Type):
STATUS: int
status: int
@dataclass
class TradingPairTicker(_Type):
SYMBOL: Optional[str]
BID: float
BID_SIZE: float
ASK: float
ASK_SIZE: float
DAILY_CHANGE: float
DAILY_CHANGE_RELATIVE: float
LAST_PRICE: float
VOLUME: float
HIGH: float
LOW: float
symbol: Optional[str]
bid: float
bid_size: float
ask: float
ask_size: float
daily_change: float
daily_change_relative: float
last_price: float
volume: float
high: float
low: float
@dataclass
class FundingCurrencyTicker(_Type):
SYMBOL: Optional[str]
FRR: float
BID: float
BID_PERIOD: int
BID_SIZE: float
ASK: float
ASK_PERIOD: int
ASK_SIZE: float
DAILY_CHANGE: float
DAILY_CHANGE_RELATIVE: float
LAST_PRICE: float
VOLUME: float
HIGH: float
LOW: float
FRR_AMOUNT_AVAILABLE: float
symbol: Optional[str]
frr: float
bid: float
bid_period: int
bid_size: float
ask: float
ask_period: int
ask_size: float
daily_change: float
daily_change_relative: float
last_price: float
volume: float
high: float
low: float
frr_amount_available: float
@dataclass
class TickersHistory(_Type):
SYMBOL: str
BID: float
ASK: float
MTS: int
symbol: str
bid: float
ask: float
mts: int
@dataclass
class TradingPairTrade(_Type):
ID: int
MTS: int
AMOUNT: float
PRICE: float
id: int
mts: int
amount: float
price: float
@dataclass
class FundingCurrencyTrade(_Type):
ID: int
MTS: int
AMOUNT: float
RATE: float
PERIOD: int
id: int
mts: int
amount: float
rate: float
period: int
@dataclass
class TradingPairBook(_Type):
PRICE: float
COUNT: int
AMOUNT: float
price: float
count: int
amount: float
@dataclass
class FundingCurrencyBook(_Type):
RATE: float
PERIOD: int
COUNT: int
AMOUNT: float
rate: float
period: int
count: int
amount: float
@dataclass
class TradingPairRawBook(_Type):
ORDER_ID: int
PRICE: float
AMOUNT: float
order_id: int
price: float
amount: float
@dataclass
class FundingCurrencyRawBook(_Type):
OFFER_ID: int
PERIOD: int
RATE: float
AMOUNT: float
offer_id: int
period: int
rate: float
amount: float
@dataclass
class Statistic(_Type):
MTS: int
VALUE: float
mts: int
value: float
@dataclass
class Candle(_Type):
MTS: int
OPEN: float
CLOSE: float
HIGH: float
LOW: float
VOLUME: float
mts: int
open: float
close: float
high: float
low: float
volume: float
@dataclass
class DerivativesStatus(_Type):
KEY: Optional[str]
MTS: int
DERIV_PRICE: float
SPOT_PRICE: float
INSURANCE_FUND_BALANCE: float
NEXT_FUNDING_EVT_TIMESTAMP_MS: int
NEXT_FUNDING_ACCRUED: float
NEXT_FUNDING_STEP: int
CURRENT_FUNDING: float
MARK_PRICE: float
OPEN_INTEREST: float
CLAMP_MIN: float
CLAMP_MAX: float
key: Optional[str]
mts: int
deriv_price: float
spot_price: float
insurance_fund_balance: float
next_funding_evt_timestamp_ms: int
next_funding_accrued: float
next_funding_step: int
current_funding: float
mark_price: float
open_interest: float
clamp_min: float
clamp_max: float
@dataclass
class Liquidation(_Type):
POS_ID: int
MTS: int
SYMBOL: str
AMOUNT: float
BASE_PRICE: float
IS_MATCH: int
IS_MARKET_SOLD: int
PRICE_ACQUIRED: float
pos_id: int
mts: int
symbol: str
amount: float
base_price: float
is_match: int
is_market_sold: int
price_acquired: float
@dataclass
class Leaderboard(_Type):
MTS: int
USERNAME: str
RANKING: int
VALUE: float
TWITTER_HANDLE: Optional[str]
mts: int
username: str
ranking: int
value: float
twitter_handle: Optional[str]
@dataclass
class FundingStatistic(_Type):
TIMESTAMP: int
FRR: float
AVG_PERIOD: float
FUNDING_AMOUNT: float
FUNDING_AMOUNT_USED: float
FUNDING_BELOW_THRESHOLD: float
timestamp: int
frr: float
avg_period: float
funding_amount: float
funding_amount_used: float
funding_below_threshold: float
@dataclass
class PulseProfile(_Type):
PUID: str
MTS: int
NICKNAME: str
PICTURE: str
TEXT: str
TWITTER_HANDLE: str
FOLLOWERS: int
FOLLOWING: int
TIPPING_STATUS: int
puid: str
mts: int
nickname: str
picture: str
text: str
twitter_handle: str
followers: int
following: int
tipping_status: int
@dataclass
class PulseMessage(_Type):
PID: str
MTS: int
PUID: str
TITLE: str
CONTENT: str
IS_PIN: int
IS_PUBLIC: int
COMMENTS_DISABLED: int
TAGS: List[str]
ATTACHMENTS: List[str]
META: List[JSON]
LIKES: int
PROFILE: PulseProfile
COMMENTS: int
pid: str
mts: int
puid: str
title: str
content: str
is_pin: int
is_public: int
comments_disabled: int
tags: List[str]
attachments: List[str]
meta: List[JSON]
likes: int
profile: PulseProfile
comments: int
@dataclass
class TradingMarketAveragePrice(_Type):
PRICE_AVG: float
AMOUNT: float
price_avg: float
amount: float
@dataclass
class FundingMarketAveragePrice(_Type):
RATE_AVG: float
AMOUNT: float
rate_avg: float
amount: float
@dataclass
class FxRate(_Type):
CURRENT_RATE: float
current_rate: float
#endregion
@@ -199,279 +199,299 @@ class FxRate(_Type):
@dataclass
class Wallet(_Type):
WALLET_TYPE: str
CURRENCY: str
BALANCE: float
UNSETTLED_INTEREST: float
AVAILABLE_BALANCE: float
LAST_CHANGE: str
TRADE_DETAILS: JSON
wallet_type: str
currency: str
balance: float
unsettled_interest: float
available_balance: float
last_change: str
trade_details: JSON
@dataclass
class Order(_Type):
ID: int
GID: int
CID: int
SYMBOL: str
MTS_CREATE: int
MTS_UPDATE: int
AMOUNT: float
AMOUNT_ORIG: float
ORDER_TYPE: str
TYPE_PREV: str
MTS_TIF: int
FLAGS: int
ORDER_STATUS: str
PRICE: float
PRICE_AVG: float
PRICE_TRAILING: float
PRICE_AUX_LIMIT: float
NOTIFY: int
HIDDEN: int
PLACED_ID: int
ROUTING: str
META: JSON
id: int
gid: int
cid: int
symbol: str
mts_create: int
mts_update: int
amount: float
amount_orig: float
order_type: str
type_prev: str
mts_tif: int
flags: int
order_status: str
price: float
price_avg: float
price_trailing: float
price_aux_limit: float
notify: int
hidden: int
placed_id: int
routing: str
meta: JSON
@dataclass
class Position(_Type):
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
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
@dataclass
class FundingOffer(_Type):
ID: int
SYMBOL: str
MTS_CREATE: int
MTS_UPDATE: int
AMOUNT: float
AMOUNT_ORIG: float
OFFER_TYPE: str
FLAGS: int
OFFER_STATUS: str
RATE: float
PERIOD: int
NOTIFY: bool
HIDDEN: int
RENEW: bool
id: int
symbol: str
mts_create: int
mts_update: int
amount: float
amount_orig: float
offer_type: str
flags: int
offer_status: str
rate: float
period: int
notify: bool
hidden: int
renew: bool
@dataclass
class Trade(_Type):
ID: int
SYMBOL: str
MTS_CREATE: int
ORDER_ID: int
EXEC_AMOUNT: float
EXEC_PRICE: float
ORDER_TYPE: str
ORDER_PRICE: float
MAKER:int
FEE: float
FEE_CURRENCY: str
CID: int
id: int
symbol: str
mts_create: int
order_id: int
exec_amount: float
exec_price: float
order_type: str
order_price: float
maker:int
fee: float
fee_currency: str
cid: int
@dataclass
class OrderTrade(_Type):
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
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
@dataclass
class Ledger(_Type):
ID: int
CURRENCY: str
MTS: int
AMOUNT: float
BALANCE: float
id: int
currency: str
mts: int
amount: float
balance: float
description: str
@dataclass
class FundingLoan(_Type):
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
@dataclass
class FundingCredit(_Type):
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
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
@dataclass
class Transfer(_Type):
MTS: int
WALLET_FROM: str
WALLET_TO: str
CURRENCY: str
CURRENCY_TO: str
AMOUNT: int
mts: int
wallet_from: str
wallet_to: str
currency: str
currency_to: str
amount: int
@dataclass
class Withdrawal(_Type):
WITHDRAWAL_ID: int
METHOD: str
PAYMENT_ID: str
WALLET: str
AMOUNT: float
WITHDRAWAL_FEE: float
withdrawal_id: int
method: str
payment_id: str
wallet: str
amount: float
withdrawal_fee: float
@dataclass
class DepositAddress(_Type):
METHOD: str
CURRENCY_CODE: str
ADDRESS: str
POOL_ADDRESS: str
method: str
currency_code: str
address: str
pool_address: str
@dataclass
class Invoice(_Type):
INVOICE_HASH: str
INVOICE: str
AMOUNT: str
invoice_hash: str
invoice: str
amount: str
@dataclass
class Movement(_Type):
ID: str
CURRENCY: str
CURRENCY_NAME: str
MTS_STARTED: int
MTS_UPDATED: int
STATUS: str
AMOUNT: int
FEES: int
DESTINATION_ADDRESS: str
TRANSACTION_ID: str
WITHDRAW_TRANSACTION_NOTE: str
id: str
currency: str
currency_name: str
mts_started: int
mts_updated: int
status: str
amount: int
fees: int
destination_address: str
transaction_id: str
withdraw_transaction_note: str
@dataclass
class SymbolMarginInfo(_Type):
SYMBOL: str
TRADABLE_BALANCE: float
GROSS_BALANCE: float
BUY: float
SELL: float
symbol: str
tradable_balance: float
gross_balance: float
buy: float
sell: float
@dataclass
class BaseMarginInfo(_Type):
USER_PL: float
USER_SWAPS: float
MARGIN_BALANCE: float
MARGIN_NET: float
MARGIN_MIN: float
user_pl: float
user_swaps: float
margin_balance: float
margin_net: float
margin_min: float
@dataclass
class Claim(_Type):
SYMBOL: str
POSITION_STATUS: str
AMOUNT: float
BASE_PRICE: float
MARGIN_FUNDING: float
MARGIN_FUNDING_TYPE: int
POSITION_ID: int
MTS_CREATE: int
MTS_UPDATE: int
POS_TYPE: int
COLLATERAL: str
MIN_COLLATERAL: str
META: JSON
symbol: str
position_status: str
amount: float
base_price: float
margin_funding: float
margin_funding_type: int
position_id: int
mts_create: int
mts_update: int
pos_type: int
collateral: str
min_collateral: str
meta: JSON
@dataclass
class IncreaseInfo(_Type):
MAX_POS: int
CURRENT_POS: float
BASE_CURRENCY_BALANCE: float
TRADABLE_BALANCE_QUOTE_CURRENCY: float
TRADABLE_BALANCE_QUOTE_TOTAL: float
TRADABLE_BALANCE_BASE_CURRENCY: float
TRADABLE_BALANCE_BASE_TOTAL: float
FUNDING_AVAIL: float
FUNDING_VALUE: float
FUNDING_REQUIRED: float
FUNDING_VALUE_CURRENCY: str
FUNDING_REQUIRED_CURRENCY: str
max_pos: int
current_pos: float
base_currency_balance: float
tradable_balance_quote_currency: float
tradable_balance_quote_total: float
tradable_balance_base_currency: float
tradable_balance_base_total: float
funding_avail: float
funding_value: float
funding_required: float
funding_value_currency: str
funding_required_currency: str
@dataclass
class Increase(_Type):
SYMBOL: str
AMOUNT: float
BASE_PRICE: float
symbol: str
amount: float
base_price: float
@dataclass
class PositionHistory(_Type):
SYMBOL: str
STATUS: str
AMOUNT: float
BASE_PRICE: float
FUNDING: float
FUNDING_TYPE: int
POSITION_ID: int
MTS_CREATE: int
MTS_UPDATE: int
symbol: str
status: str
amount: float
base_price: float
funding: float
funding_type: int
position_id: int
mts_create: int
mts_update: int
@dataclass
class PositionSnapshot(_Type):
SYMBOL: str
STATUS: str
AMOUNT: float
BASE_PRICE: float
FUNDING: float
FUNDING_TYPE: int
POSITION_ID: int
MTS_CREATE: int
MTS_UPDATE: int
symbol: str
status: str
amount: float
base_price: float
funding: float
funding_type: int
position_id: int
mts_create: int
mts_update: int
@dataclass
class PositionAudit(_Type):
SYMBOL: str
STATUS: str
AMOUNT: float
BASE_PRICE: float
FUNDING: float
FUNDING_TYPE: int
POSITION_ID: int
MTS_CREATE: int
MTS_UPDATE: int
TYPE: int
COLLATERAL: float
COLLATERAL_MIN: float
META: JSON
symbol: str
status: str
amount: float
base_price: float
funding: float
funding_type: int
position_id: int
mts_create: int
mts_update: int
type: int
collateral: float
collateral_min: float
meta: JSON
@dataclass
class DerivativePositionCollateral(_Type):
STATUS: int
status: int
@dataclass
class DerivativePositionCollateralLimits(_Type):
MIN_COLLATERAL: float
MAX_COLLATERAL: float
min_collateral: float
max_collateral: float
#endregion

View File

@@ -7,111 +7,111 @@ from .. notification import _Notification
#region Serializers definition for Websocket Public Channels
TradingPairTicker = generate_labeler_serializer("TradingPairTicker", klass=types.TradingPairTicker, labels=[
"BID",
"BID_SIZE",
"ASK",
"ASK_SIZE",
"DAILY_CHANGE",
"DAILY_CHANGE_RELATIVE",
"LAST_PRICE",
"VOLUME",
"HIGH",
"LOW"
"bid",
"bid_size",
"ask",
"ask_size",
"daily_change",
"daily_change_relative",
"last_price",
"volume",
"high",
"low"
])
FundingCurrencyTicker = generate_labeler_serializer("FundingCurrencyTicker", klass=types.FundingCurrencyTicker, labels=[
"FRR",
"BID",
"BID_PERIOD",
"BID_SIZE",
"ASK",
"ASK_PERIOD",
"ASK_SIZE",
"DAILY_CHANGE",
"DAILY_CHANGE_RELATIVE",
"LAST_PRICE",
"VOLUME",
"HIGH",
"LOW"
"frr",
"bid",
"bid_period",
"bid_size",
"ask",
"ask_period",
"ask_size",
"daily_change",
"daily_change_relative",
"last_price",
"volume",
"high",
"low"
"_PLACEHOLDER",
"_PLACEHOLDER",
"FRR_AMOUNT_AVAILABLE"
"frr_amount_available"
])
TradingPairTrade = generate_labeler_serializer("TradingPairTrade", klass=types.TradingPairTrade, labels=[
"ID",
"MTS",
"AMOUNT",
"PRICE"
"id",
"mts",
"amount",
"price"
])
FundingCurrencyTrade = generate_labeler_serializer("FundingCurrencyTrade", klass=types.FundingCurrencyTrade, labels=[
"ID",
"MTS",
"AMOUNT",
"RATE",
"PERIOD"
"id",
"mts",
"amount",
"rate",
"period"
])
TradingPairBook = generate_labeler_serializer("TradingPairBook", klass=types.TradingPairBook, labels=[
"PRICE",
"COUNT",
"AMOUNT"
"price",
"count",
"amount"
])
FundingCurrencyBook = generate_labeler_serializer("FundingCurrencyBook", klass=types.FundingCurrencyBook, labels=[
"RATE",
"PERIOD",
"COUNT",
"AMOUNT"
"rate",
"period",
"count",
"amount"
])
TradingPairRawBook = generate_labeler_serializer("TradingPairRawBook", klass=types.TradingPairRawBook, labels=[
"ORDER_ID",
"PRICE",
"AMOUNT"
"order_id",
"price",
"amount"
])
FundingCurrencyRawBook = generate_labeler_serializer("FundingCurrencyRawBook", klass=types.FundingCurrencyRawBook, labels=[
"OFFER_ID",
"PERIOD",
"RATE",
"AMOUNT"
"offer_id",
"period",
"rate",
"amount"
])
Candle = generate_labeler_serializer("Candle", klass=types.Candle, labels=[
"MTS",
"OPEN",
"CLOSE",
"HIGH",
"LOW",
"VOLUME"
"mts",
"open",
"close",
"high",
"low",
"volume"
])
DerivativesStatus = generate_labeler_serializer("DerivativesStatus", klass=types.DerivativesStatus, labels=[
"TIME_MS",
"time_ms",
"_PLACEHOLDER",
"DERIV_PRICE",
"SPOT_PRICE",
"deriv_price",
"spot_price",
"_PLACEHOLDER",
"INSURANCE_FUND_BALANCE",
"insurance_fund_balance",
"_PLACEHOLDER",
"NEXT_FUNDING_EVT_TIMESTAMP_MS",
"NEXT_FUNDING_ACCRUED",
"NEXT_FUNDING_STEP",
"next_funding_evt_timestamp_ms",
"next_funding_accrued",
"next_funding_step",
"_PLACEHOLDER",
"CURRENT_FUNDING"
"current_funding"
"_PLACEHOLDER",
"_PLACEHOLDER",
"MARK_PRICE",
"mark_price",
"_PLACEHOLDER",
"_PLACEHOLDER",
"OPEN_INTEREST",
"open_interest",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"CLAMP_MIN",
"CLAMP_MAX"
"clamp_min",
"clamp_max"
])
#endregion
@@ -119,179 +119,179 @@ DerivativesStatus = generate_labeler_serializer("DerivativesStatus", klass=types
#region Serializers definition for Websocket Authenticated Channels
Order = generate_labeler_serializer("Order", klass=types.Order, labels=[
"ID",
"GID",
"CID",
"SYMBOL",
"MTS_CREATE",
"MTS_UPDATE",
"AMOUNT",
"AMOUNT_ORIG",
"ORDER_TYPE",
"TYPE_PREV",
"MTS_TIF",
"id",
"gid",
"cid",
"symbol",
"mts_create",
"mts_update",
"amount",
"amount_orig",
"order_type",
"type_prev",
"mts_tif",
"_PLACEHOLDER",
"FLAGS",
"ORDER_STATUS",
"flags",
"order_status",
"_PLACEHOLDER",
"_PLACEHOLDER",
"PRICE",
"PRICE_AVG",
"PRICE_TRAILING",
"PRICE_AUX_LIMIT",
"price",
"price_avg",
"price_trailing",
"price_aux_limit",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"NOTIFY",
"HIDDEN",
"PLACED_ID",
"notify",
"hidden",
"placed_id",
"_PLACEHOLDER",
"_PLACEHOLDER",
"ROUTING",
"routing",
"_PLACEHOLDER",
"_PLACEHOLDER",
"META"
"meta"
])
Position = generate_labeler_serializer("Position", klass=types.Position, labels=[
"SYMBOL",
"STATUS",
"AMOUNT",
"BASE_PRICE",
"MARGIN_FUNDING",
"MARGIN_FUNDING_TYPE",
"PL",
"PL_PERC",
"PRICE_LIQ",
"LEVERAGE",
"FLAG",
"POSITION_ID",
"MTS_CREATE",
"MTS_UPDATE",
"symbol",
"status",
"amount",
"base_price",
"margin_funding",
"margin_funding_type",
"pl",
"pl_perc",
"price_liq",
"leverage",
"flag",
"position_id",
"mts_create",
"mts_update",
"_PLACEHOLDER",
"TYPE",
"type",
"_PLACEHOLDER",
"COLLATERAL",
"COLLATERAL_MIN",
"META"
"collateral",
"collateral_min",
"meta"
])
TradeExecuted = generate_labeler_serializer("TradeExecuted", klass=types.TradeExecuted, labels=[
"ID",
"SYMBOL",
"MTS_CREATE",
"ORDER_ID",
"EXEC_AMOUNT",
"EXEC_PRICE",
"ORDER_TYPE",
"ORDER_PRICE",
"MAKER",
"id",
"symbol",
"mts_create",
"order_id",
"exec_amount",
"exec_price",
"order_type",
"order_price",
"maker",
"_PLACEHOLDER",
"_PLACEHOLDER",
"CID"
"cid"
])
TradeExecutionUpdate = generate_labeler_serializer("TradeExecutionUpdate", klass=types.TradeExecutionUpdate, labels=[
"ID",
"SYMBOL",
"MTS_CREATE",
"ORDER_ID",
"EXEC_AMOUNT",
"EXEC_PRICE",
"ORDER_TYPE",
"ORDER_PRICE",
"MAKER",
"FEE",
"FEE_CURRENCY",
"CID"
"id",
"symbol",
"mts_create",
"order_id",
"exec_amount",
"exec_price",
"order_type",
"order_price",
"maker",
"fee",
"fee_currency",
"cid"
])
FundingOffer = generate_labeler_serializer("FundingOffer", klass=types.FundingOffer, labels=[
"ID",
"SYMBOL",
"MTS_CREATED",
"MTS_UPDATED",
"AMOUNT",
"AMOUNT_ORIG",
"OFFER_TYPE",
"id",
"symbol",
"mts_created",
"mts_updated",
"amount",
"amount_orig",
"offer_type",
"_PLACEHOLDER",
"_PLACEHOLDER",
"FLAGS",
"STATUS",
"flags",
"status",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"RATE",
"PERIOD",
"NOTIFY",
"HIDDEN",
"rate",
"period",
"notify",
"hidden",
"_PLACEHOLDER",
"RENEW",
"renew",
"_PLACEHOLDER"
])
FundingCredit = generate_labeler_serializer("FundingCredit", klass=types.FundingCredit, labels=[
"ID",
"SYMBOL",
"SIDE",
"MTS_CREATE",
"MTS_UPDATE",
"AMOUNT",
"FLAGS",
"STATUS",
"id",
"symbol",
"side",
"mts_create",
"mts_update",
"amount",
"flags",
"status",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"RATE",
"PERIOD",
"MTS_OPENING",
"MTS_LAST_PAYOUT",
"NOTIFY",
"HIDDEN",
"rate",
"period",
"mts_opening",
"mts_last_payout",
"notify",
"hidden",
"_PLACEHOLDER",
"RENEW",
"RATE_REAL",
"NO_CLOSE",
"POSITION_PAIR"
"renew",
"rate_real",
"no_close",
"position_pair"
])
FundingLoan = generate_labeler_serializer("FundingLoan", klass=types.FundingLoan, labels=[
"ID",
"SYMBOL",
"SIDE",
"MTS_CREATE",
"MTS_UPDATE",
"AMOUNT",
"FLAGS",
"STATUS",
"id",
"symbol",
"side",
"mts_create",
"mts_update",
"amount",
"flags",
"status",
"_PLACEHOLDER",
"_PLACEHOLDER",
"_PLACEHOLDER",
"RATE",
"PERIOD",
"MTS_OPENING",
"MTS_LAST_PAYOUT",
"NOTIFY",
"HIDDEN",
"rate",
"period",
"mts_opening",
"mts_last_payout",
"notify",
"hidden",
"_PLACEHOLDER",
"RENEW",
"RATE_REAL",
"NO_CLOSE"
"renew",
"rate_real",
"no_close"
])
Wallet = generate_labeler_serializer("Wallet", klass=types.Wallet, labels=[
"WALLET_TYPE",
"CURRENCY",
"BALANCE",
"UNSETTLED_INTEREST",
"BALANCE_AVAILABLE",
"DESCRIPTION",
"META"
"wallet_type",
"currency",
"balance",
"unsettled_interest",
"balance_available",
"description",
"meta"
])
BalanceInfo = generate_labeler_serializer("BalanceInfo", klass=types.BalanceInfo, labels=[
"AUM",
"AUM_NET",
"aum",
"aum_net",
])
#endregion

View File

@@ -10,246 +10,246 @@ from .. utils.encoder import JSON
@dataclass
class TradingPairTicker(_Type):
BID: float
BID_SIZE: float
ASK: float
ASK_SIZE: float
DAILY_CHANGE: float
DAILY_CHANGE_RELATIVE: float
LAST_PRICE: float
VOLUME: float
HIGH: float
LOW: float
bid: float
bid_size: float
ask: float
ask_size: float
daily_change: float
daily_change_relative: float
last_price: float
volume: float
high: float
low: float
@dataclass
class FundingCurrencyTicker(_Type):
FRR: float
BID: float
BID_PERIOD: int
BID_SIZE: float
ASK: float
ASK_PERIOD: int
ASK_SIZE: float
DAILY_CHANGE: float
DAILY_CHANGE_RELATIVE: float
LAST_PRICE: float
VOLUME: float
HIGH: float
LOW: float
FRR_AMOUNT_AVAILABLE: float
frr: float
bid: float
bid_period: int
bid_size: float
ask: float
ask_period: int
ask_size: float
daily_change: float
daily_change_relative: float
last_price: float
volume: float
high: float
low: float
frr_amount_available: float
@dataclass
class TradingPairTrade(_Type):
ID: int
MTS: int
AMOUNT: float
PRICE: float
id: int
mts: int
amount: float
price: float
@dataclass
class FundingCurrencyTrade(_Type):
ID: int
MTS: int
AMOUNT: float
RATE: float
PERIOD: int
id: int
mts: int
amount: float
rate: float
period: int
@dataclass
class TradingPairBook(_Type):
PRICE: float
COUNT: int
AMOUNT: float
price: float
count: int
amount: float
@dataclass
class FundingCurrencyBook(_Type):
RATE: float
PERIOD: int
COUNT: int
AMOUNT: float
rate: float
period: int
count: int
amount: float
@dataclass
class TradingPairRawBook(_Type):
ORDER_ID: int
PRICE: float
AMOUNT: float
order_id: int
price: float
amount: float
@dataclass
class FundingCurrencyRawBook(_Type):
OFFER_ID: int
PERIOD: int
RATE: float
AMOUNT: float
offer_id: int
period: int
rate: float
amount: float
@dataclass
class Candle(_Type):
MTS: int
OPEN: float
CLOSE: float
HIGH: float
LOW: float
VOLUME: float
mts: int
open: float
close: float
high: float
low: float
volume: float
@dataclass
class DerivativesStatus(_Type):
TIME_MS: int
DERIV_PRICE: float
SPOT_PRICE: float
INSURANCE_FUND_BALANCE: float
NEXT_FUNDING_EVT_TIMESTAMP_MS: int
NEXT_FUNDING_ACCRUED: float
NEXT_FUNDING_STEP: int
CURRENT_FUNDING: float
MARK_PRICE: float
OPEN_INTEREST: float
CLAMP_MIN: float
CLAMP_MAX: float
time_ms: int
deriv_price: float
spot_price: float
insurance_fund_balance: float
next_funding_evt_timestamp_ms: int
next_funding_accrued: float
next_funding_step: int
current_funding: float
mark_price: float
open_interest: float
clamp_min: float
clamp_max: float
#endregion
#region Type hinting for Websocket Authenticated Channels
@dataclass
class Order(_Type):
ID: int
GID: int
CID: int
SYMBOL: str
MTS_CREATE: int
MTS_UPDATE: int
AMOUNT: float
AMOUNT_ORIG: float
ORDER_TYPE: str
TYPE_PREV: str
MTS_TIF: int
FLAGS: int
ORDER_STATUS: str
PRICE: float
PRICE_AVG: float
PRICE_TRAILING: float
PRICE_AUX_LIMIT: float
NOTIFY: int
HIDDEN: int
PLACED_ID: int
ROUTING: str
META: JSON
id: int
gid: int
cid: int
symbol: str
mts_create: int
mts_update: int
amount: float
amount_orig: float
order_type: str
type_prev: str
mts_tif: int
flags: int
order_status: str
price: float
price_avg: float
price_trailing: float
price_aux_limit: float
notify: int
hidden: int
placed_id: int
routing: str
meta: JSON
@dataclass
class Position(_Type):
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
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
@dataclass
class TradeExecuted(_Type):
ID: int
SYMBOL: str
MTS_CREATE: int
ORDER_ID: int
EXEC_AMOUNT: float
EXEC_PRICE: float
ORDER_TYPE: str
ORDER_PRICE: float
MAKER:int
CID: int
id: int
symbol: str
mts_create: int
order_id: int
exec_amount: float
exec_price: float
order_type: str
order_price: float
maker:int
cid: int
@dataclass
class TradeExecutionUpdate(_Type):
ID: int
SYMBOL: str
MTS_CREATE: int
ORDER_ID: int
EXEC_AMOUNT: float
EXEC_PRICE: float
ORDER_TYPE: str
ORDER_PRICE: float
MAKER:int
FEE: float
FEE_CURRENCY: str
CID: int
id: int
symbol: str
mts_create: int
order_id: int
exec_amount: float
exec_price: float
order_type: str
order_price: float
maker:int
fee: float
fee_currency: str
cid: int
@dataclass
class FundingOffer(_Type):
ID: int
SYMBOL: str
MTS_CREATED: int
MTS_UPDATED: int
AMOUNT: float
AMOUNT_ORIG: float
OFFER_TYPE: str
FLAGS: int
STATUS: str
RATE: float
PERIOD: int
NOTIFY: int
HIDDEN: int
RENEW: int
id: int
symbol: str
mts_created: int
mts_updated: int
amount: float
amount_orig: float
offer_type: str
flags: int
status: str
rate: float
period: int
notify: int
hidden: int
renew: int
@dataclass
class FundingCredit(_Type):
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
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
@dataclass
class FundingLoan(_Type):
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
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
@dataclass
class Wallet(_Type):
WALLET_TYPE: str
CURRENCY: str
BALANCE: float
UNSETTLED_INTEREST: float
BALANCE_AVAILABLE: float
DESCRIPTION: str
META: JSON
wallet_type: str
currency: str
balance: float
unsettled_interest: float
balance_available: float
description: str
meta: JSON
@dataclass
class BalanceInfo(_Type):
AUM: float
AUM_NET: float
aum: float
aum_net: float
#endregion

View File

@@ -15,5 +15,5 @@ open_margin_positions = bfx.rest.auth.get_positions()
# claim all positions
for position in open_margin_positions:
print(f"Position {position}")
claim = bfx.rest.auth.claim_position(position.POSITION_ID, amount=0.000001)
print(f"Claim {claim.NOTIFY_INFO}")
claim = bfx.rest.auth.claim_position(position.position_id, amount=0.000001)
print(f"Claim {claim.notify_info}")

View File

@@ -25,7 +25,7 @@ print("Submit Order Notification:", submitted_order)
# Update it
updated_order = bfx.rest.auth.update_order(
id=submitted_order.NOTIFY_INFO.ID,
id=submitted_order.notify_info.id,
amount="0.020",
price="10100"
)
@@ -33,6 +33,6 @@ updated_order = bfx.rest.auth.update_order(
print("Update Order Notification:", updated_order)
# Delete it
canceled_order = bfx.rest.auth.cancel_order(id=submitted_order.NOTIFY_INFO.ID)
canceled_order = bfx.rest.auth.cancel_order(id=submitted_order.notify_info.id)
print("Cancel Order Notification:", canceled_order)

View File

@@ -27,5 +27,5 @@ print(f"Limits {limits}")
# Update position collateral
response = bfx.rest.auth.set_derivative_position_collateral(symbol="tBTCF0:USTF0", collateral=50)
print(response.STATUS)
print(response.status)

View File

@@ -12,7 +12,7 @@ t_symbol_response = bfx.rest.public.get_trading_market_average_price(
price_limit="20000.5"
)
print(t_symbol_response.PRICE_AVG)
print(t_symbol_response.price_avg)
f_symbol_response = bfx.rest.public.get_funding_market_average_price(
symbol="fUSD",
@@ -21,8 +21,8 @@ f_symbol_response = bfx.rest.public.get_funding_market_average_price(
rate_limit="0.00015"
)
print(f_symbol_response.RATE_AVG)
print(f_symbol_response.rate_avg)
fx_rate = bfx.rest.public.get_fx_rate(ccy1="USD", ccy2="EUR")
print(fx_rate.CURRENT_RATE)
print(fx_rate.current_rate)

View File

@@ -69,7 +69,7 @@ def log_funding_loans():
def log_funding_loans_history():
loans = bfx.rest.auth.get_funding_loan_history(symbol='fUSD', start=0, end=now)
loans = bfx.rest.auth.get_funding_loans_history(symbol='fUSD', start=0, end=now)
print("Funding loan history:")
[print(l) for l in loans]

View File

@@ -14,9 +14,9 @@ messages = bfx.rest.public.get_pulse_history(end=now, limit=100)
for message in messages:
print(f"Message: {message}")
print(message.CONTENT)
print(message.PROFILE.PICTURE)
print(message.content)
print(message.profile.picture)
profile = bfx.rest.public.get_pulse_profile("News")
print(f"Profile: {profile}")
print(f"Profile picture: {profile.PICTURE}")
print(f"Profile picture: {profile.picture}")

View File

@@ -15,4 +15,4 @@ print(increase_info)
# increase a margin position
notification = bfx.rest.auth.increase_position(symbol="tBTCUSD", amount=0.0001)
print(notification.NOTIFY_INFO)
print(notification.notify_info)

View File

@@ -12,20 +12,20 @@ bfx = Client(
def transfer_wallet():
response = bfx.rest.auth.submit_wallet_transfer(from_wallet="exchange", to_wallet="funding", from_currency="ETH", to_currency="ETH", amount=0.001)
print("Transfer:", response.NOTIFY_INFO)
print("Transfer:", response.notify_info)
def get_existing_deposit_address():
response = bfx.rest.auth.get_deposit_address(wallet="exchange", method="bitcoin", renew=False)
print("Address:", response.NOTIFY_INFO)
print("Address:", response.notify_info)
def create_new_deposit_address():
response = bfx.rest.auth.get_deposit_address(wallet="exchange", method="bitcoin", renew=True)
print("Address:", response.NOTIFY_INFO)
print("Address:", response.notify_info)
def withdraw():
# tetheruse = Tether (ERC20)
response = bfx.rest.auth.submit_wallet_withdraw(wallet="exchange", method="tetheruse", amount=1, address="0x742d35Cc6634C0532925a3b844Bc454e4438f44e")
print("Address:", response.NOTIFY_INFO)
print("Address:", response.notify_info)
def create_lighting_network_deposit_address():
invoice = bfx.rest.auth.get_deposit_invoice(wallet="funding", currency="LNX", amount=0.001)

View File

@@ -19,7 +19,7 @@ class OrderBook(object):
}
def update(self, symbol: str, data: TradingPairBook) -> None:
price, count, amount = data.PRICE, data.COUNT, data.AMOUNT
price, count, amount = data.price, data.count, data.amount
kind = (amount > 0) and "bids" or "asks"

View File

@@ -19,7 +19,7 @@ class RawOrderBook(object):
}
def update(self, symbol: str, data: TradingPairRawBook) -> None:
order_id, price, amount = data.ORDER_ID, data.PRICE, data.AMOUNT
order_id, price, amount = data.order_id, data.price, data.amount
kind = (amount > 0) and "bids" or "asks"