add
This commit is contained in:
27
ccxt/base/__init__.py
Normal file
27
ccxt/base/__init__.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# MIT License
|
||||
# Copyright (c) 2017 Igor Kroitor
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
|
||||
# The above copyright notice and this permission notice shall be included in all
|
||||
# copies or substantial portions of the Software.
|
||||
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
|
||||
from ccxt.base import errors
|
||||
from ccxt.base import exchange
|
||||
from ccxt.base import decimal_to_precision
|
||||
|
||||
__all__ = exchange.__all__ + decimal_to_precision.__all__ + errors.__all__ # noqa: F405
|
||||
BIN
ccxt/base/__pycache__/__init__.cpython-311.pyc
Normal file
BIN
ccxt/base/__pycache__/__init__.cpython-311.pyc
Normal file
Binary file not shown.
BIN
ccxt/base/__pycache__/__init__.cpython-36.pyc
Normal file
BIN
ccxt/base/__pycache__/__init__.cpython-36.pyc
Normal file
Binary file not shown.
BIN
ccxt/base/__pycache__/decimal_to_precision.cpython-311.pyc
Normal file
BIN
ccxt/base/__pycache__/decimal_to_precision.cpython-311.pyc
Normal file
Binary file not shown.
BIN
ccxt/base/__pycache__/decimal_to_precision.cpython-36.pyc
Normal file
BIN
ccxt/base/__pycache__/decimal_to_precision.cpython-36.pyc
Normal file
Binary file not shown.
BIN
ccxt/base/__pycache__/errors.cpython-311.pyc
Normal file
BIN
ccxt/base/__pycache__/errors.cpython-311.pyc
Normal file
Binary file not shown.
BIN
ccxt/base/__pycache__/errors.cpython-36.pyc
Normal file
BIN
ccxt/base/__pycache__/errors.cpython-36.pyc
Normal file
Binary file not shown.
BIN
ccxt/base/__pycache__/exchange.cpython-311.pyc
Normal file
BIN
ccxt/base/__pycache__/exchange.cpython-311.pyc
Normal file
Binary file not shown.
BIN
ccxt/base/__pycache__/exchange.cpython-36.pyc
Normal file
BIN
ccxt/base/__pycache__/exchange.cpython-36.pyc
Normal file
Binary file not shown.
BIN
ccxt/base/__pycache__/precise.cpython-311.pyc
Normal file
BIN
ccxt/base/__pycache__/precise.cpython-311.pyc
Normal file
Binary file not shown.
BIN
ccxt/base/__pycache__/precise.cpython-36.pyc
Normal file
BIN
ccxt/base/__pycache__/precise.cpython-36.pyc
Normal file
Binary file not shown.
BIN
ccxt/base/__pycache__/types.cpython-311.pyc
Normal file
BIN
ccxt/base/__pycache__/types.cpython-311.pyc
Normal file
Binary file not shown.
BIN
ccxt/base/__pycache__/types.cpython-36.pyc
Normal file
BIN
ccxt/base/__pycache__/types.cpython-36.pyc
Normal file
Binary file not shown.
178
ccxt/base/decimal_to_precision.py
Normal file
178
ccxt/base/decimal_to_precision.py
Normal file
@@ -0,0 +1,178 @@
|
||||
import decimal
|
||||
import numbers
|
||||
import itertools
|
||||
import re
|
||||
|
||||
__all__ = [
|
||||
'TRUNCATE',
|
||||
'ROUND',
|
||||
'ROUND_UP',
|
||||
'ROUND_DOWN',
|
||||
'DECIMAL_PLACES',
|
||||
'SIGNIFICANT_DIGITS',
|
||||
'TICK_SIZE',
|
||||
'NO_PADDING',
|
||||
'PAD_WITH_ZERO',
|
||||
'decimal_to_precision',
|
||||
]
|
||||
|
||||
|
||||
# rounding mode
|
||||
TRUNCATE = 0
|
||||
ROUND = 1
|
||||
ROUND_UP = 2
|
||||
ROUND_DOWN = 3
|
||||
|
||||
# digits counting mode
|
||||
DECIMAL_PLACES = 2
|
||||
SIGNIFICANT_DIGITS = 3
|
||||
TICK_SIZE = 4
|
||||
|
||||
# padding mode
|
||||
NO_PADDING = 5
|
||||
PAD_WITH_ZERO = 6
|
||||
|
||||
|
||||
def decimal_to_precision(n, rounding_mode=ROUND, precision=None, counting_mode=DECIMAL_PLACES, padding_mode=NO_PADDING):
|
||||
assert precision is not None, 'precision should not be None'
|
||||
|
||||
if isinstance(precision, str):
|
||||
precision = float(precision)
|
||||
assert isinstance(precision, float) or isinstance(precision, decimal.Decimal) or isinstance(precision, numbers.Integral), 'precision has an invalid number'
|
||||
|
||||
if counting_mode == TICK_SIZE:
|
||||
assert precision > 0, 'negative or zero precision can not be used with TICK_SIZE precisionMode'
|
||||
else:
|
||||
assert isinstance(precision, numbers.Integral)
|
||||
|
||||
assert rounding_mode in [TRUNCATE, ROUND]
|
||||
assert counting_mode in [DECIMAL_PLACES, SIGNIFICANT_DIGITS, TICK_SIZE]
|
||||
assert padding_mode in [NO_PADDING, PAD_WITH_ZERO]
|
||||
# end of checks
|
||||
|
||||
context = decimal.getcontext()
|
||||
|
||||
if counting_mode != TICK_SIZE:
|
||||
precision = min(context.prec - 2, precision)
|
||||
|
||||
# all default except decimal.Underflow (raised when a number is rounded to zero)
|
||||
context.traps[decimal.Underflow] = True
|
||||
context.rounding = decimal.ROUND_HALF_UP # rounds 0.5 away from zero
|
||||
|
||||
dec = decimal.Decimal(str(n))
|
||||
precision_dec = decimal.Decimal(str(precision))
|
||||
string = '{:f}'.format(dec) # convert to string using .format to avoid engineering notation
|
||||
precise = None
|
||||
|
||||
def power_of_10(x):
|
||||
return decimal.Decimal('10') ** (-x)
|
||||
|
||||
if precision < 0:
|
||||
if counting_mode == TICK_SIZE:
|
||||
raise ValueError('TICK_SIZE cant be used with negative numPrecisionDigits')
|
||||
to_nearest = power_of_10(precision)
|
||||
if rounding_mode == ROUND:
|
||||
return "{:f}".format(to_nearest * decimal.Decimal(decimal_to_precision(dec / to_nearest, rounding_mode, 0, DECIMAL_PLACES, padding_mode)))
|
||||
elif rounding_mode == TRUNCATE:
|
||||
return decimal_to_precision(dec - dec % to_nearest, rounding_mode, 0, DECIMAL_PLACES, padding_mode)
|
||||
|
||||
if counting_mode == TICK_SIZE:
|
||||
# python modulo with negative numbers behaves different than js/php, so use abs first
|
||||
missing = abs(dec) % precision_dec
|
||||
if missing != 0:
|
||||
if rounding_mode == ROUND:
|
||||
if dec > 0:
|
||||
if missing >= precision_dec / 2:
|
||||
dec = dec - missing + precision_dec
|
||||
else:
|
||||
dec = dec - missing
|
||||
else:
|
||||
if missing >= precision_dec / 2:
|
||||
dec = dec + missing - precision_dec
|
||||
else:
|
||||
dec = dec + missing
|
||||
elif rounding_mode == TRUNCATE:
|
||||
if dec < 0:
|
||||
dec = dec + missing
|
||||
else:
|
||||
dec = dec - missing
|
||||
parts = re.sub(r'0+$', '', '{:f}'.format(precision_dec)).split('.')
|
||||
if len(parts) > 1:
|
||||
new_precision = len(parts[1])
|
||||
else:
|
||||
match = re.search(r'0+$', parts[0])
|
||||
if match is None:
|
||||
new_precision = 0
|
||||
else:
|
||||
new_precision = - len(match.group(0))
|
||||
return decimal_to_precision('{:f}'.format(dec), ROUND, new_precision, DECIMAL_PLACES, padding_mode)
|
||||
|
||||
if rounding_mode == ROUND:
|
||||
if counting_mode == DECIMAL_PLACES:
|
||||
precise = '{:f}'.format(dec.quantize(power_of_10(precision))) # ROUND_HALF_EVEN is default context
|
||||
elif counting_mode == SIGNIFICANT_DIGITS:
|
||||
q = precision - dec.adjusted() - 1
|
||||
sigfig = power_of_10(q)
|
||||
if q < 0:
|
||||
string_to_precision = string[:precision]
|
||||
# string_to_precision is '' when we have zero precision
|
||||
below = sigfig * decimal.Decimal(string_to_precision if string_to_precision else '0')
|
||||
above = below + sigfig
|
||||
precise = '{:f}'.format(min((below, above), key=lambda x: abs(x - dec)))
|
||||
else:
|
||||
precise = '{:f}'.format(dec.quantize(sigfig))
|
||||
if precise.startswith('-0') and all(c in '0.' for c in precise[1:]):
|
||||
precise = precise[1:]
|
||||
|
||||
elif rounding_mode == TRUNCATE:
|
||||
# Slice a string
|
||||
if counting_mode == DECIMAL_PLACES:
|
||||
before, after = string.split('.') if '.' in string else (string, '')
|
||||
precise = before + '.' + after[:precision]
|
||||
elif counting_mode == SIGNIFICANT_DIGITS:
|
||||
if precision == 0:
|
||||
return '0'
|
||||
dot = string.index('.') if '.' in string else len(string)
|
||||
start = dot - dec.adjusted()
|
||||
end = start + precision
|
||||
# need to clarify these conditionals
|
||||
if dot >= end:
|
||||
end -= 1
|
||||
if precision >= len(string.replace('.', '')):
|
||||
precise = string
|
||||
else:
|
||||
precise = string[:end].ljust(dot, '0')
|
||||
if precise.startswith('-0') and all(c in '0.' for c in precise[1:]):
|
||||
precise = precise[1:]
|
||||
precise = precise.rstrip('.')
|
||||
|
||||
if padding_mode == NO_PADDING:
|
||||
return precise.rstrip('0').rstrip('.') if '.' in precise else precise
|
||||
elif padding_mode == PAD_WITH_ZERO:
|
||||
if '.' in precise:
|
||||
if counting_mode == DECIMAL_PLACES:
|
||||
before, after = precise.split('.')
|
||||
return before + '.' + after.ljust(precision, '0')
|
||||
|
||||
elif counting_mode == SIGNIFICANT_DIGITS:
|
||||
fsfg = len(list(itertools.takewhile(lambda x: x == '.' or x == '0', precise)))
|
||||
if '.' in precise[fsfg:]:
|
||||
precision += 1
|
||||
return precise[:fsfg] + precise[fsfg:].rstrip('0').ljust(precision, '0')
|
||||
else:
|
||||
if counting_mode == SIGNIFICANT_DIGITS:
|
||||
if precision > len(precise):
|
||||
return precise + '.' + (precision - len(precise)) * '0'
|
||||
elif counting_mode == DECIMAL_PLACES:
|
||||
if precision > 0:
|
||||
return precise + '.' + precision * '0'
|
||||
return precise
|
||||
|
||||
|
||||
def number_to_string(x):
|
||||
# avoids scientific notation for too large and too small numbers
|
||||
if x is None:
|
||||
return None
|
||||
d = decimal.Decimal(str(x))
|
||||
formatted = '{:f}'.format(d)
|
||||
return formatted.rstrip('0').rstrip('.') if '.' in formatted else formatted
|
||||
273
ccxt/base/errors.py
Normal file
273
ccxt/base/errors.py
Normal file
@@ -0,0 +1,273 @@
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
||||
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
||||
# EDIT THE CORRESPONDENT .ts FILE INSTEAD
|
||||
|
||||
error_hierarchy = {
|
||||
'BaseError': {
|
||||
'ExchangeError': {
|
||||
'AuthenticationError': {
|
||||
'PermissionDenied': {
|
||||
'AccountNotEnabled': {},
|
||||
},
|
||||
'AccountSuspended': {},
|
||||
},
|
||||
'ArgumentsRequired': {},
|
||||
'BadRequest': {
|
||||
'BadSymbol': {},
|
||||
},
|
||||
'OperationRejected': {
|
||||
'NoChange': {
|
||||
'MarginModeAlreadySet': {},
|
||||
},
|
||||
'MarketClosed': {},
|
||||
'ManualInteractionNeeded': {},
|
||||
'RestrictedLocation': {},
|
||||
},
|
||||
'InsufficientFunds': {},
|
||||
'InvalidAddress': {
|
||||
'AddressPending': {},
|
||||
},
|
||||
'InvalidOrder': {
|
||||
'OrderNotFound': {},
|
||||
'OrderNotCached': {},
|
||||
'OrderImmediatelyFillable': {},
|
||||
'OrderNotFillable': {},
|
||||
'DuplicateOrderId': {},
|
||||
'ContractUnavailable': {},
|
||||
},
|
||||
'NotSupported': {},
|
||||
'InvalidProxySettings': {},
|
||||
'ExchangeClosedByUser': {},
|
||||
},
|
||||
'OperationFailed': {
|
||||
'NetworkError': {
|
||||
'DDoSProtection': {},
|
||||
'RateLimitExceeded': {},
|
||||
'ExchangeNotAvailable': {
|
||||
'OnMaintenance': {},
|
||||
},
|
||||
'InvalidNonce': {
|
||||
'ChecksumError': {},
|
||||
},
|
||||
'RequestTimeout': {},
|
||||
},
|
||||
'BadResponse': {
|
||||
'NullResponse': {},
|
||||
},
|
||||
'CancelPending': {},
|
||||
},
|
||||
'UnsubscribeError': {},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class BaseError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class ExchangeError(BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class AuthenticationError(ExchangeError):
|
||||
pass
|
||||
|
||||
|
||||
class PermissionDenied(AuthenticationError):
|
||||
pass
|
||||
|
||||
|
||||
class AccountNotEnabled(PermissionDenied):
|
||||
pass
|
||||
|
||||
|
||||
class AccountSuspended(AuthenticationError):
|
||||
pass
|
||||
|
||||
|
||||
class ArgumentsRequired(ExchangeError):
|
||||
pass
|
||||
|
||||
|
||||
class BadRequest(ExchangeError):
|
||||
pass
|
||||
|
||||
|
||||
class BadSymbol(BadRequest):
|
||||
pass
|
||||
|
||||
|
||||
class OperationRejected(ExchangeError):
|
||||
pass
|
||||
|
||||
|
||||
class NoChange(OperationRejected):
|
||||
pass
|
||||
|
||||
|
||||
class MarginModeAlreadySet(NoChange):
|
||||
pass
|
||||
|
||||
|
||||
class MarketClosed(OperationRejected):
|
||||
pass
|
||||
|
||||
|
||||
class ManualInteractionNeeded(OperationRejected):
|
||||
pass
|
||||
|
||||
|
||||
class RestrictedLocation(OperationRejected):
|
||||
pass
|
||||
|
||||
|
||||
class InsufficientFunds(ExchangeError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidAddress(ExchangeError):
|
||||
pass
|
||||
|
||||
|
||||
class AddressPending(InvalidAddress):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidOrder(ExchangeError):
|
||||
pass
|
||||
|
||||
|
||||
class OrderNotFound(InvalidOrder):
|
||||
pass
|
||||
|
||||
|
||||
class OrderNotCached(InvalidOrder):
|
||||
pass
|
||||
|
||||
|
||||
class OrderImmediatelyFillable(InvalidOrder):
|
||||
pass
|
||||
|
||||
|
||||
class OrderNotFillable(InvalidOrder):
|
||||
pass
|
||||
|
||||
|
||||
class DuplicateOrderId(InvalidOrder):
|
||||
pass
|
||||
|
||||
|
||||
class ContractUnavailable(InvalidOrder):
|
||||
pass
|
||||
|
||||
|
||||
class NotSupported(ExchangeError):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidProxySettings(ExchangeError):
|
||||
pass
|
||||
|
||||
|
||||
class ExchangeClosedByUser(ExchangeError):
|
||||
pass
|
||||
|
||||
|
||||
class OperationFailed(BaseError):
|
||||
pass
|
||||
|
||||
|
||||
class NetworkError(OperationFailed):
|
||||
pass
|
||||
|
||||
|
||||
class DDoSProtection(NetworkError):
|
||||
pass
|
||||
|
||||
|
||||
class RateLimitExceeded(NetworkError):
|
||||
pass
|
||||
|
||||
|
||||
class ExchangeNotAvailable(NetworkError):
|
||||
pass
|
||||
|
||||
|
||||
class OnMaintenance(ExchangeNotAvailable):
|
||||
pass
|
||||
|
||||
|
||||
class InvalidNonce(NetworkError):
|
||||
pass
|
||||
|
||||
|
||||
class ChecksumError(InvalidNonce):
|
||||
pass
|
||||
|
||||
|
||||
class RequestTimeout(NetworkError):
|
||||
pass
|
||||
|
||||
|
||||
class BadResponse(OperationFailed):
|
||||
pass
|
||||
|
||||
|
||||
class NullResponse(BadResponse):
|
||||
pass
|
||||
|
||||
|
||||
class CancelPending(OperationFailed):
|
||||
pass
|
||||
|
||||
|
||||
class UnsubscribeError(BaseError):
|
||||
pass
|
||||
|
||||
|
||||
__all__ = [
|
||||
'error_hierarchy',
|
||||
'BaseError',
|
||||
'ExchangeError',
|
||||
'AuthenticationError',
|
||||
'PermissionDenied',
|
||||
'AccountNotEnabled',
|
||||
'AccountSuspended',
|
||||
'ArgumentsRequired',
|
||||
'BadRequest',
|
||||
'BadSymbol',
|
||||
'OperationRejected',
|
||||
'NoChange',
|
||||
'MarginModeAlreadySet',
|
||||
'MarketClosed',
|
||||
'ManualInteractionNeeded',
|
||||
'RestrictedLocation',
|
||||
'InsufficientFunds',
|
||||
'InvalidAddress',
|
||||
'AddressPending',
|
||||
'InvalidOrder',
|
||||
'OrderNotFound',
|
||||
'OrderNotCached',
|
||||
'OrderImmediatelyFillable',
|
||||
'OrderNotFillable',
|
||||
'DuplicateOrderId',
|
||||
'ContractUnavailable',
|
||||
'NotSupported',
|
||||
'InvalidProxySettings',
|
||||
'ExchangeClosedByUser',
|
||||
'OperationFailed',
|
||||
'NetworkError',
|
||||
'DDoSProtection',
|
||||
'RateLimitExceeded',
|
||||
'ExchangeNotAvailable',
|
||||
'OnMaintenance',
|
||||
'InvalidNonce',
|
||||
'ChecksumError',
|
||||
'RequestTimeout',
|
||||
'BadResponse',
|
||||
'NullResponse',
|
||||
'CancelPending',
|
||||
'UnsubscribeError'
|
||||
]
|
||||
7447
ccxt/base/exchange.py
Normal file
7447
ccxt/base/exchange.py
Normal file
File diff suppressed because it is too large
Load Diff
297
ccxt/base/precise.py
Normal file
297
ccxt/base/precise.py
Normal file
@@ -0,0 +1,297 @@
|
||||
# Author: carlo.revelli@berkeley.edu
|
||||
#
|
||||
# Precise
|
||||
# Representation
|
||||
# Expanding
|
||||
# CCXT
|
||||
# Internal
|
||||
# Scientific
|
||||
# Exponents
|
||||
#
|
||||
# (╯°□°)╯︵ ┻━┻
|
||||
|
||||
|
||||
class Precise:
|
||||
def __init__(self, number, decimals=None):
|
||||
if decimals is None:
|
||||
modifier = 0
|
||||
number = number.lower()
|
||||
if 'e' in number:
|
||||
number, modifier = number.split('e')
|
||||
modifier = int(modifier)
|
||||
decimal_index = number.find('.')
|
||||
if decimal_index > -1:
|
||||
self.decimals = len(number) - decimal_index - 1
|
||||
self.integer = int(number.replace('.', ''))
|
||||
else:
|
||||
self.decimals = 0
|
||||
self.integer = int(number)
|
||||
self.decimals = self.decimals - modifier
|
||||
else:
|
||||
self.integer = number
|
||||
self.decimals = decimals
|
||||
self.base = 10
|
||||
|
||||
def __add__(self, other):
|
||||
return self.add(other)
|
||||
|
||||
def __sub__(self, other):
|
||||
return self.sub(other)
|
||||
|
||||
def __mul__(self, other):
|
||||
return self.mul(other)
|
||||
|
||||
def __truediv__(self, other):
|
||||
return self.div(other)
|
||||
|
||||
def __mod__(self, other):
|
||||
return self.mod(other)
|
||||
|
||||
def __neg__(self):
|
||||
return self.neg()
|
||||
|
||||
def __abs__(self):
|
||||
return self.abs()
|
||||
|
||||
def __min__(self, other):
|
||||
return self.min(other)
|
||||
|
||||
def __max__(self, other):
|
||||
return self.max(other)
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.lt(other)
|
||||
|
||||
def __le__(self, other):
|
||||
return self.le(other)
|
||||
|
||||
def __gt__(self, other):
|
||||
return self.gt(other)
|
||||
|
||||
def __ge__(self, other):
|
||||
return self.ge(other)
|
||||
|
||||
def __eq__(self, other):
|
||||
if isinstance(other, str):
|
||||
# Allow comparisons with Precise("5") == "5"
|
||||
return str(self) == other
|
||||
return self.equals(other)
|
||||
|
||||
def mul(self, other):
|
||||
integer_result = self.integer * other.integer
|
||||
return Precise(integer_result, self.decimals + other.decimals)
|
||||
|
||||
def div(self, other, precision=18):
|
||||
distance = precision - self.decimals + other.decimals
|
||||
if distance == 0:
|
||||
numerator = self.integer
|
||||
elif distance < 0:
|
||||
exponent = self.base ** -distance
|
||||
numerator = self.integer // exponent
|
||||
else:
|
||||
exponent = self.base ** distance
|
||||
numerator = self.integer * exponent
|
||||
result, mod = divmod(numerator, other.integer)
|
||||
# python floors negative numbers down instead of truncating
|
||||
# if mod is zero it will be floored to itself so we do not add one
|
||||
result = result + 1 if result < 0 and mod else result
|
||||
return Precise(result, precision)
|
||||
|
||||
def add(self, other):
|
||||
if self.decimals == other.decimals:
|
||||
integer_result = self.integer + other.integer
|
||||
return Precise(integer_result, self.decimals)
|
||||
else:
|
||||
smaller, bigger = [other, self] if self.decimals > other.decimals else [self, other]
|
||||
exponent = bigger.decimals - smaller.decimals
|
||||
normalised = smaller.integer * (self.base ** exponent)
|
||||
result = normalised + bigger.integer
|
||||
return Precise(result, bigger.decimals)
|
||||
|
||||
def sub(self, other):
|
||||
negative = Precise(-other.integer, other.decimals)
|
||||
return self.add(negative)
|
||||
|
||||
def abs(self):
|
||||
return Precise(abs(self.integer), self.decimals)
|
||||
|
||||
def neg(self):
|
||||
return Precise(-self.integer, self.decimals)
|
||||
|
||||
def mod(self, other):
|
||||
rationizerNumberator = max(-self.decimals + other.decimals, 0)
|
||||
numerator = self.integer * (self.base ** rationizerNumberator)
|
||||
rationizerDenominator = max(-other.decimals + self.decimals, 0)
|
||||
denominator = other.integer * (self.base ** rationizerDenominator)
|
||||
result = numerator % denominator
|
||||
return Precise(result, rationizerDenominator + other.decimals)
|
||||
|
||||
def orn(self, other):
|
||||
integer_result = self.integer | other.integer
|
||||
return Precise(integer_result, self.decimals)
|
||||
|
||||
def min(self, other):
|
||||
return self if self.lt(other) else other
|
||||
|
||||
def max(self, other):
|
||||
return self if self.gt(other) else other
|
||||
|
||||
def gt(self, other):
|
||||
add = self.sub(other)
|
||||
return add.integer > 0
|
||||
|
||||
def ge(self, other):
|
||||
add = self.sub(other)
|
||||
return add.integer >= 0
|
||||
|
||||
def lt(self, other):
|
||||
return other.gt(self)
|
||||
|
||||
def le(self, other):
|
||||
return other.ge(self)
|
||||
|
||||
def reduce(self):
|
||||
string = str(self.integer)
|
||||
start = len(string) - 1
|
||||
if start == 0:
|
||||
if string == "0":
|
||||
self.decimals = 0
|
||||
return self
|
||||
for i in range(start, -1, -1):
|
||||
if string[i] != '0':
|
||||
break
|
||||
difference = start - i
|
||||
if difference == 0:
|
||||
return self
|
||||
self.decimals -= difference
|
||||
self.integer = int(string[:i + 1])
|
||||
|
||||
def equals(self, other):
|
||||
self.reduce()
|
||||
other.reduce()
|
||||
return self.decimals == other.decimals and self.integer == other.integer
|
||||
|
||||
def __str__(self):
|
||||
self.reduce()
|
||||
sign = '-' if self.integer < 0 else ''
|
||||
integer_array = list(str(abs(self.integer)).rjust(self.decimals, '0'))
|
||||
index = len(integer_array) - self.decimals
|
||||
if index == 0:
|
||||
item = '0.'
|
||||
elif self.decimals < 0:
|
||||
item = '0' * (-self.decimals)
|
||||
elif self.decimals == 0:
|
||||
item = ''
|
||||
else:
|
||||
item = '.'
|
||||
integer_array.insert(index, item)
|
||||
return sign + ''.join(integer_array)
|
||||
|
||||
def __repr__(self):
|
||||
return "Precise(" + str(self) + ")"
|
||||
|
||||
def __float__(self):
|
||||
return float(str(self))
|
||||
|
||||
@staticmethod
|
||||
def string_mul(string1, string2):
|
||||
if string1 is None or string2 is None:
|
||||
return None
|
||||
return str(Precise(string1).mul(Precise(string2)))
|
||||
|
||||
@staticmethod
|
||||
def string_div(string1, string2, precision=18):
|
||||
if string1 is None or string2 is None:
|
||||
return None
|
||||
string2_precise = Precise(string2)
|
||||
if string2_precise.integer == 0:
|
||||
return None
|
||||
return str(Precise(string1).div(string2_precise, precision))
|
||||
|
||||
@staticmethod
|
||||
def string_add(string1, string2):
|
||||
if string1 is None and string2 is None:
|
||||
return None
|
||||
if string1 is None:
|
||||
return string2
|
||||
elif string2 is None:
|
||||
return string1
|
||||
return str(Precise(string1).add(Precise(string2)))
|
||||
|
||||
@staticmethod
|
||||
def string_sub(string1, string2):
|
||||
if string1 is None or string2 is None:
|
||||
return None
|
||||
return str(Precise(string1).sub(Precise(string2)))
|
||||
|
||||
@staticmethod
|
||||
def string_abs(string):
|
||||
if string is None:
|
||||
return None
|
||||
return str(Precise(string).abs())
|
||||
|
||||
@staticmethod
|
||||
def string_neg(string):
|
||||
if string is None:
|
||||
return None
|
||||
return str(Precise(string).neg())
|
||||
|
||||
@staticmethod
|
||||
def string_mod(string1, string2):
|
||||
if string1 is None or string2 is None:
|
||||
return None
|
||||
return str(Precise(string1).mod(Precise(string2)))
|
||||
|
||||
@staticmethod
|
||||
def string_or(string1, string2):
|
||||
if string1 is None or string2 is None:
|
||||
return None
|
||||
return str(Precise(string1).orn(Precise(string2)))
|
||||
|
||||
@staticmethod
|
||||
def string_equals(string1, string2):
|
||||
if string1 is None or string2 is None:
|
||||
return None
|
||||
return Precise(string1).equals(Precise(string2))
|
||||
|
||||
@staticmethod
|
||||
def string_eq(string1, string2):
|
||||
if string1 is None or string2 is None:
|
||||
return None
|
||||
return Precise(string1).equals(Precise(string2))
|
||||
|
||||
@staticmethod
|
||||
def string_min(string1, string2):
|
||||
if string1 is None or string2 is None:
|
||||
return None
|
||||
return str(Precise(string1).min(Precise(string2)))
|
||||
|
||||
@staticmethod
|
||||
def string_max(string1, string2):
|
||||
if string1 is None or string2 is None:
|
||||
return None
|
||||
return str(Precise(string1).max(Precise(string2)))
|
||||
|
||||
@staticmethod
|
||||
def string_gt(string1, string2):
|
||||
if string1 is None or string2 is None:
|
||||
return None
|
||||
return Precise(string1).gt(Precise(string2))
|
||||
|
||||
@staticmethod
|
||||
def string_ge(string1, string2):
|
||||
if string1 is None or string2 is None:
|
||||
return None
|
||||
return Precise(string1).ge(Precise(string2))
|
||||
|
||||
@staticmethod
|
||||
def string_lt(string1, string2):
|
||||
if string1 is None or string2 is None:
|
||||
return None
|
||||
return Precise(string1).lt(Precise(string2))
|
||||
|
||||
@staticmethod
|
||||
def string_le(string1, string2):
|
||||
if string1 is None or string2 is None:
|
||||
return None
|
||||
return Precise(string1).le(Precise(string2))
|
||||
612
ccxt/base/types.py
Normal file
612
ccxt/base/types.py
Normal file
@@ -0,0 +1,612 @@
|
||||
import sys
|
||||
import types
|
||||
from typing import Union, List, Optional, Any as PythonAny
|
||||
from decimal import Decimal
|
||||
|
||||
|
||||
if sys.version_info >= (3, 8):
|
||||
from typing import TypedDict, Literal, Dict
|
||||
else:
|
||||
from typing import Dict
|
||||
from typing_extensions import Literal
|
||||
TypedDict = Dict
|
||||
|
||||
if sys.version_info >= (3, 11):
|
||||
from typing import NotRequired
|
||||
else:
|
||||
from typing_extensions import NotRequired
|
||||
|
||||
|
||||
OrderSide = Literal['buy', 'sell']
|
||||
OrderType = Literal['limit', 'market']
|
||||
PositionSide = Literal['long', 'short']
|
||||
Any = PythonAny
|
||||
|
||||
|
||||
class Entry:
|
||||
def __init__(self, path, api, method, config):
|
||||
self.name = None
|
||||
self.path = path
|
||||
self.api = api
|
||||
self.method = method
|
||||
self.config = config
|
||||
|
||||
def unbound_method(_self, params={}):
|
||||
return _self.request(self.path, self.api, self.method, params, config=self.config)
|
||||
|
||||
self.unbound_method = unbound_method
|
||||
|
||||
def __get__(self, instance, owner):
|
||||
if instance is None:
|
||||
return self.unbound_method
|
||||
else:
|
||||
return types.MethodType(self.unbound_method, instance)
|
||||
|
||||
def __set_name__(self, owner, name):
|
||||
self.name = name
|
||||
|
||||
|
||||
IndexType = Union[str, int]
|
||||
Num = Union[None, str, float, int, Decimal]
|
||||
Str = Optional[str]
|
||||
Strings = Optional[List[str]]
|
||||
Int = Optional[int]
|
||||
Bool = Optional[bool]
|
||||
MarketType = Literal['spot', 'margin', 'swap', 'future', 'option']
|
||||
SubType = Literal['linear', 'inverse']
|
||||
|
||||
|
||||
class FeeInterface(TypedDict):
|
||||
currency: Str
|
||||
cost: Num
|
||||
rate: NotRequired[Num]
|
||||
|
||||
|
||||
Fee = Optional[FeeInterface]
|
||||
|
||||
|
||||
class TradingFeeInterface(TypedDict):
|
||||
info: Dict[str, Any]
|
||||
symbol: Str
|
||||
maker: Num
|
||||
taker: Num
|
||||
percentage: Bool
|
||||
tierBased: Bool
|
||||
|
||||
|
||||
class Balance(TypedDict):
|
||||
free: Num
|
||||
used: Num
|
||||
total: Num
|
||||
debt: NotRequired[Num]
|
||||
|
||||
|
||||
class BalanceAccount(TypedDict):
|
||||
free: Str
|
||||
used: Str
|
||||
total: Str
|
||||
|
||||
|
||||
class Account(TypedDict):
|
||||
id: Str
|
||||
type: Str
|
||||
code: Str
|
||||
info: Dict[str, Any]
|
||||
|
||||
|
||||
class Trade(TypedDict):
|
||||
info: Dict[str, Any]
|
||||
amount: Num
|
||||
datetime: Str
|
||||
id: Str
|
||||
order: Str
|
||||
price: Num
|
||||
timestamp: Int
|
||||
type: Str
|
||||
side: Str
|
||||
symbol: Str
|
||||
takerOrMaker: Str
|
||||
cost: Num
|
||||
fee: Fee
|
||||
|
||||
|
||||
class Position(TypedDict):
|
||||
info: Dict[str, Any]
|
||||
symbol: Str
|
||||
id: Str
|
||||
timestamp: Int
|
||||
datetime: Str
|
||||
contracts: Num
|
||||
contractSize: Num
|
||||
side: Str
|
||||
notional: Num
|
||||
leverage: Num
|
||||
unrealizedPnl: Num
|
||||
realizedPnl: Num
|
||||
collateral: Num
|
||||
entryPrice: Num
|
||||
markPrice: Num
|
||||
liquidationPrice: Num
|
||||
hedged: bool
|
||||
maintenanceMargin: Num
|
||||
initialMargin: Num
|
||||
initialMarginPercentage: Num
|
||||
marginMode: Str
|
||||
marginRatio: Num
|
||||
lastUpdateTimestamp: Int
|
||||
lastPrice: Num
|
||||
percentage: Num
|
||||
stopLossPrice: Num
|
||||
takeProfitPrice: Num
|
||||
|
||||
class OrderRequest(TypedDict):
|
||||
symbol: Str
|
||||
type: Str
|
||||
side: Str
|
||||
amount: Union[None, float]
|
||||
price: Union[None, float]
|
||||
params: Dict[str, Any]
|
||||
|
||||
|
||||
class CancellationRequest(TypedDict):
|
||||
id: Str
|
||||
symbol: Str
|
||||
clientOrderId: Str
|
||||
|
||||
|
||||
class Order(TypedDict):
|
||||
info: Dict[str, Any]
|
||||
id: Str
|
||||
clientOrderId: Str
|
||||
datetime: Str
|
||||
timestamp: Int
|
||||
lastTradeTimestamp: Int
|
||||
lastUpdateTimestamp: Int
|
||||
status: Str
|
||||
symbol: Str
|
||||
type: Str
|
||||
timeInForce: Str
|
||||
side: OrderSide
|
||||
price: Num
|
||||
average: Num
|
||||
amount: Num
|
||||
filled: Num
|
||||
remaining: Num
|
||||
stopPrice: Num
|
||||
takeProfitPrice: Num
|
||||
stopLossPrice: Num
|
||||
cost: Num
|
||||
trades: List[Trade]
|
||||
reduceOnly: Bool
|
||||
postOnly: Bool
|
||||
fee: Fee
|
||||
|
||||
|
||||
class Liquidation(TypedDict):
|
||||
info: Dict[str, Any]
|
||||
symbol: Str
|
||||
timestamp: Int
|
||||
datetime: Str
|
||||
price: Num
|
||||
baseValue: Num
|
||||
quoteValue: Num
|
||||
side: OrderSide
|
||||
contracts: Num
|
||||
contractSize: Num
|
||||
|
||||
|
||||
class FundingHistory(TypedDict):
|
||||
info: Dict[str, Any]
|
||||
symbol: Str
|
||||
code: Str
|
||||
timestamp: Int
|
||||
datetime: Str
|
||||
id: Str
|
||||
amount: Num
|
||||
|
||||
|
||||
class Balances(Dict[str, Balance]):
|
||||
datetime: Str
|
||||
timestamp: Int
|
||||
|
||||
|
||||
class OrderBook(TypedDict):
|
||||
asks: List[List[Num]]
|
||||
bids: List[List[Num]]
|
||||
datetime: Str
|
||||
timestamp: Int
|
||||
nonce: Int
|
||||
symbol: Str
|
||||
|
||||
|
||||
class Transaction(TypedDict):
|
||||
info: Dict[str, any]
|
||||
id: Str
|
||||
txid: Str
|
||||
timestamp: Int
|
||||
datetime: Str
|
||||
address: Str
|
||||
addressFrom: Str
|
||||
addressTo: Str
|
||||
tag: Str
|
||||
tagFrom: Str
|
||||
tagTo: Str
|
||||
type: Str
|
||||
amount: Num
|
||||
currency: Str
|
||||
status: Str
|
||||
updated: Int
|
||||
fee: Fee
|
||||
network: Str
|
||||
comment: Str
|
||||
internal: Bool
|
||||
|
||||
|
||||
class TransferEntry(TypedDict):
|
||||
info: Dict[str, any]
|
||||
id: Str
|
||||
timestamp: Int
|
||||
datetime: Str
|
||||
currency: Str
|
||||
amount: Num
|
||||
fromAccount: Str
|
||||
toAccount: Str
|
||||
status: Str
|
||||
|
||||
|
||||
class Ticker(TypedDict):
|
||||
info: Dict[str, Any]
|
||||
symbol: Str
|
||||
timestamp: Int
|
||||
datetime: Str
|
||||
high: Num
|
||||
low: Num
|
||||
bid: Num
|
||||
bidVolume: Num
|
||||
ask: Num
|
||||
askVolume: Num
|
||||
vwap: Num
|
||||
open: Num
|
||||
close: Num
|
||||
last: Num
|
||||
previousClose: Num
|
||||
change: Num
|
||||
percentage: Num
|
||||
average: Num
|
||||
quoteVolume: Num
|
||||
baseVolume: Num
|
||||
markPrice: Num
|
||||
indexPrice: Num
|
||||
|
||||
|
||||
Tickers = Dict[str, Ticker]
|
||||
|
||||
OrderBooks = Dict[str, OrderBook]
|
||||
class MarginMode(TypedDict):
|
||||
info: Dict[str, Any]
|
||||
symbol: Str
|
||||
marginMode: Str
|
||||
|
||||
|
||||
MarginModes = Dict[str, MarginMode]
|
||||
|
||||
|
||||
class Leverage(TypedDict):
|
||||
info: Dict[str, Any]
|
||||
symbol: Str
|
||||
marginMode: Str
|
||||
longLeverage: Num
|
||||
shortLeverage: Num
|
||||
|
||||
|
||||
Leverages = Dict[str, Leverage]
|
||||
|
||||
|
||||
class Greeks(TypedDict):
|
||||
symbol: Str
|
||||
timestamp: Int
|
||||
datetime: Str
|
||||
delta: Num
|
||||
gamma: Num
|
||||
theta: Num
|
||||
vega: Num
|
||||
rho: Num
|
||||
vanna: Num
|
||||
volga: Num
|
||||
charm: Num
|
||||
bidSize: Num
|
||||
askSize: Num
|
||||
bidImpliedVolatility: Num
|
||||
askImpliedVolatility: Num
|
||||
markImpliedVolatility: Num
|
||||
bidPrice: Num
|
||||
askPrice: Num
|
||||
markPrice: Num
|
||||
lastPrice: Num
|
||||
underlyingPrice: Num
|
||||
info: Dict[str, Any]
|
||||
|
||||
|
||||
class Conversion(TypedDict):
|
||||
info: Dict[str, Any]
|
||||
timestamp: Int
|
||||
datetime: Str
|
||||
id: Str
|
||||
fromCurrency: Str
|
||||
fromAmount: Num
|
||||
toCurrency: Str
|
||||
toAmount: Num
|
||||
price: Num
|
||||
fee: Num
|
||||
|
||||
|
||||
class Option(TypedDict):
|
||||
info: Dict[str, Any]
|
||||
currency: Str
|
||||
symbol: Str
|
||||
timestamp: Int
|
||||
datetime: Str
|
||||
impliedVolatility: Num
|
||||
openInterest: Num
|
||||
bidPrice: Num
|
||||
askPrice: Num
|
||||
midPrice: Num
|
||||
markPrice: Num
|
||||
lastPrice: Num
|
||||
underlyingPrice: Num
|
||||
change: Num
|
||||
percentage: Num
|
||||
baseVolume: Num
|
||||
quoteVolume: Num
|
||||
|
||||
|
||||
OptionChain = Dict[str, Option]
|
||||
|
||||
class MarketMarginModes(TypedDict):
|
||||
cross: bool
|
||||
isolated: bool
|
||||
|
||||
class MinMax(TypedDict):
|
||||
min: Num
|
||||
max: Num
|
||||
|
||||
class MarketLimits(TypedDict):
|
||||
amount: Optional[MinMax]
|
||||
cost: Optional[MinMax]
|
||||
leverage: Optional[MinMax]
|
||||
price: Optional[MinMax]
|
||||
market: Optional[MinMax]
|
||||
|
||||
class MarketInterface(TypedDict):
|
||||
info: Dict[str, Any]
|
||||
id: Str
|
||||
symbol: Str
|
||||
base: Str
|
||||
quote: Str
|
||||
baseId: Str
|
||||
quoteId: Str
|
||||
active: Bool
|
||||
type: Str
|
||||
subType: Str
|
||||
spot: bool
|
||||
margin: bool
|
||||
marginModes: MarketMarginModes
|
||||
swap: bool
|
||||
future: bool
|
||||
option: bool
|
||||
contract: bool
|
||||
settle: Str
|
||||
settleId: Str
|
||||
contractSize: Num
|
||||
linear: bool
|
||||
inverse: bool
|
||||
expiry: Num
|
||||
expiryDatetime: Str
|
||||
strike: Num
|
||||
optionType: Str
|
||||
taker: Num
|
||||
maker: Num
|
||||
percentage: bool
|
||||
tierBased: bool
|
||||
feeSide: Str
|
||||
precision: Any
|
||||
limits: MarketLimits
|
||||
created: Int
|
||||
|
||||
class Limit(TypedDict):
|
||||
min: Num
|
||||
max: Num
|
||||
|
||||
|
||||
class CurrencyLimits(TypedDict):
|
||||
amount: Limit
|
||||
withdraw: Limit
|
||||
|
||||
|
||||
class CurrencyInterface(TypedDict):
|
||||
id: Str
|
||||
code: Str
|
||||
numericId: Int
|
||||
precision: Num
|
||||
type: Str
|
||||
margin: Bool
|
||||
name: Str
|
||||
active: Bool
|
||||
deposit: Bool
|
||||
withdraw: Bool
|
||||
fee: Num
|
||||
limits: CurrencyLimits
|
||||
networks: Dict[str, any]
|
||||
info: any
|
||||
|
||||
|
||||
class LastPrice(TypedDict):
|
||||
symbol: Str
|
||||
timestamp: Int
|
||||
datetime: Str
|
||||
price: Num
|
||||
side: OrderSide
|
||||
info: Dict[str, Any]
|
||||
|
||||
|
||||
class MarginModification(TypedDict):
|
||||
info: Dict[str, any]
|
||||
symbol: str
|
||||
type: Optional[Literal['add', 'reduce', 'set']]
|
||||
marginMode: Optional[Literal['isolated', 'cross']]
|
||||
amount: Optional[float]
|
||||
code: Str
|
||||
status: Str
|
||||
timestamp: Int
|
||||
datetime: Str
|
||||
|
||||
|
||||
class CrossBorrowRate(TypedDict):
|
||||
info: Dict[str, any]
|
||||
currency: Str
|
||||
rate: float
|
||||
period: Optional[float]
|
||||
timestamp: Int
|
||||
datetime: Str
|
||||
|
||||
|
||||
class IsolatedBorrowRate(TypedDict):
|
||||
info: Dict[str, any]
|
||||
symbol: str
|
||||
base: str
|
||||
baseRate: float
|
||||
quote: str
|
||||
quoteRate: float
|
||||
period: Int
|
||||
timestamp: Int
|
||||
datetime: Str
|
||||
|
||||
|
||||
class FundingRate(TypedDict):
|
||||
symbol: Str
|
||||
timestamp: Int
|
||||
fundingRate: Num
|
||||
datetime: Str
|
||||
markPrice: Num
|
||||
indexPrice: Num
|
||||
interestRate: Num
|
||||
estimatedSettlePrice: Num
|
||||
fundingTimestamp: Int
|
||||
fundingDatetime: Str
|
||||
nextFundingTimestamp: Int
|
||||
nextFundingDatetime: Str
|
||||
nextFundingRate: Num
|
||||
previousFundingTimestamp: Int
|
||||
previousFundingDatetime: Str
|
||||
previousFundingRate: Num
|
||||
info: Dict[str, Any]
|
||||
interval: Str
|
||||
|
||||
class OpenInterest(TypedDict):
|
||||
symbol: Str
|
||||
openInterestAmount: Num
|
||||
openInterestValue: Num
|
||||
baseVolume: Num
|
||||
quoteVolume: Num
|
||||
timestamp: Int
|
||||
datetime: Str
|
||||
info: Dict[str, Any]
|
||||
|
||||
class LeverageTier:
|
||||
tier: Num
|
||||
symbol: Str
|
||||
currency: Str
|
||||
minNotional: Num
|
||||
maxNotional: Num
|
||||
maintenanceMarginRate: Num
|
||||
maxLeverage: Num
|
||||
info: Dict[str, Any]
|
||||
|
||||
|
||||
class LedgerEntry:
|
||||
id: Str
|
||||
info: Any
|
||||
timestamp: Int
|
||||
datetime: Str
|
||||
direction: Str
|
||||
account: Str
|
||||
referenceId: Str
|
||||
referenceAccount: Str
|
||||
type: Str
|
||||
currency: Str
|
||||
amount: Str
|
||||
before: float
|
||||
after: float
|
||||
status: Str
|
||||
fee: Fee
|
||||
|
||||
|
||||
class DepositAddress:
|
||||
info: Any
|
||||
currency: Str
|
||||
network: Optional[Str]
|
||||
address: Str
|
||||
tag: Optional[Str]
|
||||
|
||||
|
||||
class LongShortRatio:
|
||||
info: Any
|
||||
symbol: Str
|
||||
timestamp: Optional[Int]
|
||||
datetime: Optional[Str]
|
||||
timeframe: Optional[Str]
|
||||
longShortRatio: float
|
||||
|
||||
|
||||
class BorrowInterest:
|
||||
info: Any
|
||||
symbol: Optional[Str]
|
||||
currency: Optional[Str]
|
||||
interest: Optional[Num]
|
||||
interestRate: Optional[Num]
|
||||
amountBorrowed: Optional[Num]
|
||||
marginMode: Optional[Str]
|
||||
timestamp: Optional[Int]
|
||||
datetime: Optional[Str]
|
||||
|
||||
|
||||
FundingRates = Dict[Str, FundingRate]
|
||||
OpenInterests = Dict[Str, OpenInterest]
|
||||
LastPrices = Dict[Str, LastPrice]
|
||||
Currencies = Dict[Str, CurrencyInterface]
|
||||
TradingFees = Dict[Str, TradingFeeInterface]
|
||||
IsolatedBorrowRates = Dict[Str, IsolatedBorrowRate]
|
||||
CrossBorrowRates = Dict[Str, CrossBorrowRate]
|
||||
LeverageTiers = Dict[Str, List[LeverageTier]]
|
||||
|
||||
Market = Optional[MarketInterface]
|
||||
Currency = Optional[CurrencyInterface]
|
||||
|
||||
class ConstructorArgs(TypedDict, total=False):
|
||||
apiKey: str
|
||||
secret: str
|
||||
passphrase: str
|
||||
password: str
|
||||
privateKey: str
|
||||
walletAddress: str
|
||||
uid: str
|
||||
verbose: bool
|
||||
testnet: bool
|
||||
sandbox: bool # redudant but kept for backwards compatibility
|
||||
options: Dict[str, Any]
|
||||
enableRateLimit: bool
|
||||
httpsProxy: str
|
||||
socksProxy: str
|
||||
wssProxy: str
|
||||
proxy: str
|
||||
rateLimit: Num
|
||||
commonCurrencies: Dict[str, Any]
|
||||
userAgent: str
|
||||
userAgents: Dict[str, Any]
|
||||
timeout: Num
|
||||
markets: Dict[str, Any]
|
||||
currencies: Dict[str, Any]
|
||||
hostname: str
|
||||
urls: Dict[str, Any]
|
||||
headers: Dict[str, Any]
|
||||
session: Any
|
||||
Reference in New Issue
Block a user