def update_transaction_free(self): option = Setting.get_json('general_option') transaction_free_generation = option['transaction_free_generation'] transaction_free_amount = option['transaction_free_amount'] community_free_generation = option['community_free_generation'] community_free_amount = option['community_free_amount'] # 加速释放每一代 layer = 0 sponsor = self.sponsor while sponsor and layer < community_free_generation: if sponsor.is_community_node == 0 and layer < transaction_free_generation: amount = transaction_free_amount elif sponsor.is_community_node == 1: amount = community_free_amount else: amount = 0 if amount != 0: details = { 'message': '交易加速释放,交易完成者:{}, 第几代:{}'.format(self.uid, layer + 1) } assets = Assets.get_assets(sponsor.id) # amount = min(assets.total_balance, amount) if assets.update_total_balance( -amount, g_assets_record_type.ACCELERATE_FREE, details): assets.update_transaction_balance( amount, g_assets_record_type.ACCELERATE_FREE, details) layer += 1 sponsor = sponsor.sponsor
def post(self): # parser = reqparse.RequestParser() # parser.add_argument('price', type=decimal.Decimal, required=True, nullable=False, location='json') # parser.add_argument('amount', type=decimal.Decimal, required=True, nullable=False, location='json') # parser.add_argument('security_password', type=str, required=True, nullable=False, location='json') # parsed_args = parser.parse_args() start_time = time.time() option = Setting.get_json('general_option') buy_amount = option['sell_amount'] transaction_time_begin = [ time.strptime(x, '%H:%M') for x in option['transaction_time_begin'] ] transaction_time_end = [ time.strptime(x, '%H:%M') for x in option['transaction_time_end'] ] # if not g.current_user.security_password: # abort(400, code=1012, message={'security_password': '******'}) # if not g.current_user.verify_security_password(parsed_args['security_password']): # abort(400, code=1002, message={'security_password': '******'}) time_now = time.strptime(time.strftime('%H:%M'), '%H:%M') if ((time_now < transaction_time_begin[0] or time_now > transaction_time_end[0]) and ((time_now < transaction_time_begin[1] or time_now > transaction_time_end[1]))): abort(400, code=1006, message={'time': 'current time does not allow transaction'}) if g.current_user.allow_transaction == 0: abort(400, code=1006, message={'user': '******'}) order = BuyOrder.query.filter( BuyOrder.user_id == g.current_user.id, BuyOrder.status == g_sell_order_status.UNPROCESSED).first() if order: return order # order = Order.query.filter( # Order.match_user_id == g.current_user.id, # Order.status.op('&')(g_order_status.CONFIRMED | g_order_status.CANCELLED) == 0).all() # if len(order) > 0: # abort(400, code=1006, message={'user': '******'}) ret, reason = BuyOrder.order_create(g.current_user, buy_amount) if not ret: abort(400, code=reason['code'], message=reason['message']) order = reason db.session.add(order) db.session.commit() crl_time = time.time() - start_time logging.info('buy_crl_time:{}'.format(crl_time)) return order
def query_payment_amount(order): if order.match_order is None: option = Setting.get_json('general_option') dollar2rmb = decimal.Decimal(option['dollar2rmb']) dollar = Currency.get_price() * order.amount price = dollar * dollar2rmb else: price = order.match_order.payment_amount return '{}'.format(price)
def post(self): parser = CustomRequestParser() parser.add_argument('mobile', type=str, required=True, nullable=False, location='json') # 收款人的用户手机号 parser.add_argument('amount', type=int, required=True, nullable=False, location='json') parser.add_argument('security_password', type=str, required=True, nullable=False, location='json') parsed_args = parser.parse_args() user = User.query.filter(User.mobile == parsed_args['mobile']).first() if user is None: abort(400, code=1001, message={'mobile': 'user does not exist'}) if parsed_args['amount'] <= 0: abort(400, code=1003, message={'amount': 'amount <= 0'}) if not g.current_user.security_password: abort(400, code=1012, message={'security_password': '******'}) if not g.current_user.verify_security_password(parsed_args['security_password']): abort(400, code=1002, message={'security_password': '******'}) if not g.current_user.is_community_node: abort(400, code=1001, message={'current_user': '******'}) if user.is_community_node: abort(400, code=1001, message={'user': '******'}) option = Setting.get_json('general_option') community_transaction_fee_rate = option['community_transaction_fee_rate'] # exchange_amount_min = option['exchange_amount_min'] # exchange_amount_max = option['exchange_amount_max'] # # if parsed_args['amount'] < exchange_amount_min or parsed_args['amount'] > exchange_amount_max: # abort(400, code=1006, # message={'amount': 'amount < {} or amount > {}'.format(exchange_amount_min, exchange_amount_max)}) fee = decimal.Decimal(parsed_args['amount']) * decimal.Decimal(community_transaction_fee_rate) amount = decimal.Decimal(parsed_args['amount']) + decimal.Decimal(fee) assets = Assets.get_assets(g.current_user.id) detail = { 'message': '{}转给{}, 金额:{}, 手续费:{}'.format( g.current_user.mobile, user.mobile, parsed_args['amount'], fee) } if not assets.update_transaction_balance(-amount, g_assets_record_type.TRANSACTION, detail): abort(400, code=1008, message={'balance': 'current balance < {}'.format(amount)}) assets = Assets.get_assets(user.id) assets.update_total_balance(parsed_args['amount'], g_assets_record_type.TRANSACTION, detail) db.session.commit() return assets
def post(self): parser = CustomRequestParser() parser.add_argument('amount', type=int, required=True, nullable=False, location='json') parser.add_argument('security_password', type=str, required=True, nullable=False, location='json') parsed_args = parser.parse_args() if parsed_args['amount'] <= 0: abort(400, code=1003, message={'amount': 'amount <= 0'}) if not g.current_user.security_password: abort(400, code=1012, message={'security_password': '******'}) if not g.current_user.verify_security_password(parsed_args['security_password']): abort(400, code=1002, message={'security_password': '******'}) option = Setting.get_json('general_option') exchange_amount_min = option['exchange_amount_min'] exchange_amount_max = option['exchange_amount_max'] if parsed_args['amount'] % exchange_amount_min > 0: abort(400, code=1001, message={'amount': 'the amount must be a multiple of {}'.format(exchange_amount_min)}) # 用于计算今天兑换的数量 str_time = datetime.datetime.now().strftime('%Y-%m-%d') sum_amount = db.session.query(db.func.sum(AssetsBalanceRecord.delta_amount)).filter( db.func.date_format(AssetsBalanceRecord.created_at, '%Y-%m-%d') == str_time, AssetsBalanceRecord.user_id == g.current_user.id, AssetsBalanceRecord.record_type == g_assets_record_type.EXCHANGE, AssetsBalanceRecord.assets_type == g_assets_type.COMMUNITY).first()[0] sum_amount = sum_amount if sum_amount is not None else 0 if sum_amount + parsed_args['amount'] > exchange_amount_max: abort(400, code=1006, message={ 'amount': 'already amount {} + current amount {} > {}'.format(sum_amount, parsed_args['amount'], exchange_amount_max)}) assets = Assets.get_assets(g.current_user.id) detail = {'message': '兑换'} if not assets.update_transaction_balance(-parsed_args['amount'], g_assets_record_type.EXCHANGE, detail): abort(400, code=1008, message={'balance': 'current balance < {}'.format(parsed_args['amount'])}) assets.update_community_balance(parsed_args['amount'], g_assets_record_type.EXCHANGE, detail) db.session.commit() return assets
def initialize(): currency = Currency.query.filter( Currency.id == Currency.CURRENCY_ROOT_ID, Currency.usd_price.isnot(None)).first() if currency is None: option = Setting.get_json('general_option') lebo_price = decimal.Decimal(option['lebo_price']) currency = Currency(usd_price=lebo_price) db.session.add(currency) db.session.flush() for i in range(7, 0, -1): record = CurrencyPriceRecord( current_price=lebo_price, delta_price=0, transaction_cnt=0, created_at=datetime.datetime.now() - timedelta(days=i)) db.session.add(record) db.session.flush() db.session.commit()
def update_recommend_reward(self): option = Setting.get_json('general_option') recommend_reward_amount = [ decimal.Decimal(x) for x in option['recommend_reward_amount'] ] evaluation_reward_amount = decimal.Decimal( option['evaluation_reward_amount']) # 先赠送本用户 usd_price = Currency.get_price() if usd_price == 0: abort(400, code=1002, message={'usd_price': 'usd_price is invaild'}) # amount = evaluation_reward_amount / usd_price amount = 1000 assets = Assets.get_assets(self.id) details = {'message': u'完成评测奖励'} assets.update_total_balance(amount, g_assets_record_type.EVALUATION, details) # 再赠送每一代推荐 layer = 0 layer_max = len(recommend_reward_amount) sponsor = self.sponsor while sponsor and layer < layer_max: details = { 'message': '被推荐人:{}, 第几代:{}'.format(self.uid, layer + 1) } if sponsor.state == g_user_state_type.EVALUATION: assets = Assets.get_assets(sponsor.id) assets.update_total_balance(recommend_reward_amount[layer], g_assets_record_type.SPONSOR, details) layer += 1 sponsor = sponsor.sponsor
def confirm_order_process(): order_list = ConfirmOrder.query.filter(ConfirmOrder.status == g_confirm_order_status.UNPROCESSED).all() for order in order_list: change = ConfirmOrder.query.filter( ConfirmOrder.id == order.id, ConfirmOrder.status == g_confirm_order_status.UNPROCESSED).update( dict(status=g_confirm_order_status.PROCESSED)) if not change: continue detail = {'message': '挂单交易'} assets = Assets.get_assets(order.buy_user_id) assets.update_community_today_balance(order.amount, g_assets_record_type.BUY, detail) # 用于计算一个买卖周期 order.buy_user.buy_order_cnt += 1 if order.sell_user.buy_order_cnt > 0: order.sell_user.buy_order_cnt -= 1 option = Setting.get_json('general_option') buy_sell_free_amount = option['buy_sell_free_amount'] buy_sell_rate = decimal.Decimal(option['buy_sell_rate']) fee = order.amount * buy_sell_rate amount = buy_sell_free_amount - fee detail = { 'message': '成功买卖各一单,释放数量:{}, 单数量:{}, 扣除手续费:{}'.format( buy_sell_free_amount, order.amount, fee) } assets = Assets.get_assets(order.sell_user_id) if assets.update_total_balance(-buy_sell_free_amount, g_assets_record_type.BUY_SELL_FREE, detail): assets.update_transaction_balance(amount, g_assets_record_type.BUY_SELL_FREE, detail) sell_user = order.sell_user sell_user.update_today_have_transaction() sell_user.update_transaction_free() currency = Currency.get_currency() currency.update_transaction_cnt() db.session.commit()
def update_transaction_cnt(self): option = Setting.get_json('general_option') lebo_change_price_cnt = option['lebo_change_price_cnt'] lebo_price_step = decimal.Decimal(option['lebo_price_step']) sell_amount = option['sell_amount'] Currency.query.filter(Currency.id == self.id).update( dict(transaction_cnt=Currency.transaction_cnt + 1, today_transaction_amount=Currency.today_transaction_amount + sell_amount)) rows_changed = Currency.query.filter( Currency.id == self.id, Currency.transaction_cnt >= lebo_change_price_cnt).update( dict(usd_price=Currency.usd_price + lebo_price_step, transaction_cnt=0)) if rows_changed: record = CurrencyPriceRecord(current_price=self.usd_price, delta_price=lebo_price_step, transaction_cnt=lebo_change_price_cnt) db.session.add(record) db.session.flush() return True
def check_order_process(): option = Setting.get_json('general_option') change_time = int(option['order_status_change_time']) # 接单后不打款 q = db.session.query(Order).filter(Order.id == MatchOrder.sell_order_id, MatchOrder.created_at < datetime.datetime.now() - datetime.timedelta(hours=change_time), Order.status == g_order_status.MATCH).all() for order in q: match_order = order.match_order if match_order is None: continue rows_changed = Order.query.filter( Order.side == g_order_side.SELL, Order.number == match_order.sell_number, Order.status == g_order_status.MATCH).update(dict(status=g_order_status.CANCELLED)) if not rows_changed: continue detail = {'message': "超时不打款,卖单号:{},买单号:{},买方手机:{}".format(match_order.sell_number, match_order.buy_number, match_order.buy_user.mobile)} rows_changed = Order.query.filter( Order.side == g_order_side.BUY, Order.number == match_order.buy_number, Order.status == g_order_status.MATCH).update(dict(status=g_order_status.CANCELLED)) if rows_changed: assets = Assets.get_assets(order.user_id) assets.update_community_balance(order.amount, g_assets_record_type.SELL, detail) else: order.status = g_order_status.MATCH db.session.commit()
def update_total_balance(self, delta_amount, record_type, details): delta_amount = decimal.Decimal(delta_amount) rows_changed = Assets.query.filter( Assets.id == self.id, Assets.total_balance >= -delta_amount).update( dict(total_balance=Assets.total_balance + delta_amount)) if rows_changed == 1: option = Setting.get_json('general_option') transaction_allow_amount = option['transaction_allow_amount'] if self.total_balance >= transaction_allow_amount: self.user.allow_transaction = 1 self.update_grand_total_balance(delta_amount) record = AssetsBalanceRecord(user_id=self.user_id, current_amount=self.total_balance, delta_amount=delta_amount, assets_type=g_assets_type.TOTAL, record_type=record_type, details=json.dumps(details)) db.session.add(record) db.session.flush() return True return False
def generate_order_process(): option = Setting.get_json('general_option') sell_people = option['sell_people'] buy_people = option['buy_people'] sell_count = option['sell_count'] buy_count = option['buy_count'] str_time = datetime.datetime.now().strftime('%Y-%m-%d') order_list = SellOrder.query.filter(SellOrder.status == g_sell_order_status.UNPROCESSED).all() buy_list = BuyOrder.query.filter(BuyOrder.status == g_buy_order_status.UNPROCESSED).all() order_list.extend(buy_list) order_list = sorted(order_list, key=lambda e: e.created_at) for item in order_list: logging.info('Order side:{}, id:{}'.format(item.side, item.id)) if item.side == g_order_side.SELL: if item.user.transaction_level != g_user_transaction_level.ULTIMATE: order = Order.query.filter(Order.user_id == item.user_id, Order.side == g_order_side.BUY, Order.status == g_order_status.CONFIRMED).first() if not order: # 提示语"该用户从未购买过" error_details = dict(code=1001, message={'user': '******'}) item.details = json.dumps(error_details) item.status = g_sell_order_status.FAILED db.session.commit() continue order_people = db.session.query(Order.user_id).filter( Order.created_at >= str_time, Order.side == g_order_side.SELL, Order.status != g_order_status.CANCELLED).count() order_people = order_people if order_people else 0 if order_people >= sell_people: # 提示语"当日入场单量已满" error_details = dict(code=1003, message={'count': 'count >= {}'.format(sell_people)}) item.details = json.dumps(error_details) item.status = g_sell_order_status.FAILED db.session.commit() continue count = db.session.query(db.func.count(SellOrder.id)).filter( db.func.date_format(SellOrder.created_at, '%Y-%m-%d') == str_time, SellOrder.user_id == item.user_id, SellOrder.status == g_sell_order_status.PROCESSED).first()[0] count = count if count else 0 if count >= sell_count: # 提示语"今天卖出的单数已满" error_details = dict(code=1006, message={'user': '******'.format(sell_count)}) item.details = json.dumps(error_details) item.status = g_sell_order_status.FAILED db.session.commit() continue detail = {'message': '挂单冻结'} assets = Assets.get_assets(item.user_id) if not assets.update_community_balance(-item.amount, g_assets_record_type.SELL, detail): # 提示语"余额不足" if assets.community_today_balance > 0: error_details = dict(code=1007, message={ 'order': 'please tomorrow to sell, today buy balance:{}'.format( assets.community_today_balance)}) else: error_details = dict(code=1008, message={'balance': 'current balance < {}'.format(item.amount)}) item.details = json.dumps(error_details) item.status = g_sell_order_status.FAILED db.session.commit() continue item.status = g_sell_order_status.PROCESSED else: order_people = db.session.query(Order.user_id).filter( Order.created_at >= str_time, Order.side == g_order_side.BUY, Order.status != g_order_status.CANCELLED).count() order_people = order_people if order_people else 0 if order_people >= buy_people: # 提示语"当日入场单量已满" error_details = dict(code=1003, message={'count': 'count >= {}'.format(buy_people)}) item.details = json.dumps(error_details) item.status = g_sell_order_status.FAILED db.session.commit() continue # 用于计算今天买入的单数 count = db.session.query(db.func.count(BuyOrder.id)).filter( db.func.date_format(BuyOrder.created_at, '%Y-%m-%d') == str_time, BuyOrder.user_id == item.user_id, BuyOrder.status == g_buy_order_status.PROCESSED).first()[0] count = count if count else 0 if count >= buy_count: # 提示语"今天买入的单数已满" error_details = dict(code=1006, message={'user': '******'.format(buy_count)}) item.details = json.dumps(error_details) item.status = g_sell_order_status.FAILED db.session.commit() continue item.status = g_buy_order_status.PROCESSED order = Order(created_at=item.created_at, user_id=item.user_id, side=item.side, amount=item.amount, number=item.number) db.session.add(order) db.session.commit()
def match_order_process(): option = Setting.get_json('general_option') # match_order_cnt = option['match_order_cnt'] dollar2rmb = decimal.Decimal(option['dollar2rmb']) task = MatchOrderTask.query.filter(MatchOrderTask.status == g_match_order_task_status.UNPROCESSED).first() if task is None: return change = MatchOrderTask.query.filter(MatchOrderTask.status == g_match_order_task_status.UNPROCESSED).update( dict(status=g_match_order_task_status.PROCESSED)) if not change: return sell_list = Order.query.filter( Order.side == g_order_side.SELL, Order.status == g_order_status.PENDING) sell_list = sell_list.order_by(Order.priority.desc(), Order.created_at.asc()) i = 0 for item in sell_list: if i >= task.order_cnt: break buy_order = Order.query.filter( Order.side == g_order_side.BUY, Order.user_id != item.user_id, Order.status == g_order_status.PENDING).order_by(Order.priority.desc(), Order.created_at.asc()).first() if buy_order is None: continue change = Order.query.filter(Order.id == item.id, Order.status == g_order_status.PENDING).update( dict(status=g_order_status.MATCH)) if not change: continue change = Order.query.filter(Order.id == buy_order.id, Order.status == g_order_status.PENDING).update( dict(status=g_order_status.MATCH)) if not change: item.status = g_order_status.PENDING db.session.commit() continue usd_price = CryptoCurrency.query.filter(CryptoCurrency.currency_code == 'USDT').first().usd_price dollar = Currency.get_price() * item.amount usdt = dollar / usd_price order = MatchOrder(sell_user_id=item.user_id, buy_user_id=buy_order.user_id, sell_order_id=item.id, buy_order_id=buy_order.id, sell_number=item.number, buy_number=buy_order.number, payment_amount=dollar * dollar2rmb, payment_amount_usdt=usdt, current_price=Currency.get_price()) db.session.add(order) db.session.flush() item.match_order_id = order.id buy_order.match_order_id = order.id db.session.commit() try: if order.buy_user.order_mobile: clnt = YunpianClient('fcf725316cbb8ff1438c90ff76c6cebe') param = {YC.MOBILE: '+' + order.buy_user.order_mobile.replace(' ', ''), YC.TEXT: "【乐宝】您的订单{}已匹配成功,请尽快安排处理。".format('')} clnt.sms().single_send(param) except: pass i += 1 db.session.commit()
def settlement_handler(): option = Setting.get_json('general_option') community_node_cnt = option['community_node_cnt'] community_total_balance = option['community_total_balance'] community_transaction_day_cnt = option['community_transaction_day_cnt'] community_sponsor_cnt = option['community_sponsor_cnt'] community_line_cnt = option['community_line_cnt'] community_line_people_cnt = option['community_line_people_cnt'] # 更新连续购买天数 User.update_continuous_buy_cnt() User.query.update(dict(team_qualified_cnt=0)) # TODO 测试是否可以写成一个update Assets.query.filter(Assets.community_today_balance > 0).update( dict(community_balance=Assets.community_balance + Assets.community_today_balance)) Assets.query.update(dict(community_today_balance=0)) # 筛选出合格用户,并更新每个团队合格用户人数 q = User.query.filter( User.continuous_buy_cnt >= community_transaction_day_cnt, User.active == 1).all() for user in q: user.update_team_qualified_cnt() count = db.session.query(db.func.count(User.id)).filter( User.is_community_node == 1, User.active == 1).first()[0] user_q = db.session.query(User).filter( User.id == Assets.user_id, Assets.grand_total_balance >= community_total_balance[0], User.is_community_node == 0).all() for user in user_q: ret = 0 if count < community_node_cnt[0]: ret = DailySettlement.community_check_user( user, community_total_balance[0], community_transaction_day_cnt, community_sponsor_cnt[0], community_line_cnt[0], community_line_people_cnt) elif count < community_node_cnt[1]: ret = DailySettlement.community_check_user( user, community_total_balance[1], community_transaction_day_cnt, community_sponsor_cnt[1], community_line_cnt[1], community_line_people_cnt) elif count < community_node_cnt[2]: ret = DailySettlement.community_check_user( user, community_total_balance[2], community_transaction_day_cnt, community_sponsor_cnt[2], community_line_cnt[2], community_line_people_cnt) else: pass if ret: user.update_is_community_node() count += 1 if not count: return # 计算节点分红 community_dividend_rate = decimal.Decimal( option['community_dividend_rate']) currency = Currency.get_currency() amount = currency.today_transaction_amount * community_dividend_rate / count q = User.query.filter(User.is_community_node == 1, User.active == 1).all() detail = { 'message': '社区节点分红, 当天交易量:{}, 分红比例:{}, 社区节点数量:{}'.format( currency.today_transaction_amount, community_dividend_rate, count) } for user in q: assets = Assets.get_assets(user.id) assets.update_total_balance(amount, g_assets_record_type.DIVIDEND, detail) currency.clear_today_transaction_amount()