示例#1
0
 def add(self):
     session = get_dbsession()
     try:
         session.add(
             CombinationModel(combination=self.combination,
                              user=self.user,
                              first_market=self.first_market,
                              second_market=self.second_market,
                              big_coin=self.big_coin,
                              small_coin=self.small_coin,
                              big_coin_amount=self.big_coin_amount,
                              small_coin_amount=self.small_coin_amount,
                              trade_threshold=self.trade_threshold,
                              first_market_api_key=aes_encrypt(
                                  self.first_market_api_key),
                              first_market_api_secret=aes_encrypt(
                                  self.first_market_api_secret),
                              second_market_api_key=aes_encrypt(
                                  self.second_market_api_key),
                              second_market_api_secret=aes_encrypt(
                                  self.second_market_api_secret),
                              status=self.status,
                              huobi_account=self.huobi_account,
                              huobipoint_account=self.huobipoint_account))
         session.commit()
     except Exception as e:
         session.rollback()
         print '{}|AddCombinationException|{}'.format(
             datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f'), self)
         raise
     obj = self.fetch_by_combination(self.combination)
     self.id = obj.id
     print '{}|AddCombination|{}'.format(
         datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f'), self)
示例#2
0
 def add(self):
     session = get_dbsession()
     try:
         session.add(self)
         session.commit()
     except:
         session.rollback()
         raise
def run():
    obj_dict = dict()
    session = get_dbsession()
    try:
        order_list = session.query(CombinationTradeInfoModel) \
            .filter(and_(CombinationTradeInfoModel.state == OrderState.Filled,
                         CombinationTradeInfoModel.market == Market.HUOBI,
                         CombinationTradeInfoModel.trade_side == TradeSide.SIDE_SELL)) \
            .all()
        for order_data in order_list:
            # 这种情况不应该发生
            if order_data.order_id is None:
                print("{}|InvalidOrder|{}|{}|{}".format(
                    datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f'),
                    order_data.trade_pair_id, order_data.combination,
                    order_data.market))
                continue
            if order_data.combination not in obj_dict:
                try:
                    _obj = HuobiBinanceCombinationTask(
                        rds=None, combination=order_data.combination)
                    obj_dict[order_data.combination] = _obj
                except:
                    obj_dict[order_data.combination] = None
            combination_obj = obj_dict.get(order_data.combination)
            if combination_obj is None:
                print("{}|CombinationNotFound|{}|{}|{}".format(
                    datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f'),
                    order_data.trade_pair_id, order_data.combination,
                    order_data.market))
                continue
            huobi_order_info = combination_obj.huobi_trade_api.query_order(
                order_data.order_id)
            # 先只管订单完成了的
            if huobi_order_info['state'] == 'filled':
                order_data.filled_amount = Decimal(
                    huobi_order_info['field-cash-amount'])
                print("{}|ChangeFilledAmount|{}|{}|{}|{}|{}".format(
                    datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f'),
                    order_data.trade_pair_id, order_data.combination,
                    order_data.market, order_data.trade_side,
                    order_data.filled_amount))
                session.commit()
            # 1s最多一次操作
            time.sleep(1)
    except Exception as e:
        print("{}|TaskError|{}|{}".format(
            datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f'), e.message,
            traceback.format_exc()))
        # 重开对象
        session.rollback()
    print("{}|WaitForNextTurn".format(
        datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f')))
    # 休息1分钟
    time.sleep(60)
示例#4
0
def end_combination(name):
    """
    结束组合
    :param name:
    :return:
    """
    session = get_dbsession()
    try:
        combination_obj = Combination.fetch_by_combination(name)
        fetch_combination_account(combination_obj, Status.End)
        _db = session.query(CombinationModel).filter_by(
            combination=name).one_or_none()
        _db.status = Status.End
        session.commit()
    except:
        session.rollback()
        raise
    print("{}|EndCombination|{}".format(
        datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f'), name))
示例#5
0
 def fetch_by_id(cls, id):
     """
     获取指定id对应的组合
     :param id:
     :return:
     """
     session = get_dbsession()
     try:
         _db = session.query(CombinationModel).filter_by(
             id=id).one_or_none()
         if _db is None:
             raise CombinationNotExistError(
                 u'Combination of id {} not exist'.format(id))
         res = cls(
             id=_db.id,
             combination=_db.combination,
             user=_db.user,
             first_market=_db.first_market,
             second_market=_db.second_market,
             big_coin=_db.big_coin,
             small_coin=_db.small_coin,
             big_coin_amount=_db.big_coin_amount,
             small_coin_amount=_db.small_coin_amount,
             trade_threshold=_db.trade_threshold,
             first_market_api_key=aes_decrypt(_db.first_market_api_key),
             first_market_api_secret=aes_decrypt(
                 _db.first_market_api_secret),
             second_market_api_key=aes_decrypt(_db.second_market_api_key),
             second_market_api_secret=aes_decrypt(
                 _db.second_market_api_secret),
             status=_db.status,
             huobi_account=_db.huobi_account,
             huobipoint_account=_db.huobipoint_account)
         session.commit()
     except:
         session.rollback()
         raise
     return res
示例#6
0
 def all_active(cls):
     """
     获取所有组合
     :return: combination object list
     """
     session = get_dbsession()
     try:
         db_list = session.query(CombinationModel).filter_by(
             status=Status.Active).all()
         res_list = list()
         for _db in db_list:
             res_list.append(
                 cls(id=_db.id,
                     combination=_db.combination,
                     user=_db.user,
                     first_market=_db.first_market,
                     second_market=_db.second_market,
                     big_coin=_db.big_coin,
                     small_coin=_db.small_coin,
                     big_coin_amount=_db.big_coin_amount,
                     small_coin_amount=_db.small_coin_amount,
                     trade_threshold=_db.trade_threshold,
                     first_market_api_key=aes_decrypt(
                         _db.first_market_api_key),
                     first_market_api_secret=aes_decrypt(
                         _db.first_market_api_secret),
                     second_market_api_key=aes_decrypt(
                         _db.second_market_api_key),
                     second_market_api_secret=aes_decrypt(
                         _db.second_market_api_secret),
                     status=_db.status,
                     huobi_account=_db.huobi_account,
                     huobipoint_account=_db.huobipoint_account))
         session.commit()
     except:
         session.rollback()
         raise
     return res_list
示例#7
0
 def get(cls, name):
     session = get_dbsession()
     return session.query(cls).filter_by(name=name).one_or_none()
示例#8
0
def run():
    obj_dict = dict()
    session = get_dbsession()
    while 1:
        try:
            order_list = session.query(CombinationTradeInfoModel)\
                .filter(and_(CombinationTradeInfoModel.state != OrderState.Filled,
                             CombinationTradeInfoModel.state != OrderState.Exception))\
                .order_by(CombinationTradeInfoModel.create_time.desc()).limit(10)
            session.commit()
            # 移除之前没找到的combination
            for k, v in obj_dict.items():
                if v is None:
                    del obj_dict[k]
            for order_data in order_list:
                # 这种情况不应该发生
                if order_data.order_id is None:
                    print("{}|InvalidOrder|{}|{}|{}".format(
                        datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f'),
                        order_data.trade_pair_id, order_data.combination,
                        order_data.market))
                    continue
                if order_data.combination not in obj_dict:
                    try:
                        _obj = get_task_object(
                            rds=None, combination=order_data.combination)
                        obj_dict[order_data.combination] = _obj
                    except:
                        obj_dict[order_data.combination] = None
                combination_obj = obj_dict.get(order_data.combination)
                if combination_obj is None:
                    print("{}|CombinationNotFound|{}|{}|{}".format(
                        datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f'),
                        order_data.trade_pair_id, order_data.combination,
                        order_data.market))
                    continue
                if order_data.market == Market.HUOBI:
                    huobi_order_info = combination_obj.huobi_trade_api.query_order(
                        order_data.order_id)
                    # 先只管订单完成了的
                    if huobi_order_info['state'] == 'filled':
                        order_data.state = OrderState.Filled
                        if order_data.trade_side == TradeSide.SIDE_BUY:
                            order_data.filled_amount = Decimal(
                                huobi_order_info['field-amount'])
                        else:
                            order_data.filled_amount = Decimal(
                                huobi_order_info['field-cash-amount'])
                        order_data.filled_fees = Decimal(
                            huobi_order_info['field-fees'])
                        order_data.order_time = datetime.utcfromtimestamp(
                            1.0 * huobi_order_info['created-at'] / 1000)
                        session.commit()
                        print("{}|OrderFilled|{}|{}|{}".format(
                            datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f'),
                            order_data.trade_pair_id, order_data.combination,
                            order_data.market))
                elif order_data.market == Market.BINANCE:
                    binance_order_info = combination_obj.binance_trade_api.get_order(
                        symbol=order_data.symbol, orderId=order_data.order_id)
                    if binance_order_info['status'] == 'FILLED':
                        order_data.state = OrderState.Filled
                        order_data.filled_amount = Decimal(
                            binance_order_info['executedQty'])
                        order_data.order_time = datetime.utcfromtimestamp(
                            1.0 * binance_order_info['time'] / 1000)
                        session.commit()
                        print("{}|OrderFilled|{}|{}|{}".format(
                            datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f'),
                            order_data.trade_pair_id, order_data.combination,
                            order_data.market))
                elif order_data.market == Market.OKEX:
                    okex_order_info = combination_obj.okex_trade_api.get_order(
                        symbol=order_data.symbol,
                        order_id=order_data.order_id)[0]
                    print order_data.query_amount, order_data.query_price, okex_order_info
                    if okex_order_info['status'] == 2:
                        order_data.state = OrderState.Filled
                        if order_data.trade_side == TradeSide.SIDE_BUY:
                            order_data.filled_amount = Decimal(okex_order_info['deal_amount']) / \
                                                       Decimal(okex_order_info['avg_price'])
                        else:
                            order_data.filled_amount = Decimal(okex_order_info['deal_amount']) * \
                                                       Decimal(okex_order_info['avg_price'])
                        order_data.order_time = datetime.utcfromtimestamp(
                            1.0 * okex_order_info['create_date'] / 1000)
                        session.commit()
                        print("{}|OrderFilled|{}|{}|{}".format(
                            datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f'),
                            order_data.trade_pair_id, order_data.combination,
                            order_data.market))
                # 1s最多一次操作
                time.sleep(1)
        except Exception as e:
            session.rollback()
            print("{}|TaskError|{}|{}".format(
                datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f'), e.message,
                traceback.format_exc()))
            try:
                ExceptionInfoModel(host=ip,
                                   source='CHECK_ORDER',
                                   message=e.message,
                                   log_time=datetime.utcnow()).add()
            except:
                pass
            # 重开对象
            session.close()
            session = get_dbsession()
            obj_dict = dict()
        print("{}|WaitForNextTurn".format(
            datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S.%f')))
        # 休息1分钟
        time.sleep(60)
示例#9
0
def report_supervisor_status():
    """
    汇报supervisor状态
    :return:
    """
    session = get_dbsession()
    try:
        # shell获取到的是服务器当地时间
        begin_datetime = datetime.now() - timedelta(seconds=1800)
        utc_begin_datetime = datetime.utcnow() - timedelta(seconds=1800)
        db_list = session.query(SupervisorStatusModel).\
            filter(SupervisorStatusModel.log_time > begin_datetime).all()
        message_list = list()
        for db in db_list:
            status_parts = db.info.split('\n')
            parts_len = len(status_parts)
            for index, item in enumerate(status_parts):
                item_parts = item.split(' ', 1)
                if index == 0:
                    message = u"""
                        <tr>
                        <td rowspan="{rowspan}">{host}</td>
                        <td>{task}</td>
                        <td>{status}</td>
                        <td>{log_time}</td>
                        </tr>
                    """.format(
                        host=db.host,
                        task=item_parts[0],
                        status=item_parts[1].strip(),
                        log_time=db.log_time.strftime('%Y-%m-%d %H:%M:%S'),
                        rowspan=parts_len)
                else:
                    message = u"""
                        <tr>
                        <td>{task}</td>
                        <td>{status}</td>
                        <td>{log_time}</td>
                        </tr>
                    """.format(
                        task=item_parts[0],
                        status=item_parts[1].strip(),
                        log_time=db.log_time.strftime('%Y-%m-%d %H:%M:%S'))
                message_list.append(message)
        # 异常,异常记录的是UTC时间
        db_list = session.query(ExceptionInfoModel). \
            filter(ExceptionInfoModel.log_time > utc_begin_datetime).all()
        cal_dict = dict()
        exception_cal_message_list = list()
        exception_message_list = list()
        for db in db_list:
            if db.host not in cal_dict:
                cal_dict[db.host] = dict()
            if db.source not in cal_dict[db.host]:
                cal_dict[db.host][db.source] = 1
            else:
                cal_dict[db.host][db.source] += 1
            message = u"""
                <tr>
                <td>{host}</td>
                <td>{source}</td>
                <td>{info}</td>
                </tr>
            """.format(host=db.host, source=db.source, info=db.message)
            exception_message_list.append(message)
        for host, host_cal in cal_dict.items():
            for source, count in host_cal.items():
                message = u"""
                    <tr>
                    <td>{host}</td>
                    <td>{source}</td>
                    <td>{count}</td>
                    </tr>
                    """.format(host=host, source=source, count=count)
                exception_cal_message_list.append(message)
        user_html = u"""
            <h2>运行状态</h2>
            <table border="1" cellspacing="0">
            {header}
            {message}
            </table>
            <h2>异常统计</h2>
            <table border="1" cellspacing="0">
            {exception_cal_header}
            {exception_cal_message}
            </table>
             <h2>异常信息</h2>
            <table border="1" cellspacing="0">
            {exception_info_header}
            {exception_info_message}
            </table>
        """.format(header=supervisor_status_header,
                   message='\n'.join(message_list),
                   exception_cal_header=exception_cal_header,
                   exception_cal_message='\n'.join(exception_cal_message_list),
                   exception_info_header=exception_info_header,
                   exception_info_message='\n'.join(exception_message_list))
        send_email(['*****@*****.**'],
                   header='运行状态报表',
                   text=None,
                   html=user_html)
    except:
        session.rollback()
        print(traceback.format_exc())
        raise
示例#10
0
def report_profit():
    """
    汇报收益
    :return:
    """
    active_combination_list = Combination.all_active()
    user_profit = defaultdict(list)
    today_str = datetime.utcnow().strftime('%Y-%m-%d')
    # today_str = '2018-03-31'
    session = get_dbsession()
    res = session.execute(
        'SELECT combination, init_big, init_small, init_bnb, init_huobi, yes_big, '
        'yes_small, yes_bnb, yes_huobi, now_big, now_small, now_bnb, now_huobi, '
        'daily_profit_rate, total_profit_rate, daily_profit, total_profit from '
        'combination_profit where substr(log_time, 1, 10)="{}"'.format(
            today_str))
    data_res = dict()
    for item in res:
        data_res[item[0]] = item
    for combination_obj in active_combination_list:
        if data_res.get(combination_obj.combination) is None:
            continue
        combination, init_big, init_small, init_bnb, init_huobi, yes_big, yes_small, yes_bnb, \
            yes_huobi, now_big, now_small, now_bnb, now_huobi, daily_profit_rate, total_profit_rate, \
            daily_profit, total_profit = data_res[combination_obj.combination]
        init_point_list = list()
        yes_point_list = list()
        now_point_list = list()
        if combination_obj.first_market == Market.HUOBI or combination_obj.second_market == Market.HUOBI:
            init_point_list.append(u'<p>火币点卡: {}</p>'.format(init_huobi))
            yes_point_list.append(u'<p>火币点卡: {}</p>'.format(yes_huobi))
            now_point_list.append(u'<p>火币点卡: {}</p>'.format(now_huobi))
        if combination_obj.first_market == Market.BINANCE or combination_obj.second_market == Market.BINANCE:
            init_point_list.append(u'<p>bnb: {}</p>'.format(init_bnb))
            yes_point_list.append(u'<p>bnb: {}</p>'.format(yes_bnb))
            now_point_list.append(u'<p>bnb: {}</p>'.format(now_bnb))
        message = u"""
        <tr>
        <td>{id}</td>
        <td><p>{first_market}: {second_market}</p><p>{small_coin}: {big_coin}</p></td>
        <td><p>当日:{daily_profit_rate}%</p><p>总体:{total_profit_rate}%</p></td>
        <td><p>当日:{daily_profit}</p><p>总体:{total_profit}</p></td>
        <td><p>{big_coin}:{now_big}</p><p>{small_coin}:{now_small}</p>{now_point}</td>
        <td><p>{big_coin}:{yes_big}</p><p>{small_coin}:{yes_small}</p>{yes_point}</td>
        <td><p>{big_coin}:{init_big}</p><p>{small_coin}:{init_small}</p>{init_point}</td>
        </tr>
        """.format(id=combination_obj.id,
                   small_coin=combination_obj.small_coin,
                   big_coin=combination_obj.big_coin,
                   init_big=init_big,
                   init_small=init_small,
                   yes_big=yes_big,
                   yes_small=yes_small,
                   now_big=now_big,
                   now_small=now_small,
                   daily_profit=daily_profit,
                   total_profit=total_profit,
                   daily_profit_rate='%.3f' % (daily_profit_rate * 100),
                   total_profit_rate='%.3f' % (total_profit_rate * 100),
                   init_point=u''.join(init_point_list),
                   yes_point=u''.join(yes_point_list),
                   now_point=u''.join(now_point_list),
                   first_market=combination_obj.first_market,
                   second_market=combination_obj.second_market)
        user_profit[combination_obj.user].append(message)

    for user, message_list in user_profit.items():
        if not message_list:
            continue
        user_db = UserModel.get(user)
        if user_db is None or user_db.email is None:
            continue
        user_html = u"""
            <table border="1" cellspacing="0">
            {header}
            {message}
            </table>
        """.format(header=profit_table_header, message='\n'.join(message_list))
        send_email(
            [user_db.email, '*****@*****.**', '*****@*****.**'],
            header='收益报表',
            text=None,
            html=user_html)
示例#11
0
 def add(self):
     session = get_dbsession()
     session.add(self)
     session.commit()