示例#1
0
class app():
    def __init__(self):
        self.key = config.key
        self.secret = config.secret

        self._log = None
        self.dic_balance = defaultdict(lambda: None)
        self.order_list = defaultdict(lambda: None)
        self.stop = False

        self.buy_order_id = None
        self.sell_order_id = None
        self.time_order = time.time()

        self.db = mongodb()
        self.fcoin = Fcoin()
        self.fcoin.auth(self.key, self.secret)
        self._init_log()

    def _init_log(self):
        self._log = logging.getLogger(__name__)
        self._log.setLevel(level=logging.INFO)
        formatter = logging.Formatter('%(asctime)s - %(message)s')

        handler = logging.FileHandler("app.log")
        handler.setLevel(logging.INFO)
        handler.setFormatter(formatter)
        self._log.addHandler(handler)


        console = logging.StreamHandler()
        console.setLevel(logging.INFO)
        console.setFormatter(formatter)
        self._log.addHandler(console)

    #查询订单
    def get_orders(self, symbol, states, limit=1):
        '''
        :param symbol:
        :param states: submitted/partial_filled/partial_canceled/canceled/pending_cancel/filled
        :return:
        '''
        success, data = self.fcoin.list_orders(symbol=symbol, states=states, limit=limit)
        if success:
            return data['data']
        else:
            print(data)
            return None
    #获取余额
    def get_blance(self):
        dic_blance = defaultdict(lambda: None)
        success, data = self.fcoin.get_balance()
        if success:
            for item in data['data']:
                dic_blance[item['currency']] = balance(float(item['available']), float(item['frozen']),float(item['balance']))
        return dic_blance
    #精度
    def digits(self,num, digit):
        site = pow(10, digit)
        tmp = num * site
        tmp = math.floor(tmp) / site
        return tmp
    #过程
    def process(self):
        if self.buy_order_id is None and self.sell_order_id is None:
            success, data = self.fcoin.get_market_depth('L20', config.symbol)
            if success:
                bids = data['data']['bids']  # 买
                asks = data['data']['asks']  # 卖
                total_bids = 0
                total_asks = 0

                for i in range(3):
                    total_bids += bids[2*i - 1]
                    total_asks += asks[2*i - 1]

                buy_price = bids[0]
                buy_amount = bids[1]

                sell_price = asks[0]
                sell_amount = asks[1]

                usdt = self.dic_balance['usdt']
                btc = self.dic_balance['btc']
                amount = 0
                price = 0
                order = None
                if btc:
                    r = self.db.get('buy',buy_price)
                    if r:
                        amount = self.digits(r['amount'], 4)
                        order = {'id': r['_id'], 'amount': amount, 'price': r['price']}

                    #if btc.available >= 0.001 and amount < 0.001:
                    #    amount = self.digits(btc.available, 4)

                    if amount >= 0.001:
                        price = self.digits(sell_price, 2)
                        success, data = self.fcoin.sell(config.symbol, price, amount)#卖
                        if success:
                            self.time_order = time.time()
                            self.sell_order_id = data['data']
                            self._log.info('挂卖单成功[%s:%s]' % (amount, price))
                            if order:
                                self.order_list[self.sell_order_id] = order
                            return
                if usdt:

                    if btc and btc.available >= config.limit_account:
                        self.dic_balance = self.get_blance()
                        self._log.info('余额度超过%s个BTC,停止买入[%s]' % (config.limit_account, btc.available))
                        return

                    if usdt.available > buy_price * config.max_amount:
                        amount = config.max_amount if total_bids > config.total_amount and total_asks > config.total_amount else config.min_amount
                    else:
                        amount = usdt.available/buy_price
                    amount = self.digits(amount, 4)
                    price = self.digits(buy_price, 2)
                    success, data = self.fcoin.buy(config.symbol, price, amount)#买
                    if success:
                        self.time_order = time.time()
                        self.buy_order_id = data['data']
                        self._log.info('挂买单成功[%s:%s]' % (amount, price))

                else:
                    self._log.info('余额错误')
                    self.dic_balance = self.get_blance()
        else:
            if self.sell_order_id:
                success, data = self.fcoin.get_order(self.sell_order_id)
                if success:
                    state = data['data']['state']
                    amount = float(data['data']['filled_amount'])

                    if state in ('filled','partial_canceled'):
                        order = self.order_list[self.sell_order_id]
                        if order:
                            self.db.update( order['id'], amount)

                    if state == 'filled':
                        self.sell_order_id = None
                        self._log.info('卖单已成交')
                        self.dic_balance = self.get_blance()

                    elif state == 'canceled' or state == 'partial_canceled':
                        self.sell_order_id = None
                        self._log.info('卖单已撤单')
                        self.dic_balance = self.get_blance()

                    elif state not in ('pending_cancel'):
                        if time.time() - self.time_order >= 15:
                            self.fcoin.cancel_order(self.sell_order_id)
                            self._log.info('15秒超时撤单')

            if self.buy_order_id:
                success, data = self.fcoin.get_order(self.buy_order_id)
                if success:
                    state = data['data']['state']
                    amount = float(data['data']['filled_amount']) - float(data['data']['fill_fees'])
                    price = float(data['data']['price'])

                    if amount > 0 and state in ('filled','partial_canceled'):
                        self.db.add('buy', price, amount)

                    if state == 'filled':
                        self.buy_order_id = None
                        self._log.info('买单已成交')
                        self.dic_balance = self.get_blance()

                    elif state == 'canceled' or state == 'partial_canceled':

                        self.buy_order_id = None
                        self._log.info('买单已撤单')
                        self.dic_balance = self.get_blance()

                    elif state not in ('pending_cancel'):
                        if time.time() - self.time_order >= 15:
                            self.fcoin.cancel_order(self.buy_order_id)
                            self._log.info('15秒超时撤单')

    def task(self):

        dic = self.get_orders(config.symbol, 'submitted', 20)
        for item in dic:
            self.fcoin.cancel_order(item['id'])
        self.dic_balance = self.get_blance()

        self.loop()

    def loop(self):
        while not self.stop:
            self.process()
            time.sleep(1)
示例#2
0
def cancelAll():
    print("cancelAll")
    sleep(1.5)

    cancel_order_nums = 3
    public_order_deal = Fcoin()
    public_order_deal.auth(accessKey, secretyKey)

    all_orders = []

    for state in ["submitted", "partial_filled"]:
        result, data = public_order_deal.list_orders(symbol="btcusdt",
                                                     states=state)

        if str(data["status"]) == "0":
            orders = data["data"]

            for use_order in orders:
                all_orders.append(use_order)

        sleep(2)

    if len(all_orders) > 0:
        buy_order_array = []
        sell_order_array = []

        for use_order in all_orders:
            systemID = str(use_order["id"])
            status = use_order["state"]
            tradedVolume = float(use_order["filled_amount"])
            totalVolume = float(use_order["amount"])
            price = float(use_order["price"])
            side = use_order["side"]

            if status in ["partial_filled", "submitted", "partial_canceled"]:
                if side == "buy":
                    buy_order_array.append([price, systemID])
                else:
                    sell_order_array.append([price, systemID])

        all_need_cancel = []
        if len(buy_order_array) > cancel_order_nums:
            sort_buy_arr = sorted(buy_order_array,
                                  key=lambda price_pair: price_pair[0])
            sort_buy_arr.reverse()

            print('sort_buy_arr :{}'.format(sort_buy_arr))

            for i in range(cancel_order_nums, len(sort_buy_arr)):
                all_need_cancel.append(str(sort_buy_arr[i][1]))
                # public_order_deal.cancel_order( str(sort_buy_arr[i][1]))

        if len(sell_order_array) > cancel_order_nums:
            sort_sell_arr = sorted(sell_order_array,
                                   key=lambda price_pair: price_pair[0])

            print(u'sort_sell_arr'.format(sort_sell_arr))

            for i in range(cancel_order_nums, len(sell_order_array)):
                all_need_cancel.append(str(sort_sell_arr[i][1]))

        for systemID in all_need_cancel:
            try:
                print(public_order_deal.cancel_order(systemID))
                sleep(1.5)
            except Exception as ex:
                print(ex, file=sys.stderr)

    else:
        print("order_all is not ")
示例#3
0
class wss_app:

    def __init__(self):
        self.client = fcoin_client()
        self.client.stream.stream_depth.subscribe(self.depth)
        self.client.stream.stream_klines.subscribe(self.candle)
        self.client.stream.stream_ticker.subscribe(self.ticker)
        self.fcoin = Fcoin()
        self.fcoin.auth(config.key, config.secret)

        self.buy_price = None  # 买1价
        self.buy_amount = None  # 买1量
        self.sell_price = None  # 卖1价
        self.sell_amount = None  # 卖1量
        self.ts = None  # 深度更新时间

        self.market_price = None  # 市价

        self.total_bids = 0
        self.total_asks = 0

        self.filled_buy_order_list = []
        self.order_list = defaultdict(lambda: None)
        self.buy_order_id = None
        self.dic_balance = defaultdict(lambda: None)
        self.time_order = time.time()

        self.price_list = []
        self.candle_list = None
        self.SMA = None
        self._init_log()

    # 日志初始化
    def _init_log(self):
        self._log = logging.getLogger(__name__)
        self._log.setLevel(level=logging.INFO)
        formatter = logging.Formatter("%(asctime)s - %(message)s")  # 格式

        """
        保存文档
        """
        handler = logging.FileHandler("app.log")
        handler.setLevel(logging.INFO)
        handler.setFormatter(formatter)
        self._log.addHandler(handler)

        """
        控制台显示
        """
        console = logging.StreamHandler()
        console.setLevel(logging.INFO)
        console.setFormatter(formatter)
        self._log.addHandler(console)

    # 精度控制,直接抹除多余位数,非四舍五入
    def digits(self, num, digit):
        site = pow(10, digit)
        tmp = num * site
        tmp = math.floor(tmp) / site
        return tmp

    # wss订阅深度接收
    def depth(self, data):
        bids = data["bids"]
        asks = data["asks"]

        self.ts = time.time()

        self.buy_price = bids[0]  # 买
        self.buy_amount = bids[1]
        self.sell_price = asks[0]  # 卖
        self.sell_amount = asks[1]

        for i in range(3):
            self.total_bids += bids[2 * i - 1]
            self.total_asks += asks[2 * i - 1]

    # wss订阅K线接收
    def candle(self, data):
        if self.candle_list is None:
            self.candle_list = [
                {
                    "timestamp": data["id"],
                    "open": data["open"],
                    "high": data["high"],
                    "low": data["low"],
                    "close": data["close"],
                    "volume": data["base_vol"],
                }
            ]
        else:
            last_candle = self.candle_list[-1]
            if last_candle["timestamp"] == data["id"]:
                self.candle_list[-1] = {
                    "timestamp": data["id"],
                    "open": data["open"],
                    "high": data["high"],
                    "low": data["low"],
                    "close": data["close"],
                    "volume": data["base_vol"],
                }
            else:
                self.candle_list.append(
                    {
                        "timestamp": data["id"],
                        "open": data["open"],
                        "high": data["high"],
                        "low": data["low"],
                        "close": data["close"],
                        "volume": data["base_vol"],
                    }
                )

            if len(self.candle_list) > 10:
                self.candle_list.pop(0)

        if len(self.candle_list) >= 7:
            close_array = np.array([item["close"] for item in self.candle_list])
            self.SMA = talib.SMA(close_array, timeperiod=7)

    # 市价
    def ticker(self, data):
        self.ts = time.time()
        self.market_price = data["ticker"][0]

    # 刷单流程
    def process(self):

        if (
            self.ts
            and time.time() - self.ts < 10
            and self.buy_price
            and self.market_price
        ):
            price = self.market_price if config.fix_price == 0 else config.fix_price
            amount = 0

            """
            挂卖单
            """
            success_item_list = []
            for item in self.filled_buy_order_list:
                amount = self.digits(item["amount"], config.symbol["amount_precision"])
                price = self.digits(
                    max(item["price"], price), config.symbol["price_precision"]
                )
                order = [amount, price]
                if amount >= config.symbol["min_amount"]:
                    success, data = self.fcoin.sell(
                        config.symbol["name"], price, amount
                    )  # 卖
                    if success:
                        success_item_list.append(item)
                        self.order_list[data["data"]] = order
                        self._log.info("挂卖单成功[%s:%s]" % (amount, price))

            """
            删除已成功订单
            """
            for item in success_item_list:
                self.filled_buy_order_list.remove(item)

            keys = []
            for key in self.order_list.keys():
                success, data = self.fcoin.get_order(key)
                if success:
                    state = data["data"]["state"]
                    if state == "filled":
                        keys.append([0, key])
                    elif state in ("partial_canceled", "canceled"):
                        keys.append([1, key])

            for tag, key in keys:
                self.order_list.pop(key)
                if tag == 0:
                    self._log.info("已经成交:" + key)
                else:
                    self._log.info("已经撤单:" + key)

            """
            买单不存在时
            """
            if not self.buy_order_id:
                """
                 价格异动识别,可以根据实际情况改动,价格固定时无效
                 """
                if config.fix_price == 0:
                    if abs(self.buy_price - self.sell_price) > 0.5:
                        self._log.info(
                            "价格异动买卖差价:%s" % abs(self.buy_price - self.sell_price)
                        )
                        return
                    elif self.SMA is None:
                        if len(self.price_list) > 0:
                            avg = sum(self.price_list) / len(self.price_list)
                            if abs(avg - self.buy_price) > 10:
                                self._log.info(
                                    "价格异动avg:%s [%s]" % (avg, self.buy_price)
                                )
                                self.price_list.append(self.buy_price)
                                self.price_list.append(self.sell_price)
                                if len(self.price_list) >= 120:
                                    self.price_list.pop(0)
                                return
                        else:
                            self.price_list.append(self.buy_price)
                            self.price_list.append(self.sell_price)
                    else:
                        last = self.SMA[-2]
                        if not np.isnan(last):
                            if abs(self.buy_price - last) >= 0.5:
                                self._log.info("价格异动:%s" % abs(self.buy_price - last))
                                return

                """
                查询余额度
                """
                self.dic_balance = self.get_balance()

                """
                判断币种持仓量,到设定值停止买入。
                """
                coin = self.dic_balance[config.symbol["coin"]]
                if coin and coin.balance > config.limit_amount:
                    self._log.info(
                        "%s余额度达到最大值[%s]" % (config.symbol["coin"], coin.balance)
                    )
                    return
                """
                挂买单
                """
                usdt = self.dic_balance["usdt"]
                if usdt:
                    if config.fix_price:
                        diff = abs(config.fix_price - self.market_price)
                        if config.diff_price < diff:
                            self._log.info("固定价格模式差价异常[%-0.2f]" % diff)
                            return

                    price = (
                        self.market_price if config.fix_price == 0 else config.fix_price
                    )
                    if usdt.available > price * config.max_amount:
                        amount = (
                            config.max_amount
                            if self.total_bids > config.total_amount
                            and self.total_asks > config.total_amount
                            else config.min_amount
                        )
                    else:
                        amount = usdt.available / price
                    amount = self.digits(amount, config.symbol["amount_precision"])
                    if amount >= config.symbol["min_amount"]:
                        price = self.digits(price, config.symbol["price_precision"])
                        success, data = self.fcoin.buy(
                            config.symbol["name"], price, amount
                        )  # 买
                        if success:
                            self.time_order = time.time()
                            self.buy_order_id = data["data"]
                            self._log.info("挂买单成功[%s:%s]" % (amount, price))
                    else:
                        self._log.info("usdt不足[%s]" % (usdt.available))
                else:
                    self._log.info("查询余额错误")
            else:
                """
                买单ID存在时查询订单状态
                """
                success, data = self.fcoin.get_order(self.buy_order_id)
                if success:
                    state = data["data"]["state"]
                    amount = float(data["data"]["filled_amount"]) - float(
                        data["data"]["fill_fees"]
                    )
                    price = float(data["data"]["price"])

                    if amount > 0 and state in ("filled", "partial_canceled"):
                        self.filled_buy_order_list.append(
                            {"price": price, "amount": amount}
                        )

                    if state == "filled":
                        self.buy_order_id = None
                        self._log.info("买单已成交")

                    elif state == "canceled" or state == "partial_canceled":
                        self.buy_order_id = None
                        self._log.info("买单已撤单")

                    elif state not in ("pending_cancel"):
                        """
                        超时判断
                        """
                        if time.time() - self.time_order >= config.delay:
                            self.fcoin.cancel_order(self.buy_order_id)
                            self._log.info("%s秒超时撤单" % config.delay)
        else:
            self._log.info("等待WebSocket数据……")

    # 循环
    def loop(self):

        if (
            config.min_amount < config.symbol["min_amount"]
            or config.min_amount < config.symbol["min_amount"]
        ):
            self._log.info(
                "max_amount,min_amount ≥ 规定的最小数量[%s]" % (config.symbol["min_amount"])
            )
            return

        self.client.start()

        while not self.client.isConnected:
            self._log.info("waitting……")
            time.sleep(1)

        self.client.subscribe_depth(config.symbol["name"], "L20")
        self.client.subscribe_candle(config.symbol["name"], "M1")
        self.client.subscribe_ticker(config.symbol["name"])
        while True:
            try:
                self.process()
            except Exception as error:
                self._log.info("未知错误")
            time.sleep(0.5)

    # 获取余额
    def get_balance(self):
        dic_balance = defaultdict(lambda: None)
        success, data = self.fcoin.get_balance()
        if success:
            for item in data["data"]:
                dic_balance[item["currency"]] = balance(
                    float(item["available"]),
                    float(item["frozen"]),
                    float(item["balance"]),
                )
        return dic_balance

    # 获取订单
    def get_orders(self, symbol, states, limit=1):
        """
        :param symbol:
        :param states: submitted/partial_filled/partial_canceled/canceled/pending_cancel/filled
        :return:
        """
        success, data = self.fcoin.list_orders(
            symbol=symbol, states=states, limit=limit
        )
        if success:
            return data["data"]
        else:
            print(data)
            return None
示例#4
0
class wss_app():
    def __init__(self):
        self.client = fcoin_client()
        self.client.stream.stream_depth.subscribe(self.depth)
        self.client.stream.stream_klines.subscribe(self.candle)
        self.client.stream.stream_ticker.subscribe(self.ticker)
        self.fcoin = Fcoin()
        self.fcoin.auth(config.key, config.secret)

        self.buy_price = None  # 买1价
        self.buy_amount = None  # 买1量
        self.sell_price = None  # 卖1价
        self.sell_amount = None  # 卖1量
        self.ts = None  # 深度更新时间

        self.market_price = None  # 市价

        self.total_bids = 0
        self.total_asks = 0

        self.filled_buy_order_list = []
        self.order_list = defaultdict(lambda: None)
        self.buy_order_id = None
        self.dic_balance = defaultdict(lambda: None)
        self.time_order = time.time()

        self.price_list = []
        self.candle_list = None
        self.SMA = None
        self._init_log()

    # 日志初始化
    def _init_log(self):
        self._log = logging.getLogger(__name__)
        self._log.setLevel(level=logging.INFO)
        formatter = logging.Formatter('%(asctime)s - %(message)s')  # 格式
        '''
        保存文档
        '''
        handler = logging.FileHandler("app.log")
        handler.setLevel(logging.INFO)
        handler.setFormatter(formatter)
        self._log.addHandler(handler)
        '''
        控制台显示
        '''
        console = logging.StreamHandler()
        console.setLevel(logging.INFO)
        console.setFormatter(formatter)
        self._log.addHandler(console)

    # 精度控制,直接抹除多余位数,非四舍五入
    def digits(self, num, digit):
        site = pow(10, digit)
        tmp = num * site
        tmp = math.floor(tmp) / site
        return tmp

    # wss订阅深度接收
    def depth(self, data):
        bids = data['bids']
        asks = data['asks']

        self.ts = time.time()

        self.buy_price = bids[0]  # 买
        self.buy_amount = bids[1]
        self.sell_price = asks[0]  # 卖
        self.sell_amount = asks[1]

        for i in range(3):
            self.total_bids += bids[2 * i - 1]
            self.total_asks += asks[2 * i - 1]

    # wss订阅K线接收
    def candle(self, data):
        if self.candle_list is None:
            self.candle_list = [{
                'timestamp': data['id'],
                'open': data['open'],
                'high': data['high'],
                'low': data['low'],
                'close': data['close'],
                'volume': data['base_vol']
            }]
        else:
            last_candle = self.candle_list[-1]
            if last_candle['timestamp'] == data['id']:
                self.candle_list[-1] = {
                    'timestamp': data['id'],
                    'open': data['open'],
                    'high': data['high'],
                    'low': data['low'],
                    'close': data['close'],
                    'volume': data['base_vol']
                }
            else:
                self.candle_list.append({
                    'timestamp': data['id'],
                    'open': data['open'],
                    'high': data['high'],
                    'low': data['low'],
                    'close': data['close'],
                    'volume': data['base_vol']
                })

            if len(self.candle_list) > 10:
                self.candle_list.pop(0)

        if len(self.candle_list) >= 7:
            close_array = np.array(
                [item['close'] for item in self.candle_list])
            self.SMA = talib.SMA(close_array, timeperiod=7)

    # 市价
    def ticker(self, data):
        self.ts = time.time()
        self.market_price = data['ticker'][0]

    # 刷单流程
    def process(self):

        if self.ts and time.time(
        ) - self.ts < 10 and self.buy_price and self.market_price:
            price = self.market_price if config.fix_price == 0 else config.fix_price
            amount = 0
            '''
            挂卖单
            '''
            success_item_list = []
            for item in self.filled_buy_order_list:
                amount = self.digits(item['amount'],
                                     config.symbol['amount_precision'])
                price = self.digits(max(item['price'], price),
                                    config.symbol['price_precision'])
                order = [amount, price]
                if amount >= config.symbol['min_amount']:
                    success, data = self.fcoin.sell(config.symbol['name'],
                                                    price, amount)  # 卖
                    if success:
                        success_item_list.append(item)
                        self.order_list[data['data']] = order
                        self._log.info('挂卖单成功[%s:%s]' % (amount, price))
            '''
            删除已成功订单
            '''
            for item in success_item_list:
                self.filled_buy_order_list.remove(item)

            keys = []
            for key in self.order_list.keys():
                success, data = self.fcoin.get_order(key)
                if success:
                    state = data['data']['state']
                    if state == 'filled':
                        keys.append([0, key])
                    elif state in ('partial_canceled', 'canceled'):
                        keys.append([1, key])

            for tag, key in keys:
                self.order_list.pop(key)
                if tag == 0:
                    self._log.info('已经成交:' + key)
                else:
                    self._log.info('已经撤单:' + key)
            '''
            买单不存在时
            '''
            if not self.buy_order_id:
                '''
                 价格异动识别,可以根据实际情况改动,价格固定时无效
                 '''
                if config.fix_price == 0:
                    if abs(self.buy_price - self.sell_price) > 0.5:
                        self._log.info('价格异动买卖差价:%s' %
                                       abs(self.buy_price - self.sell_price))
                        return
                    elif self.SMA is None:
                        if len(self.price_list) > 0:
                            avg = sum(self.price_list) / len(self.price_list)
                            if abs(avg - self.buy_price) > 10:
                                self._log.info('价格异动avg:%s [%s]' %
                                               (avg, self.buy_price))
                                self.price_list.append(self.buy_price)
                                self.price_list.append(self.sell_price)
                                if len(self.price_list) >= 120:
                                    self.price_list.pop(0)
                                return
                        else:
                            self.price_list.append(self.buy_price)
                            self.price_list.append(self.sell_price)
                    else:
                        last = self.SMA[-2]
                        if not np.isnan(last):
                            if abs(self.buy_price - last) >= 0.5:
                                self._log.info('价格异动:%s' %
                                               abs(self.buy_price - last))
                                return
                '''
                查询余额度
                '''
                self.dic_balance = self.get_balance()
                '''
                判断币种持仓量,到设定值停止买入。
                '''
                coin = self.dic_balance[config.symbol['coin']]
                if coin and coin.balance > config.limit_amount:
                    self._log.info('%s余额度达到最大值[%s]' %
                                   (config.symbol['coin'], coin.balance))
                    return
                '''
                挂买单
                '''
                usdt = self.dic_balance['usdt']
                if usdt:
                    if config.fix_price:
                        diff = abs(config.fix_price - self.market_price)
                        if config.diff_price < diff:
                            self._log.info('固定价格模式差价异常[%-0.2f]' % diff)
                            return

                    price = self.market_price if config.fix_price == 0 else config.fix_price
                    if usdt.available > price * config.max_amount:
                        amount = config.max_amount if self.total_bids > config.total_amount and self.total_asks > config.total_amount else config.min_amount
                    else:
                        amount = usdt.available / price
                    amount = self.digits(amount,
                                         config.symbol['amount_precision'])
                    if amount >= config.symbol['min_amount']:
                        price = self.digits(price,
                                            config.symbol['price_precision'])
                        success, data = self.fcoin.buy(config.symbol['name'],
                                                       price, amount)  # 买
                        if success:
                            self.time_order = time.time()
                            self.buy_order_id = data['data']
                            self._log.info('挂买单成功[%s:%s]' % (amount, price))
                    else:
                        self._log.info('usdt不足[%s]' % (usdt.available))
                else:
                    self._log.info('查询余额错误')
            else:
                '''
                买单ID存在时查询订单状态
                '''
                success, data = self.fcoin.get_order(self.buy_order_id)
                if success:
                    state = data['data']['state']
                    amount = float(data['data']['filled_amount']) - float(
                        data['data']['fill_fees'])
                    price = float(data['data']['price'])

                    if amount > 0 and state in ('filled', 'partial_canceled'):
                        self.filled_buy_order_list.append({
                            'price': price,
                            'amount': amount
                        })

                    if state == 'filled':
                        self.buy_order_id = None
                        self._log.info('买单已成交')

                    elif state == 'canceled' or state == 'partial_canceled':
                        self.buy_order_id = None
                        self._log.info('买单已撤单')

                    elif state not in ('pending_cancel'):
                        '''
                        超时判断
                        '''
                        if time.time() - self.time_order >= config.delay:
                            self.fcoin.cancel_order(self.buy_order_id)
                            self._log.info('%s秒超时撤单' % config.delay)
        else:
            self._log.info('等待WebSocket数据……')

    # 循环
    def loop(self):

        if config.min_amount < config.symbol[
                'min_amount'] or config.min_amount < config.symbol[
                    'min_amount']:
            self._log.info('max_amount,min_amount ≥ 规定的最小数量[%s]' %
                           (config.symbol['min_amount']))
            return

        self.client.start()

        while not self.client.isConnected:
            self._log.info('waitting……')
            time.sleep(1)

        self.client.subscribe_depth(config.symbol['name'], 'L20')
        self.client.subscribe_candle(config.symbol['name'], 'M1')
        self.client.subscribe_ticker(config.symbol['name'])
        while True:
            try:
                self.process()
            except Exception as error:
                self._log.info('未知错误')
            time.sleep(0.5)

    # 获取余额
    def get_balance(self):
        dic_balance = defaultdict(lambda: None)
        success, data = self.fcoin.get_balance()
        if success:
            for item in data['data']:
                dic_balance[item['currency']] = balance(
                    float(item['available']), float(item['frozen']),
                    float(item['balance']))
        return dic_balance

    # 获取订单
    def get_orders(self, symbol, states, limit=1):
        '''
        :param symbol:
        :param states: submitted/partial_filled/partial_canceled/canceled/pending_cancel/filled
        :return:
        '''
        success, data = self.fcoin.list_orders(symbol=symbol,
                                               states=states,
                                               limit=limit)
        if success:
            return data['data']
        else:
            print(data)
            return None
示例#5
0
class Robot(object):
    logging.basicConfig(filename='logger.log', level=logging.WARN)
    """docstring for Robot"""
    def __init__(self):
        self.fcoin = Fcoin(api_key, api_secret)

    # 截取指定小数位数
    def trunc(self, f, n):
        return round(f, n)

    def ticker_handler(self, message):
        if 'ticker' in message:
            self.ticker = message['ticker']
        # print('ticker', self.ticker)

    def symbols_action(self):
        all_symbols = self.fcoin.get_symbols()
        for info in all_symbols:
            if symbol == info['name']:
                self.price_decimal = int(info['price_decimal'])
                self.amount_decimal = int(info['amount_decimal'])
                print('price_decimal:', self.price_decimal, 'amount_decimal:',
                      self.amount_decimal)
                return

    # 查询账户余额
    def get_balance_action(self, symbols, specfic_symbol=None):
        balance_info = self.fcoin.get_balance()
        specfic_balance = 0
        for info in balance_info['data']:
            for symbol in symbols:
                if info['currency'] == symbol:
                    balance = info
                    print(balance['currency'], '账户余额', balance['balance'],
                          '可用', balance['available'], '冻结', balance['frozen'])
                    if info['currency'] == specfic_symbol:
                        specfic_balance = float(info['available'])
        return specfic_balance

    # 买操作
    def buy_action(self,
                   this_symbol,
                   this_price,
                   this_amount,
                   diff,
                   should_repeat=0):
        ticker = self.ticker
        cur_price = str(self.trunc(this_price - diff, self.price_decimal))
        print('准备买入', this_price, ticker)
        buy_result = self.fcoin.buy(this_symbol, cur_price, str(this_amount))
        print('buy_result is', buy_result)
        buy_order_id = buy_result['data']
        if buy_order_id:
            print('++++++++++++++++++++++++++++买单: ' + cur_price +
                  '价格成功委托, 订单ID: ' + buy_order_id)
            logging.warning('买单: ' + cur_price + '价格成功委托, 订单ID: ' +
                            buy_order_id)
        return buy_order_id

    # 卖操作
    def sell_action(self, this_symbol, this_price, this_amount, diff):
        ticker = self.ticker
        cur_price = str(self.trunc(this_price + diff, self.price_decimal))
        print('准备卖出', cur_price, ticker)
        sell_result = self.fcoin.sell(this_symbol, cur_price, str(this_amount))
        print('sell_result is: ', sell_result)
        sell_order_id = sell_result['data']
        if sell_order_id:
            print('----------------------------卖单: ' + cur_price +
                  '价格成功委托, 订单ID: ' + sell_order_id)
            logging.warning('卖单: ' + cur_price + '价格成功委托, 订单ID: ' +
                            sell_order_id)
        return sell_order_id

    def list_active_orders(self, this_symbol, state='submitted'):
        dt = datetime(fees_start_time['year'], fees_start_time['month'],
                      fees_start_time['day'], fees_start_time['hour'],
                      fees_start_time['minute'], fees_start_time['second'])
        timestamp = int(dt.timestamp() * 1000)
        return self.fcoin.list_orders(symbol=this_symbol,
                                      states=state,
                                      after=timestamp)

    def get_order_count(self, this_symbol):
        order_list = self.list_active_orders(this_symbol)
        order_buy = 0
        order_sell = 0
        price_buy_max = 0
        price_buy_min = 655350
        id_buy_min = ""
        price_sell_min = 655350
        price_sell_max = 0
        id_sell_max = ""
        for i in range(len(order_list['data'])):
            price_cur = float(order_list['data'][i]['price'])
            if order_list['data'][i]['side'] == 'buy':
                order_buy = order_buy + 1
                if price_cur > price_buy_max:
                    price_buy_max = price_cur
                if price_cur < price_buy_min:
                    price_buy_min = price_cur
                    id_buy_min = order_list['data'][i]['id']
            else:
                order_sell = order_sell + 1
                if price_cur < price_sell_min:
                    price_sell_min = price_cur
                if price_cur > price_sell_max:
                    price_sell_max = price_cur
                    id_sell_max = order_list['data'][i]['id']
        order_price_range = abs(price_sell_max - price_buy_min)
        print("buy_count:", order_buy, "buy_min:", price_buy_min, "buy_max:",
              price_buy_max, "sell_count:", order_sell, "sell_min",
              price_sell_min, "sell_max", price_sell_max, "order_price_range",
              order_price_range)
        return (order_buy, price_buy_max, id_buy_min, order_sell,
                price_sell_min, id_sell_max, order_price_range)

    def adjust(self, real_diff, order_price):
        diff = order_price * price_diff
        if (diff < real_diff):
            diff = real_diff
        buy_diff = diff
        sell_diff = diff
        return (buy_diff, sell_diff)

    def strategy(self, symbol, order_price, amount, real_diff):
        order_buy, price_buy_max, id_buy_min, order_sell, price_sell_min, id_sell_max, order_price_range = self.get_order_count(
            symbol)
        if (order_price_range > trade_range):
            if (order_buy > order_sell + order_count_diff):
                if "" != id_buy_min:
                    print("order_price_range:", order_price_range,
                          "buy_order_cancel:", id_buy_min)
                    self.fcoin.cancel_order(id_buy_min)
            if (order_sell > order_buy + order_count_diff):
                if "" != id_sell_max:
                    print("order_price_range", order_price_range,
                          "sell_order_cancel:", id_sell_max)
                    self.fcoin.cancel_order(id_sell_max)

        buy_diff, sell_diff = self.adjust(real_diff, order_price)
        cur_price_range = price_range * order_price
        if ((price_buy_max + cur_price_range) < order_price):
            try:
                buy_id = self.buy_action(symbol, order_price, amount, buy_diff)
            except Exception as err:
                print("failed to buy", err)
        if ((price_sell_min - cur_price_range) > order_price):
            try:
                sell_id = self.sell_action(symbol, order_price, amount,
                                           sell_diff)
            except Exception as err:
                print("failed to sell", err)

    def trade(self):
        time.sleep(second)
        ticker = self.ticker
        newest_price = ticker[0]
        high_bids = ticker[2]
        high_bids_amount = ticker[3]
        low_ask = ticker[4]
        low_ask_amount = ticker[5]
        order_price = self.trunc((low_ask + high_bids) / 2, self.price_decimal)
        real_price_difference = float(low_ask - high_bids)
        print('最低卖价:', low_ask, '最高买价', high_bids, '欲下订单价: ', order_price,
              '当前差价:', '{:.9f}'.format(real_price_difference), '设定差价:',
              '{:.9f}'.format(price_difference))
        if real_price_difference > price_difference:
            print('现在价格:', newest_price, '挂单价格', order_price)
            self.strategy(symbol, order_price, amount,
                          real_price_difference / 2)
        else:
            print('差价太小,放弃本次成交')

    def run(self):
        self.client = fcoin_client()
        self.client.start()
        self.client.subscribe_ticker(symbol, self.ticker_handler)
        self.symbols_action()
        self.get_balance_action(symbols)

        time = 0
        while True:
            self.trade()
            time = time + 1
            if (time > 100):
                break