Commit 26116e1a authored by 李宗熹's avatar 李宗熹

Merge remote-tracking branch 'origin/manage-public' into manage-public

parents ac8b9983 03fa8113
......@@ -83,12 +83,12 @@ class UserCustomerDataAdaptor:
tamp_diagnose_app_session = tamp_diagnose_app.session
tamp_product_session = tamp_product.session
tamp_fund_session = tamp_fund.session
sql_user = """select f1.fund_id, f2.realname,f3.customer_name,f3.valueSex,f1.type,f1.order_type,f1.pay_date,f1.subscription_fee,f1.confirm_share_date,f1.confirm_share,f1.confirm_amount,f1.nav,f1.folio_name from tamp_diagnose_app.customer_order_view f1, tamp_user.user_info f2,tamp_diagnose_app.customer_view f3 where f2.id=f1.user_id and f3.id=f1.customer_id and f1.delete_tag=0 and user_id='{}' and customer_id='{}'""".format(self.user_id, self.customer_id)
sql_user = """select f1.fund_id, f2.realname,f3.customer_name,f3.valueSex,f1.type,f1.order_type,f1.pay_date,f1.subscription_fee,f1.confirm_share_date,f1.confirm_share,f1.confirm_amount,f1.nav,f1.folio_name, f1.comefrom from tamp_diagnose_app.customer_order_view f1, tamp_user.user_info f2,tamp_diagnose_app.customer_view f3 where f2.id=f1.user_id and f3.id=f1.customer_id and f1.delete_tag=0 and user_id='{}' and customer_id='{}'""".format(self.user_id, self.customer_id)
cur = tamp_diagnose_app_session.execute(sql_user)
data = cur.fetchall()
order_df = pd.DataFrame(list(data), columns=['fund_id', 'username', 'customer_name', 'valueSex', 'type', 'order_type', 'pay_date',
'subscription_fee', 'confirm_share_date', 'confirm_share',
'confirm_amount', 'nav', 'folio_name'])
'confirm_amount', 'nav', 'folio_name', 'comefrom'])
cur_fund_id = list(order_df["fund_id"].unique())
fund_list_str = str(cur_fund_id).replace("[", "(").replace("]", ")")
......@@ -121,6 +121,21 @@ class UserCustomerDataAdaptor:
product_df = product_df.append(fund_df_3)
product_df = product_df.drop_duplicates("fund_id")
fund_type0 = order_df[order_df["type"] == 0]
if len(fund_type0) > 0:
type0_fund_id = list(fund_type0["fund_id"].unique())
fund_list_str_0 = str(type0_fund_id).replace("[", "(").replace("]", ")")
sql_fund_0 = "select distinct `id`, `fund_short_name`, `substrategy` from `tx_fund_info` where `id` in {}".format(
fund_list_str_0)
cur = tamp_fund_session.execute(sql_fund_0)
data = cur.fetchall()
fund_df_0 = pd.DataFrame(list(data), columns=['fund_id', 'fund_name', 'substrategy'])
fund_df_0["freq"] = 1
if len(fund_df_0) > 0:
product_df = product_df.append(fund_df_0)
product_df = product_df.drop_duplicates("fund_id")
user_customer_order_df = order_df.set_index('fund_id').join(product_df.set_index('fund_id')).reset_index()
user_customer_order_df["confirm_share_date"] = user_customer_order_df["confirm_share_date"].apply(lambda x: pd.to_datetime(x.date()))
self.customer_real_name = user_customer_order_df["customer_name"].values[0]
......@@ -128,31 +143,100 @@ class UserCustomerDataAdaptor:
self.valueSex = user_customer_order_df["valueSex"].values[0]
user_customer_order_df = user_customer_order_df[user_customer_order_df["confirm_share_date"] <= self.end_date]
user_customer_order_df["confirm_amount"] = user_customer_order_df["confirm_amount"] - user_customer_order_df["subscription_fee"]
user_customer_order_df.sort_values(by="confirm_share_date", inplace=True)
user_customer_order_df.index = pd.Series(range(len(user_customer_order_df)))
user_customer_order_df["original_confirm_share"] = user_customer_order_df["confirm_share"]
user_customer_order_df["divident_share"] = user_customer_order_df["confirm_share"]
user_customer_order_df["reduce_share"] = user_customer_order_df["confirm_share"]
user_customer_order_df["coefficient"] = Decimal(1.0)
for index, row in user_customer_order_df.iterrows():
if row["order_type"] == 2:
need_less_share = row["confirm_share"]
for index_ori, row_ori in user_customer_order_df.iterrows():
if index_ori >= index:
break
if row["fund_id"] == row_ori["fund_id"] and row_ori["order_type"] == 1:
ori_share = row_ori["confirm_share"]
if need_less_share >= ori_share:
need_less_share -= ori_share
user_customer_order_df.loc[index_ori, "confirm_share"] = 0
else:
user_customer_order_df.loc[index_ori, "confirm_share"] = row_ori["confirm_share"] - need_less_share
need_less_share = 0
# user_customer_order_df.loc[index_ori, "confirm_share"] = row_ori[
# "confirm_share"] - need_less_share
if need_less_share <= 0:
break
user_customer_order_df = user_customer_order_df[(user_customer_order_df["order_type"] == 1)&(user_customer_order_df["confirm_share"] > 0)]
# 内部订单
inter_df = user_customer_order_df[user_customer_order_df["comefrom"] == "inter"]
inter_order_df = self.reduce_inter_order(inter_df)
# 外部订单
outside_df = user_customer_order_df[user_customer_order_df["comefrom"] == "app"]
outside_order_df = self.reduce_outside_order(outside_df)
# outside_order_df["comefrom"] = "app"
# outside_order_df = outside_order_df[outside_order_df["fund_id"] == "HF00005AFK"]
user_customer_order_df = pd.concat([inter_order_df, outside_order_df])
user_customer_order_df = user_customer_order_df[(user_customer_order_df["order_type"] <= 4)]
user_customer_order_df.index = pd.Series(range(len(user_customer_order_df)))
self.start_date = user_customer_order_df["confirm_share_date"].min()
return user_customer_order_df
# 核减内部订单
def reduce_inter_order(self, order_df):
inter_order_df = order_df.copy()
inter_order_df.sort_values(by="confirm_share_date", inplace=True)
def reduce_order(fund_order, d_fund_id, d_date, d_nav):
"""
再平衡分红后单子的份额数量,对分红前的单子进行拆分
:param fund_order: 订单dataframe
:param d_date: 分红订单日期
:param d_nav: 分红后单位净值
:return:
"""
for _index, _row in fund_order.iterrows():
if _row["confirm_share_date"] > d_date:
break
if _row["order_type"] == 1 and _row["fund_id"] == d_fund_id and _row["nav"] > d_nav:
coefficient = _row["nav"] / d_nav
fund_order.loc[_index, "coefficient"] = coefficient
fund_order.loc[_index, "divident_share"] = _row["confirm_share"] * coefficient
return fund_order
for index, row in inter_order_df.iterrows():
if row["order_type"] == 4:
dividend_date = row["confirm_share_date"]
dividend_nav = row["nav"]
reduce_order(inter_order_df, row["fund_id"], dividend_date, dividend_nav)
continue
if row["order_type"] == 2:
need_less_share = row["confirm_share"]
for index_ori, row_ori in inter_order_df.iterrows():
if index_ori >= index:
break
if row["fund_id"] == row_ori["fund_id"] and row_ori["order_type"] == 1:
ori_share = row_ori["divident_share"]
if need_less_share >= ori_share:
need_less_share -= ori_share
inter_order_df.loc[index_ori, "divident_share"] = 0
else:
inter_order_df.loc[index_ori, "divident_share"] = row_ori["divident_share"] - need_less_share
need_less_share = 0
if need_less_share <= 0:
break
inter_order_df["reduce_share"] = inter_order_df["divident_share"] / inter_order_df["coefficient"]
inter_order_df["confirm_share"] = inter_order_df["reduce_share"]
return inter_order_df
# 核减外部订单
def reduce_outside_order(self, order_df):
outside_order_df = order_df.copy()
for index, row in outside_order_df.iterrows():
if row["order_type"] == 2:
need_less_share = row["confirm_share"]
for index_ori, row_ori in outside_order_df.iterrows():
if index_ori >= index:
break
if row["fund_id"] == row_ori["fund_id"] and row_ori["order_type"] == 1:
ori_share = row_ori["reduce_share"]
if need_less_share >= ori_share:
need_less_share -= ori_share
outside_order_df.loc[index_ori, "reduce_share"] = 0
else:
outside_order_df.loc[index_ori, "reduce_share"] = row_ori["reduce_share"] - need_less_share
need_less_share = 0
if need_less_share <= 0:
break
outside_order_df["confirm_share"] = outside_order_df["reduce_share"]
return outside_order_df
# 获取客户持有的基金净值数据
def get_customer_fund_nav_data(self):
with TAMP_SQL(tamp_product_engine) as tamp_product, TAMP_SQL(tamp_fund_engine) as tamp_fund:
......@@ -175,35 +259,49 @@ class UserCustomerDataAdaptor:
fund_type = row["type"]
# 对应基金净值
if fund_type == 0:
sql = """select distinct `end_date`, `unit_nav`,`accum_nav` from `public_fund_nav` where `id`='{}' order by `end_date` ASC""".format(cur_fund_id)
sql = """select distinct `price_date`, `nav`,`cumulative_nav` from `tx_fund_nav` where `fund_id`='{}' and `delete_tag`=0 order by `price_date` ASC""".format(cur_fund_id)
cur = tamp_fund_session.execute(sql)
elif fund_type == 1:
sql = """select distinct `price_date`, `nav`,`cumulative_nav` from `fund_nav` where `fund_id`='{}' order by `price_date` ASC""".format(
sql = """select distinct `price_date`, `nav`,`cumulative_nav` from `fund_nav` where `fund_id`='{}' and `delete_tag`=0 order by `price_date` ASC""".format(
cur_fund_id)
cur = tamp_fund_session.execute(sql)
elif fund_type == 2:
sql = """select distinct `price_date`, `nav`,`cumulative_nav` from `fund_nav` where `fund_id`='{}' order by `price_date` ASC""".format(
sql = """select distinct `price_date`, `nav`,`cumulative_nav` from `fund_nav` where `fund_id`='{}' and `delete_tag`=0 order by `price_date` ASC""".format(
cur_fund_id)
cur = tamp_product_session.execute(sql)
elif fund_type == 3:
sql = """select distinct `price_date`, `nav`,`cumulative_nav` from `ifa_imported_fund_nav` where `fund_id`='{}' order by `price_date` ASC""".format(
sql = """select distinct `price_date`, `nav`,`cumulative_nav` from `ifa_imported_fund_nav` where `fund_id`='{}' and `delete_tag`=0 order by `price_date` ASC""".format(
cur_fund_id)
cur = tamp_fund_session.execute(sql)
data = cur.fetchall()
cur_fund_nav_df = pd.DataFrame(list(data), columns=['price_date', 'nav', 'cnav'])
# # 对应基金分红
sql = """select distinct `distribute_date`, `distribution` from `fund_distribution` where `fund_id`='{}' and `distribute_type`='1' order by `distribute_date` ASC""".format(
dis_sql = """select distinct `distribute_date`, `distribution` from `fund_distribution` where `fund_id`='{}' and `distribute_type`='1' order by `distribute_date` ASC""".format(
cur_fund_id)
cur = tamp_product_session.execute(sql)
if fund_type == 0:
dis_sql = """select distinct `distribute_date`, `distribution` from `tx_fund_distribution` where `fund_id`='{}' and `distribute_type`='1' order by `distribute_date` ASC""".format(
cur_fund_id)
cur = tamp_fund_session.execute(dis_sql)
else:
cur = tamp_product_session.execute(dis_sql)
data = cur.fetchall()
cur_fund_distribution_df = pd.DataFrame(list(data), columns=['price_date', 'distribution'])
self.all_fund_distribution[cur_fund_id] = cur_fund_distribution_df
# 对应基金performance数据
sql = """select distinct `price_date`, `ret_1w`, `ret_cum_1m`, `ret_cum_6m`, `ret_cum_1y`, `ret_cum_ytd`, `ret_cum_incep` from `fund_performance` where `fund_id`='{}' order by `price_date` ASC""".format(
per_sql = """select distinct `price_date`, `ret_1w`, `ret_cum_1m`, `ret_cum_6m`, `ret_cum_1y`, `ret_cum_ytd`, `ret_cum_incep` from `fund_performance` where `fund_id`='{}' order by `price_date` ASC""".format(
cur_fund_id)
cur = tamp_product_session.execute(sql)
if fund_type == 0:
per_sql = """select distinct `price_date`, `ret_1w`, `ret_1m`, `ret_6m`, `ret_1y`, `ret_ytd`, `ret_incep` from `tx_fund_count` where `fund_id`='{}' order by `price_date` ASC""".format(
cur_fund_id)
cur = tamp_fund_session.execute(per_sql)
elif fund_type == 3:
per_sql = """select distinct `price_date`, `ret_1w`, `ret_1m`, `ret_6m`, `ret_1y`, `ret_ytd`, `ret_incep` from `ifa_imported_fund_count` where `fund_id`='{}' order by `price_date` ASC""".format(
cur_fund_id)
cur = tamp_product_session.execute(per_sql)
else:
cur = tamp_product_session.execute(per_sql)
data = cur.fetchall()
cur_fund_performance_df = pd.DataFrame(list(data),
columns=['price_date', 'ret_1w', 'ret_cum_1m', 'ret_cum_6m', 'ret_cum_1y', 'ret_cum_ytd', 'ret_cum_incep'])
......@@ -246,6 +344,7 @@ class UserCustomerDataAdaptor:
index_df["price_date"] = pd.to_datetime(index_df["price_date"])
index_df.set_index("price_date", inplace=True)
self.fund_cnav_total["index"] = index_df["index"]
self.fund_nav_total["index"] = index_df["index"]
self.index_df = index_df
return index_df
......@@ -265,14 +364,25 @@ class UserCustomerDataAdaptor:
def signal_folio_operate(self, p_folio, p_order_df, p_nav_df, p_cnav_df):
start_date = pd.to_datetime(p_order_df["confirm_share_date"].min())
p_order_df = p_order_df[(p_order_df["order_type"] == 1) | (p_order_df["order_type"] == 4)]
p_nav_df = self.fund_nav_total.copy()
p_cnav_df = self.fund_cnav_total.copy()
start_date = pd.to_datetime(p_order_df["confirm_share_date"].min())
nav_df = p_nav_df[p_nav_df.index >= start_date].copy()
cnav_df = p_cnav_df[p_cnav_df.index >= start_date].copy()
p_fund_id_list = list(p_order_df["fund_id"].unique())
self.all_fund_id_list = p_fund_id_list
self.all_fund_type_dict = {values["fund_id"]: values["type"] for values in
p_order_df[["fund_id", "type"]].drop_duplicates().to_dict(orient='records')}
for p_fund_id in p_fund_id_list:
order_min_date = p_order_df[p_order_df["fund_id"] == p_fund_id]["confirm_share_date"].min()
if pd.to_datetime(order_min_date) > start_date:
cnav_df.loc[:order_min_date - datetime.timedelta(days=1), p_fund_id] = np.nan
# 处理累积净值
p_outside_order_df = p_order_df[p_order_df["comefrom"] == "app"]
for index, row in p_order_df.iterrows():
cur_fund_id = str(row["fund_id"])
confirm_share_date = pd.to_datetime(row["confirm_share_date"])
......@@ -298,25 +408,10 @@ class UserCustomerDataAdaptor:
cnav_df.loc[confirm_share_date, cur_fund_id] = cur_cnav
cnav_df = cnav_df.dropna(axis=0, how="all").fillna(method='ffill')
for index, row in p_order_df.iterrows():
for index, row in p_outside_order_df.iterrows():
cur_fund_id = str(row["fund_id"])
confirm_share_date = pd.to_datetime(row["confirm_share_date"])
# # 根据确认净值日查看是否含有累积净值的数据,如果没有按照前后差值推算当天累积净值
# if pd.isnull(cnav_df.loc[confirm_share_date, cur_fund_id]):
# last_nav_data = p_nav_df[p_nav_df.index < confirm_share_date][cur_fund_id].dropna().tail(1)
# last_cnav_data = p_cnav_df[p_cnav_df.index < confirm_share_date][cur_fund_id].dropna().tail(1)
# # 判断上个净值日和当前确认日之中是否存在分红日
# """need add judge"""
#
# if len(last_nav_data) < 1:
# cnav_df.loc[confirm_share_date, cur_fund_id] = row["nav"]
# else:
# diff_nav = row["nav"] - last_nav_data.values[0]
# cur_cnav = last_cnav_data.values[0] + diff_nav
# cnav_df.loc[confirm_share_date, cur_fund_id] = cur_cnav
if cur_fund_id+"_amount" not in cnav_df:
if cur_fund_id + "_amount" not in cnav_df:
price = cnav_df[cur_fund_id].dropna()
profit = price.diff().fillna(Decimal(0))
cnav_df[cur_fund_id + "_profit"] = profit
......@@ -324,42 +419,118 @@ class UserCustomerDataAdaptor:
profit_ratio = profit / cnav_df[cur_fund_id].dropna().shift(1)
cnav_df[cur_fund_id + "_profit_ratio"] = profit_ratio
cnav_df[cur_fund_id + "_profit_ratio"] = cnav_df[cur_fund_id + "_profit_ratio"].fillna(Decimal(0))
cnav_df[cur_fund_id+"_amount"] = 0
cnav_df[cur_fund_id + "_amount"] = 0
cnav_df[cur_fund_id + "_earn"] = 0
cnav_df[cur_fund_id + "_share"] = 0
# buy
if row['order_type'] == 1:
cnav_df.loc[confirm_share_date:, cur_fund_id + "_amount"] += row["confirm_amount"]
if row['order_type'] == 1 or row['order_type'] == 4:
# if row['order_type'] == 1:
cnav_df.loc[confirm_share_date:, cur_fund_id + "_amount"] += row["nav"] * row["confirm_share"]
cnav_df.loc[confirm_share_date:, cur_fund_id + "_share"] += row["confirm_share"]
# sell
elif row['order_type'] == 2:
cnav_df.loc[confirm_share_date:, cur_fund_id + "_amount"] -= row["confirm_amount"]
cnav_df.loc[confirm_share_date:, cur_fund_id + "_share"] -= row["confirm_share"]
# cnav_df[cur_fund_id + "_earn"] = cnav_df[cur_fund_id + "_profit"] * cnav_df[cur_fund_id + "_share"]
# cnav_df[cur_fund_id + "_earn"] = cnav_df[cur_fund_id + "_earn"].apply(lambda x: float(x))
# cnav_df[cur_fund_id + "_cum_earn"] = cnav_df[cur_fund_id + "_earn"].cumsum()
# 处理单位净值
nav_df = nav_df.dropna(axis=0, how="all").fillna(method='ffill')
p_inter_order_df = p_order_df[p_order_df["comefrom"] == "inter"]
for index, row in p_inter_order_df.iterrows():
cur_fund_id = str(row["fund_id"])
confirm_share_date = pd.to_datetime(row["confirm_share_date"])
confirm_share_nav = row["nav"]
for p_fund_id_ in p_fund_id_list:
cnav_df[p_fund_id_ + "_earn"] = (cnav_df[p_fund_id_ + "_profit"] * cnav_df[p_fund_id_ + "_share"]).apply(lambda x: float(x)).fillna(0)
# cnav_df[p_fund_id_ + "_earn"] = cnav_df[p_fund_id_ + "_earn"].apply(lambda x: float(x))
nav_df.loc[confirm_share_date, cur_fund_id] = confirm_share_nav
# 内部订单是用单位净值算收益
nav_df = nav_df.fillna(method='ffill')
actual_share_dict = {}
for index, row in p_inter_order_df.iterrows():
cur_fund_id = str(row["fund_id"])
confirm_share_date = pd.to_datetime(row["confirm_share_date"])
if cur_fund_id + "_amount" not in nav_df:
nav_df[cur_fund_id + "_profit"] = Decimal(0)
nav_df[cur_fund_id + "_profit_ratio"] = Decimal(0)
nav_df[cur_fund_id + "_amount"] = 0
nav_df[cur_fund_id + "_earn"] = 0
nav_df[cur_fund_id + "_share"] = 0
nav_df[cur_fund_id + "_reduce_share"] = 0
# buy
if row['order_type'] == 1:
cur_fund_share = actual_share_dict.get(cur_fund_id, 0)
cur_fund_share += row["reduce_share"] / row["coefficient"]
nav_df.loc[confirm_share_date:, cur_fund_id + "_amount"] += row["reduce_share"] * row["nav"]
nav_df.loc[confirm_share_date:, cur_fund_id + "_share"] = cur_fund_share
nav_df.loc[confirm_share_date:, cur_fund_id + "_reduce_share"] += row["reduce_share"]
actual_share_dict[cur_fund_id] = cur_fund_share
if row['order_type'] == 4:
cur_fund_share = actual_share_dict.get(cur_fund_id, 0)
# cur_fund_share += row["reduce_share"]
# nav_df.loc[confirm_share_date:, cur_fund_id + "_amount"] = cur_fund_share * row["nav"]
# nav_df.loc[confirm_share_date:, cur_fund_id + "_share"] = cur_fund_share
nav_df.loc[confirm_share_date:, cur_fund_id + "_reduce_share"] = cur_fund_share + row["reduce_share"]
# actual_share_dict[cur_fund_id] = cur_fund_share
for p_fund_id_ in p_outside_order_df["fund_id"].unique():
cnav_df[p_fund_id_ + "_earn"] = (cnav_df[p_fund_id_ + "_profit"] * cnav_df[p_fund_id_ + "_share"]).apply(
lambda x: float(x)).fillna(0)
cnav_df[p_fund_id_ + "_cum_earn"] = cnav_df[p_fund_id_ + "_earn"].cumsum().fillna(0)
cnav_df[p_fund_id_ + "_net_amount"] = cnav_df[p_fund_id_ + "_cum_earn"].apply(lambda x: Decimal(x)) + cnav_df[p_fund_id_ + "_amount"]
# cnav_df[p_fund_id_ + "_net_amount"] = cnav_df[p_fund_id_ + "_share"] * cnav_df[p_fund_id_]
# cnav_df[p_fund_id_ + "_profit_ratio"] = cnav_df[p_fund_id_ + "_earn"].apply(lambda x: Decimal(x)) / cnav_df[
# p_fund_id_ + "_net_amount"].shift()
self.group_data[p_folio] = {"result_cnav_data": cnav_df, "order_df": p_order_df}
cnav_df[p_fund_id_ + "_net_amount"] = cnav_df[p_fund_id_ + "_cum_earn"].apply(lambda x: Decimal(x)) + \
cnav_df[p_fund_id_ + "_amount"]
for p_fund_id_ in p_inter_order_df["fund_id"].unique():
nav_df[p_fund_id_ + "_net_amount"] = (nav_df[p_fund_id_] * nav_df[p_fund_id_ + "_reduce_share"]).apply(
lambda x: float(x)).fillna(0)
nav_df[p_fund_id_ + "_cum_earn"] = nav_df[p_fund_id_ + "_net_amount"] - nav_df[
p_fund_id_ + "_amount"].apply(lambda x: float(x))
nav_df[p_fund_id_ + "_earn"] = nav_df[p_fund_id_ + "_cum_earn"].diff().fillna(0)
nav_df[p_fund_id_ + "_profit_ratio"] = (
nav_df[p_fund_id_ + "_earn"] / nav_df[p_fund_id_ + "_amount"].apply(lambda x: float(x))).apply(
lambda x: Decimal(x))
nav_df[p_fund_id_ + "_net_amount"] = nav_df[p_fund_id_ + "_net_amount"].apply(lambda x: Decimal(x))
nav_df[p_fund_id_ + "_profit_ratio"] = nav_df[p_fund_id_ + "_profit_ratio"].apply(
lambda x: Decimal(0) if math.isnan(x) else x)
finall_cnav_df = cnav_df.copy()
all_nav_df = p_nav_df[p_nav_df.index >= start_date].copy().dropna(axis=0, how="all").fillna(method='ffill')
for p_fund_id_ in p_order_df["fund_id"].unique():
finall_cnav_df[p_fund_id_ + "_nav"] = all_nav_df[p_fund_id_]
if p_fund_id_ + "_profit_ratio" not in finall_cnav_df.columns:
finall_cnav_df[p_fund_id_ + "_profit_ratio"] = Decimal(0)
finall_cnav_df[p_fund_id_ + "_amount"] = 0
finall_cnav_df[p_fund_id_ + "_earn"] = 0
finall_cnav_df[p_fund_id_ + "_share"] = 0
finall_cnav_df[p_fund_id_ + "_net_amount"] = Decimal(0)
# try:
# finall_cnav_df[p_fund_id_] = cnav_df[p_fund_id_]
# finall_cnav_df[p_fund_id_ + "_net_amount"] += cnav_df[p_fund_id_ + "_net_amount"]
# finall_cnav_df[p_fund_id_ + "_profit_ratio"] += cnav_df[p_fund_id_ + "_profit_ratio"]
# finall_cnav_df[p_fund_id_ + "_amount"] += cnav_df[p_fund_id_ + "_amount"]
# finall_cnav_df[p_fund_id_ + "_earn"] += cnav_df[p_fund_id_ + "_earn"]
# finall_cnav_df[p_fund_id_ + "_share"] += cnav_df[p_fund_id_ + "_share"]
# except:
# pass
try:
finall_cnav_df[p_fund_id_ + "_nav"] = nav_df[p_fund_id_]
finall_cnav_df[p_fund_id_ + "_net_amount"] += nav_df[p_fund_id_ + "_net_amount"]
finall_cnav_df[p_fund_id_ + "_profit_ratio"] += nav_df[p_fund_id_ + "_profit_ratio"]
finall_cnav_df[p_fund_id_ + "_amount"] += nav_df[p_fund_id_ + "_amount"]
finall_cnav_df[p_fund_id_ + "_earn"] += nav_df[p_fund_id_ + "_earn"]
finall_cnav_df[p_fund_id_ + "_share"] += nav_df[p_fund_id_ + "_share"]
except:
pass
self.group_data[p_folio] = {"result_cnav_data": finall_cnav_df, "order_df": p_order_df}
return cnav_df
# 所有的数据操作
def total_combine_data(self):
p_order_df = self.user_customer_order_df.copy()
p_order_df = self.user_customer_order_df[(self.user_customer_order_df["order_type"] == 1) |
(self.user_customer_order_df["order_type"] == 4)]
p_nav_df = self.fund_nav_total.copy()
p_cnav_df = self.fund_cnav_total.copy()
start_date = pd.to_datetime(p_order_df["confirm_share_date"].min())
nav_df = p_nav_df[p_nav_df.index >= start_date].copy()
cnav_df = p_cnav_df[p_cnav_df.index >= start_date].copy()
p_fund_id_list = list(p_order_df["fund_id"].unique())
......@@ -370,6 +541,8 @@ class UserCustomerDataAdaptor:
if pd.to_datetime(order_min_date) > start_date:
cnav_df.loc[:order_min_date - datetime.timedelta(days=1), p_fund_id] = np.nan
# 处理累积净值
p_outside_order_df = p_order_df[p_order_df["comefrom"] == "app"]
for index, row in p_order_df.iterrows():
cur_fund_id = str(row["fund_id"])
confirm_share_date = pd.to_datetime(row["confirm_share_date"])
......@@ -395,7 +568,7 @@ class UserCustomerDataAdaptor:
cnav_df.loc[confirm_share_date, cur_fund_id] = cur_cnav
cnav_df = cnav_df.dropna(axis=0, how="all").fillna(method='ffill')
for index, row in p_order_df.iterrows():
for index, row in p_outside_order_df.iterrows():
cur_fund_id = str(row["fund_id"])
confirm_share_date = pd.to_datetime(row["confirm_share_date"])
if cur_fund_id + "_amount" not in cnav_df:
......@@ -410,33 +583,93 @@ class UserCustomerDataAdaptor:
cnav_df[cur_fund_id + "_earn"] = 0
cnav_df[cur_fund_id + "_share"] = 0
# profit = cnav_df[cur_fund_id].dropna() - cnav_df[cur_fund_id].dropna().shift(1)
# cnav_df[cur_fund_id + "_profit"] = profit
# cnav_df[cur_fund_id + "_profit"] = cnav_df[cur_fund_id + "_profit"].fillna(Decimal(0))
# cnav_df[cur_fund_id + "_profit_ratio"] = profit / cnav_df[cur_fund_id].dropna().shift(1)
# cnav_df[cur_fund_id + "_profit_ratio"] = cnav_df[cur_fund_id + "_profit_ratio"].fillna(Decimal(0))
# cnav_df[cur_fund_id + "_amount"] = 0
# cnav_df[cur_fund_id + "_earn"] = 0
# cnav_df[cur_fund_id + "_cum_earn"] = 0
# cnav_df[cur_fund_id + "_share"] = 0
# buy
if row['order_type'] == 1:
cnav_df.loc[confirm_share_date:, cur_fund_id + "_amount"] += row["confirm_amount"]
if row['order_type'] == 1 or row['order_type'] == 4:
# if row['order_type'] == 1:
cnav_df.loc[confirm_share_date:, cur_fund_id + "_amount"] += row["nav"] * row["confirm_share"]
cnav_df.loc[confirm_share_date:, cur_fund_id + "_share"] += row["confirm_share"]
# sell
elif row['order_type'] == 2:
cnav_df.loc[confirm_share_date:, cur_fund_id + "_amount"] -= row["confirm_amount"]
cnav_df.loc[confirm_share_date:, cur_fund_id + "_share"] -= row["confirm_share"]
for p_fund_id_ in p_fund_id_list:
# 处理单位净值
nav_df = nav_df.dropna(axis=0, how="all").fillna(method='ffill')
p_inter_order_df = p_order_df[p_order_df["comefrom"] == "inter"]
for index, row in p_inter_order_df.iterrows():
cur_fund_id = str(row["fund_id"])
confirm_share_date = pd.to_datetime(row["confirm_share_date"])
confirm_share_nav = row["nav"]
nav_df.loc[confirm_share_date, cur_fund_id] = confirm_share_nav
# 内部订单是用单位净值算收益
nav_df = nav_df.fillna(method='ffill')
actual_share_dict = {}
for index, row in p_inter_order_df.iterrows():
cur_fund_id = str(row["fund_id"])
confirm_share_date = pd.to_datetime(row["confirm_share_date"])
if cur_fund_id + "_amount" not in nav_df:
nav_df[cur_fund_id + "_profit"] = Decimal(0)
nav_df[cur_fund_id + "_profit_ratio"] = Decimal(0)
nav_df[cur_fund_id + "_amount"] = 0
nav_df[cur_fund_id + "_earn"] = 0
nav_df[cur_fund_id + "_share"] = 0
nav_df[cur_fund_id + "_reduce_share"] = 0
# buy
if row['order_type'] == 1:
cur_fund_share = actual_share_dict.get(cur_fund_id, 0)
cur_fund_share += row["reduce_share"] / row["coefficient"]
nav_df.loc[confirm_share_date:, cur_fund_id + "_amount"] += row["reduce_share"] * row["nav"]
nav_df.loc[confirm_share_date:, cur_fund_id + "_share"] = cur_fund_share
nav_df.loc[confirm_share_date:, cur_fund_id + "_reduce_share"] += row["reduce_share"]
actual_share_dict[cur_fund_id] = cur_fund_share
if row['order_type'] == 4:
cur_fund_share = actual_share_dict.get(cur_fund_id, 0)
# cur_fund_share += row["reduce_share"]
# nav_df.loc[confirm_share_date:, cur_fund_id + "_amount"] = cur_fund_share * row["nav"]
# nav_df.loc[confirm_share_date:, cur_fund_id + "_share"] = cur_fund_share
nav_df.loc[confirm_share_date:, cur_fund_id + "_reduce_share"] = cur_fund_share + row["reduce_share"]
# actual_share_dict[cur_fund_id] = cur_fund_share
for p_fund_id_ in p_outside_order_df["fund_id"].unique():
cnav_df[p_fund_id_ + "_earn"] = (cnav_df[p_fund_id_ + "_profit"] * cnav_df[p_fund_id_ + "_share"]).apply(lambda x: float(x)).fillna(0)
# cnav_df[p_fund_id_ + "_earn"] = cnav_df[p_fund_id_ + "_earn"].apply(lambda x: float(x))
cnav_df[p_fund_id_ + "_cum_earn"] = cnav_df[p_fund_id_ + "_earn"].cumsum().fillna(0)
cnav_df[p_fund_id_ + "_net_amount"] = cnav_df[p_fund_id_ + "_cum_earn"].apply(lambda x: Decimal(x)) + cnav_df[p_fund_id_ + "_amount"]
# cnav_df[p_fund_id_ + "_profit_ratio"] = cnav_df[p_fund_id_ + "_earn"].apply(lambda x: Decimal(x)) / cnav_df[
# p_fund_id_ + "_net_amount"].shift()
# cnav_df[p_fund_id_ + "_net_amount"] = cnav_df[p_fund_id_ + "_share"] * cnav_df[p_fund_id_]
return cnav_df
for p_fund_id_ in p_inter_order_df["fund_id"].unique():
nav_df[p_fund_id_ + "_net_amount"] = (nav_df[p_fund_id_] * nav_df[p_fund_id_ + "_reduce_share"]).apply(lambda x: float(x)).fillna(0)
nav_df[p_fund_id_ + "_cum_earn"] = nav_df[p_fund_id_ + "_net_amount"] - nav_df[p_fund_id_ + "_amount"].apply(lambda x: float(x))
nav_df[p_fund_id_ + "_earn"] = nav_df[p_fund_id_ + "_cum_earn"].diff().fillna(0)
nav_df[p_fund_id_ + "_profit_ratio"] = (nav_df[p_fund_id_ + "_earn"] / nav_df[p_fund_id_ + "_amount"].apply(lambda x: float(x))).apply(lambda x: Decimal(x))
nav_df[p_fund_id_ + "_net_amount"] = nav_df[p_fund_id_ + "_net_amount"].apply(lambda x: Decimal(x))
nav_df[p_fund_id_ + "_profit_ratio"] = nav_df[p_fund_id_ + "_profit_ratio"].apply(lambda x: Decimal(0) if math.isnan(x) else x)
finall_cnav_df = cnav_df.copy()
all_nav_df = p_nav_df[p_nav_df.index >= start_date].copy().dropna(axis=0, how="all").fillna(method='ffill')
for p_fund_id_ in p_order_df["fund_id"].unique():
finall_cnav_df[p_fund_id_ + "_nav"] = all_nav_df[p_fund_id_]
if p_fund_id_ + "_profit_ratio" not in finall_cnav_df.columns:
finall_cnav_df[p_fund_id_ + "_profit_ratio"] = Decimal(0)
finall_cnav_df[p_fund_id_ + "_amount"] = 0
finall_cnav_df[p_fund_id_ + "_earn"] = 0
finall_cnav_df[p_fund_id_ + "_share"] = 0
finall_cnav_df[p_fund_id_ + "_net_amount"] = Decimal(0)
# try:
# finall_cnav_df[p_fund_id_] = cnav_df[p_fund_id_]
# finall_cnav_df[p_fund_id_ + "_net_amount"] += cnav_df[p_fund_id_ + "_net_amount"]
# finall_cnav_df[p_fund_id_ + "_profit_ratio"] += cnav_df[p_fund_id_ + "_profit_ratio"]
# finall_cnav_df[p_fund_id_ + "_amount"] += cnav_df[p_fund_id_ + "_amount"]
# finall_cnav_df[p_fund_id_ + "_earn"] += cnav_df[p_fund_id_ + "_earn"]
# finall_cnav_df[p_fund_id_ + "_share"] += cnav_df[p_fund_id_ + "_share"]
# except:
# pass
try:
finall_cnav_df[p_fund_id_ + "_nav"] = nav_df[p_fund_id_]
finall_cnav_df[p_fund_id_ + "_net_amount"] += nav_df[p_fund_id_ + "_net_amount"]
finall_cnav_df[p_fund_id_ + "_profit_ratio"] += nav_df[p_fund_id_ + "_profit_ratio"]
finall_cnav_df[p_fund_id_ + "_amount"] += nav_df[p_fund_id_ + "_amount"]
finall_cnav_df[p_fund_id_ + "_earn"] += nav_df[p_fund_id_ + "_earn"]
finall_cnav_df[p_fund_id_ + "_share"] += nav_df[p_fund_id_ + "_share"]
except:
pass
return finall_cnav_df
......@@ -14,6 +14,7 @@ from app.pypfopt import risk_models
from app.pypfopt import expected_returns
from app.pypfopt import EfficientFrontier
from app.api.engine import tamp_product_engine, tamp_fund_engine, TAMP_SQL
from app.service.substrategy_dict import get_substrategy_name
def cal_correlation(prod):
......@@ -155,25 +156,41 @@ def choose_bad_evaluation(evaluation):
return evaluation
def get_fund_rank():
def get_fund_rank(fund_type=1):
"""获取基金指标排名
:return: 基金指标排名表
"""
with TAMP_SQL(tamp_fund_engine) as tamp_fund:
tamp_fund_session = tamp_fund.session
sql = "SELECT * FROM new_fund_rank"
if fund_type == 1:
with TAMP_SQL(tamp_fund_engine) as tamp_fund:
tamp_fund_session = tamp_fund.session
sql = "SELECT * FROM new_fund_rank"
# df = pd.read_sql(sql, con)
# df = pd.read_csv('fund_rank.csv', encoding='gbk')
cur = tamp_fund_session.execute(sql)
data = cur.fetchall()
df = pd.DataFrame(list(data), columns=['index', 'fund_id', 'range_return', 'annual_return', 'max_drawdown',
'sharp_ratio', 'volatility', 'sortino_ratio', 'downside_risk',
'substrategy', 'manager', 'annual_return_rank', 'downside_risk_rank',
'max_drawdown_rank', 'sharp_ratio_rank', 'z_score'])
df.drop('index', axis=1, inplace=True)
return df
# df = pd.read_sql(sql, con)
# df = pd.read_csv('fund_rank.csv', encoding='gbk')
cur = tamp_fund_session.execute(sql)
data = cur.fetchall()
df = pd.DataFrame(list(data), columns=['index', 'fund_id', 'range_return', 'annual_return', 'max_drawdown',
'sharp_ratio', 'volatility', 'sortino_ratio', 'downside_risk',
'substrategy', 'manager', 'annual_return_rank', 'downside_risk_rank',
'max_drawdown_rank', 'sharp_ratio_rank', 'z_score'])
df.drop('index', axis=1, inplace=True)
return df
else:
with TAMP_SQL(tamp_fund_engine) as tamp_fund:
tamp_fund_session = tamp_fund.session
sql = "SELECT * FROM tx_fund_rank"
# df = pd.read_sql(sql, con)
# df = pd.read_csv('fund_rank.csv', encoding='gbk')
cur = tamp_fund_session.execute(sql)
data = cur.fetchall()
df = pd.DataFrame(list(data), columns=['index', 'fund_id', 'range_return', 'annual_return', 'max_drawdown',
'sharp_ratio', 'volatility', 'sortino_ratio', 'downside_risk',
'substrategy', 'manager', 'annual_return_rank', 'downside_risk_rank',
'max_drawdown_rank', 'sharp_ratio_rank', 'z_score'])
df.drop('index', axis=1, inplace=True)
return df
def get_index_daily(index_id, start_date):
......@@ -267,7 +284,7 @@ def get_tamp_nav(fund, start_date, rollback=False, invest_type=2):
# # df = pd.read_sql(sql, con).dropna(how='any')
# cur = tamp_product_session.execute(sql)
if invest_type == 0:
sql = """select distinct `id`, `end_date`, `accum_nav` from `public_fund_nav` where `id`='{}' order by `end_date` ASC""".format(
sql = """select distinct `fund_id`, `price_date`, `cumulative_nav` from `tx_fund_nav` where `fund_id`='{}' and `delete_tag`=0 order by `price_date` ASC""".format(
fund)
cur = tamp_fund_session.execute(sql)
elif invest_type == 1:
......@@ -388,7 +405,7 @@ def get_fund_name(fund, fund_type=1):
if fund_type == 0:
with TAMP_SQL(tamp_fund_engine) as tamp_fund:
tamp_fund_session = tamp_fund.session
sql = "SELECT name FROM public_fund_basic WHERE ts_code='{}'".format(fund)
sql = "SELECT fund_short_name FROM tx_fund_info WHERE `id`='{}'".format(fund)
# df = pd.read_sql(sql, con)
cur = tamp_fund_session.execute(sql)
data = cur.fetchall()
......@@ -425,6 +442,7 @@ def get_fund_name(fund, fund_type=1):
# 获取排名信息
fund_rank = get_fund_rank()
tx_fund_rank = get_fund_rank(0)
# 获取探普产品池
tamp_fund = get_tamp_fund()
......@@ -848,7 +866,7 @@ class PortfolioDiagnose(object):
data_adaptor.user_customer_order_df["folio_name"] == group_name]
strategy_list = group_order_df["substrategy"]
uniqe_strategy = list(strategy_list.unique())
uniqe_strategy_name = [dict_substrategy[int(x)] + "、" for x in uniqe_strategy]
uniqe_strategy_name = [get_substrategy_name(x) + "、" for x in uniqe_strategy]
# 覆盖的基金名称
strategy_name_evaluate = "".join(uniqe_strategy_name)[:-1]
......@@ -1012,7 +1030,7 @@ class PortfolioDiagnose(object):
# 基金名称,策略分级
propose_fund_id_name_list = [propose_fund_df[propose_fund_df["fund_id"] == fund_id]["fund_name"].values[0] for
fund_id in propose_fund_id_list]
propose_fund_id_strategy_name_list = [dict_substrategy[int(propose_fund_df[propose_fund_df["fund_id"] == fund_id]["substrategy"].values[0])] for
propose_fund_id_strategy_name_list = [dict_substrategy(propose_fund_df[propose_fund_df["fund_id"] == fund_id]["substrategy"].values[0]) for
fund_id in propose_fund_id_list]
propose_fund_asset = [round(self.new_weights[i] * total_asset, 2) for i in range(len(propose_fund_id_name_list))]
......@@ -1174,7 +1192,12 @@ class PortfolioDiagnose(object):
Returns:
"""
z_score = search_rank(fund_rank, fund_id, metric='z_score')
if fund_id_type == 0:
rank_df = tx_fund_rank
else:
rank_df = tx_fund_rank
z_score = search_rank(rank_df, fund_id, metric='z_score')
total_level = np.select([z_score >= 80,
70 <= z_score < 80,
z_score < 70], [0, 1, 2]).item()
......@@ -1192,7 +1215,7 @@ class PortfolioDiagnose(object):
compare = pd.merge(index_return_monthly, fund_return_monthly, how='inner', left_index=True, right_index=True)
fund_win_rate = ((compare[fund_id] - compare['pct_chg']) > 0).sum() / compare[fund_id].count()
return_rank = search_rank(fund_rank, fund_id, metric='annual_return_rank')
return_rank = search_rank(rank_df, fund_id, metric='annual_return_rank')
return_level = np.select([return_rank >= 0.8,
0.7 <= return_rank < 0.8,
0.6 <= return_rank < 0.7,
......@@ -1200,8 +1223,8 @@ class PortfolioDiagnose(object):
return_bool = 1 if return_level > 2 else 0
return_triple = return_level - 1 if return_level >= 2 else return_level
drawdown_rank = search_rank(fund_rank, fund_id, metric='max_drawdown_rank')
drawdown_value = search_rank(fund_rank, fund_id, metric='max_drawdown')
drawdown_rank = search_rank(rank_df, fund_id, metric='max_drawdown_rank')
drawdown_value = search_rank(rank_df, fund_id, metric='max_drawdown')
drawdown_level = np.select([drawdown_rank >= 0.8,
0.7 <= drawdown_rank < 0.8,
0.6 <= drawdown_rank < 0.7,
......@@ -1209,7 +1232,7 @@ class PortfolioDiagnose(object):
drawdown_bool = 1 if drawdown_level > 2 else 0
drawdown_triple = drawdown_level - 1 if drawdown_level >= 2 else drawdown_level
sharp_rank = search_rank(fund_rank, fund_id, metric='sharp_ratio_rank')
sharp_rank = search_rank(rank_df, fund_id, metric='sharp_ratio_rank')
sharp_level = np.select([sharp_rank >= 0.8,
0.6 <= sharp_rank < 0.8,
sharp_rank < 0.6], [0, 1, 2]).item()
......@@ -1311,7 +1334,7 @@ class PortfolioDiagnose(object):
result = []
for fund in self.portfolio:
try:
result.append(self.single_evaluation(fund, objective))
result.append(self.single_evaluation(fund, self.portfolio_dict.get(fund, 1), objective))
except IndexError:
continue
return result
......
......@@ -14,6 +14,7 @@ from app.service.data_service_v2_1 import UserCustomerDataAdaptor
from app.utils.fund_rank import get_frequency
from app.service.portfolio_diagnose import cal_correlation, get_fund_name, get_frequency
from app.utils.week_evaluation import *
from app.service.substrategy_dict import get_substrategy_name
class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
......@@ -65,7 +66,6 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
resample_df.set_index("index_date", inplace=True)
resample_df = resample_df[resample_df.index <= self.end_date]
# 收益分解df
contribution_decomposition_df = contribution_decomposition.fillna(0)*100
p_plot_data = []
......@@ -79,7 +79,7 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
"cumulative": cumulative_data}
# 总成本
total_cost = round(float((cur_folio_order_data[cur_folio_order_data["order_type"] == 1]["confirm_share"]*cur_folio_order_data[cur_folio_order_data["order_type"] == 1]["nav"]).sum()), 0)
total_cost = round(float(round(float(cur_folio_result_cnav_data[[i + "_amount" for i in fund_id_list]].tail(1).sum().sum()), 0)), 0)
folio_report_data["total_cost"] = total_cost
# 累积盈利
......@@ -109,8 +109,8 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
folio_report_data["sharpe"] = float(sharpe) if not math.isnan(sharpe) else 0.0
# 期末资产
ending_assets = cumulative_profit + total_cost
folio_report_data["ending_assets"] = float(ending_assets)
ending_assets = round(float(cur_folio_result_cnav_data[[i + "_net_amount" for i in fund_id_list]].tail(1).sum().sum()), 0)
folio_report_data["ending_assets"] = ending_assets
# 本月收益
cur_month_profit_df = profit_df.loc[self.month_start_date:self.end_date+datetime.timedelta(days=1), fund_id_list_earn]
......@@ -250,7 +250,7 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
resample_df = resample_df[resample_df.index <= self.end_date]
# 总成本
total_cost = round(float((cur_folio_order_data[cur_folio_order_data["order_type"] == 1]["confirm_share"]*cur_folio_order_data[cur_folio_order_data["order_type"] == 1]["nav"]).sum()), 0)
total_cost = round(float(cur_folio_result_cnav_data[[i + "_amount" for i in fund_id_list]].tail(1).sum().sum()), 0)
report_data["total_cost"] = total_cost
# 累积盈利
......@@ -277,8 +277,8 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
# report_data["sharpe"] = float(sharpe)
# 期末资产
ending_assets = cumulative_profit + total_cost
report_data["ending_assets"] = float(ending_assets)
ending_assets = round(float(cur_folio_result_cnav_data[[i + "_net_amount" for i in fund_id_list]].tail(1).sum().sum()), 0)
report_data["ending_assets"] = ending_assets
# 本月收益
cur_month_profit_df = profit_df.loc[self.month_start_date:self.end_date + datetime.timedelta(days=1),
......@@ -377,8 +377,6 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
index_result = self.signal_fund_profit_result(index_df[index_df.index >= pd.to_datetime(first_trade_date)], "index")
report_data["index_result"] = index_result
# self.__month_return(cur_folio_result_cnav_data, fund_id_list)
self.total_result_data = report_data
return report_data
......@@ -389,12 +387,14 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
freq_max = p_order_df["freq"].max()
n_freq = freq_days(int(freq_max))
resample_df = resample(p_result_cnav_data, self.trade_cal_date, freq_max)
for index, row in p_order_df.iterrows():
if row['order_type'] == 2 or row["confirm_share"] <= 0:
continue
# for index, row in p_order_df.iterrows():
for hold_fund_id in p_order_df["fund_id"].unique():
order = p_order_df[(p_order_df["fund_id"] == hold_fund_id)]
row = order[order["order_type"] == 1].iloc[0]
cur_fund_id = str(row["fund_id"])
cur_fund_performance = self.all_fund_performance[cur_fund_id]
if len(cur_fund_performance) <=0:
if len(cur_fund_performance) <= 0:
fund_basic_info = {"fund_name": row["fund_name"], "confirm_nav": round(row["nav"], 4)}
fund_basic_info["cur_nav"] = round(float(self.fund_nav_total[cur_fund_id].dropna().values[-1]), 4)
fund_basic_info["cur_cnav"] = round(float(self.fund_cnav_total[cur_fund_id].dropna().values[-1]), 4)
......@@ -408,8 +408,8 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
# 申购以来
confirm_date = pd.to_datetime(row["confirm_share_date"])
confirm_cnav = float(p_result_cnav_data.loc[confirm_date, cur_fund_id])
fund_basic_info["ret_after_confirm"] = round(
(fund_basic_info["cur_cnav"] - confirm_cnav) / confirm_cnav * 100, 2)
fund_basic_info["ret_after_confirm"] = str(round(
(fund_basic_info["cur_cnav"] - confirm_cnav) / confirm_cnav * 100, 2)) + "%"
# 分红
distribution_df = self.all_fund_distribution[cur_fund_id]
if distribution_df.empty:
......@@ -448,23 +448,19 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
# 基金持仓数据
total_market_values = p_sum_profit + p_total_amount # 月末总市值
fund_strategy_name = dict_substrategy[int(row["substrategy"])]
fund_strategy_name = get_substrategy_name(row["substrategy"])
if "长富" in row["fund_name"] or "盈沛" in row["fund_name"]:
fund_strategy_name = "FOF"
fund_hoding_info = {"fund_strategy_name": fund_strategy_name, "fund_name": row["fund_name"]}
fund_hoding_info["confirm_date"] = row["confirm_share_date"].strftime("%Y-%m-%d")
fund_hoding_info["hold_year"] = "%.2f" % round((self.end_date - pd.to_datetime(row["confirm_share_date"])).days/365.0, 2) # 存续年数
fund_hoding_info["market_values"] = round((float(row["confirm_share"]) * (fund_basic_info["cur_cnav"] - confirm_cnav) + float(row["confirm_amount"]))/10000, 2)
# temp_market_values = float(row["confirm_share"]) * (fund_basic_info["cur_cnav"] - confirm_cnav) + float(row["confirm_amount"])
# fund_hoding_info["weight"] = "%.2f" % round(float(fund_hoding_info["market_values"]) / total_market_values * 10000.0 * 100, 2) # 月末占比
# # fund_hoding_info["cost"] = "%.2f" % round(float(row["confirm_amount"])/10000, 2) # 投资本金
# fund_hoding_info["cost"] = "%.2f" % round(float(row["confirm_share"]*row["nav"])/10000, 2)
temp_market_values = float(row["confirm_share"]) * (
fund_basic_info["cur_cnav"] - confirm_cnav + float(row["nav"]))
# fund_hoding_info["market_values"] = round((float(row["confirm_share"]) * (fund_basic_info["cur_cnav"] - confirm_cnav) + float(row["confirm_amount"]))/10000, 2)
temp_market_values = float(p_result_cnav_data[cur_fund_id + "_net_amount"].values[-1])
fund_hoding_info["market_values"] = round(temp_market_values / 10000.0, 2)
fund_hoding_info["weight"] = "%.2f" % round(
float(fund_hoding_info["market_values"]) / total_market_values * 10000.0 * 100, 2) # 月末占比
fund_hoding_info["cost"] = "%.2f" % round(float(row["confirm_share"] * row["nav"]) / 10000, 2) # 投资本金
temp_cost = float(p_result_cnav_data[cur_fund_id + "_amount"].values[-1])
fund_hoding_info["cost"] = "%.2f" % round( temp_cost / 10000, 2) # 投资本金
# 当月收益
if row['confirm_share_date'] > self.month_start_date:
......@@ -472,28 +468,29 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
last_month_cnav_serise = p_result_cnav_data[p_result_cnav_data.index == pd.to_datetime(cal_month_start_date)][
row["fund_id"]].dropna()
else:
# cal_month_start_date = self.month_start_date - datetime.timedelta(days=1)
cal_month_start_date = self.month_start_date
last_month_cnav_serise = p_result_cnav_data[p_result_cnav_data.index<pd.to_datetime(cal_month_start_date)][row["fund_id"]].dropna()
cal_month_cnav_result = p_result_cnav_data[p_result_cnav_data.index >= pd.to_datetime(cal_month_start_date)]
if len(last_month_cnav_serise) == 0:
fund_hoding_info["profit"] = round(float(row["confirm_share"]) * (fund_basic_info["cur_cnav"] - confirm_cnav) / 10000, 2)
temp_profit = float(row["confirm_share"]) * (fund_basic_info["cur_cnav"] - confirm_cnav)
temp_profit_ratio = (fund_basic_info["cur_cnav"] - confirm_cnav)/confirm_cnav
temp_profit = 0
fund_hoding_info["profit"] = temp_profit
temp_profit_ratio = 0
else:
last_month_cnav = float(last_month_cnav_serise.values[-1])
temp_profit = float(cal_month_cnav_result[cur_fund_id + "_earn"].sum())
fund_hoding_info["profit"] = round(float(row["confirm_share"]) * (fund_basic_info["cur_cnav"] - last_month_cnav)/10000, 2)
temp_profit = float(row["confirm_share"]) * (fund_basic_info["cur_cnav"] - last_month_cnav)
temp_profit_ratio = (fund_basic_info["cur_cnav"] - last_month_cnav) / last_month_cnav
# 当月收益率
# fund_hoding_info["month_return_ratio"] = "%.2f" % round(temp_profit / temp_market_values*100, 2)
fund_hoding_info["month_return_ratio"] = "%.2f" % round(temp_profit_ratio * 100, 2)
fund_hoding_info["month_return_ratio"] = "%.2f" % round(temp_profit / temp_market_values*100, 2)
# fund_hoding_info["month_return_ratio"] = "%.2f" % round(temp_profit_ratio * 100, 2)
# 累积收益
fund_hoding_info["cum_profit"] = "%.2f" % round(float(row["confirm_share"]) * (fund_basic_info["cur_cnav"] - confirm_cnav) / 10000, 2)
cum_profit = float(p_result_cnav_data[cur_fund_id + "_earn"].sum())
fund_hoding_info["cum_profit"] = "%.2f" % round(cum_profit / 10000, 2)
# 累积收益率
fund_hoding_info["cum_profit_ratio"] = "%.2f" % round((fund_basic_info["cur_cnav"] - confirm_cnav)/confirm_cnav*100, 2)
cum_profit_ratio_temp = (fund_basic_info["cur_cnav"] - confirm_cnav) / confirm_cnav
fund_hoding_info["cum_profit_ratio"] = "%.2f" % round(cum_profit / temp_cost *100, 2)
cum_profit_ratio_temp = cum_profit / temp_cost
# 累积年化收益率
cur_resample_df = resample_df[[row["fund_id"]]].dropna()
cur_resample_df = resample_df[[row["fund_id"]]]
return_ratio_year = annual_return(float(cum_profit_ratio_temp), cur_resample_df, n_freq)
fund_hoding_info["return_ratio_year"] = "%.2f" % round(float(return_ratio_year)*100, 2)
group_fund_hoding_info.append(fund_hoding_info)
......@@ -504,28 +501,28 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
fund_id_list_amount = [i + "_net_amount" for i in fund_id_list]
fund_id_list_profit_ratio = [i + "_profit_ratio" for i in fund_id_list]
nav_net_amount_df = p_combina_df[fund_id_list + fund_id_list_amount+fund_id_list_profit_ratio].copy()
# nav_net_amount_df = resample(return_ratio_df, self.trade_cal_date, freq_max)
nav_net_amount_df["sum_net_amount"] = nav_net_amount_df[fund_id_list_amount].sum(axis=1).apply(lambda x: Decimal.from_float(x))
for amount_name in fund_id_list:
price = nav_net_amount_df[amount_name].dropna()
profit = price.diff().fillna(Decimal(0))
profit_ratio_new = profit / price.shift(1)
profit_ratio_old = nav_net_amount_df[amount_name+"_profit_ratio"]
nan_index = profit_ratio_new[pd.isna(profit_ratio_new)].index
profit_ratio_new[nan_index] = profit_ratio_old[nan_index]
nav_net_amount_df[amount_name + "_profit_ratio"] = profit_ratio_new
# price = nav_net_amount_df[amount_name].dropna()
# profit = price.diff().fillna(Decimal(0))
# profit_ratio_new = profit / price.shift(1)
# profit_ratio_old = nav_net_amount_df[amount_name+"_profit_ratio"]
# nan_index = profit_ratio_new[pd.isna(profit_ratio_new)].index
# profit_ratio_new[nan_index] = profit_ratio_old[nan_index]
#
# nav_net_amount_df[amount_name + "_profit_ratio"] = profit_ratio_new
nav_net_amount_df[amount_name+"_amount_ratio"] = nav_net_amount_df[amount_name+"_net_amount"]/(nav_net_amount_df["sum_net_amount"])
fund_profit_ratio = nav_net_amount_df[amount_name + "_profit_ratio"].dropna() + 1
amount_ratio_shift = nav_net_amount_df[amount_name + "_amount_ratio"].shift(1)
num_va = len(amount_ratio_shift[amount_ratio_shift.values==0])
num_va = len(amount_ratio_shift[amount_ratio_shift.values == 0])
if num_va+1 >= len(amount_ratio_shift):
amount_ratio_shift.iloc[num_va] = 0
else:
amount_ratio_shift.iloc[num_va] = amount_ratio_shift.values[num_va+1]
nav_net_amount_df[amount_name + "_profit_ratio_weight"] = amount_ratio_shift * nav_net_amount_df[amount_name + "_profit_ratio"]
nav_net_amount_df[amount_name + "_profit_ratio_weight"] = amount_ratio_shift * nav_net_amount_df[amount_name + "_profit_ratio"]
nav_net_amount_df[amount_name + "_profit_cum_ratio_weight"] = (fund_profit_ratio.cumprod()-1)*amount_ratio_shift # enter_date = nav_net_amount_df[amount_name+"_profit_ratio"].dropna()
fund_id_list_profit_ratio_weight = [i + "_profit_ratio_weight" for i in fund_id_list]
......@@ -544,7 +541,7 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
cum_return_ratio_df.index = return_ratio.index
# 单个基金累计收益分解df
weight_name_list = [i + "_profit_cum_ratio_weight" for i in fund_id_list]
weight_name_list = [i + "_profit_cum_ratio_weight" for i in fund_id_list]
signal_fund_cum_weight = nav_net_amount_df[weight_name_list]
re_name = {x: x.replace("_profit_cum_ratio_weight", "") for x in weight_name_list}
signal_fund_cum_weight.rename(columns=re_name, inplace=True)
......
dict_substrategy = {
"-1": "其他策略",
"1010": '主观多头',
"1020": '股票多空',
"1030": '量化多头',
"2010": '宏观策略',
"3010": '主观趋势',
"3020": '主观套利',
"3030": '量化趋势',
"3040": '量化套利',
"3050": 'CTA策略',
"4010": '并购重组',
"4020": '定向增发',
"4030": '大宗交易',
"4040": '事件驱动复合',
"5010": '市场中性',
"5020": '套利策略',
"5030": '相对价值复合',
"6010": '纯债策略',
"6020": '强债策略',
"6030": '债券策略',
"7010": 'MOM',
"7020": 'FOF',
"8010": '主观多策略',
"8020": '量化多策略',
"A": "股票型",
"B": "混合型",
"C": "债券型",
"D": "货币基金",
"E": "QDII",
"F": "其他",
"J": "商品",
"K": "FOF",
"A01": "股票->积极投资股票型",
"A02": "股票->指数型",
"B01": "混合->灵活配置型",
"B02": "混合->积极配置型",
"B03": "混合->保守配置型",
"B04": "混合->保本型",
"B05": "混合->特定策略型",
"C01": "债券->纯债型",
"C02": "债券->一级债基",
"C03": "债券->二级债基",
"C04": "债券->理财债基",
"D01": "货币A",
"D02": "货币B",
"D03": "货币R",
"E01": "QDII->股票",
"E02": "QDII->混合",
"J01": "商品ETF",
"J02": "商品期货",
"J03": "商品ETF联接",
"A0101": "积极股票型",
"A0102": "稳健股票型",
"A0201": "纯指数型",
"A0202": "增强指数型",
"C0101": "债券->纯债型",
"C0102": "债券->指数型债券",
"C0103": "债券->债券ETF",
"C0104": "债券->债券ETF联接",
"C0105": "债券->增强型指数型债券",
"E0101": "QDII->股票被动型",
"E0102": "QDII->股票主动型",
"E0201": "QDII->混合",
"E0202": "QDII->债券",
"E0203": "QDII->商品",
"E0204": "QDII->FOF",
"E0205": "QDII->其他基金",
"A020101": "股票->股票ETF",
"A020102": "股票->股票ETF联接",
"A020103": "股票->纯指数型",
"E010101": "QDII->股票被动型",
"E010102": "QDII->股票被动型",
"E010103": "QDII->股票被动型",
"E010104": "QDII->股票被动型",
"E010201": "QDII->股票主动型",
"E010202": "QDII->股票主动型",
"E010203": "QDII->股票主动型",
"E010204": "QDII->股票主动型",
"E010205": "QDII->股票主动型",
"E010206": "QDII->股票主动型",
"E020101": "QDII->全球股债混合",
"E020102": "QDII->亚太股债混合",
"E020103": "QDII->大中华市场",
"E020104": "QDII->新兴股债混合",
"E020201": "QDII->债券主动型",
"E020202": "QDII->债券主动型",
"E020203": "QDII->债券主动型",
"E020204": "QDII->债券主动型",
"E020205": "QDII->债券被动型",
"E020206": "QDII->债券被动型",
"E020207": "QDII->债券被动型",
"E020301": "QDII->商品实物",
"E020302": "QDII->商品ETF",
"E020303": "QDII->商品主动股票"
}
def get_substrategy_name(sub):
try:
sub = int(sub)
code = str(sub)
strategy_name = dict_substrategy[code]
return strategy_name
except ValueError:
pass
try:
code = str(sub)
strategy_name = dict_substrategy[code]
return strategy_name
except:
return dict_substrategy["-1"]
......@@ -11,10 +11,10 @@ import calendar
import math
dict_substrategy = {1010: '主观多头', 1020: '股票多空', 1030: '量化多头', 2010: '宏观策略', 3010: '主观趋势', 3020: '主观套利',
3030: '量化趋势', 3040: '量化套利', 3050: 'CTA策略', 4010: '并购重组', 4020: '定向增发', 4030: '大宗交易',
4040: '事件驱动复合', 5010: '市场中性', 5020: '套利策略', 5030: '相对价值复合', 6010: '纯债策略', 6020: '强债策略',
6030: '债券策略', 7010: 'MOM', 7020: 'FOF', 8010: '主观多策略', 8020: '量化多策略', -1: '其他策略'}
# dict_substrategy = {1010: '主观多头', 1020: '股票多空', 1030: '量化多头', 2010: '宏观策略', 3010: '主观趋势', 3020: '主观套利',
# 3030: '量化趋势', 3040: '量化套利', 3050: 'CTA策略', 4010: '并购重组', 4020: '定向增发', 4030: '大宗交易',
# 4040: '事件驱动复合', 5010: '市场中性', 5020: '套利策略', 5030: '相对价值复合', 6010: '纯债策略', 6020: '强债策略',
# 6030: '债券策略', 7010: 'MOM', 7020: 'FOF', 8010: '主观多策略', 8020: '量化多策略', -1: '其他策略'}
BANK_RATE = 0.015
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment