Exemplo n.º 1
0
    def set_symbols_precision(self):
        symbols = self.hbapi.get_symbols()  # 初始化
        log.info('获取usdt交易对价格精度: ts: %s' %
                 datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"))
        symbols_pd = pd.DataFrame(data=list(symbols['data']),
                                  columns=[
                                      'base-currency', 'quote-currency',
                                      'price-precision', 'amount-precision',
                                      'symbol-partition', 'symbol'
                                  ])
        symbols_pd.rename(columns={
            'base-currency': 'base_currency',
            'quote-currency': 'quote_currency',
            'price-precision': 'price_precision',
            'amount-precision': 'amount_precision',
            'symbol-partition': 'symbol_partition'
        },
                          inplace=True)

        symbol_price = {
            'platform': 'huobi',
            'data': json_util.loads(symbols_pd.to_json(orient='records'))
        }
        self.DB_CONN.get_collection('symbol_precision').replace_one(
            {'platform': 'huobi'}, symbol_price, True)
Exemplo n.º 2
0
    def set_rt_price_to_mongo(self):
        symbols_pd = self.get_symbols_precision()

        usdt_symbols = list(
            symbols_pd.loc[symbols_pd.quote_currency == 'usdt'].loc[
                symbols_pd.symbol_partition == 'main']['symbol'])
        real_price_list = []
        log.info('获取usdt交易对 实时价格存库,ts: %s' %
                 datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"))
        for symbol in usdt_symbols:
            if 'hb10' not in symbol:
                trade_detail = self.hbapi.get_trade(symbol)
                real_price = trade_detail['tick']['data'][0]['price']
                real_price_list.append((symbol, real_price))

        price_df = pd.DataFrame(data=real_price_list,
                                columns=['symbol', 'rt_price'])

        symbol_price = {
            'platform': 'huobi',
            'ts': datetime.datetime.utcnow(),
            'data': json_util.loads(price_df.to_json(orient='records'))
        }
        self.DB_CONN.get_collection('symbol_price').replace_one(
            {'platform': 'huobi'}, symbol_price, True)
Exemplo n.º 3
0
    def get_predict_sign(self, interval=30):
        log.info('尝试获取交易信号, ts: %s' %
                 datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"))
        signal = self.DB_CONN.get_collection('sign_detail').find_one(
            {
                "ts": {
                    '$lt':
                    datetime.datetime.utcnow(),
                    '$gte':
                    datetime.datetime.utcnow() -
                    datetime.timedelta(minutes=interval)
                },
                "deal": False
            }, {"data": 1},
            sort=[('ts', -1)],
            limit=1)

        if signal is not None:
            log.info('获取到 交易信号, ts: %s' %
                     datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"))
            id = signal['_id']
            self.DB_CONN.get_collection('sign_detail').find_one_and_update(
                {"_id": id}, {'$set': {
                    'deal': True
                }})
            return signal['data']
        else:
            return None
Exemplo n.º 4
0
    def set_base_trade_price(self):
        tickers = self.hbapi.get_market_ticker()
        log.info('获取基准价格: ts: %s' %
                 datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"))
        base_trade_list = []
        symbol_set = set()
        for ticker in tickers['data']:
            if 'usdt' in ticker['symbol']:
                symbol = ticker['symbol']
                symbol_kline = self.hbapi.get_kline(symbol, '60min', 24)
                if symbol_kline is not None and 'ok' in symbol_kline['status']:
                    for tick in symbol_kline['data']:
                        if time.localtime(
                                tick['id']).tm_hour == 0 and time.localtime(
                                    tick['id']).tm_min == 0:
                            # if time.localtime(tick['id']).tm_hour == 16 and time.localtime(tick['id']).tm_min == 0:
                            close = tick['close']
                            if symbol not in symbol_set:
                                base_trade_list.append((symbol, close))
                                symbol_set.add(symbol)
        # base_trade_list = [('eosusdt', 8.8), ('eth', 5.2), ('trx/usdt', 0.03)]
        symbols_pd = pd.DataFrame(data=base_trade_list,
                                  columns=['symbol', 'base_price'])
        symbol__base_price = {
            'platform': 'huobi',
            'data': json_util.loads(symbols_pd.to_json(orient='records'))
        }

        self.DB_CONN.get_collection('symbol_base_price').replace_one(
            {'platform': 'huobi'}, symbol__base_price, True)
Exemplo n.º 5
0
 def set_rt_account_holding(self, acct_id=ACCOUNT_ID):
     # 拿到所有持仓,更新余额到mongo,拿出不为0的持仓返回
     log.info('获取账户实时持仓,acct_id: %s, ts: %s' %
              (acct_id,
               datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")))
     holding = self.hbapi.get_balance(acct_id)
     loads = json_util.loads(json.dumps(holding))
     db_res = self.DB_CONN.get_collection('account').replace_one(
         {'data.id': acct_id}, loads, True)
Exemplo n.º 6
0
    def set_currency_back_list(self):
        log.info('获取已交易币种并存库,acct_id: %s, ts: %s' %
                 (self.ACCOUNT_ID,
                  datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")))
        '''
            拿到现有非usdt头寸,将头寸加入到backlist
        '''

        hold_list = self.get_account_holding(self.ACCOUNT_ID)
        real_price_list = self.get_real_trade_price()

        hold_df = pd.DataFrame(data=hold_list,
                               columns=['currency', 'type', 'balance'])
        real_df = pd.DataFrame(data=real_price_list,
                               columns=['symbol', 'rt_price'])
        real_df['currency'] = real_df['symbol'].str.replace('usdt', '')
        account_currenncy_df = pd.merge(hold_df,
                                        real_df,
                                        how='left',
                                        on='currency')
        account_currenncy_df['rt_price'] = pd.to_numeric(
            account_currenncy_df['rt_price'], errors='coerce').fillna(1)
        account_currenncy_df['balance'] = pd.to_numeric(
            account_currenncy_df['balance'], errors='coerce').fillna(0)
        account_currenncy_df['eval_usdt'] = account_currenncy_df[
            'rt_price'] * account_currenncy_df['balance']

        # hold_df = account_currenncy_df.query('eval_usdt > 1.0 and rt_price != 1.0 ')
        hold_df = account_currenncy_df.query('eval_usdt > 1.0')
        if len(hold_df) > 0:
            hold_list = self.get_currency_black_list()
            if hold_list is None:
                hold_set = set(hold_df['currency'])
            else:
                hold_set = set(hold_list).union(list(hold_df['currency']))

            holds = ''
            for currency in hold_set:
                holds = holds + ',' + currency

            hold_symbol = {
                'platform': 'huobi',
                'ts': datetime.datetime.utcnow(),
                'data': holds.replace(',', '', 1)
            }
            self.DB_CONN.get_collection('trade_black_list_today').replace_one(
                {'platform': 'huobi'}, hold_symbol, True)
Exemplo n.º 7
0
    def get_predict_sign2(self, interval=30):
        log.info('尝试获取交易信号, ts: %s' %
                 datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"))
        mongo_uri = 'mongodb://%s:%s@%s:%s' % ('cocola_2018', 'cocola_dmx~!`',
                                               '149.28.18.43', 27017)
        DB_COIN = MongoClient(mongo_uri,
                              authSource='coin',
                              authMechanism='SCRAM-SHA-1')
        DB_COIN_CONN = DB_COIN['coin']

        # now = math.ceil((datetime.datetime.utcnow() + datetime.timedelta(hours=8)).timestamp())
        now = math.ceil((datetime.datetime.utcnow()).timestamp())
        now_before_interval = now - 120

        signal = DB_COIN_CONN.get_collection('result_currency').find_one(
            {
                "ts": {
                    '$lt': now,
                    '$gte': now_before_interval
                },
                "deal": False
            }, {
                "data": 1,
                "symbol": 1
            },
            sort=[('ts', -1)],
            limit=1)

        if signal is not None:
            log.info('获取到 交易信号, ts: %s' %
                     datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"))
            id = signal['_id']
            DB_COIN_CONN.get_collection('result_currency').find_one_and_update(
                {"_id": id}, {'$set': {
                    'deal': True
                }})
            DB_COIN.close()
            # 转换 tuple 格式
            signal_tupe = self.signal_fmt(signal)
            return signal_tupe
        else:
            DB_COIN.close()
            return None
Exemplo n.º 8
0
    def signal_fmt(self, signal):
        data = signal['data']
        symbol = signal['symbol']
        # begin_ts = math.floor(signal['data']['begin_ts']/1000)
        # end_ts = math.floor(signal['data']['end_ts']/1000)
        updown = signal['data']['updown']
        signal = {}
        signal_tuple = list()

        # 获取当前时间,如果当前时间小于end_ts,且updown是1,则返回
        # if round(datetime.datetime.now().timestamp()) < end_ts and updown == 1:
        if updown == 1:
            signal['symbol'] = str(symbol).replace('usdt', '')
            signal['direction'] = updown
            # 判断当日该交易对  是否发生过交易
            log.info(str(signal))
            signal_tuple.append(signal)
            return signal_tuple
        else:
            return None
Exemplo n.º 9
0
def robin_stop_loss():
    '''
        1.获取账户头寸
        2.遍历持仓头寸,判断是否止盈/止损
        3.止盈/止损, 发起卖单
    '''
    acct_id = afttrade.ACCOUNT_ID

    hold_df = pretrade.get_account_trade_currency(acct_id)

    # 未冻结账户
    trade_currency = hold_df.loc[(hold_df.balance > 0)
                                 & (hold_df.type == 'trade')]

    if len(trade_currency) == 0:
        log.info('持仓为空,暂停止盈止损,ts: %s' %
                 datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"))
        afttrade.clear_records()
        # afttrade 清空所有数据

    for i in range(0, len(trade_currency)):
        symbol = trade_currency.iloc[i]['currency'] + 'usdt'
        balance = trade_currency.iloc[i]['balance']

        log.info('持有币种:%s, 数量:%s ,判断止盈止损, ts: %s' %
                 (symbol, balance,
                  datetime.datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")))

        if afttrade.take_profit(symbol):
            # 止盈
            log.warn('%s 触发 止盈 请求' % symbol)
            order_id = deal.sell_operate(symbol, balance)
            deal.solve_unfillex_order(order_id, 'sell')

        if afttrade.stop_losses(symbol):
            # 止损,卖出操作
            log.warn('%s 触发 止损 请求' % symbol)
            order_id = deal.sell_operate(symbol, balance)
            deal.solve_unfillex_order(order_id, 'sell')
Exemplo n.º 10
0
    def is_global_env_fine(self):

        base_price_list = self.get_base_trade_price()
        real_price_list = self.get_real_trade_price()

        if len(real_price_list) != len(base_price_list):
            base_price_list = self.get_base_trade_price()
            real_price_list = self.get_real_trade_price()

        len_real = len(real_price_list)
        len_base = len(base_price_list)

        # if len_real >= len_base:
        base_pd = pd.DataFrame(data=base_price_list,
                               columns=['symbol', 'base_price'])
        real_pd = pd.DataFrame(data=real_price_list,
                               columns=['symbol', 'rt_price'])
        price_merge_pd = pd.merge(base_pd, real_pd, on='symbol')
        price_merge_pd['change'] = (
            price_merge_pd['rt_price'] -
            price_merge_pd['base_price']) / price_merge_pd['base_price']
        # 涨跌计数
        up_change = len(price_merge_pd.loc[price_merge_pd.change >= 0.008])
        down_change = len(price_merge_pd.loc[price_merge_pd.change <= 0.008])

        if down_change / len(price_merge_pd) > 0.7:
            log.warn("大盘 usdt交易对%s对, %s涨%s跌,清仓" %
                     (len_real, up_change, down_change))
            return True, False  # 清仓,交易
        elif up_change > down_change:
            log.info("大盘 usdt交易对%s对, %s涨%s跌,涨多跌少,正常交易" %
                     (len_real, up_change, down_change))
            return False, True
        else:
            # todo 改为允许卖出方向的交易
            log.info("大盘 usdt交易对%s对, %s涨%s跌,跌多涨少,暂停交易" %
                     (len_real, up_change, down_change))
            return False, False
Exemplo n.º 11
0
    def stop_losses(self, symbol):
        # 买入时价格
        match_order = self.hbapi.orders_matchresults(
            symbol, types='buy-market,buy-limit,buy-ioc')
        if len(match_order['data']) == 0:
            log.info("近两月 %s 没有持仓,不需要止损,若有持仓,请手动" % symbol)
            return False

        match_price = float(match_order['data'][0]['price'])

        trade_detail = self.hbapi.get_trade(symbol)
        # 实时价格
        real_price = trade_detail['tick']['data'][0]['price']

        change = round((real_price - match_price) / match_price, 4)
        if change <= -0.02:
            log.warn("%s 买入价%s 现价%s,达到止损条件 " %
                     (symbol, match_price, real_price))
            self.DB_CONN.get_collection('takeprofit').delete_one(
                {'symbol': symbol})
            return True

        return False
Exemplo n.º 12
0
def generate_trade_plan():
    '''
        拿到账号持仓和信号,做第一决策
    '''

    acct_id = pretrade.ACCOUNT_ID

    # 信号币种
    # signs_tuple = pretrade.get_predict_sign(interval=2)
    signs_tuple = pretrade.get_predict_sign2(interval=2)
    log.info(signs_tuple)
    if signs_tuple is None:
        return
    # signs_tuple = list()
    # a = {"symbol": "neo", "direction": 1}
    # signs_tuple.append(a)

    # 拿到所有币种的价格/数量精度
    precesion_pd = pretrade.get_symbols_precision()

    signs_data = [(d['symbol'], d['direction']) for d in signs_tuple]
    sign_pd = pd.DataFrame(data=signs_data, columns=['currency', 'direction'])
    # 持仓币种
    hold_df = pretrade.get_account_trade_currency(acct_id)

    # 未冻结账户
    trade_currency = hold_df.loc[(hold_df.balance > 0)
                                 & (hold_df.type == 'trade')]

    # 要保留的头寸    ['','','']
    keep_holds = pd.merge(trade_currency,
                          sign_pd.loc[sign_pd.direction == 1],
                          how='inner',
                          on='currency')
    # 要清仓的头寸    ['','','']
    sell_holds = pd.merge(trade_currency,
                          sign_pd.loc[sign_pd.direction == 0],
                          how='inner',
                          on='currency')
    # 要买入的头寸  ['','','']
    buy_holds = pdtool.difference(sign_pd.loc[sign_pd.direction == 1],
                                  trade_currency, 'currency', 'currency')

    # 排除掉当日禁止交易的币种
    base_blacklist = pretrade.get_currency_black_list()
    if base_blacklist is not None:
        blackpd = pd.DataFrame(data=base_blacklist, columns=['currency'])
        buy_holds = pdtool.difference(buy_holds, blackpd, 'currency',
                                      'currency')

    # 合并 价格/数量 精度信息
    buy_holds = pd.merge(
        buy_holds,
        precesion_pd.loc[precesion_pd.quote_currency == 'usdt'],
        how='inner',
        left_on='currency',
        right_on='base_currency')
    '''
        获取大盘信息,做第二决策
    '''
    (clear, continue_ex) = pretrade.is_global_env_fine()

    if clear:
        # 大盘跌,全部清仓变成usdt
        clear_df = hold_df.query('currency != "usdt"')
        '''
        rt_price_list = pretrade.get_real_trade_price()
        rt_price_df = pd.DataFrame(data=rt_price_list, columns=['symbol', 'rt_price'])
        rt_price_df['currency'] = rt_price_df['symbol'].str.replace('usdt', '')
        rt_price_df.drop('symbol', axis=1, inplace=True)

        # 卖出总额usdt
        clear_df = pd.merge(clear_df, rt_price_df, how='inner', on='currency')
        clear_df['value'] = clear_df['balance'] * clear_df['rt_price']
        # 排除卖出额在1美元以下的品种,交易所阻止交易
        clear_df = clear_df[clear_df.value >= 1]
        '''
        log.info('大盘整体下跌,开始清仓')
        # todo 未测试
        insert_id = pretrade.set_tradeplan(None, None, clear_df)
        log.info('生成清仓计划成功,计划id是: %s,时间: %s' %
                 (insert_id,
                  datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S %f')))

    continue_ex = True
    if continue_ex:
        '''
            算出交易资金,调整交易计划并入库 
        '''
        rt_price_list = pretrade.get_real_trade_price()
        rt_price_df = pd.DataFrame(data=rt_price_list,
                                   columns=['symbol', 'rt_price'])
        rt_price_df['currency'] = rt_price_df['symbol'].str.replace('usdt', '')
        rt_price_df.drop('symbol', axis=1, inplace=True)

        # 卖出总额usdt
        sell_holds = pd.merge(sell_holds,
                              rt_price_df,
                              how='inner',
                              on='currency')
        if len(sell_holds) != 0:
            sell_holds[
                'value'] = sell_holds['balance'] * sell_holds['rt_price']
            # 排除卖出额在1美元以下的品种,交易所阻止交易
            sell_holds = sell_holds[sell_holds.value >= 1]
            sell_value = sell_holds['value'].sum()
        else:
            sell_value = 0

        # 持仓usdt
        sum_usdt, hold_usdt = pretrade.get_account_currency()

        # 买入总额等于 待买币种数 * 账户资金*1/100    sum_usdt 1/100 (滑点 + 手续费)

        available_total = sell_value + hold_usdt - sum_usdt / 100
        consumed_total = (sum_usdt / 10) * len(buy_holds)

        # 算出买入币种的数量
        buy_holds = pd.merge(buy_holds,
                             rt_price_df,
                             how='inner',
                             on='currency')
        buy_holds['buy_sum'] = sum_usdt / 10
        buy_holds['balance'] = round(
            buy_holds['buy_sum'] / buy_holds['rt_price'], 4)
        for i in range(0, len(buy_holds)):
            buy_holds.at[(i, 'balance')] = int(buy_holds.iloc[i].balance * pow(
                10, buy_holds.iloc[i].amount_precision)) / pow(
                    10, buy_holds.iloc[i].amount_precision)

        if available_total > consumed_total:
            # 可以交易

            # tradeplan 所在的记录,暂时不用
            insert_id = pretrade.set_tradeplan(keep_holds, buy_holds,
                                               sell_holds)
            log.info(
                '生成交易计划成功,计划id是: %s,时间: %s' %
                (insert_id,
                 datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S %f')))

        else:
            # 资金不足,取出保留仓位中亏损的币种,将其加入到sell_holds
            # 算出差额多少,需要卖几个持仓币种
            log.info('资金不足,重新规划仓位')
            sell_cnt = math.ceil(
                round((consumed_total - available_total) / sum_usdt, 2) * 10)

            if len(keep_holds) > 0:
                keep_holds['changerate'] = 1
                keep_holds['rt_price'] = 0
                keep_holds['symbol'] = 'usdt'
                for k in range(0, len(keep_holds)):
                    currency = keep_holds.iloc[k]['currency']
                    amount = keep_holds.iloc[k]['balance']
                    symbol = currency + 'usdt'
                    trade_detail = hbapi.get_trade(symbol)
                    # 实时价格
                    real_price = trade_detail['tick']['data'][0]['price']
                    keep_holds.loc[k, 'rt_price'] = real_price
                    keep_holds.loc[k, 'symbol'] = currency + 'usdt'
                    # 买入时价格
                    match_order = hbapi.orders_matchresults(
                        symbol, types='buy-market,buy-limit,buy-ioc')
                    if len(match_order['data']) > 0:
                        match_price = match_order['data'][0]['price']
                        keep_holds.loc[k, 'changerate'] = round(
                            (real_price - float(match_price)) /
                            float(match_price), 4)
                    else:
                        keep_holds.loc[k, 'changerate'] = 0

                pre_clear_df = keep_holds.query(
                    'changerate < 0.1').sort_values(
                        by='changerate', ascending=True).head(sell_cnt)

                keep_holds = pdtool.difference(keep_holds, pre_clear_df,
                                               'currency', 'currency')

                sell_holds = sell_holds.append(pre_clear_df)

            insert_id = pretrade.set_tradeplan(keep_holds, buy_holds,
                                               sell_holds)
            log.info(
                '生成交易计划成功,计划id是: %s,时间: %s' %
                (insert_id,
                 datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S %f')))

    else:
        '''
            两次交易信号上涨,价格也上涨,属于独立行情币种,忽略大盘,单独策略
        '''
        pass
Exemplo n.º 13
0
    def take_profit(self, symbol):
        # 买入时价格
        match_order = self.hbapi.orders_matchresults(
            symbol, types="buy-limit,buy-market,buy-ioc")
        if len(match_order['data']) == 0:
            log.info("近两月 %s 没有持仓,不需要止盈, 若有持仓,请手动" % symbol)
            return False

        match_price = match_order['data'][0]['price']
        match_time = match_order['data'][0]['created-at']

        # match_price = 0.0133
        # match_time = 1494870000

        # 实时价格
        trade_detail = self.hbapi.get_trade(symbol)
        real_price = trade_detail['tick']['data'][0]['price']
        real_time = trade_detail['tick']['data'][0]['ts']

        rt_data = {
            'rt_price': real_price,
            'rt_time': int(real_time),
            'created_at': int(match_time),
            'price': match_price,
            'is_hold': True
        }

        # 取出最大价格
        max_price = self.DB_CONN.get_collection('takeprofit').find_one(
            {'symbol': symbol}, {
                'max_price': 1,
                '_id': 0
            })

        if max_price is not None:
            if len(max_price) != 0 and real_price > float(
                    max_price['max_price']):
                rt_data = {
                    'rt_price': real_price,
                    'rt_time': int(real_time),
                    'created_at': int(match_time),
                    'price': match_price,
                    'max_price': round(float(real_price), 4),
                    'max_price_time': int(real_time)
                }
            elif len(max_price) == 0:
                rt_data = {
                    'rt_price': real_price,
                    'rt_time': int(real_time),
                    'created_at': int(match_time),
                    'price': match_price,
                    'max_price': round(float(match_price), 4),
                    'max_price_time': int(match_time)
                }

        update_res = self.DB_CONN.get_collection(
            'takeprofit').find_one_and_update(
                {'symbol': symbol}, {'$set': rt_data},
                upsert=True,
                return_document=ReturnDocument.AFTER)

        # 最大值有值 且 最大值与现价 回撤是否大于5%
        if max_price is not None and len(max_price) != 0:
            max_price = update_res['max_price']
            rt_price = update_res['rt_price']
            rise_back_point = float(max_price) * 0.95
            if rt_price < rise_back_point:
                log.warn("%s 买入价%s 最高价%s 现价%s,达到止盈条件 " %
                         (symbol, match_price, max_price, real_price))
                self.DB_CONN.get_collection('takeprofit').delete_one(
                    {'symbol': symbol})
                return True

        return False
Exemplo n.º 14
0
 def clear_records(self):
     res = self.DB_CONN.get_collection('takeprofit').delete_many(
         {'is_hold': True})
     log.info('清空 各交易对-最高价状态记录')