diff --git a/bfxapi/__init__.py b/bfxapi/__init__.py index 1f9755e..124b630 100644 --- a/bfxapi/__init__.py +++ b/bfxapi/__init__.py @@ -6,5 +6,6 @@ from .client import Client from .models import (Order, Trade, OrderBook, Subscription, Wallet, Position, FundingLoan, FundingOffer, FundingCredit) from .websockets.GenericWebsocket import GenericWebsocket +from .utils.Decimal import Decimal NAME = 'bfxapi' diff --git a/bfxapi/models/Order.py b/bfxapi/models/Order.py index dc05ba7..f209bb8 100644 --- a/bfxapi/models/Order.py +++ b/bfxapi/models/Order.py @@ -5,7 +5,6 @@ Module used to describe all of the different data types import time import datetime - class OrderType: """ Enum used to describe all of the different order types available for use diff --git a/bfxapi/models/order.py b/bfxapi/models/order.py index dc05ba7..f209bb8 100644 --- a/bfxapi/models/order.py +++ b/bfxapi/models/order.py @@ -5,7 +5,6 @@ Module used to describe all of the different data types import time import datetime - class OrderType: """ Enum used to describe all of the different order types available for use diff --git a/bfxapi/rest/BfxRest.py b/bfxapi/rest/BfxRest.py index 129abf8..fc5c0f0 100644 --- a/bfxapi/rest/BfxRest.py +++ b/bfxapi/rest/BfxRest.py @@ -22,11 +22,13 @@ class BfxRest: """ def __init__(self, API_KEY, API_SECRET, host='https://api.bitfinex.com/v2', loop=None, - logLevel='INFO', *args, **kwargs): + logLevel='INFO', parse_float=float, *args, **kwargs): self.loop = loop or asyncio.get_event_loop() self.API_KEY = API_KEY self.API_SECRET = API_SECRET self.host = host + # this value can also be set to bfxapi.Decimal for much higher precision + self.parse_float = parse_float self.logger = CustomLogger('BfxRest', logLevel=logLevel) async def fetch(self, endpoint, params=""): @@ -42,7 +44,8 @@ class BfxRest: if resp.status is not 200: raise Exception('GET {} failed with status {} - {}' .format(url, resp.status, text)) - return await resp.json() + parsed = json.loads(text, parse_float=self.parse_float) + return parsed async def post(self, endpoint, data={}, params=""): """ @@ -61,7 +64,8 @@ class BfxRest: if resp.status is not 200: raise Exception('POST {} failed with status {} - {}' .format(url, resp.status, text)) - return await resp.json() + parsed = json.loads(text, parse_float=self.parse_float) + return parsed ################################################## # Public Data # diff --git a/bfxapi/utils/Decimal.py b/bfxapi/utils/Decimal.py new file mode 100644 index 0000000..679ae8b --- /dev/null +++ b/bfxapi/utils/Decimal.py @@ -0,0 +1,52 @@ +import decimal as dec + +class Decimal(dec.Decimal): + + @classmethod + def from_float(cls, f): + return cls(str(f)) + + def __new__(cls, value=0, *args, **kwargs): + if isinstance(value, float): + value = Decimal.from_float(value) + return super(Decimal, cls).__new__(cls, value, *args, **kwargs) + + def __mul__(self, rhs): + if isinstance(rhs, float): + rhs = Decimal.from_float(rhs) + return Decimal(super().__mul__(rhs)) + + def __rmul__(self, lhs): + return self.__mul__(lhs) + + def __add__(self, rhs): + if isinstance(rhs, float): + rhs = Decimal.from_float(rhs) + return Decimal(super().__add__(rhs)) + + def __radd__(self, lhs): + return self.__add__(lhs) + + def __sub__(self, rhs): + if isinstance(rhs, float): + rhs = Decimal.from_float(rhs) + return Decimal(super().__sub__(rhs)) + + def __rsub__(self, lhs): + return self.__sub__(lhs) + + def __truediv__(self, rhs): + if isinstance(rhs, float): + rhs = Decimal.from_float(rhs) + return Decimal(super().__truediv__(rhs)) + + def __rtruediv__(self, rhs): + return self.__truediv__(rhs) + + def __floordiv__(self, rhs): + if isinstance(rhs, float): + rhs = Decimal.from_float(rhs) + return Decimal(super().__floordiv__(rhs)) + + def __rfloordiv__ (self, rhs): + return self.__floordiv__(rhs) diff --git a/bfxapi/websockets/BfxWebsocket.py b/bfxapi/websockets/BfxWebsocket.py index 79d8c48..0c760b2 100644 --- a/bfxapi/websockets/BfxWebsocket.py +++ b/bfxapi/websockets/BfxWebsocket.py @@ -7,7 +7,6 @@ import json import time import random -from decimal import * from .GenericWebsocket import GenericWebsocket, AuthError from .SubscriptionManager import SubscriptionManager from .WalletManager import WalletManager