Commit b4c95f2e authored by 李宗熹's avatar 李宗熹

Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	app/service/portfolio_diagnose.py
parents e6e5d8e8 82206f51
...@@ -35,10 +35,10 @@ class UserCustomerDataAdaptor: ...@@ -35,10 +35,10 @@ class UserCustomerDataAdaptor:
p_end_date = pd.to_datetime(end_date).date() p_end_date = pd.to_datetime(end_date).date()
p_end_date = datetime.date(year=p_end_date.year, month=p_end_date.month, day=1) - datetime.timedelta(days=1) p_end_date = datetime.date(year=p_end_date.year, month=p_end_date.month, day=1) - datetime.timedelta(days=1)
self.end_date = pd.to_datetime(str(p_end_date)) self.end_date = pd.to_datetime(str(p_end_date))
# self.end_date = pd.to_datetime("2020-11-23") # self.end_date = pd.to_datetime("2020-12-04")
p_start_date = datetime.date(year=p_end_date.year, month=p_end_date.month, day=1) p_start_date = datetime.date(year=p_end_date.year, month=p_end_date.month, day=1)
self.month_start_date = p_start_date self.month_start_date = p_start_date
# self.month_start_date = pd.to_datetime("2020-11-16") # self.month_start_date = pd.to_datetime("2020-11-01")
self.user_customer_order_df = self.get_user_customer_order_data() self.user_customer_order_df = self.get_user_customer_order_data()
self.fund_nav_total, self.fund_cnav_total = self.get_customer_fund_nav_data() self.fund_nav_total, self.fund_cnav_total = self.get_customer_fund_nav_data()
self.index_df = self.get_customer_index_nav_data() self.index_df = self.get_customer_index_nav_data()
...@@ -68,10 +68,10 @@ class UserCustomerDataAdaptor: ...@@ -68,10 +68,10 @@ class UserCustomerDataAdaptor:
with TAMP_SQL(tamp_user_engine) as tamp_user, TAMP_SQL(tamp_product_engine) as tamp_product: with TAMP_SQL(tamp_user_engine) as tamp_user, TAMP_SQL(tamp_product_engine) as tamp_product:
tamp_user_session = tamp_user.session tamp_user_session = tamp_user.session
tamp_product_session = tamp_product.session tamp_product_session = tamp_product.session
sql_user = """select f2.realname,f3.customer_name,fund_id,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 customer_order f1, user_info f2,customer_info f3 where f2.id=f1.user_id and f3.id=f1.customer_id and f1.user_id='{}' and f1.customer_id='{}'""".format(self.user_id, self.customer_id) sql_user = """select f1.id, f2.realname,f3.customer_name,fund_id,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 customer_order f1, user_info f2,customer_info f3 where f2.id=f1.user_id and f3.id=f1.customer_id and f1.user_id='{}' and f1.customer_id='{}'""".format(self.user_id, self.customer_id)
cur = tamp_user_session.execute(sql_user) cur = tamp_user_session.execute(sql_user)
data = cur.fetchall() data = cur.fetchall()
order_df = pd.DataFrame(list(data), columns=['username', 'customer_name', 'fund_id', 'order_type', 'pay_date', order_df = pd.DataFrame(list(data), columns=['order_id', 'username', 'customer_name', 'fund_id', 'order_type', 'pay_date',
'subscription_fee', 'confirm_share_date', 'confirm_share', 'subscription_fee', 'confirm_share_date', 'confirm_share',
'confirm_amount', 'nav', 'folio_name']) 'confirm_amount', 'nav', 'folio_name'])
...@@ -122,7 +122,7 @@ class UserCustomerDataAdaptor: ...@@ -122,7 +122,7 @@ class UserCustomerDataAdaptor:
cur_fund_nav_df["price_date"] = pd.to_datetime(cur_fund_nav_df["price_date"]) cur_fund_nav_df["price_date"] = pd.to_datetime(cur_fund_nav_df["price_date"])
cur_fund_nav_df.drop_duplicates(subset="price_date", keep='first', inplace=True) cur_fund_nav_df.drop_duplicates(subset="price_date", keep='first', inplace=True)
cur_fund_nav_df.set_index("price_date", inplace=True) cur_fund_nav_df.set_index("price_date", inplace=True)
cur_fund_nav_df = cur_fund_nav_df[cur_fund_nav_df.index.isin(all_fund_nav.index & cur_fund_nav_df.index)] cur_fund_nav_df = cur_fund_nav_df[cur_fund_nav_df.index.isin(all_fund_nav.index)]
all_fund_nav[cur_fund_id] = cur_fund_nav_df["nav"] all_fund_nav[cur_fund_id] = cur_fund_nav_df["nav"]
all_fund_cnav[cur_fund_id] = cur_fund_nav_df["cnav"] all_fund_cnav[cur_fund_id] = cur_fund_nav_df["cnav"]
...@@ -186,6 +186,12 @@ class UserCustomerDataAdaptor: ...@@ -186,6 +186,12 @@ class UserCustomerDataAdaptor:
diff_nav = row["nav"] - last_nav_data.values[0] diff_nav = row["nav"] - last_nav_data.values[0]
cur_cnav = last_cnav_data.values[0] + diff_nav cur_cnav = last_cnav_data.values[0] + diff_nav
cnav_df.loc[confirm_share_date, cur_fund_id] = cur_cnav cnav_df.loc[confirm_share_date, cur_fund_id] = cur_cnav
else:
confirm_date_nav_data = p_nav_df[p_nav_df.index == confirm_share_date][cur_fund_id].tail(1)
confirm_date_cnav_data = p_cnav_df[p_cnav_df.index == confirm_share_date][cur_fund_id].tail(1)
diff_nav = row["nav"] - confirm_date_nav_data.values[0]
cur_cnav = confirm_date_cnav_data.values[0] + diff_nav
cnav_df.loc[confirm_share_date, cur_fund_id] = cur_cnav
cnav_df = cnav_df.dropna(axis=0, how="all").fillna(method='ffill') 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_order_df.iterrows():
...@@ -237,6 +243,8 @@ class UserCustomerDataAdaptor: ...@@ -237,6 +243,8 @@ class UserCustomerDataAdaptor:
cnav_df[p_fund_id_ + "_cum_earn"] = cnav_df[p_fund_id_ + "_earn"].cumsum().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_ + "_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_ + "_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} self.group_data[p_folio] = {"result_cnav_data": cnav_df, "order_df": p_order_df}
return cnav_df return cnav_df
...@@ -273,6 +281,12 @@ class UserCustomerDataAdaptor: ...@@ -273,6 +281,12 @@ class UserCustomerDataAdaptor:
diff_nav = row["nav"] - last_nav_data.values[0] diff_nav = row["nav"] - last_nav_data.values[0]
cur_cnav = last_cnav_data.values[0] + diff_nav cur_cnav = last_cnav_data.values[0] + diff_nav
cnav_df.loc[confirm_share_date, cur_fund_id] = cur_cnav cnav_df.loc[confirm_share_date, cur_fund_id] = cur_cnav
else:
confirm_date_nav_data = p_nav_df[p_nav_df.index == confirm_share_date][cur_fund_id].tail(1)
confirm_date_cnav_data = p_cnav_df[p_cnav_df.index == confirm_share_date][cur_fund_id].tail(1)
diff_nav = row["nav"] - confirm_date_nav_data.values[0]
cur_cnav = confirm_date_cnav_data.values[0] + diff_nav
cnav_df.loc[confirm_share_date, cur_fund_id] = cur_cnav
cnav_df = cnav_df.dropna(axis=0, how="all").fillna(method='ffill') 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_order_df.iterrows():
...@@ -314,5 +328,8 @@ class UserCustomerDataAdaptor: ...@@ -314,5 +328,8 @@ class UserCustomerDataAdaptor:
# cnav_df[p_fund_id_ + "_earn"] = cnav_df[p_fund_id_ + "_earn"].apply(lambda x: float(x)) # 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_ + "_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_ + "_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_] # cnav_df[p_fund_id_ + "_net_amount"] = cnav_df[p_fund_id_ + "_share"] * cnav_df[p_fund_id_]
return cnav_df return cnav_df
...@@ -139,7 +139,6 @@ def choose_bad_evaluation(evaluation): ...@@ -139,7 +139,6 @@ def choose_bad_evaluation(evaluation):
if v1[0] < 2: if v1[0] < 2:
del evaluation[1] del evaluation[1]
if v2[0] < 2: if v2[0] < 2:
# if v2:
del evaluation[2] del evaluation[2]
if v3[0] < 2: if v3[0] < 2:
del evaluation[3] del evaluation[3]
...@@ -473,7 +472,7 @@ class PortfolioDiagnose(object): ...@@ -473,7 +472,7 @@ class PortfolioDiagnose(object):
elif np.any(self.old_correlation[fund] > 0.8): elif np.any(self.old_correlation[fund] > 0.8):
self.abandon_fund_corr.append(fund) self.abandon_fund_corr.append(fund)
prod.drop(self.abandon_fund_score + self.abandon_fund_corr, axis=1, inplace=True) prod = prod.drop(self.abandon_fund_score + self.abandon_fund_corr, axis=1)
self.old_correlation = self.old_correlation.fillna(1).round(2) self.old_correlation = self.old_correlation.fillna(1).round(2)
self.old_correlation.columns = self.old_correlation.columns.map(lambda x: get_fund_name(x).values[0][0]) self.old_correlation.columns = self.old_correlation.columns.map(lambda x: get_fund_name(x).values[0][0])
self.old_correlation.index = self.old_correlation.index.map(lambda x: get_fund_name(x).values[0][0]) self.old_correlation.index = self.old_correlation.index.map(lambda x: get_fund_name(x).values[0][0])
...@@ -488,6 +487,8 @@ class PortfolioDiagnose(object): ...@@ -488,6 +487,8 @@ class PortfolioDiagnose(object):
Returns: 增加建议申购基金的组合净值表 Returns: 增加建议申购基金的组合净值表
""" """
# 组合内已包含的策略
# included_strategy = set()
# 按每种基金最少投资100w确定组合包含的最大基金数量 # 按每种基金最少投资100w确定组合包含的最大基金数量
max_len = len(self.portfolio) - len(prod.columns) max_len = len(self.portfolio) - len(prod.columns)
...@@ -778,11 +779,9 @@ class PortfolioDiagnose(object): ...@@ -778,11 +779,9 @@ class PortfolioDiagnose(object):
# 基金名称,策略分级 # 基金名称,策略分级
propose_fund_id_name_list = [propose_fund_df[propose_fund_df["fund_id"] == fund_id]["fund_name"].values[0] for 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] fund_id in propose_fund_id_list]
propose_fund_id_strategy_name_list = [ propose_fund_id_strategy_name_list = [dict_substrategy[int(propose_fund_df[propose_fund_df["fund_id"] == fund_id]["substrategy"].values[0])] for
dict_substrategy[int(propose_fund_df[propose_fund_df["fund_id"] == fund_id]["substrategy"].values[0])] for
fund_id in propose_fund_id_list] fund_id in propose_fund_id_list]
propose_fund_asset = [round(self.new_weights[i] * total_asset, 2) for i in propose_fund_asset = [round(self.new_weights[i] * total_asset, 2) for i in range(len(propose_fund_id_name_list))]
range(len(propose_fund_id_name_list))]
propose_info = {propose_fund_id_strategy_name_list[i]: propose_info = {propose_fund_id_strategy_name_list[i]:
{"fund_name": propose_fund_id_name_list[i], {"fund_name": propose_fund_id_name_list[i],
...@@ -824,25 +823,23 @@ class PortfolioDiagnose(object): ...@@ -824,25 +823,23 @@ class PortfolioDiagnose(object):
# 新组合累积收益df # 新组合累积收益df
propose_fund_return_limit_data = propose_fund_return[propose_fund_return.index >= group_order_start_date] propose_fund_return_limit_data = propose_fund_return[propose_fund_return.index >= group_order_start_date]
start_return = propose_fund_return_limit_data['return'].values[0] start_return = propose_fund_return_limit_data['return'].values[0]
propose_fund_return_limit_data["new_return"] = (propose_fund_return_limit_data["return"] - start_return) / ( propose_fund_return_limit_data["new_return"] = (propose_fund_return_limit_data["return"] - start_return)/(1+start_return)
1 + start_return)
# 新组合累积收益 # 新组合累积收益
new_return_ratio = propose_fund_return_limit_data["new_return"].values[-1] new_return_ratio = propose_fund_return_limit_data["new_return"].values[-1]
# 新组合区间年化收益率 # 新组合区间年化收益率
freq_max = group_order_df["freq"].max() freq_max = group_order_df["freq"].max()
n_freq = freq_days(int(freq_max)) n_freq = freq_days(int(freq_max))
new_return_ratio_year = annual_return(new_return_ratio, propose_fund_return_limit_data, n_freq) new_return_ratio_year = annual_return(propose_fund_return_limit_data["new_return"].values[-1], propose_fund_return_limit_data, n_freq)
# 新组合波动率 # 新组合波动率
new_volatility = volatility(propose_fund_return_limit_data["new_return"] + 1, n_freq) new_volatility = volatility(propose_fund_return_limit_data["new_return"]+1, n_freq)
# 新组合最大回撤 # 新组合最大回撤
new_drawdown = max_drawdown(propose_fund_return_limit_data["new_return"] + 1) new_drawdown = max_drawdown(propose_fund_return_limit_data["new_return"]+1)
# 新组合夏普比率 # 新组合夏普比率
sim = simple_return(propose_fund_return_limit_data["new_return"] + 1) sim = simple_return(propose_fund_return_limit_data["new_return"]+1)
exc = excess_return(sim, BANK_RATE, n_freq) exc = excess_return(sim, BANK_RATE, n_freq)
new_sharpe = sharpe_ratio(exc, sim, n_freq) new_sharpe = sharpe_ratio(exc, sim, n_freq)
...@@ -851,23 +848,21 @@ class PortfolioDiagnose(object): ...@@ -851,23 +848,21 @@ class PortfolioDiagnose(object):
start_index_return = index_return[" close"].values[0] start_index_return = index_return[" close"].values[0]
index_return["new_index_return"] = (index_return[" close"] - start_index_return) / (1 + start_index_return) index_return["new_index_return"] = (index_return[" close"] - start_index_return) / (1 + start_index_return)
index_return_ratio = index_return["new_index_return"].values[-1] index_return_ratio = index_return["new_index_return"].values[-1]
index_return_ratio_year = annual_return(index_return["new_index_return"].values[-1], index_return_ratio_year = annual_return(index_return["new_index_return"].values[-1], index_return["new_index_return"], n_freq)
index_return["new_index_return"], n_freq) index_volatility = volatility(index_return["new_index_return"]+1, n_freq)
index_volatility = volatility(index_return["new_index_return"] + 1, n_freq) index_drawdown = max_drawdown(index_return["new_index_return"]+1)
index_drawdown = max_drawdown(index_return["new_index_return"] + 1) index_sim = simple_return(propose_fund_return_limit_data["new_return"]+1)
index_sim = simple_return(propose_fund_return_limit_data["new_return"] + 1)
index_exc = excess_return(index_sim, BANK_RATE, n_freq) index_exc = excess_return(index_sim, BANK_RATE, n_freq)
index_sharpe = sharpe_ratio(index_exc, index_sim, n_freq) index_sharpe = sharpe_ratio(index_exc, index_sim, n_freq)
# 收益对比数据 # 收益对比数据
return_compare_df = pd.merge(index_return[["new_index_return"]], old_return_df[["cum_return_ratio"]], return_compare_df = pd.merge(index_return[["new_index_return"]], old_return_df[["cum_return_ratio"]], right_index=True,
right_index=True,
left_index=True) left_index=True)
return_compare_df = pd.merge(return_compare_df, propose_fund_return_limit_data["new_return"], right_index=True, return_compare_df = pd.merge(return_compare_df, propose_fund_return_limit_data["new_return"], right_index=True,
left_index=True) left_index=True)
return_compare_df["date"] = return_compare_df.index return_compare_df["date"] = return_compare_df.index
return_compare_df["date"] = return_compare_df["date"].apply(lambda x: x.strftime("%Y-%m-%d")) return_compare_df["date"] = return_compare_df["date"].apply(lambda x: x.strftime("%Y-%m-%d"))
return_compare_df.iloc[1:-1, :]["date"] = "" return_compare_df.iloc[1:-1,:]["date"] = ""
return_compare_result = { return_compare_result = {
"new_combination": {"name": "新组合", "data": return_compare_df["new_return"].values}, "new_combination": {"name": "新组合", "data": return_compare_df["new_return"].values},
"index": {"name": "中证500", "data": return_compare_df["new_index_return"].values}, "index": {"name": "中证500", "data": return_compare_df["new_index_return"].values},
...@@ -876,20 +871,15 @@ class PortfolioDiagnose(object): ...@@ -876,20 +871,15 @@ class PortfolioDiagnose(object):
} }
# 指标对比 # 指标对比
old_indicator = {"group_name": "现有持仓组合", "return_ratio": round((old_return - 1) * 100, 2), old_indicator = {"group_name": "现有持仓组合", "return_ratio": round((old_return-1)*100, 2), "return_ratio_year": round(old_return_ratio_year*100,2),
"return_ratio_year": round(old_return_ratio_year * 100, 2), "volatility": round(old_volatility*100, 2), "max_drawdown": round(old_max_drawdown[0]*100, 2), "sharpe": round(old_sharpe, 2)}
"volatility": round(old_volatility * 100, 2), new_indicator = {"group_name": "建议优化组合", "return_ratio": round(new_return_ratio*100, 2), "return_ratio_year": round(new_return_ratio_year*100, 2),
"max_drawdown": round(old_max_drawdown[0] * 100, 2), "sharpe": round(old_sharpe, 2)} "volatility": round(new_volatility*100, 2), "max_drawdown": round(new_drawdown[0]*100, 2), "sharpe": round(new_sharpe, 2)}
new_indicator = {"group_name": "建议优化组合", "return_ratio": round(new_return_ratio * 100, 2), index_indicator = {"group_name": "中证500", "return_ratio": round(index_return_ratio*100, 2), "return_ratio_year": round(index_return_ratio_year*100, 2),
"return_ratio_year": round(new_return_ratio_year * 100, 2), "volatility": round(index_volatility*100, 2), "max_drawdown": round(index_drawdown[0]*100, 2), "sharpe": round(index_sharpe, 2)}
"volatility": round(new_volatility * 100, 2), "max_drawdown": round(new_drawdown[0] * 100, 2),
"sharpe": round(new_sharpe, 2)}
index_indicator = {"group_name": "中证500", "return_ratio": round(index_return_ratio * 100, 2),
"return_ratio_year": round(index_return_ratio_year * 100, 2),
"volatility": round(index_volatility * 100, 2),
"max_drawdown": round(index_drawdown[0] * 100, 2), "sharpe": round(index_sharpe, 2)}
indicator_compare = [new_indicator, old_indicator, index_indicator] indicator_compare = [new_indicator, old_indicator, index_indicator]
# 在保留{}的基础上,建议赎回{},并增配{}后,整体组合波动率大幅降低,最大回撤从{}降到不足{},年化收益率提升{}个点 # 在保留{}的基础上,建议赎回{},并增配{}后,整体组合波动率大幅降低,最大回撤从{}降到不足{},年化收益率提升{}个点
hold_fund = set(self.portfolio) - set(self.abandon_fund_score + self.abandon_fund_corr + self.no_data_fund) hold_fund = set(self.portfolio) - set(self.abandon_fund_score + self.abandon_fund_corr + self.no_data_fund)
hold_fund_name = [get_fund_name(x).values[0][0] for x in hold_fund] hold_fund_name = [get_fund_name(x).values[0][0] for x in hold_fund]
...@@ -1076,13 +1066,14 @@ class PortfolioDiagnose(object): ...@@ -1076,13 +1066,14 @@ class PortfolioDiagnose(object):
radar_data.append(get_radar_data(fund)) radar_data.append(get_radar_data(fund))
return radar_data return radar_data
#
# test_portfolio = ['HF00002JJ2', 'HF00005DBQ', 'HF0000681Q', 'HF00006693', 'HF00006AZF', 'HF00006BGS'] # portfolio = ['HF00002JJ2', 'HF00005DBQ', 'HF0000681Q', 'HF00006693', 'HF00006AZF', 'HF00006BGS']
# portfolio_diagnose = PortfolioDiagnose(client_type=3, portfolio=test_portfolio, invest_amount=10000000) # portfolio_diagnose = PortfolioDiagnose(client_type=1, portfolio=portfolio, invest_amount=10000000)
# portfolio_diagnose.optimize() # portfolio_diagnose.optimize()
# if __name__ == '__main__': # if __name__ == '__main__':
# print(portfolio_diagnose.single_fund_radar()) # print(portfolio_diagnose.single_fund_radar())
# print(portfolio_diagnose.propose_fund_radar()) # print(portfolio_diagnose.propose_fund_radar())
# print(portfolio_diagnose.old_portfolio_evaluation())
# print('旧组合相关性:', portfolio_diagnose.old_correlation) # print('旧组合相关性:', portfolio_diagnose.old_correlation)
# print('新组合相关性:', portfolio_diagnose.new_correlation) # print('新组合相关性:', portfolio_diagnose.new_correlation)
# print('旧组合个基评价:', portfolio_diagnose.old_portfolio_evaluation()) # print('旧组合个基评价:', portfolio_diagnose.old_portfolio_evaluation())
......
...@@ -402,11 +402,21 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor): ...@@ -402,11 +402,21 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
# nav_net_amount_df = resample(return_ratio_df, self.trade_cal_date, freq_max) # 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)) 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: 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
nav_net_amount_df[amount_name+"_amount_ratio"] = nav_net_amount_df[amount_name+"_net_amount"]/(nav_net_amount_df["sum_net_amount"]) nav_net_amount_df[amount_name+"_amount_ratio"] = nav_net_amount_df[amount_name+"_net_amount"]/(nav_net_amount_df["sum_net_amount"])
nav_net_amount_df[amount_name+"_profit_ratio_weight"] = nav_net_amount_df[amount_name+"_amount_ratio"].shift(1) * nav_net_amount_df[amount_name+"_profit_ratio"]
fund_profit_ratio = nav_net_amount_df[amount_name + "_profit_ratio"].dropna() + 1 fund_profit_ratio = nav_net_amount_df[amount_name + "_profit_ratio"].dropna() + 1
nav_net_amount_df[amount_name + "_profit_cum_ratio_weight"] = (fund_profit_ratio.cumprod()-1)*nav_net_amount_df[amount_name+"_amount_ratio"].shift(1) amount_ratio_shift = nav_net_amount_df[amount_name + "_amount_ratio"].shift(1)
# enter_date = nav_net_amount_df[amount_name+"_profit_ratio"].dropna() num_va = len(amount_ratio_shift[amount_ratio_shift.values==0])
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_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] fund_id_list_profit_ratio_weight = [i + "_profit_ratio_weight" for i in fund_id_list]
nav_profit_ratio_weight = nav_net_amount_df[fund_id_list_profit_ratio_weight].copy().fillna(method='ffill') nav_profit_ratio_weight = nav_net_amount_df[fund_id_list_profit_ratio_weight].copy().fillna(method='ffill')
......
...@@ -1037,27 +1037,55 @@ ...@@ -1037,27 +1037,55 @@
<table class="tss1_table"> <table class="tss1_table">
<tr> <tr>
<td> <td>
{%if month_rise>=0%}
本月涨幅:<span class="red">{{month_rise}}%</span> 本月涨幅:<span class="red">{{month_rise}}%</span>
{%else%}
本月涨幅:<span class="green">{{month_rise}}%</span>
{%endif%}
</td> </td>
<td> <td>
{%if now_month_income>=0%}
本月收益:<span class="red">{{now_month_income}}元</span>
{%else%}
本月收益:<span class="green">{{now_month_income}}元</span> 本月收益:<span class="green">{{now_month_income}}元</span>
{%endif%}
</td> </td>
<td> <td>
{%if year_totoal_rate_of_return>=0%}
今年累计收益率:<span class="red">{{year_totoal_rate_of_return}}%</span> 今年累计收益率:<span class="red">{{year_totoal_rate_of_return}}%</span>
{%else%}
今年累计收益率:<span class="green">{{year_totoal_rate_of_return}}%</span>
{%endif%}
</td> </td>
<td> <td>
{%if now_year_income>=0%}
今年累计收益:<span class="red">{{now_year_income}}元</span>
{%else%}
今年累计收益:<span class="green">{{now_year_income}}元</span> 今年累计收益:<span class="green">{{now_year_income}}元</span>
{%endif%}
</td> </td>
</tr> </tr>
<tr> <tr>
<td> <td>
{%if totoal_rate_of_return>=0%}
成立以来累计收益率:<span class="red">{{totoal_rate_of_return}}%</span> 成立以来累计收益率:<span class="red">{{totoal_rate_of_return}}%</span>
{%else%}
成立以来累计收益率:<span class="green">{{totoal_rate_of_return}}%</span>
{%endif%}
</td> </td>
<td> <td>
{%if now_annualised_return>=0%}
年化收益率:<span class="red">{{now_annualised_return}}%</span>
{%else%}
年化收益率:<span class="green">{{now_annualised_return}}%</span> 年化收益率:<span class="green">{{now_annualised_return}}%</span>
{%endif%}
</td> </td>
<td> <td>
{%if now_withdrawal>=0%}
最大回撤:<span class="red">{{now_withdrawal}}%</span> 最大回撤:<span class="red">{{now_withdrawal}}%</span>
{%else%}
最大回撤:<span class="green">{{now_withdrawal}}%</span>
{%endif%}
</td> </td>
<td> <td>
</td> </td>
...@@ -1076,10 +1104,20 @@ ...@@ -1076,10 +1104,20 @@
投资成本:<span class="red">{{now_allocation_amount}}元</span> 投资成本:<span class="red">{{now_allocation_amount}}元</span>
</td> </td>
<td> <td>
{%if final_balance>=now_allocation_amount%}
期末资产:<span class="red">{{final_balance}}元</span>
{%else%}
期末资产:<span class="green">{{final_balance}}元</span> 期末资产:<span class="green">{{final_balance}}元</span>
{%endif%}
</td> </td>
<td> <td>
{%if total_profit>=0%}
累计盈利:<span class="red">{{total_profit}}元</span> 累计盈利:<span class="red">{{total_profit}}元</span>
{%else%}
累计盈利:<span class="green">{{total_profit}}元</span>
{%endif%}
</td> </td>
<td> <td>
</td> </td>
...@@ -1296,7 +1334,7 @@ ...@@ -1296,7 +1334,7 @@
<th>目标最大回撤(%)</th> <th>目标最大回撤(%)</th>
</tr> </tr>
<tr> <tr>
<td>2000</td> <td>{{cost_of_investment}}</td>
<td>5%-10%</td> <td>5%-10%</td>
<td>5%-10%</td> <td>5%-10%</td>
</tr> </tr>
...@@ -1513,7 +1551,7 @@ ...@@ -1513,7 +1551,7 @@
<table border="1"> <table border="1">
<tr> <tr>
<th colspan="5">投资本金</th> <th colspan="5">投资本金</th>
<th colspan="4">10月业绩</th> <th colspan="4">{{month}}月业绩</th>
<th colspan="3">累计业绩</th> <th colspan="3">累计业绩</th>
</tr> </tr>
<tr> <tr>
......
...@@ -211,6 +211,7 @@ class DataIntegrate: ...@@ -211,6 +211,7 @@ class DataIntegrate:
'customer_name': self.customer_name, 'customer_name': self.customer_name,
'customer_gender': '女', 'customer_gender': '女',
'year_month': self.user_customer.month_start_date.strftime("%Y-%m"), 'year_month': self.user_customer.month_start_date.strftime("%Y-%m"),
'month': self.user_customer.month_start_date.strftime("%m"),
'start_date': self.user_customer.start_date.strftime("%Y-%m-%d"), 'start_date': self.user_customer.start_date.strftime("%Y-%m-%d"),
'ifa_company': '飞度工作室', 'ifa_company': '飞度工作室',
'title': '10月综述', 'title': '10月综述',
...@@ -273,5 +274,5 @@ class DataIntegrate: ...@@ -273,5 +274,5 @@ class DataIntegrate:
if __name__ == '__main__': if __name__ == '__main__':
start = time.time() start = time.time()
DataIntegrate() DataIntegrate(ifa_id='USER_INFO15916072577875', customer_id='6716613804966817792')
print('耗时{}秒'.format(round(time.time()-start, 2))) print('耗时{}秒'.format(round(time.time()-start, 2)))
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