def write_log(text=""): try: with open(log_path) as f: s = f.read() except FileNotFoundError: s = "" mm = str(from_time_stamp())[0:7] if s == "" or s.find(mm) != -1: with open(log_path, 'w') as f: f.write(text + "\n" + s) else: with open(log_path, 'a') as f: f.writelines("\n") # write old logs with open( str(from_time_stamp(int(time.time()) - 86400 * 10))[0:7] + '.txt', 'w') as old_f: with open(log_path) as f: old_f.writelines(f.readlines()[::-1]) # write count try: symbols = json.loads(config.get("trade", "symbol")) for symbol in symbols: cfg_field = symbol + "-stat" sum_count = 0 try: sum_count = sum( json.loads(config.get(cfg_field, "count"))) except Exception as err: logger.error("Error: write_log,{}".format(err)) old_f.writelines(symbol + " [" + str(sum_count) + "]") except Exception as err: logger.error("Error: write_log,{}".format(err)) with open(log_path, 'w') as f: f.write(text)
def get_klines(self, symbol, period, size): result = {} granularity = granularityDict[period] end_s = int("%0.0f" % datetime.datetime.utcnow().timestamp()) start_s = end_s - granularity * size start = datetime.datetime.fromtimestamp(start_s).strftime( "%Y-%m-%dT%H:%M:%S.000Z") end = datetime.datetime.fromtimestamp(end_s).strftime( "%Y-%m-%dT%H:%M:%S.000Z") try: result = self.spotAPI.get_kline(symbol, start, end, granularity) except Exception as e: logger.error("***klines:%s" % e) is_list = isinstance(result, list) if is_list and len(result) == size: self.kline_data = list(map(self.get_line_data, result)) if len(self.kline_data) == 0: logger.error("***klines retry...") self.get_klines(symbol, period, size) elif is_list and len( result) == size - 1 and self.kline_data[0][5] != end: first = json.loads(json.dumps(result[0])) first[0] = end first[1] = first[4] first[2] = first[4] first[3] = first[4] first[5] = "0" result.insert(0, first) self.kline_data = list(map(self.get_line_data, result)) elif is_list and len(result) != size and len(result) != size - 1: logger.warning("***klines not refresh,{}".format(result))
def make_order(self, my_order_info): logger.info( u'\n-------------------------------------------spot order------------------------------------------------' ) try: result = self.API.send_order(self.ACCOUNT_ID, my_order_info.amount, my_order_info.symbol, my_order_info.orderType, my_order_info.price, my_order_info.offset) except Exception as e: logger.error("***send_order:{}".format(e, traceback.format_exc())) send_msg("%s:send_order failed:%s" % (my_order_info.symbol, e)) exit() result = self.check_order_list(my_order_info) if result is not None and result.get('status') == 'ok': logger_join("OrderId", result['data'], my_order_info.symbol, my_order_info.orderType, my_order_info.price, my_order_info.amount, " ", from_time_stamp()) return result['data'] else: logger_join("order failed!", my_order_info.symbol, my_order_info.orderType, my_order_info.price, my_order_info.amount) return "-1"
def get_option_val(section, option): val = None try: val = config.get(section, option) except configparser.NoSectionError or configparser.NoOptionError as e: logger.error(str(e)) return val
def socket_recv(cls, client): client.recvException = False try: client.socketData = (cls.inflate( client.ws.recv())).decode(encoding="utf-8") except Exception as e: logger.error('recv Exception:[{}]'.format(e))
def get_account_info(self): logger.info( u'---------------------------------------spot account info------------------------------------------------' ) try: accounts = self.API.get_accounts() if accounts.get('status') == 'ok': spot_account = list( filter(lambda x: x["type"] == 'spot', accounts.get("data"))) self.ACCOUNT_ID = spot_account[0].get('id') my_account_info = self.API.get_balance(self.ACCOUNT_ID) symbols = [self.BALANCE_E, self.BALANCE_T] if my_account_info.get('status') == 'ok': data = from_dict(my_account_info, "data", "list") for symbol in symbols: symbol_infos = list( filter(lambda x: x["currency"] == symbol, data)) symbol_info = self.accountInfo[symbol] symbol_info["available"] = float( symbol_infos[0]["balance"]) symbol_info["freezed"] = float( symbol_infos[1]["balance"]) symbol_info["total"] = symbol_info[ "available"] + symbol_info["freezed"] logger_join(symbol.upper(), symbol_info["total"], "available", symbol_info["available"], "freezed", symbol_info["freezed"]) else: self.get_account_info() else: self.get_account_info() except Exception as err: logger.error(err) self.get_account_info()
def make_order(self, my_order_info): logger.info( '-----------------------------------------make order----------------------------------------------' ) result = {} try: result = self.TradeApi.place_order(my_order_info.symbol, "cross", my_order_info.orderType, "fok", my_order_info.amount, my_order_info.offset, my_order_info.price) except Exception as e: logger.error("***trade:%s" % e) if result is not None and result.get('code') == "0" and result.get( 'data'): logger.info("Order {} {} {} {} {} {}".format( result['data'][0]['ordId'], my_order_info.symbol, my_order_info.orderType, my_order_info.price, my_order_info.amount, from_time_stamp())) return result['data'][0]['ordId'] else: logger.error("order failed!{} {} {} {} {}".format( my_order_info.symbol, my_order_info.orderType, my_order_info.price, my_order_info.amount, round(my_order_info.price * my_order_info.amount, 3))) return -1
def get_klines(self, symbol, period, size): result = {} try: result = self.API.get_kline(symbol, period, size) except Exception as e: logger.error("***get_kline:%s" % e) if result is not None and result.get('status') == 'ok' and len(result.get('data')) >= size: self.kline_data = list(map(self.get_line_data, result.get('data'))) else: self.get_klines(symbol, period, size)
def withdraw_one(key, symbol, amount, to_address): account_api = AccountAPI(key[0], key[1], key[2]) try: if not amount: amount = get_account_currency(symbol, key)[0]["available"] account_api.coin_withdraw(symbol, float(amount), 3, to_address, key[3], 0) return 1, "ok" except Exception as e: logger.error(str(e)) return 0, str(e)
def send_telegram(message, is_report=False): token = deal_token if not is_report else daily_report_token data = {"chat_id": chat_id, "text": message} url = f"https://api.telegram.org/bot{token}/sendMessage" try: if requests.post(url, data=data).json()["ok"]: return True else: return False except Exception as e: logger.error(f"send telegram msg exception:{str(e)}") return False
def transfer_one(key, symbol, amount, _from, _to): account_api = AccountAPI(key[0], key[1], key[2]) try: if not amount: if _from == "6": amount = get_account_currency(symbol, key)[0]["available"] else: amount = get_spot_currency(symbol, key)["available"] account_api.coin_transfer(symbol, float(amount), int(_from), int(_to)) return 1, "ok" except Exception as e: logger.error(str(e)) return 0, str(e)
def order_one(key, order_type, symbol, price, amount): spot_api = SpotAPI(key[0], key[1], key[2]) try: if not amount: amount = get_spot_currency(symbol.split("_"[0]), key)["available"] result = spot_api.take_order(order_type, symbol, 2, price, amount) if result is not None and result.get('result'): return 1, result['order_id'] else: return 0, "下单未成功" except Exception as e: logger.error(str(e)) return 0, str(e)
def get_currency(environ, start_response): start_response('200 OK', [('Content-type', 'application/json')]) params = environ['params'] symbol = params["symbol"] key = accounts_init[params["account"]] try: yield Result( True, "", { "fund": get_account_currency(symbol, key), "coin": get_spot_currency(symbol, key) }).response() except Exception as e: logger.error(str(e)) yield Result(False, str(e)).response()
def get_coin_price(self, symbol): data = {} try: data = self.MarketApi.get_orderbook(symbol, '20') data = data['data'][0] except Exception as e: logger.error("***depth:%s" % e) price_info = self.priceInfo[symbol] if data is not None and data.get("asks") is not None: price_info["asks"] = list( map(lambda x: list(map(lambda d: float(d), x)), data["asks"])) price_info["bids"] = list( map(lambda x: list(map(lambda d: float(d), x)), data["bids"])) else: self.get_coin_price(symbol)
def check_order_list(self, my_order_info): result = {} try: result = self.API.orders_list(my_order_info.symbol, 'pre-submitted,submitting,submitted,partial-filled,filled', my_order_info.orderType, 1) except Exception as e: logger.error("***orders_list:%s" % e) if result is not None and result.get('status') == 'ok': order = result.get("data")[0] if float(order.get("price")) == my_order_info.price: return {'status': 'ok', 'data': order['id']} else: return {} else: logger_join(my_order_info.symbol, "check_order_list failed,try again.") return self.check_order_list(my_order_info)
def get_coin_price(self, symbol): data = {} try: data = self.API.get_depth(symbol) except Exception as e: logger.error("***get_depth:%s" % e) if data is not None and data.get('status') == 'ok': # check version last_version = self.priceInfo["version"] version = data["tick"]["version"] if version == last_version: self.get_coin_price(symbol) self.priceInfo["version"] = version price_info = self.priceInfo[symbol] price_info["asks"] = data["tick"]["asks"] price_info["bids"] = data["tick"]["bids"] else: self.get_coin_price(symbol)
def get_account_info(self): logger.info( '-----------------------------------spot account info--------------------------------------------' ) try: accounts = [self.BALANCE_E.upper(), self.BALANCE_T.upper()] for symbol in accounts: t_account = self.spotAPI.get_coin_account_info(symbol) if t_account.get('currency') == symbol: logger.info("%s:balance %s available %s frozen %s" % (symbol, t_account["balance"], t_account["available"], t_account["frozen"])) else: logger.warning("getAccountInfo Fail,Try again!") self.get_account_info() except Exception as err: logger.error(err) self.get_account_info()
def check_order_status(self, my_order_info, wait_count=0): order_id = my_order_info.orderId order_result = {} try: logger.info("check order status {}".format(wait_count)) order_result = self.spotAPI.get_order_info(my_order_info.orderId, my_order_info.symbol) except Exception as e: logger.error("***orderinfo:%s" % e) if order_result is not None and order_result.get( 'order_id') == my_order_info.orderId: order = order_result order_id = order["order_id"] status = order["status"] filled_size = float(order["filled_size"]) if filled_size > 0: my_order_info.set_deal_amount(filled_size) my_order_info.set_avg_price( float(order["filled_notional"]) / filled_size) if status == self.CANCELLED_STATUS: logger.info("order {} canceled".format(order_id)) elif status == 'open': if wait_count == self.TRADE_WAIT_COUNT: logger.info("timeout no deal") else: logger.info("no deal") elif status == 'part_filled': if wait_count == self.TRADE_WAIT_COUNT: logger.info("timeout part deal {}".format( my_order_info.dealAmount)) else: logger.info("part deal {}".format( my_order_info.dealAmount)) elif status == self.FILLED_STATUS: logger.info("order {} filled".format(order_id)) elif status == 'canceling': logger.info("order {} canceling".format(order_id)) elif status == 'ordering': logger.info("order {} ordering".format(order_id)) return status else: logger.warning( "order {} checkOrderStatus failed,try again.".format(order_id)) return self.check_order_status(my_order_info, wait_count)
def ws_connect(self): if self.ws is None or not self.ws.connected: try: self.ws = create_connection("wss://real.okex.com:8443/ws/v3", timeout=5) logger.info('websocket connected!') pair = self.SYMBOL_T.upper().replace("_", "-") sub_param = { "op": "subscribe", "args": ["spot/depth5:{}".format(pair)] } sub_str = json.dumps(sub_param) self.ws.send(sub_str) result = self.inflate(self.ws.recv()) logger.info("{} subscribe:{}".format(pair, result)) except Exception as e: logger.error('\nconnect ws error[{}],retry...'.format(e)) time.sleep(2) self.ws_connect()
def send_email(content, _subtype='plain', _subject="bitcoinrobot"): # 第三方 SMTP 服务 mail_host = "smtp.gmail.com" # 设置服务器 mail_user = "******" # 用户名 mail_pass = "******" # 口令 message = MIMEText(content, _subtype, 'utf-8') message['From'] = Header(mail_user) message['To'] = Header(",".join(receivers)) message['Subject'] = Header(_subject) try: server = smtplib.SMTP_SSL(mail_host, 465) server.ehlo() server.login(mail_user, mail_pass) server.sendmail(mail_user, receivers, message.as_string()) server.close() logger.info("邮件发送成功") return True except smtplib.SMTPException as err: logger.error("Error: 邮件发送失败,{}".format(err)) return False
def check_order_status(self, my_order_info, wait_count=0): order_id = my_order_info.orderId order_result = {} try: logger.info("check order status {}".format(wait_count)) order_result = self.TradeApi.get_orders(my_order_info.symbol, my_order_info.orderId) except Exception as e: logger.error("***orderinfo:%s" % e) if order_result is not None and order_result.get( 'code') == "0" and order_result.get('data'): order = order_result['data'][0] order_id = order["ordId"] status = order["state"] filled_size = float(order["accFillSz"]) if filled_size > 0: my_order_info.set_deal_amount(filled_size) my_order_info.set_avg_price(float(order["avgPx"])) if status == self.CANCELLED_STATUS: logger.info("order {} canceled".format(order_id)) elif status == 'live': if wait_count == self.TRADE_WAIT_COUNT: logger.info("timeout no deal") else: logger.info("no deal") elif status == 'partially_filled': if wait_count == self.TRADE_WAIT_COUNT: logger.info("timeout part deal {}".format( my_order_info.dealAmount)) else: logger.info("part deal {}".format( my_order_info.dealAmount)) elif status == self.FILLED_STATUS: logger.info("order {} filled".format(order_id)) return status else: logger.warning( "order {} checkOrderStatus failed,try again.".format(order_id)) return self.check_order_status(my_order_info, wait_count)
def get_coin_price(self, symbol): self.ws_connect() self.socketData = None gevent.spawn(self.socket_recv, self).join(15) if not self.socketData: self.ping = True self.pong = False t = 0 while not self.pong and t < 3: try: self.ws.send("ping") logger.info("[{}]ping.........".format(symbol)) gevent.spawn(self.socket_recv, self).join(3) except Exception as e: logger.info("[{}]ping exception,{}".format(symbol, e)) if self.socketData: self.pong = True logger.info("[{}]pong!!!!!!!!!".format(symbol)) t += 1 if self.ping: self.ping = False if not self.pong: logger.warning("[{}]no pong in 5s,reconnect!".format(symbol)) self.ws.close() self.get_coin_price(symbol) return res = None try: res = json.loads(self.socketData) except Exception as e: logger.error("{} : {}".format(self.socketData, e)) if res and res.get("data") is not None: data = res.get("data")[0] price_info = self.priceInfo[symbol] price_info["asks"] = list( map(lambda x: list(map(lambda d: float(d), x)), data["asks"])) price_info["bids"] = list( map(lambda x: list(map(lambda d: float(d), x)), data["bids"]))
def make_order(self, my_order_info): logger.info( '-----------------------------------------spot order----------------------------------------------' ) result = {} try: result = self.spotAPI.take_order(my_order_info.orderType, my_order_info.symbol, 2, my_order_info.price, my_order_info.amount) except Exception as e: logger.error("***trade:%s" % e) if result is not None and result.get('result'): logger.info("Order {} {} {} {} {} {}".format( result['order_id'], my_order_info.symbol, my_order_info.orderType, my_order_info.price, my_order_info.amount, from_time_stamp())) return result['order_id'] else: logger.error("order failed!{} {} {} {} {}".format( my_order_info.symbol, my_order_info.orderType, my_order_info.price, my_order_info.amount, round(my_order_info.price * my_order_info.amount, 3))) return -1
def get_klines(self, symbol, period, size): result = {} try: result = self.MarketApi.get_history_candlesticks( symbol, period, size) except Exception as e: logger.error("***klines:%s" % e) time.sleep(0.2) if result["code"] == "0": data = result["data"] is_list = isinstance(data, list) if is_list and len(data) == size: self.kline_data = list(map(self.get_line_data, data)) if len(self.kline_data) == 0: logger.error("***klines retry...") self.get_klines(symbol, period, size) elif is_list and len(data) != size and len(data) != size - 1: logger.warning("***klines not refresh,{}".format(data)) else: logger.error("***klines:%s" % result["msg"])