def get_order_history(self, pair, since=None, until=int(time.time())): """Returns the past 200 trades, or up to 50,000 trades between a range specified in UNIX timestamps by the "start" and "end" GET parameters.""" if pair is not "all": query = { "command": "returnTradeHistory", "currencyPair": self.format_pair(pair) } else: query = {"command": "returnTradeHistory", "currencyPair": 'all'} if since is None: # default, return 200 last trades return self.private_api(query) if since > time.time(): raise APIError( "AYYY LMAO start time is in the future, take it easy.") if self._to_timestamp(datetime.datetime.now() - self.time_limit) <= since: query.update({"start": str(since), "end": str(until)}) return self.private_api(query) else: raise APIError( '''Poloniex API does no support queries for data older than a year.\n Earilest data we can get is since {0} UTC'''. format( (datetime.datetime.now() - self.time_limit).isoformat()))
def private_api(self, command, params): '''handles private api methods''' if not self.apikey or not self.secret: raise ValueError("API key and secret key required!") params["api_key"] = self.apikey params["sign"] = self.build_signature(params) result = requests.post(self.url.replace("$", "com") + command, params=params, headers=self.headers, timeout=3) if self.domain == "com": result = requests.get(self.url.replace("$", "com") + command, params=params, headers=self.headers, timeout=3) if self.domain == "cny": result = requests.get(self.url.replace("$", "cn") + command, params=params, headers=self.headers, timeout=3) assert result.status_code == 200, {"error": "http_error: " + str(result.status_code)} try: ## try to get the error if result.json().get("result") is False: # API is not consistent about naming error field if result.json()["errorCode"]: raise APIError(self.error_codes.get(result.json()["errorCode"])) else: raise APIError(self.error_codes.get(result.json()["error_code"])) except AttributeError: pass return result.json()
def get_market_ohlcv_data( self, market: str, interval: int, since: int = int(time.time() - 2.419e+6), until: int = int(time.time()) ) -> list: ''' : since - UNIX timestamp : until - UNIX timestamp ''' if interval not in "5m, 15m, 30m, 1h, 2h, 1d".split(', '): raise APIError('Unsupported OHLCV interval.') upstream = super(PoloniexNormalized, self).get_chart_data(market, self._format_interval(interval), since, until) r = [] for ohlcv in upstream: r.append({ 'volume': ohlcv['volume'], 'close': ohlcv['close'], 'high': ohlcv['high'], 'low': ohlcv['low'], 'open': ohlcv['open'], 'time': self._tstamp_to_datetime(ohlcv['date']) }) return r
def get_trade_history( self, pair: str = "all", limit: int = 500, since: int = int(time.time() - 2.419e+6), until=int(time.time()) ) -> list: """ Returns your trade history for a given market, specified by the <pair> POST parameter. You may specify "all" as the <pair> to receive your trade history for all markets. You may optionally specify a range via <since> and/or <until> POST parameters, given in UNIX timestamp format; if you do not specify a range, it will be limited to one day. You may optionally limit the number of entries returned using the <limit> parameter, up to a maximum of 10,000. If the <limit> parameter is not specified, no more than 500 entries will be returned. """ query = { "command": "returnTradeHistory", "currencyPair": self.format_pair(pair) } if since > time.time(): raise APIError( "AYYY LMAO start time is in the future, take it easy.") if since is not None: query.update({"start": str(since), "end": str(until)}) return self.api(query)
def get_market_ohlcv_data(self, pair, interval, since=None, until=None, limit=500): ''' https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md#klinecandlestick-data Kline/candlestick bars for a symbol. Klines are uniquely identified by their open time. If since and until are not sent, the most recent klines are returned. : market [str]: market pair : interval [str]: 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M : limit [int]: Default 500; max 500. : since [int]: timestamp : util [int]: timestamp ''' if interval not in "1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M".split( ', '): raise APIError('Unsupported interval.') return self.api(self.url + "api/v1/klines", params={ 'symbol': self.format_pair(pair), 'interval': interval, 'limit': 500, 'startTime': since, 'endTime': until })
def get_market_ohlcv_data(self, market, interval, since=0, until=datetime.now().timestamp()): ''' : since - UNIX timestamp : until - UNIX timestamp ''' supported_intervals = "1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M" if interval not in supported_intervals.split(', '): raise APIError('Unsupported OHLCV interval.') upstream = super(BinanceNormalized, self).get_market_ohlcv_data(market, interval, int(since * 1000), int(until * 1000)) r = [] for ohlcv in upstream: r.append({ 'open': float(ohlcv[1]), 'high': float(ohlcv[2]), 'low': float(ohlcv[3]), 'close': float(ohlcv[4]), 'volume': float(ohlcv[5]), 'time': self._tstamp_to_datetime(int(ohlcv[6])) }) return r
def _verify_response(self, response): '''verify if API responded properly and raise apropriate error.''' try: if response.json()['error']: raise APIError(response.json()) except TypeError: pass
def _verify_response(self, response): '''verify if API responded properly and raise apropriate error.''' try: if "error" in response.json().keys(): raise APIError(response.json()['error']) except AttributeError: # response has no error key pass
def _verify_response(self, response): '''verify if API responded properly and raise apropriate error.''' try: if 'errors' in response.json().keys(): raise APIError(response.json()['errors'][0]['message']) except KeyError: pass
def _verify_response(self, response): '''verify if API responded properly and raise apropriate error.''' if 'v2' in response.url: # works only for v2 calls try: if response.json()['error']: raise APIError(response.json()['reason']) except (KeyError, TypeError): pass
def api(cls, url): '''call api''' try: result = requests.get(url, headers=cls.headers, timeout=3) assert result.status_code == 200 return result.json() except requests.exceptions.RequestException as e: raise APIError(e)
def get_market_trade_history(self, pair, depth=200, since=None, until=int(time.time())): """Requests trade history for >pair<, of <depth> from >since< to >until< selected timeframe expressed in seconds (unix time) Each request is limited to 50000 trades or 1 year. If called without arguments, it will request last 200 trades for the pair.""" query = { "command": "returnTradeHistory", "currencyPair": self.format_pair(pair) } if depth is None: depth = 200 if since is None and depth is not None and depth > 200: raise APIError( "You can't get depth > 200 without <since> argument.") if since is None: # default, return 200 last trades if depth is not None: return self.api(query)[-depth:] else: return self.api(query) if since > time.time(): raise APIError( "AYYY LMAO start time is in the future, take it easy.") if since is not None and self._to_timestamp(datetime.datetime.now() - self.time_limit) <= since: query.update({"start": str(since), "end": str(until)}) return self.api(query) else: raise APIError( '''Poloniex API does no support queries for data older than a month. Earilest data we can get is since {0} UTC'''.format( (datetime.datetime.now() - self.time_limit).isoformat()))
def get_market_ohlcv_data(self, pair, interval, since=None): '''Get OHLC data :pair [str] - market pair :interval [int] - 1 (default), 5, 15, 30, 60, 240, 1440, 10080, 21600 minutes ''' if str(interval) not in "1, 5, 15, 30, 60, 240, 1440, 10080, 21600".split(', '): raise APIError('Unsupported interval.') return self.api(self.url + 'public/OHLC', params={'pair': self.format_pair(pair), 'interval': interval, 'since': since})
def api(cls, command, params): """call api""" if "usd" in params["symbol"]: # OKcoin API uses .com domain for USD pairs result = requests.get(cls.url.replace("$", "com") + command, params=params, headers=cls.headers, timeout=3) if "cny" in params["symbol"]: # OKcoin API uses .cn domain for CNY pairs result = requests.get(cls.url.replace("$", "cn") + command, params=params, headers=cls.headers, timeout=3) assert result.status_code == 200, {"error": "http_error: " + str(result.status_code)} try: ## try to get the error if result.json().get("result") is False: try: # API is not consistant about naming error field raise APIError(cls.error_codes.get(result.json()["errorCode"])) except KeyError: raise APIError(cls.error_codes.get(result.json()["error_code"])) except AttributeError: pass return result.json()
def api(self, command): """call remote API""" try: response = self.api_session.get(self.api_url + 'v2/' + command, headers=self.headers, timeout=self.timeout, proxies=self.proxy) response.raise_for_status() except requests.exceptions.HTTPError as e: raise APIError(e) self._verify_response(response) return response.json()
def get_deposits_withdrawals(self, since=None, until=int(time.time())): """Returns your deposit and withdrawal history within a range, specified by the <since> and <until> parameters, both of which should be given as UNIX timestamps. (defaults to 1 month)""" if not since: since = self._to_timestamp( self._subtract_one_month(datetime.datetime.now())) if since > time.time(): raise APIError("Start time can't be future.") return self.private_api({ 'command': 'returnDepositsWithdrawals', 'start': since, 'end': until })
def get_market_ohlcv_data(self, market, interval, since=None): ''' Gets the candles for a <market>. : market - market pair : interval must be in: [“oneMin”, “fiveMin”, “thirtyMin”, “hour”, “day”] : since - unix timestmap This method is using the v2 of the Bittrex public API. ''' if interval not in ['oneMin', 'fiveMin', 'thirtyMin', 'hour', 'day']: raise APIError('Unsupported OHLCV interval.') res = self.api(self.url2 + 'pub/market/GetTicks', params={'marketName': self.format_pair(market), 'tickInterval': interval})['result'] return res
def get_market_trade_history(self, pair, limit=1000): """get market trade history""" pair = self.format_pair(pair) if limit > 2000: raise APIError("Btc-e API can only return last 2000 trades.") if not isinstance(pair, list): return self.api("trades" + "/" + pair + "/?limit={0}".format(limit))[pair] if pair == "all": # returns market history for all pairs with default history size. return self.api("trades" + "/" + "-".join(cls.get_markets() + "/?limit={0}".format(limit))) else: # simply concat pairs in the list return self.api("trades" + "/" + "-".join(pair) + "/?limit={0}".format(limit))
def get_market_ohlcv_data(self, market, interval): if interval not in ['1m', '5m', '30m', '1h', '1d']: raise APIError('Unsupported OHLCV interval.') upstream = super(BittrexNormalized, self).get_market_ohlcv_data( market, self._format_interval(interval)) r = [] for ohlcv in upstream: r.append({ 'volume': ohlcv['V'], 'close': ohlcv['C'], 'high': ohlcv['H'], 'low': ohlcv['L'], 'open': ohlcv['O'], 'time': self._iso_string_to_datetime(ohlcv['T']) }) return r
def get_market_ohlcv_data(self, market, interval, since=None, until=None): if interval not in "1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M".split( ', '): raise APIError('Unsupported OHLCV interval.') upstream = super().get_market_ohlcv_data(market, interval, since, until) r = [] for ohlcv in upstream: r.append({ 'open': ohlcv[1], 'high': ohlcv[2], 'low': ohlcv[3], 'close': ohlcv[4], 'volume': ohlcv[5], 'time': self._tstamp_to_datetime(int(ohlcv[6])) }) return r
def get_lending_history(self, since=None, until=int(time.time()), limit=None): ''' Returns your lending history within a time range specified by the <since> and <until> parameters as UNIX timestamps. <limit> may also be specified to limit the number of rows returned. ''' if not since: since = self.to_timestamp( self.subtract_one_month(datetime.datetime.now())) if since > time.time(): raise APIError("Start time can't be future.") return self.private_api({ 'command': 'returnLendingHistory', 'start': since, 'end': until, 'limit': limit })
def get_market_ohlcv_data(self, market, interval=1, since=1): ''' : since - UNIX timestamp ''' # kraken only takes minutes so convert it all in minutes if interval.endswith('m'): interval = str(interval).rstrip('m') elif interval.endswith('d'): interval = int(interval.rstrip('d')) * 1440 elif interval.endswith('h'): interval = int(interval.rstrip('h')) * 60 if str(interval ) not in "1, 5, 15, 30, 60, 240, 1440, 10080, 21600".split( ', '): raise APIError('Unsupported interval.') upstream = super(KrakenNormalized, self).get_market_ohlcv_data(market, interval, int(since)) r = [] for ohlcv in upstream[next(iter(upstream))]: r.append({ 'open': float(ohlcv[1]), 'high': float(ohlcv[2]), 'low': float(ohlcv[3]), 'close': float(ohlcv[4]), 'volume': float(ohlcv[6]), 'time': self._tstamp_to_datetime(int(ohlcv[0])) }) return r
def _verify_response(self, response): '''verify if API responded properly and raise apropriate error.''' if not response.json()['Success'] or response.json()['Error']: raise APIError(response.json()['Error'])
def _verify_response(self, response): if type(response.json()) is dict and 'error' in response.json(): raise APIError(response.json()['error'])
def _verify_response(self, response): if response.json()['error']: raise APIError(response.json()['error'])
def _verify_response(self, response): '''verify if API responded properly and raise apropriate error.''' if "msg" in response.json() and "code" in response.json(): raise APIError(response.json()['msg'])
def _verify_response(self, response): '''verify if API responded properly and raise apropriate error.''' if not response.json()['success'] is True: raise APIError(response.json()['message'])
def _verify_response(self, response): if 'errors' in response.json().keys(): raise APIError(response.json()['errors'])