diff --git a/binance/client.py b/binance/client.py index 1ba4cb13a..f815eddbf 100644 --- a/binance/client.py +++ b/binance/client.py @@ -617,14 +617,14 @@ def aggregate_trade_iter(self, symbol, start_str=None, last_id=None): if start_str is None: trades = self.get_aggregate_trades(symbol=symbol, fromId=0) else: - # It doesn't matter what the end time is, as long as it's less - # than a day and the result set contains at least one trade. - # A half a day should be fine. + # The difference between startTime and endTime should be less + # or equal than an hour and the result set should contain at + # least one trade. start_ts = date_to_milliseconds(start_str) trades = self.get_aggregate_trades( symbol=symbol, startTime=start_ts, - endTime=start_ts + (1000 * 86400 / 2)) + endTime=start_ts + (60 * 60 * 1000)) for t in trades: yield t last_id = trades[-1][self.AGG_ID] @@ -688,6 +688,26 @@ def get_klines(self, **params): """ return self._get('klines', data=params) + def _get_earliest_valid_timestamp(self, symbol, interval): + """Get earliest valid open timestamp from Binance + + :param symbol: Name of symbol pair e.g BNBBTC + :type symbol: str + :param interval: Binance Kline interval + :type interval: str + + :return: first valid timestamp + + """ + kline = self.get_klines( + symbol=symbol, + interval=interval, + limit=1, + startTime=0, + endTime=None + ) + return kline[0][0] + def get_historical_klines(self, symbol, interval, start_str, end_str=None): """Get Historical Klines from Binance @@ -719,14 +739,16 @@ def get_historical_klines(self, symbol, interval, start_str, end_str=None): # convert our date strings to milliseconds start_ts = date_to_milliseconds(start_str) + # establish first available start timestamp + first_valid_ts = self._get_earliest_valid_timestamp(symbol, interval) + start_ts = max(start_ts, first_valid_ts) + # if an end time was passed convert it end_ts = None if end_str: end_ts = date_to_milliseconds(end_str) idx = 0 - # it can be difficult to know when a symbol was listed on Binance so allow start time to be before list date - symbol_existed = False while True: # fetch the klines from start_ts up to max 500 entries or the end_ts if set temp_data = self.get_klines( @@ -737,21 +759,15 @@ def get_historical_klines(self, symbol, interval, start_str, end_str=None): endTime=end_ts ) - # handle the case where our start date is before the symbol pair listed on Binance - if not symbol_existed and len(temp_data): - symbol_existed = True - - if symbol_existed: - - # handle the case where exactly the limit amount of data was returned last loop - if not len(temp_data): - break + # handle the case where exactly the limit amount of data was returned last loop + if not len(temp_data): + break - # append this loops data to our output data - output_data += temp_data + # append this loops data to our output data + output_data += temp_data - # set our start timestamp using the last value in the array - start_ts = temp_data[-1][0] + # set our start timestamp using the last value in the array + start_ts = temp_data[-1][0] idx += 1 # check if we received less than the required limit and exit the loop @@ -1712,6 +1728,28 @@ def get_deposit_address(self, **params): """ return self._request_withdraw_api('get', 'depositAddress.html', True, data=params) + def get_withdraw_fee(self, **params): + """Fetch the withdrawal fee for an asset + + :param asset: required + :type asset: str + :param recvWindow: the number of milliseconds the request is valid for + :type recvWindow: int + + :returns: API response + + .. code-block:: python + + { + "withdrawFee": "0.0005", + "success": true + } + + :raises: BinanceRequestException, BinanceAPIException + + """ + return self._request_withdraw_api('get', 'withdrawFee.html', True, data=params) + # User Stream Endpoints def stream_get_listen_key(self): diff --git a/binance/exceptions.py b/binance/exceptions.py index 027a78823..39c450a7c 100644 --- a/binance/exceptions.py +++ b/binance/exceptions.py @@ -3,8 +3,6 @@ class BinanceAPIException(Exception): - LISTENKEY_NOT_EXIST = '-1125' - def __init__(self, response): self.code = 0 try: diff --git a/docs/withdraw.rst b/docs/withdraw.rst index 8bec21ef0..ac23d27ee 100644 --- a/docs/withdraw.rst +++ b/docs/withdraw.rst @@ -63,3 +63,10 @@ Raises a `BinanceWithdrawException `_ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code:: python + + address = client.get_withdraw_fee(asset='BTC') diff --git a/tests/test_historical_klines.py b/tests/test_historical_klines.py index 6c903a25b..0f221bb86 100644 --- a/tests/test_historical_klines.py +++ b/tests/test_historical_klines.py @@ -12,8 +12,10 @@ def test_exact_amount(): """Test Exact amount returned""" + first_available_res = [[1500004800000, "0.00005000", "0.00005300", "0.00001000", "0.00004790", "663152.00000000", 1500004859999, "30.55108144", 43, "559224.00000000", "25.65468144", "83431971.04346950"]] + first_res = [] - row = [1519892340000,"0.00099400","0.00099810","0.00099400","0.00099810","4806.04000000",1519892399999,"4.78553253",154,"1785.14000000","1.77837524","0"] + row = [1519892340000, "0.00099400", "0.00099810", "0.00099400", "0.00099810", "4806.04000000", 1519892399999, "4.78553253", 154, "1785.14000000", "1.77837524", "0"] for i in range(0, 500): first_res.append(row) @@ -21,6 +23,7 @@ def test_exact_amount(): second_res = [] with requests_mock.mock() as m: + m.get('https://api.binance.com/api/v1/klines?interval=1m&limit=1&startTime=0&symbol=BNBBTC', json=first_available_res) m.get('https://api.binance.com/api/v1/klines?interval=1m&limit=500&startTime=1519862400000&symbol=BNBBTC', json=first_res) m.get('https://api.binance.com/api/v1/klines?interval=1m&limit=500&startTime=1519892400000&symbol=BNBBTC', json=second_res) client.get_historical_klines(