def un_follow(cls, user_id: (str, ObjectId)) -> dict: """ 取消跟踪老师 :param user_id: :return: """ mes = {"message": "取消跟踪失败"} user = cls.find_by_id(o_id=user_id, to_dict=True) if isinstance(user, dict): user_id = user['_id'] f = {"_id": user_id} u = {"$set": {"follow": []}} db = mongo_db.get_client() con1 = mongo_db.get_conn(table_name=cls.get_table_name(), db_client=db) con2 = mongo_db.get_conn(table_name=FollowRecord.get_table_name(), db_client=db) w = WriteConcern(w=1, j=True) with db.start_session(causal_consistency=True) as ses: with ses.start_transaction(): r = con1.find_one_and_update( filter=f, upsert=False, update=u, return_document=ReturnDocument.AFTER, session=ses) if r is None or len(r['follow']) > 0: mes['message'] = "保存数据失败" else: f2 = {"user_id": user_id, "end": {"$exists": False}} u2 = {"$set": {"end": datetime.datetime.now()}} r2 = con2.find_one_and_update( filter=f2, upsert=True, update=u2, return_document=ReturnDocument.AFTER, session=ses) if r2 is None or not isinstance( r2.get("end"), datetime.datetime): mes['message'] = "保存record失败" else: mes['message'] = "success" else: ms = "错误的用户id: {}".format(user_id) logger.exception(msg=ms) print(ms) mes['message'] = "用户id错误" return mes
def login(cls, phone: str, password: str) -> dict: """ 登录 :param phone: :param password: :return: """ mes = {"message": "success"} cli = mongo_db.get_client() col = mongo_db.get_conn(table_name=cls.get_table_name(), db_client=cli) with cli.start_session(causal_consistency=True) as session: with session.start_transaction(): f = {"phone": phone} r = col.find_one(filter=f, session=session) if r is None: mes['message'] = "手机号码未注册" else: pw2 = r['password'] if password != pw2: mes['message'] = '密码错误' else: _id = r['_id'] mes['_id'] = _id now = datetime.datetime.now() f = dict() f['_id'] = _id u = {"$set": {"last_login": now}} # 更新最后的登录时间 col.find_one_and_update(filter=f, update=u, session=session) return mes
def register(cls, phone: str, password: str) -> dict: """ 注册 :param phone: :param password: :return: """ mes = {"message": "success"} cli = mongo_db.get_client() col = mongo_db.get_conn(table_name=cls.get_table_name(), db_client=cli) with cli.start_session(causal_consistency=True) as session: with session.start_transaction(): f = {"phone": phone} r = col.find_one(filter=f, session=session) if isinstance(r, dict): mes['message'] = "手机号码重复" else: f['password'] = password nick_name = "用户{}".format(phone[-4:]) f['nick_name'] = nick_name now = datetime.datetime.now() f['create_date'] = now r = col.insert_one(document=f, session=session) if r is None: mes['message'] = "插入失败" else: pass return mes
def follow_count(cls) -> dict: """ 按老师分组统计跟随人数。 :return: """ f = dict() p = ["_id", "name", "head_img"] ts = cls.find(filter_dict=f, projection=p) t_ids = [x['_id'] for x in ts] # t_ids = [ObjectId("5bbd3279c5aee8250bbe17d0")] ses = mongo_db.get_conn(table_name="wx_user") m = {"$match": {"follow": {"$elemMatch": {"$in": t_ids}}}} u = {"$unwind": "$follow"} g = {"$group": {"_id": "$follow", "total": {"$sum": 1}}} pipeline = [m, u, g] # pipeline = [m, u] r = ses.aggregate(pipeline=pipeline) count = {x['_id']: x['total'] for x in r} ts = { x['_id']: { "name": x['name'], "head_img": x.get("head_img", "/static/images/head_image/t1.jpg") } for x in ts } res = dict() for k, v in ts.items(): temp = dict() temp['total'] = count.get(k, 0) temp['name'] = v['name'] temp['head_img'] = v["head_img"] res[k] = temp return res
def add(cls, **kwargs) -> dict: """ 添加角色 :param kwargs: :return: """ mes = {"message": "success"} role_name = kwargs.get("role_name", '') db = orm_module.get_client() conn = orm_module.get_conn(table_name=cls.get_table_name(), db_client=db) write_concern = WriteConcern(w=1, j=True) with db.start_session(causal_consistency=True) as ses: with ses.start_transaction(write_concern=write_concern): r = conn.find_one(filter={'role_name': role_name}) if r is not None: ms = "角色 {} 已存在!".format(role_name) mes['message'] = ms else: """添加""" r = conn.insert_one(kwargs) if r is None: ms = "保存用户账户失败" mes['message'] = ms else: pass return mes
def user_logout(cls, user_id): """用户登出""" ses = mongo_db.get_conn(AppLoginToken.get_table_name()) result = ses.find_one({"user_id": user_id}) """记录事件""" func_name = sys._getframe().f_code.co_name event_desc = "{}注销".format(user_id) event_date = datetime.datetime.now() args = { "event_type": func_name, "event_description": event_desc, "event_date": event_date } if result is not None: args = { "event_type": func_name, "event_description": event_desc, "event_date": event_date, "user_id": result['user_id'] } EventRecord.save(**args) """删除token""" if result is not None: ses.delete_one({"_id": result.get_id()}) mongo_db.cache.delete(result.token) else: raise ValueError("{} 没有对应的登录记录".format(user_id))
def draw_data_dict_from_db_mix2(t_id: (str, ObjectId), begin: datetime.datetime = None, end: datetime.datetime = None) -> dict: """ 不细分产品种类,从数据库trade获取分析师的喊单信号。 :param t_id: :param begin: 开始时间 :param end: 截至时间 :return: """ records = dict() now = datetime.datetime.now() f = { "teacher_id": ObjectId(t_id) if isinstance(t_id, str) else t_id, "each_profit": { "$exists": True, "$ne": None }, "exit_price": { "$exists": True, "$ne": None }, "exit_time": { "$exists": True, "$type": 9 } } if isinstance(begin, datetime.datetime) and isinstance( end, datetime.datetime): if end <= begin: pass else: f['exit_time'] = { "$exists": True, "$type": 9, "$lte": end, "$gte": begin } elif isinstance(begin, datetime.datetime) and end is None: f['exit_time'] = { "$exists": True, "$type": 9, "$lte": now, "$gte": begin } elif isinstance(end, datetime.datetime) and begin is None: f['exit_time'] = {"$exists": True, "$type": 9, "$lte": end} else: pass ses = mongo_db.get_conn("trade") s = [('exit_time', -1)] signals = ses.find(filter=f, sort=s) signals = [x for x in signals] print("共计{}条记录".format(len(signals))) return signals
def hold_overflow(cls, teacher_id: ObjectId) -> bool: """ 检查老师是否持仓过多?超过5个,超过了就不能开单了. :param teacher_id: :return: """ f = {"teacher_id": teacher_id, "case_type": "enter"} col = mongo_db.get_conn(table_name="trade") r = col.count_documents(filter=f) return True if r >= 5 else False
def read_sheet_01(sh) -> list: """ 读取excel文件里的工作簿,这里代码要根据读取的文件不同自行该比那 :param sh: :return: """ res = list() now = datetime.datetime.now() for i, tr in enumerate(sh): if i == 0: pass else: create_time = tr[0].value name = tr[10].value update_time = tr[11].value init = { "op": "data_update", "datetime": create_time, "create_time": create_time, "update_time": update_time, "product": tr[1].value, "the_type": tr[2].value, "direction": tr[3].value, "enter_price": tr[4].value, "exit_price": tr[5].value, "profit": tr[6].value, "each_profit_dollar": tr[7].value, "each_profit": tr[8].value, "each_cost": tr[9].value, "creator_name": name, "updater_name": name, "from": "excel" } if tr[8].value != "徐立杰": res.append(init) f = {"creator_name": {"$ne": "徐立杰"}} s = {'receive_time': 1} insert = list() al = Signal.find_one_plus(filter_dict=f, sort_dict=s, instance=False) if isinstance(al, dict): last = get_datetime_from_str(al['datetime']) for x in res: create_time = x['create_time'] if create_time < last: insert.append(x) else: insert = res print(len(insert)) conn = get_conn("signal_info") for i in insert: f = {"datetime": i.pop("datetime"), "creator_name": i.pop("creator_name")} conn.update_one(filter=f, update={"$set": i}, upsert=True) return res
def rebuild_json(): """从本机数据库创建json文件""" f = {"user_id": {"$exists": True, "$type": 3}, "pr": "gps"} ses = mongo_db.get_conn("gps_info") records = ses.find(filter=f) records = [transform_type(x) for x in records] d_path = os.path.join(__project_dir, "tool_box", "json") if not os.path.exists(d_path): os.makedirs(d_path) f_path = os.path.join(d_path, "all_gps.json") with open(f_path, mode="w", encoding="utf-8") as file: json.dump(records, file)
def docs_from_raw(cls, filter_dict: dict = None, multi: bool = False) -> (dict, list): """ 从RawWebChatMessage的表中,按照条件获取记录,并转换成WebChatMessage的doc, 主要的工作就是把xml字段从str转换为OrderedDict :param filter_dict: :param multi: 返回一个还是多个文档? :return: """ f = dict() if filter_dict is None else filter_dict ses = mongo_db.get_conn(table_name="raw_webchat_message") res = ses.find(filter=f, limit=(0 if multi else 1)) result = list() for one in res: xml_str = one.get("xml", "") if xml_str == "": pass else: error = None try: xml = xmltodict.parse(xml_input=xml_str, encoding="utf-8") except ExpatError as e: logger.exception(e) print(e) try: xml = json.loads(xml_str) except Exception as e2: logger.exception(e2) print(e2) error = e2 finally: pass finally: if error is None: print(xml) data = xml.get('xml') if data is None: pass else: if 'CreateTime' in data: create_time = datetime.datetime.fromtimestamp( float(data['CreateTime'])) data['create_time'] = create_time else: pass xml = data one['xml'] = xml else: pass result.append(one) return result
def log(cls, t_id: ObjectId, url: str, error_time: datetime.datetime, error: str, content: str) -> None: """记录""" d = dict() d['_id'] = ObjectId() d['t_id'] = t_id d['error'] = error d['url'] = url d['args'] = content d['error_time'] = error_time d['save_time'] = datetime.datetime.now() ses = mongo_db.get_conn(table_name=cls.get_table_name()) ses.insert_one(d)
def add_user(cls, **kwargs) -> dict: """ 添加用户 :param kwargs: :return: """ mes = {"message": "success"} user_name = kwargs.get("user_name", '') pwd = kwargs.get("password", '') args = {"user_name": user_name, "password": pwd} db = orm_module.get_client() conn = orm_module.get_conn(table_name=cls.get_table_name(), db_client=db) write_concern = WriteConcern(w=1, j=True) with db.start_session(causal_consistency=True) as ses: with ses.start_transaction(write_concern=write_concern): r = conn.find_one(filter={'user_name': user_name}) if r is not None: ms = "账户 {} 已存在!".format(user_name) mes['message'] = ms else: """提取其他信息""" role_id_str = kwargs.get("role_id", '') if isinstance(role_id_str, str) and len(role_id_str) == 24: role_id = ObjectId(role_id_str) elif isinstance(role_id_str, ObjectId): role_id = role_id_str else: role_id = None args['role_id'] = role_id args['dept_id'] = None now = datetime.datetime.now() # 创建时间 args['time'] = now args['last'] = now args['status'] = 1 nick_name = kwargs.get("nick_name", "") if isinstance(nick_name, str) and len(nick_name) > 0: args['nick_name'] = nick_name else: nick_name = "guest_{}".format( str(random.randint(1, 99)).zfill(2)) args['nick_name'] = nick_name r = conn.insert_one(args) if r is None: ms = "保存用户账户失败" mes['message'] = ms else: pass return mes
def repair_gps(): """修整gps数据""" obj_list = GPS.find() ses = get_conn(GPS.get_table_name()) for obj in obj_list: geo = obj.__dict__.get("geo") if geo is not None: oid = obj.get_id() geo = obj.geo loc = GeoJSON("Point", geo) obj.__dict__.pop("geo") obj.__dict__['loc'] = loc doc = obj.to_flat_dict() doc.pop("_id") ses.find_one_and_replace(filter={"_id": oid}, replacement=doc)
def delete(cls, user_id): """ 删除一个token。注意,此方法并不清空cache里token :param user_id: 用户id。 :return: int 一个删除的计数器 """ if isinstance(user_id, ObjectId): pass else: try: user_id = ObjectId(user_id) except Exception as e: print(e) raise ValueError("{} 不能被转换为ObjectId".format(user_id)) ses = mongo_db.get_conn(cls._table_name) result = ses.delete_many({"user_id": user_id}) return result.deleted_count
def get_uploaded(cls) -> dict: """ 获取已上传的数据 :return: """ ses = mongo_db.get_conn(cls.get_table_name()) system_names = ses.distinct("system") filter_dict = {"upload": 1} if len(system_names) == 0: return dict() else: data = dict(zip(system_names, [[]] * len(system_names))) records = cls.find_plus(filter_dict=filter_dict, projection=['system', 'ticket'], to_dict=True) for x in records: temp = data[x['system']] temp.append(x['ticket']) return data
def trade_history(cls, t_id: ObjectId, filter_dict: dict, page_size: int = 50, can_json: bool = False) -> list: """ 分页查询喊单历史(已离场的) :param t_id: 老师id :param filter_dict: 查询条件字典, :param page_size: 一页有多少条记录? :param can_json: :return: """ filter_dict["teacher_id"] = t_id filter_dict["case_type"] = "exit" sort_list = [("exit_time", -1)] projection = [ '_id', 'exit_time', 'product', 'direction', 'enter_price', 'exit_price', 'lots', 'each_profit' ] ses = mongo_db.get_conn(table_name="trade") args = { "filter": filter_dict, "sort": sort_list, # 可能是None,但是没问题. "projection": projection, "limit": page_size } args = {k: v for k, v in args.items() if v is not None} """开始查询页面""" res = list() r = ses.find(**args) if r is None: pass else: if r.count() > 0: if can_json: res = [mongo_db.to_flat_dict(x) for x in r] else: res = [x for x in r] else: pass return res
def change_pw(cls, u_id: ObjectId, pwd_old: str, pw_n1: str, pw_n2: str) -> dict: """ 修改密码 :param u_id: :param pwd_old: :param pw_n1: :param pw_n2: :return: """ mes = {"message": 'unknow error!'} db_client = orm_module.get_client() w = orm_module.get_write_concern() col = orm_module.get_conn(table_name=cls.get_table_name(), db_client=db_client, write_concern=w) with db_client.start_session(causal_consistency=True) as ses: with ses.start_transaction(write_concern=w): f = {"_id": u_id} p = ["_id", "password"] r = col.find_one(filter=f, projection=p) if r is None: mes['message'] = "错误的用户id:{}".format(u_id) else: if r.get("password", "").lower() == pwd_old.lower(): if pw_n1 == pw_n2: pw = pw_n1.lower() u = {"$set": {"password": pw}} r = col.find_one_and_update( filter=f, update=u, return_document=orm_module.ReturnDocument.AFTER ) if r['password'] == pw: mes['message'] = "success" else: mes['message'] = "保存失败" else: mes['message'] = "原始密码错误" return mes
def history_and_hold(cls, t_id: (str, ObjectId), prev: int = 60) -> dict: """ 获取老师最近的60天持仓和交易历史 :param t_id: :param prev: :return: """ now = datetime.datetime.now() prev = now - datetime.timedelta(days=prev) t_id = ObjectId(t_id) if isinstance(t_id, str) and len(t_id) == 24 else t_id f = {"teacher_id": t_id, "enter_time": {"$gte": prev}} s = [("enter_time", -1)] ses = mongo_db.get_conn(table_name="trade") r = ses.find(filter=f, sort=s) history = list() hold = list() [ hold.append(x) if x['case_type'] == "enter" else history.append(x) for x in r ] return {"hold": hold, "history": history}
def get_allotted(cls, the_time: datetime.datetime, the_groups: list) -> dict: """ 获取已分配用户的分布情况,。 返回一个由group,用户计数组成的字典组成的数据, :param the_time: :param the_groups: :return: { group1: count1, group2: count2, group3: count3, .... } """ """ 聚合查询示范 ses = mongo_db.get_conn(Customer.get_table_name()) the_groups = [ '页面标题:MT4交易管家' ] the_time = datetime.datetime.now() pipeline = [ {"$match": {"description": {"$in": the_groups}, "time": {"$lte": the_time}}}, # 匹配 {"$group": {"_id": "$description", "count": {"$sum": 1}}} # 分组统计 ] res = ses.aggregate(pipeline=pipeline) res = [{"group": x['_id'], "count": x['count']} for x in res] """ ses = mongo_db.get_conn(Customer.get_table_name()) pipeline = [ {"$match": {"group_by": {"$in": the_groups}, "time": {"$gte": the_time}}}, # 匹配 {"$group": {"_id": "$group_by", "count": {"$sum": 1}}} # 分组统计 ] res = ses.aggregate(pipeline=pipeline) res = {x['_id']: x['count'] for x in res} return res
def hold_info_from_db(t_id: (str, ObjectId) = None, begin: datetime.datetime = None, end: datetime.datetime = None, h_id: (str, ObjectId) = None) -> list: """ 从数据库获取分析师的持仓。,替代draw_hold_list_from_db函数. 如果h_id是None,返回全部数据的list对象,否则返回对应的记录的list(单个元素的list) :param t_id: 老师id :param begin: 开始时间 :param end: 截至时间 :param h_id: 持仓Trade的_id :return: """ table_name = "trade" records = list() now = datetime.datetime.now() if isinstance(t_id, ObjectId) or (isinstance(t_id, str) and len(t_id) == 24): f = { "teacher_id": ObjectId(t_id) if isinstance(t_id, str) else t_id, "exit_price": { "$exists": False } } else: f = {"exit_price": {"$exists": False}} if isinstance(begin, datetime.datetime) and isinstance( end, datetime.datetime): if end <= begin: pass else: f['enter_time'] = { "$exists": True, "$type": 9, "$lte": end, "$gte": begin } elif isinstance(begin, datetime.datetime) and end is None: f['enter_time'] = { "$exists": True, "$type": 9, "$lte": now, "$gte": begin } elif isinstance(end, datetime.datetime) and begin is None: f['enter_time'] = {"$exists": True, "$type": 9, "$lte": end} else: pass if isinstance(h_id, str) and len(h_id) == 24: f['_id'] = ObjectId(h_id) ses = mongo_db.get_conn(table_name=table_name) if table_name == "signal_info": s = [("create_time", -1)] else: s = [("enter_time", -1)] signals = ses.find(filter=f, sort=s) if signals.count() > 0: signals = [x for x in signals if x.get("product") in p_list] for signal in signals: teacher = signal.get('teacher_id') product = signal['product'] code = signal.get("code", "") lots = signal.get("lots", 1) each_profit = signal['each_profit'] enter_time = signal['enter_time'] win = 1 if each_profit >= 0 else 0 temp = dict() temp['_id'] = signal['_id'] temp['teacher'] = teacher temp['product'] = product temp['lots'] = lots temp['code'] = code temp['direction'] = signal['direction'] temp['each_profit'] = each_profit # 每手实际盈利 temp['enter_time'] = enter_time temp['enter_time_str'] = enter_time.strftime("%F") # 进场日 temp['hold_hour'] = round( (now - enter_time).total_seconds() / 3600, 0) # 持仓时间 temp['enter_price'] = signal['enter_price'] temp['timestamp'] = enter_time.timestamp() # 出场日的timestamp对象,用于排序 week_list = enter_time.isocalendar() temp['week'] = "{}年{}周".format(week_list[0], week_list[1]) temp['win'] = win records.append(temp) else: pass print("共计{}条记录".format(len(records))) return records
def follow(cls, user_id: (str, ObjectId), t_id: (str, ObjectId)) -> dict: """ 用户跟单行为。 1. 如果用户积分不足,那就不能跟单 2. 如果用户已经跟随了一位老师,那就换人。同时扣分 :param user_id: :param t_id: 老师id :return: """ """计算是否需要扣除跟单积分""" user = cls.find_by_id(o_id=user_id, to_dict=True) if isinstance(user, dict): user_id = user['_id'] score = user.get("score", None) if score is None: score = Score.re_calculate(u_dict=user) f_id = ObjectId(t_id) if isinstance( t_id, str) and len(t_id) == 24 else t_id now = datetime.datetime.now() res = {"message": "关注失败"} """ 跟单扣分制度: 参考上一周的老师胜率排行榜 第一 -500, 第二 -300, 第三-200, 第四第五-100, >6 -50 """ num_dict = {0: -500, 1: -300, 2: -200, 3: -100, 4: -100} ses = mongo_db.get_conn(table_name="teacher") f = dict() s = [("win_ratio", -1)] p = ['_id', "win_ratio"] rank = ses.find(filter=f, sort=s, projection=p) rank = { x['_id']: { "index": i + 1, "num": num_dict.get(i, -50) } for i, x in enumerate(rank) } x = rank[f_id] num = x['num'] i = x['index'] if score >= abs(num): score += num temp = { "type": "follow", "num": num, "user_id": user_id, "desc": "跟随老师 {}, 排名: {}".format(t_id, i), "time": now } """事务,开始添加扣分记录和更新用户积分""" client = mongo_db.get_client() t1 = client[mongo_db.db_name][Score.get_table_name()] t2 = client[mongo_db.db_name][WXUser.get_table_name()] t3 = client[mongo_db.db_name][FollowRecord.get_table_name()] with client.start_session(causal_consistency=True) as ses: with ses.start_transaction(): t1.insert_one(document=temp, session=ses) f = {"_id": user_id} u = {"$set": {"score": score, "follow": [f_id]}} t2.find_one_and_update(filter=f, update=u, upsert=False, session=ses) """ 检查用户以前是否有跟踪老师? 检查的方式是:检查用户的follow记录。如果有,更新再新建。没有,新建。 """ follow = user.get("follow", dict()) if len(follow) == 0: """没有跟随过老师""" pass else: """有跟随过老师,需要先终结以前的跟随关系。""" f2 = {"user_id": user_id, "t_id": f_id} u2 = {"$set": {"end": now}} t3.find_one_and_update(filter=f2, update=u2, upsert=False, session=ses) """添加一条跟随老师的记录""" temp = { "_id": ObjectId(), "user_id": user_id, "t_id": f_id, "begin": now } t3.insert_one(document=temp, session=ses) res['message'] = "success" else: res['message'] = "积分不足" return res else: ms = "错误的user_id: {}".format(user_id) logger.exception(msg=ms) raise ValueError(ms)
async def new_order_message2(t_id: str, t_name: str, product: str, order_type: str, enter_time: str, enter_price: (str, float, int), exit_time: str = None, exit_price: (str, float, int) = None) -> bool: """ 新订单模板消息,使用批量发送. 2018-10-18启用 待发送的模板消息字典 格式: 2018-10-18之前: {'t_id': '5b8c5452dbea62189b5c28f9', 'order_type': '开仓'} 2018-10-18之后: { 'product': '原油', 'order_type': '开仓', 'enter_time': datetime.datetime(2018, 10, 18, 3, 53, 11, 670692), 'exit_time': datetime.datetime(2018, 10, 18, 3, 53, 11, 670692), # 只有平仓才有 't_id': 5b8c5452dbea62189b5c28f9, 't_name': 非功, 'enter_price': 69.955, 'exit_price': 69.955, # 只有平仓才有 } :param t_id: :param t_name: :param product: :param order_type: :param enter_time: :param enter_price: :param exit_time: :param exit_price: :return: """ ms = "new_order_message2正在处理发送请求:t_name={}, t_id={}".format(t_name, t_id) logger.info(ms) # send_mail(title="func begin...", content='{}'.format(datetime.datetime.now())) ses = mongo_db.get_conn("teacher") t_id = ObjectId(t_id) if isinstance(t_id, str) else t_id f = {"_id": t_id} p = {"_id", "name"} t = ses.find_one(filter=f, projection=p) if t is None: ms = "发送模板消息出错,无效的t_id:{}".format(t_id) logger.exception(msg=ms) send_mail(title=ms) return False else: t_id = t['_id'] t_name = t['name'] f = {"follow": {"$elemMatch": {"$in": [t_id]}}} p = ['_id', "openid", "nick_name"] now = datetime.datetime.now() ses = mongo_db.get_conn(table_name="wx_user") us = ses.find(filter=f, projection=p) us = [x for x in us] us_l = len(us) # send_mail(title="if begin ...", content='us_l={}, {}'.format(us_l, datetime.datetime.now())) ms = "准备发送{}条模板消息,查询条件={}".format(us_l, f) # send_mail(title=ms) logger.info(msg=ms) if us_l > 0: u = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={}".format( AccessToken.get_token()) info = {"t_id": t_id, "t_name": t_name, "time": now} # send_mail(title="async begin ...", content='{}'.format(datetime.datetime.now())) async with aiohttp.ClientSession() as session: for x in us: openid = x['openid'] nick_name = x['nick_name'] info['openid'] = openid info['nick_name'] = nick_name # send_mail(title="for begin ...", content='{}'.format(datetime.datetime.now())) template_id = 'i6NuPzoeW1HqSNSf97KwDn3AVQk1_jmUHKoHtlCxA7k' args = { "touser": openid, "template_id": template_id, "url": "http://wx.91master.cn/user/html/currentCrunchy.html?t_id={}" .format( str(t_id) if isinstance(t_id, ObjectId) else t_id), "data": { "first": { "value": "你关注的{}老师有新的操作..".format(t_name), "color": "grey", }, "keyword1": { "value": product, # 交易品种 "color": "#82B6F4" }, "keyword2": { "value": enter_time, # 开仓时间 "color": "#82B6F4" }, "keyword3": { "value": "建仓" if order_type == "开仓" else order_type, "color": "#82B6F4", }, "keyword4": { "value": enter_price, # 开仓价格 "color": "#82B6F4" }, "keyword5": { "value": exit_price, # 平仓价格 "color": "#82B6F4" }, "remark": { "value": "此信息代表{}老师个人观点,仅供参考.点击“详情”查看完整信息".format( t_name), "color": "#dc1c1c" } } } title = "发送给{}的模板消息".format(nick_name) content = "模板消息内容 data={}".format(args) ms = "{} | {}".format(title, content) logger.info(ms) # send_mail(title=title, content=content) async with session.post(url=u, data=json.dumps(args), timeout=5) as response: resp = await response.json() if isinstance(resp, dict): info['return'] = "success" info.update(resp) else: info['return'] = "error" info['_id'] = ObjectId() info['args'] = args info['time'] = now ses = TemplateMessageResponse.get_collection() ses.insert_one(document=info) return True else: return False
def insert_error_code(**kwargs): """插入错误代码""" ses = get_conn("error_code_info") inserted_id = ses.insert_one(kwargs).inserted_id return inserted_id
def draw_data_list_from_db(t_id: (str, ObjectId) = None, begin: datetime.datetime = None, end: datetime.datetime = None) -> list: """ 从数据库获取分析师的(已经close)喊单信号。返回数据的list对象 :param t_id: 老师id :param begin: 开始时间 :param end: 截至时间 :return: """ table_name = "trade" # table_name = "signal_info" records = list() now = datetime.datetime.now() if isinstance(t_id, ObjectId) or (isinstance(t_id, str) and len(t_id) == 24): if table_name == "signal_info": f = { "creator_id": str(t_id) if isinstance(t_id, ObjectId) else t_id, "each_profit": { "$exists": True, "$ne": None }, "exit_price": { "$exists": True, "$ne": None }, "update_time": { "$exists": True, "$type": 9 } } else: f = { "teacher_id": ObjectId(t_id) if isinstance(t_id, str) else t_id, "each_profit": { "$exists": True, "$ne": None }, "exit_price": { "$exists": True, "$ne": None }, "exit_time": { "$exists": True, "$type": 9 } } else: if table_name == "signal_info": f = { "each_profit": { "$exists": True, "$ne": None }, "exit_price": { "$exists": True, "$ne": None }, "update_time": { "$exists": True, "$type": 9 } } else: f = { "each_profit": { "$exists": True, "$ne": None }, "exit_price": { "$exists": True, "$ne": None }, "exit_time": { "$exists": True, "$type": 9 } } if isinstance(begin, datetime.datetime) and isinstance( end, datetime.datetime): if end <= begin: pass else: if table_name == "signal_info": f['datetime'] = { "$exists": True, "$type": 9, "$lte": end, "$gte": begin } else: f['enter_time'] = { "$exists": True, "$type": 9, "$lte": end, "$gte": begin } elif isinstance(begin, datetime.datetime) and end is None: if table_name == "signal_info": f['datetime'] = { "$exists": True, "$type": 9, "$lte": now, "$gte": begin } else: f['enter_time'] = { "$exists": True, "$type": 9, "$lte": now, "$gte": begin } elif isinstance(end, datetime.datetime) and begin is None: if table_name == "signal_info": f['datetime'] = {"$exists": True, "$type": 9, "$lte": end} else: f['enter_time'] = {"$exists": True, "$type": 9, "$lte": end} else: pass ses = mongo_db.get_conn(table_name=table_name) if table_name == "signal_info": s = [("update_time", -1)] else: s = [("exit_time", -1)] signals = ses.find(filter=f, sort=s) if signals.count() > 0: signals = [x for x in signals if x.get("product") in p_list] for signal in signals: if table_name == "signal_info": teacher = signal.get('creator_id') else: teacher = signal.get('teacher_id') product = signal['product'] each_profit = signal['each_profit'] if table_name == "signal_info": enter_time = signal['datetime'] else: enter_time = signal['enter_time'] if table_name == "signal_info": exit_time = signal['update_time'] else: exit_time = signal['exit_time'] win = 1 if each_profit >= 0 else 0 temp = dict() temp['teacher'] = teacher temp['product'] = product temp['direction'] = signal['direction'] temp['enter_price'] = signal['enter_price'] temp['exit_price'] = signal['exit_price'] temp['each_profit'] = round(each_profit, 1) # 每手实际盈利 temp['enter_time'] = enter_time.strftime("%F") # 进场日 temp['exit_time'] = exit_time.strftime("%F") # 出场日 temp['timestamp'] = exit_time.timestamp() # 出场日的timestamp对象,用于排序 week_list = exit_time.isocalendar() temp['week'] = "{}年{}周".format(week_list[0], week_list[1]) temp['win'] = win records.append(temp) else: pass print("共计{}条记录".format(len(records))) return records
def draw_data_list_from_db(begin: datetime.datetime = None, end: datetime.datetime = None) -> list: """ 从数据库获取分析师的喊单信号。返回数据的list对象 :param begin: 开始时间 :param end: 截至时间 :return: """ records = list() now = datetime.datetime.now() f = { "each_profit": { "$exists": True, "$ne": None }, "exit_price": { "$exists": True, "$ne": None }, "update_time": { "$exists": True, "$type": 9 } } if isinstance(begin, datetime.datetime) and isinstance( end, datetime.datetime): if end <= begin: pass else: f['datetime'] = { "$exists": True, "$type": 9, "$lte": end, "$gte": begin } elif isinstance(begin, datetime.datetime) and end is None: f['datetime'] = { "$exists": True, "$type": 9, "$lte": now, "$gte": begin } elif isinstance(end, datetime.datetime) and begin is None: f['datetime'] = {"$exists": True, "$type": 9, "$lte": end} else: pass ses = mongo_db.get_conn("signal_info") signals = ses.find(filter=f) if signals.count() > 0: signals = [x for x in signals if x.get("product") in p_list] for signal in signals: teacher = signal['creator_name'] product = signal['product'] each_profit = signal['each_profit'] enter_time = signal['datetime'] exit_time = signal['update_time'] win = 1 if each_profit >= 0 else 0 temp = dict() temp['teacher'] = teacher temp['product'] = product temp['each_profit'] = each_profit # 每手实际盈利 temp['enter_date'] = enter_time.strftime("%F") # 进场日 temp['exit_date'] = exit_time.strftime("%F") # 出场日 week_list = exit_time.isocalendar() temp['week'] = "{}年{}周".format(week_list[0], week_list[1]) temp['win'] = win records.append(temp) else: pass print("共计{}条记录".format(len(records))) return records
def draw_data_dict_from_db(begin: datetime.datetime = None, end: datetime.datetime = None) -> dict: """ 从数据库获取分析师的喊单信号。以老师名为一级key,产品名为二级key打包成dict并返回 :param begin: 开始时间 :param end: 截至时间 :return: """ records = dict() now = datetime.datetime.now() f = { "each_profit": { "$exists": True, "$ne": None }, "exit_price": { "$exists": True, "$ne": None }, "update_time": { "$exists": True, "$type": 9 } } if isinstance(begin, datetime.datetime) and isinstance( end, datetime.datetime): if end <= begin: pass else: f['datetime'] = { "$exists": True, "$type": 9, "$lte": end, "$gte": begin } elif isinstance(begin, datetime.datetime) and end is None: f['datetime'] = { "$exists": True, "$type": 9, "$lte": now, "$gte": begin } elif isinstance(end, datetime.datetime) and begin is None: f['datetime'] = {"$exists": True, "$type": 9, "$lte": end} else: pass ses = mongo_db.get_conn("signal_info") signals = ses.find(filter=f) count = 0 if signals.count() > 0: signals = [x for x in signals if x.get("product") in p_list] for signal in signals: teacher = signal['creator_name'] product = signal['product'] t_value = records.get(teacher) t_value = dict() if t_value is None else t_value p_value = t_value.get(product) p_value = list() if p_value is None else p_value p_value.append(signal) t_value[product] = p_value records[teacher] = t_value count += 1 print("共计{}条记录".format(count)) return records
def win_and_bar(t_id: (str, ObjectId) = None) -> list: """ 查询老师的,状图表数据并统计获胜场次. 2018-9-17 分组标志: 月份+老师id 排序 老师Id正序, 月份正序 :param t_id: :return: db.trade.aggregate([ {"$match":{"change": "raw", "enter_time":{$exists:true, $ne:null, "$gte":ISODate("2018-08-31T23:00:00.000Z")},"each_profit":{$exists: true}}}, { "$project": { "teacher_id": "$teacher_id", "teacher_name": "$teacher_name", "enter_time": "$enter_time", "str":{$dateToString: {date:"$enter_time", format:"%G-%m-%d %H:%M:%S"}}, "win":{$gte:["$each_profit", 0]} }, }, {$addFields:{"case":1, "w":{$cond:{if:{"$eq":["$win", true]},then:1,else:0}}}}, {"$sort":{"enter_time":1}}, {"$match": {"w": 0}} ]) """ t_id = t_id if isinstance(t_id, ObjectId) or t_id is None else ObjectId(t_id) if isinstance(t_id, ObjectId): match_dict = { "exit_time": { "$exists": True, "$ne": None }, "teacher_id": t_id, "case_type": "exit" } else: match_dict = { "exit_time": { "$exists": True, "$ne": None }, "case_type": "exit" } pipeline = [{ "$match": match_dict }, { "$project": { "teacher_id": "$teacher_id", "exit_time": "$exit_time", "ym": { "$dateFromParts": { "year": { "$year": "$exit_time" }, "month": { "$month": "$exit_time" }, "day": 1 } }, "win": { '$gte': ["$each_profit", 0] } } }, { "$group": { "_id": { "t_id": "$teacher_id", "date": "$ym" }, "count": { "$sum": 1 }, "win": { "$sum": { "$cond": { "if": "$win", "then": 1, "else": 0 } } } } }, { "$sort": { "_id.t_id": 1, "_id.date": 1 } }] ses = mongo_db.get_conn(table_name="trade") res = ses.aggregate(pipeline=pipeline) data = [x for x in res] return data
def draw_data_dict_from_db_mix(begin: datetime.datetime = None, end: datetime.datetime = None) -> dict: """ 不细分产品种类,从数据库获取分析师的喊单信号。以老师名为一级key,产品名为二级key打包成dict并返回 :param begin: 开始时间 :param end: 截至时间 :return: """ records = dict() now = datetime.datetime.now() f = { "each_profit": { "$exists": True, "$ne": None }, "exit_price": { "$exists": True, "$ne": None }, "update_time": { "$exists": True, "$type": 9 } } if isinstance(begin, datetime.datetime) and isinstance( end, datetime.datetime): if end <= begin: pass else: f['datetime'] = { "$exists": True, "$type": 9, "$lte": end, "$gte": begin } elif isinstance(begin, datetime.datetime) and end is None: f['datetime'] = { "$exists": True, "$type": 9, "$lte": now, "$gte": begin } elif isinstance(end, datetime.datetime) and begin is None: f['datetime'] = {"$exists": True, "$type": 9, "$lte": end} else: pass ses = mongo_db.get_conn("signal_info") signals = ses.find(filter=f) count = 0 if signals.count() > 0: for x in signals: if x.get("product") in p_list: count += 1 teacher = ObjectId(x['creator_id']) if isinstance( x['creator_id'], str) else x['creator_id'] t_value = records.get(teacher) t_value = list() if t_value is None else t_value t_value.append(x) records[teacher] = t_value else: pass print("共计{}条记录".format(count)) return records
def new_order_message1(t_id: str, t_name: str, product: str, order_type: str, enter_time: str, enter_price: (str, float, int), direction: str, exit_time: str = None, exit_price: (str, float, int) = None) -> bool: """ 新订单模板消息,使用批量发送. 2018-10-25启用,同步函数 待发送的模板消息字典 格式: 2018-10-18之前: {'t_id': '5b8c5452dbea62189b5c28f9', 'order_type': '开仓'} 2018-10-18之后: { 'product': '原油', 'order_type': '开仓', 'enter_time': datetime.datetime(2018, 10, 18, 3, 53, 11, 670692), 'exit_time': datetime.datetime(2018, 10, 18, 3, 53, 11, 670692), # 只有平仓才有 't_id': 5b8c5452dbea62189b5c28f9, 't_name': 非功, 'enter_price': 69.955, 'exit_price': 69.955, # 只有平仓才有 } :param t_id: :param t_name: :param product: :param order_type: :param enter_time: :param enter_price: :param exit_time: :param exit_price: :return: """ ms = "new_order_message1正在处理发送请求:t_name={}, t_id={}".format(t_name, t_id) logger.info(ms) # send_mail(title="func begin...", content='{}'.format(datetime.datetime.now())) ses = mongo_db.get_conn("teacher") t_id = ObjectId(t_id) if isinstance(t_id, str) else t_id f = {"_id": t_id} p = {"_id", "name"} t = ses.find_one(filter=f, projection=p) if t is None: ms = "发送模板消息出错,无效的t_id:{}".format(t_id) logger.exception(msg=ms) send_mail(title=ms) return False else: t_id = t['_id'] t_name = t['name'] f = {"follow": {"$elemMatch": {"$in": [t_id]}}} p = ['_id', "openid", "nick_name"] now = datetime.datetime.now() ses = mongo_db.get_conn(table_name="wx_user") us = ses.find(filter=f, projection=p) us = [x for x in us] us_l = len(us) # send_mail(title="if begin ...", content='us_l={}, {}'.format(us_l, datetime.datetime.now())) ms = "准备发送{}条模板消息,查询条件={}".format(us_l, f) # send_mail(title=ms) logger.info(msg=ms) if us_l > 0: u = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={}".format( AccessToken.get_token()) info = {"t_id": t_id, "t_name": t_name, "time": now} doc_list = [] # 发送成功的结果集.需要记录到数据库 with requests.Session() as ses: for x in us: openid = x['openid'] nick_name = x['nick_name'] info['openid'] = openid info['nick_name'] = nick_name # send_mail(title="for begin ...", content='{}'.format(datetime.datetime.now())) template_id = 'bc6Z0AhnPbisIxK6ZuPtuLR9L0aNNu01uNg_fKHfy8I' args = { "touser": openid, "template_id": template_id, "url": "http://wx.91master.cn/user/html/currentCrunchy.html?t_id={}" .format( str(t_id) if isinstance(t_id, ObjectId) else t_id), "data": { "first": { "value": "你关注的{}老师有新的操作.".format(t_name), "color": "grey", }, "keyword1": { "value": "建仓" if order_type == "开仓" else order_type, # 订单类型 "color": "#82B6F4", }, "keyword2": { "value": direction, # 交易方向 "color": "#82B6F4" }, "keyword3": { "value": '', # 交易手数 "color": "#82B6F4" }, "keyword4": { "value": product, # 交易品种 "color": "#82B6F4" }, "keyword5": { "value": enter_price if order_type == "开仓" else exit_price, # 开仓/平仓价格 "color": "#82B6F4" }, "remark": { "value": "此信息代表{}老师个人观点,仅供参考.不作为入市依据.点击“详情”查看完整信息". format(t_name), "color": "#dc1c1c" } } } title = "发送给{}的模板消息".format(nick_name) content = "模板消息内容 data={}".format(args) ms = "{} | {}".format(title, content) logger.info(ms) response = ses.post(url=u, data=json.dumps(args), timeout=5) status = response.status_code if status == 200: resp = response.json() if isinstance(resp, dict): info['return'] = "success" info.update(resp) else: info['return'] = "error" info['_id'] = ObjectId() info['args'] = args info['time'] = now doc_list.append(info) else: title = "调用微信模板消息接口出错,{}".format(now) content = "微信模板接口返回了错误的代码:{}".format(status) send_mail(title=title, content=content) """检查结果集""" if len(doc_list) > 0: col = TemplateMessageResponse.get_collection() col.insert_many(documents=doc_list) else: pass return True else: return False