def trade_krw_withdrawal(self, bank, account, price): URL = 'https://api.bithumb.com/trade/krw_withdrawal' try: params = {'bank': bank, 'account': account, 'price': price} return self._post(URL, params) except Exception as e: mylogger.error('trade_krw_withdrawal() failed(%s)' % str(e)) raise Exception(e)
def trade_krw_deposit(self): URL = 'https://api.bithumb.com/trade/krw_deposit' try: params = {} return self._post(URL, params) except Exception as e: mylogger.error('trade_krw_deposit() failed(%s)' % str(e)) raise Exception(e)
def downloadPicture(url, filepath, sleep=0.2, headers={}): if os.path.exists(filepath): mylogger.info('skip', filepath) return try: writePicture(url, filepath, sleep, headers) except Exception as e: os.remove(filepath) mylogger.error('error skip', filepath)
def _delete(self, url, headers, data, result_code=200): resp = requests.delete(url, headers=headers, data=data) if resp.status_code != result_code: mylogger.error('delete(%s) failed(%d)' % (url, resp.status_code)) if resp.text is not None: raise Exception('request.delete() failed(%s)' % resp.text) raise Exception('request.delete() failed(status_code:%d)' % result_code) return json.loads(resp.text)
def _get(self, url, params=None): resp = requests.get(url, params=params) if resp.status_code != 200: mylogger.error('get(%s) failed(%d)' % (url, resp.status_code)) if len(resp.text) > 0: mylogger.error('resp: %s' % resp.text) raise Exception('requests.get() failed(%s)' % resp.text) raise Exception('requests.get() failed(status_code:%d)' % resp.status_code) return json.loads(resp.text)
def _get(self, url, headers=None, data=None, params=None, result_code=200): resp = requests.get(url, headers=headers, data=data, params=params) if resp.status_code != result_code: mylogger.error('get(%s) failed(%d)' % (url, resp.status_code)) if resp.text is not None: mylogger.error('resp: %s' % resp.text) raise Exception('request.get() failed(%s)' % resp.text) raise Exception('request.get() failed(status_code:%d)' % result_code) return json.loads(resp.text)
def ticker(self, currency): URL = 'https://api.bithumb.com/public/ticker/' try: if currency != 'ALL' and currency not in self.all_currency: mylogger.error('invalid currency: %s' % currency) raise Exception('invalid currency: %s' % currency) return self._get(URL + currency) except Exception as e: mylogger.error('ticker() failed(%s)' % str(e)) raise Exception(e)
def trade_market_sell(self, currency, units): URL = 'https://api.bithumb.com/trade/market_sell' try: if currency not in self.all_currency: mylogger.error('invalid currency: %s' % currency) raise Exception('invalid currency: %s' % currency) params = {'currency': currency, 'units': units} return self._post(URL, params) except Exception as e: mylogger.error('trade_market_sell() failed(%s)' % str(e)) raise Exception(e)
def info_ticker(self, currency): URL = 'https://api.bithumb.com/info/ticker' try: if currency not in self.all_currency: mylogger.error('invalid currency: %s' % currency) raise Exception('invalid currency: %s' % currency) params = {'order_currency': currency, 'payment_currency': 'KRW'} return self._post(URL, params) except Exception as e: mylogger.error('info_ticker() failed(%s)' % str(e)) raise Exception(e)
def info_wallet_address(self, currency): URL = 'https://api.bithumb.com/info/wallet_address' try: if currency not in self.all_currency: mylogger.error('invalid currency: %s' % currency) raise Exception('invalid currency: %s' % currency) params = {'currency': currency} return self._post(URL, params) except Exception as e: mylogger.error('info_wallet_address() failed(%s)' % str(e)) raise Exception(e)
def _load_markets(self): try: market_all = self.get_market_all() if market_all is None: return markets = [] for market in market_all: markets.append(market['market']) return markets except Exception as e: mylogger.error(e) raise Exception(e)
def get_chance(self, market): ''' 주문 가능 정보 마켓별 주문 가능 정보를 확인한다. https://docs.upbit.com/v1.0/reference#%EC%A3%BC%EB%AC%B8-%EA%B0%80%EB%8A%A5-%EC%A0%95%EB%B3%B4 :param str market: Market ID :return: json object ''' URL = 'https://api.upbit.com/v1/orders/chance' if market not in self.markets: mylogger.error('invalid market: %s' % market) raise Exception('invalid market: %s' % market) data = {'market': market} return self._get(URL, self._get_headers(data), data)
def get_order(self, uuid): ''' 개별 주문 조회 주문 UUID 를 통해 개별 주문건을 조회한다. https://docs.upbit.com/v1.0/reference#%EA%B0%9C%EB%B3%84-%EC%A3%BC%EB%AC%B8-%EC%A1%B0%ED%9A%8C :param str uuid: 주문 UUID :return: json object ''' URL = 'https://api.upbit.com/v1/order' try: data = {'uuid': uuid} return self._get(URL, self._get_headers(data), data) except Exception as e: mylogger.error(e) raise Exception(e)
def trade_btc_withdrawal(self, currency, units, address, destination): URL = 'https://api.bithumb.com/trade/btc_withdrawal' try: if currency not in self.all_currency: mylogger.error('invalid currency: %s' % currency) raise Exception('invalid currency: %s' % currency) params = { 'currency': currency, 'address': address, 'destination': destination, 'units': units } return self._post(URL, params) except Exception as e: mylogger.error('trade_btc_withdrawal() failed(%s)' % str(e)) raise Exception(e)
def _post(self, url, params): BASE_URL = 'https://api.bithumb.com' path = url[len(BASE_URL):] nonce = str(int(time.time() * 1000)) headers = { 'Api-Key': self.api_key, 'Api-Sign': self._get_sign(path, params, nonce), 'Api-Nonce': nonce } resp = requests.post(url, headers=headers, data=params) if resp.status_code != 200: mylogger.error('_post(%s) failed(%d)' % (url, resp.status_code)) if resp.text is not None: raise Exception('requests.post() failed(%s)' % resp.text) raise Exception('requests.post() failed(status_code:%d)' % resp.status_code) return json.loads(resp.text)
def _load_all_currency(self): try: ticker = self.ticker('ALL') if ticker == None: raise Exception('self.ticker() failed') if int(ticker['status']) != 0: mylogger.error('invalid status: %d' % int(ticker['status'])) raise Exception('invalid status: %d' % int(ticker['status'])) all_currency = [] for key in ticker['data'].keys(): all_currency.append(key) return all_currency except Exception as e: mylogger.error('_load_all_currency failed(%s)' % str(e)) raise Exception(e)
def get_weeks_candles(self, market, to=None, count=None): ''' 주(Week) 캔들 https://docs.upbit.com/v1.0/reference#%EC%A3%BCweek-%EC%BA%94%EB%93%A4-1 :param str market: 마켓 코드 (ex. KRW-BTC, BTC-BCC) :param str to: 마지막 캔들 시각 (exclusive). 포맷 : yyyy-MM-dd'T'HH:mm:ssXXX. 비워서 요청시 가장 최근 캔들 :param int count: 캔들 개수 :return: json array ''' URL = 'https://api.upbit.com/v1/candles/weeks' if market not in self.markets: mylogger.error('invalid market: %s' % market) raise Exception('invalid market: %s' % market) params = {'market': market} if to is not None: params['to'] = to if count is not None: params['count'] = count return self._get(URL, params=params)
def get_orderbook(self, markets): ''' 호가 정보 조회 https://docs.upbit.com/v1.0/reference#%ED%98%B8%EA%B0%80-%EC%A0%95%EB%B3%B4-%EC%A1%B0%ED%9A%8C :param str[] markets: 마켓 코드 목록 리스트 (ex. KRW-BTC,KRW-ADA) :return: json array ''' URL = 'https://api.upbit.com/v1/orderbook?' if not isinstance(markets, list): mylogger.error('invalid parameter: markets should be list') raise Exception('invalid parameter: markets should be list') if len(markets) == 0: mylogger.error('invalid parameter: no markets') raise Exception('invalid parameter: no markets') for market in markets: if market not in self.markets: mylogger.error('invalid market: %s' % market) raise Exception('invalid market: %s' % market) markets_data = markets[0] for market in markets[1:]: markets_data += ',%s' % market params = {'markets': markets_data} return self._get(URL, params=params)
def get_ticker(self, markets): ''' 현재가 정보 요청 당시 종목의 스냅샷을 반환한다. https://docs.upbit.com/v1.0/reference#%EC%8B%9C%EC%84%B8-ticker-%EC%A1%B0%ED%9A%8C :param str[] markets: 마켓 코드 리스트 (ex. KRW-BTC, BTC-BCC) :return: json array ''' URL = 'https://api.upbit.com/v1/ticker' if not isinstance(markets, list): mylogger.error('invalid parameter: markets should be list') raise Exception('invalid parameter: markets should be list') if len(markets) == 0: mylogger.error('invalid parameter: no markets') raise Exception('invalid parameter: no markets') for market in markets: if market not in self.markets: mylogger.error('invalid market: %s' % market) raise Exception('invalid market: %s' % market) markets_data = markets[0] for market in markets[1:]: markets_data += ',%s' % market params = {'markets': markets_data} return self._get(URL, params=params)
def order(self, market, side, volume, price): ''' 주문하기 주문 요청을 한다. https://docs.upbit.com/v1.0/reference#%EC%A3%BC%EB%AC%B8%ED%95%98%EA%B8%B0-1 :param str market: 마켓 ID (필수) :param str side: 주문 종류 (필수) bid : 매수 ask : 매도 :param str volume: 주문량 (필수) :param str price: 유닛당 주문 가격. (필수) ex) KRW-BTC 마켓에서 1BTC당 1,000 KRW로 거래할 경우, 값은 1000 이 된다. :return: json object ''' URL = 'https://api.upbit.com/v1/orders' if market not in self.markets: mylogger.error('invalid market: %s' % market) raise Exception('invalid market: %s' % market) if side not in ['bid', 'ask']: mylogger.error('invalid side: %s' % side) raise Exception('invalid side: %s' % side) if not self._is_valid_price(price): mylogger.error('invalid price: %.2f' % price) raise Exception('invalid price: %.2f' % price) data = { 'market': market, 'side': side, 'volume': str(volume), 'price': str(price), 'ord_type': 'limit' } return self._post(URL, self._get_headers(data), data, result_code=201)
def application(environ, set_response_header): set_response_header('200 OK', [('Content-Type', 'text/html;charset=utf-8')]) file_name = environ['PATH_INFO'] # if file_name == '/index.py': # return index() # elif file_name == '/center.py': # return center() # else: # return '<h1>我爱你中国!</h1>' mylogger.info("访问的是%s" % file_name) try: for url, func in URL_FUNC_DICT.items(): ret = re.match(url, file_name) if ret: return func(ret) else: mylogger.warning("请求的url(%s)没有对应的函数...." % file_name) return "请求的url(%s)没有对应的函数...." % file_name except Exception as ret: mylogger.error("产生了异常: %s" % str(ret)) return "产生了异常: %s" % str(ret)
def get_trades_ticks(self, market, to=None, count=None, cursor=None): ''' 당일 체결 내역 https://docs.upbit.com/v1.0/reference#%EC%8B%9C%EC%84%B8-%EC%B2%B4%EA%B2%B0-%EC%A1%B0%ED%9A%8C :param str market: 마켓 코드 (ex. KRW-BTC, BTC-BCC) :param str to: 마지막 체결 시각. 형식 : [HHmmss 또는 HH:mm:ss]. 비워서 요청시 가장 최근 데이터 :param int count: 체결 개수 :param str cursor: 페이지네이션 커서 (sequentialId) :return: json array ''' URL = 'https://api.upbit.com/v1/trades/ticks' if market not in self.markets: mylogger.error('invalid market: %s' % market) raise Exception('invalid market: %s' % market) params = {'market': market} if to is not None: params['to'] = to if count is not None: params['count'] = count if cursor is not None: params['cursor'] = cursor return self._get(URL, params=params)
def get_withraws(self, currency, state, limit): ''' 출금 리스트 조회 https://docs.upbit.com/v1.0/reference#%EC%A0%84%EC%B2%B4-%EC%B6%9C%EA%B8%88-%EC%A1%B0%ED%9A%8C :param str currency: Currency 코드 :param str state: 출금 상태 submitting : 처리 중 submitted : 처리 완료 almost_accepted : 출금대기중 rejected : 거부 accepted : 승인됨 processing : 처리 중 done : 완료 canceled : 취소됨 :param int limit: 갯수 제한 :return: json array ''' LIMIT_MAX = 100 VALID_STATE = [ 'submitting', 'submitted', 'almost_accepted', 'rejected', 'accepted', 'processing', 'done', 'canceled' ] URL = 'https://api.upbit.com/v1/withdraws' data = {} if currency is not None: data['currency'] = currency if state is not None: if state not in VALID_STATE: mylogger.error('invalid state(%s)' % state) raise Exception('invalid state(%s)' % state) data['state'] = state if limit is not None: if limit <= 0 or limit > LIMIT_MAX: mylogger.error('invalid limit(%d)' % limit) raise Exception('invalid limit(%d)' % limit) data['limit'] = limit return self._get(URL, self._get_headers(data), data)
def get_minutes_candles(self, unit, market, to=None, count=None): ''' 분(Minute) 캔들 https://docs.upbit.com/v1.0/reference#%EB%B6%84minute-%EC%BA%94%EB%93%A4-1 :param int unit: 분 단위. 가능한 값 : 1, 3, 5, 15, 10, 30, 60, 240 :param str market: 마켓 코드 (ex. KRW-BTC, BTC-BCC) :param str to: 마지막 캔들 시각 (exclusive). 포맷 : yyyy-MM-dd'T'HH:mm:ssXXX. 비워서 요청시 가장 최근 캔들 :param int count: 캔들 개수(최대 200개까지 요청 가능) :return: json array ''' URL = 'https://api.upbit.com/v1/candles/minutes/%s' % str(unit) if unit not in [1, 3, 5, 10, 15, 30, 60, 240]: mylogger.error('invalid unit: %s' % str(unit)) raise Exception('invalid unit: %s' % str(unit)) if market not in self.markets: mylogger.error('invalid market: %s' % market) raise Exception('invalid market: %s' % market) params = {'market': market} if to is not None: params['to'] = to if count is not None: params['count'] = count return self._get(URL, params=params)
def orderbook(self, currency, group_orders=1, count=5): URL = 'https://api.bithumb.com/public/orderbook/' try: if currency != 'ALL' and currency not in self.all_currency: mylogger.error('invalid currency: %s' % currency) raise Exception('invalid currency: %s' % currency) if group_orders not in [0, 1]: mylogger.error('invalid group_orders: %d' % group_orders) raise Exception('invalid group_orders: %d' % group_orders) if count < 1 or count > 50: mylogger.error('invalid count: %d' % count) raise Exception('invalid count: %d' % count) params = {'group_orders': group_orders, 'count': count} return self._get(URL + currency, params=params) except Exception as e: mylogger.error('orderbook() failed(%s)' % str(e)) raise Exception(e)
def trade_cancel(self, currency, order_id, type): URL = 'https://api.bithumb.com/trade/cancel' try: if currency not in self.all_currency: mylogger.error('invalid currency: %s' % currency) raise Exception('invalid currency: %s' % currency) if type not in ['bid', 'ask']: mylogger.error('invalid type: %s' % type) raise Exception('invalid type: %s' % type) params = {'currency': currency, 'type': type, 'order_id': order_id} return self._post(URL, params) except Exception as e: mylogger.error('trade_cancel() failed(%s)' % str(e)) raise Exception(e)
def transaction_history(self, currency, cont_no=None, count=20): URL = 'https://api.bithumb.com/public/transaction_history/' try: if currency not in self.all_currency: mylogger.error('invalid currency: %s' % currency) raise Exception('invalid currency: %s' % currency) if count < 1 or count > 100: mylogger.error('invalid count: %d' % count) raise Exception('invalid count: %d' % count) params = {'count': count} if cont_no != 0: params['cont_no'] = cont_no return self._get(URL + currency, params=params) except Exception as e: mylogger.error('transaction_history() failed(%s)' % str(e)) raise Exception(e)
def info_orders(self, currency, order_id, type, count=None, after=None): URL = 'https://api.bithumb.com/info/orders' try: if currency not in self.all_currency: mylogger.error('invalid currency: %s' % currency) raise Exception('invalid currency: %s' % currency) if type not in ['bid', 'ask']: mylogger.error('invalid type: %s' % type) raise Exception('invalid type: %s' % type) params = {'currency': currency, 'order_id': order_id, 'type': type} if after is not None: params['after'] = after if count is not None: params['count'] = count return self._post(URL, params) except Exception as e: mylogger.error('info_orders() failed(%s)' % str(e)) raise Exception(e)
def trade_place(self, currency, units, price, type): URL = 'https://api.bithumb.com/trade/place' try: if currency not in self.all_currency: mylogger.error('invalid currency: %s' % currency) raise Exception('invalid currency: %s' % currency) if type not in ['bid', 'ask']: mylogger.error('invalid type: %s' % type) raise Exception('invalid type: %s' % type) params = { 'order_currency': currency, 'Payment_currency': 'KRW', 'type': type, 'price': price, 'units': units } return self._post(URL, params) except Exception as e: mylogger.error('trade_place() failed(%s)' % str(e)) raise Exception(e)
def info_user_transactions(self, currency, searchGb, offset=None, count=None): URL = 'https://api.bithumb.com/info/user_transactions' try: if currency not in self.all_currency: mylogger.error('invalid currency: %s' % currency) raise Exception('invalid currency: %s' % currency) if searchGb not in [0, 1, 2, 3, 4, 5, 9]: mylogger.error('invalid searchGb: %d' % searchGb) raise Exception('invalid searchGb: %d' % searchGb) params = {'currency': currency, 'searchGb': searchGb} if offset is not None: params['offset'] = offset if count is not None: params['count'] = count return self._post(URL, params) except Exception as e: mylogger.error('info_user_transactions() failed(%s)' % str(e)) raise Exception(e)