Commit 745c54cb authored by pengxiong@wealthgrow.cn's avatar pengxiong@wealthgrow.cn

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

parents 1f273295 ab92ee39
This diff is collapsed.
...@@ -9,18 +9,144 @@ ...@@ -9,18 +9,144 @@
import pandas as pd import pandas as pd
import numpy as np import numpy as np
import datetime import datetime
from decimal import Decimal
from app.service.data_service import UserCustomerDataAdaptor from app.service.data_service import UserCustomerDataAdaptor
from app.utils.week_evaluation import *
def resample(df, trading_cal, freq):
"""对基金净值表进行粒度不同的重采样,并剔除不在交易日中的结果
Args:
df ([DataFrame]): [原始基金净值表]
trading_cal ([type]): [上交所交易日表]
freq ([type]): [重采样频率: 1:工作日,2:周, 3:月, 4:半月, 5:季度]
Returns:
[DataFrame]: [重采样后剔除不在交易日历中的净值表和交易日历以净值日期为索引的合表]
"""
freq_dict = {1: 'B', 2: 'W-FRI', 3: 'M', 4: 'SM', 5: 'Q'}
resample_freq = freq_dict[freq]
# 按采样频率进行重采样并进行净值的前向填充
df = df.resample(rule=resample_freq).ffill()
# 根据采样频率确定最大日期偏移量(保证偏移后的日期与重采样的日期在同一周,同一月,同一季度等)
timeoffset_dict = {1: 1, 2: 5, 3: 30, 4: 15, 5: 120}
timeoffetmax = timeoffset_dict[freq]
# Dataframe不允许直接修改index,新建一份index的复制并转为list
new_index = list(df.index)
# 遍历重采样后的日期
for idx, date in enumerate(df.index):
# 如果重采样后的日期不在交易日历中
if date not in trading_cal.index:
# 对重采样后的日期进行偏移
for time_offset in range(1, timeoffetmax):
# 如果偏移后的日期在交易日历中,保留偏移后的日期
if date - datetime.timedelta(days=time_offset) in trading_cal.index:
new_index[idx] = date - datetime.timedelta(days=time_offset)
# 任意一天满足立即退出循环
break
# 更改净值表的日期索引为重采样后且在交易日内的日期
df.index = pd.Series(new_index)
return df
class UserCustomerResultAdaptor(UserCustomerDataAdaptor): class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
total_result_data = {}
group_result_data = []
def __init__(self, user_id, customer_id, end_date=str(datetime.date.today())): def __init__(self, user_id, customer_id, end_date=str(datetime.date.today())):
UserCustomerDataAdaptor.__init__(user_id, customer_id, end_date) # super().__init__()
super().__init__(user_id, customer_id, end_date)
# 综述数据 # 综述数据
def get_total_data(self): def get_total_data(self):
for folio in self.group_data.keys():
# self.group_result_data.append({folio: {}})
cur_folio_result_cnav_data = self.group_data[folio]["result_cnav_data"]
cur_folio_order_data = self.group_data[folio]["order_df"]
fund_id_list = list(cur_folio_order_data["fund_id"].unique())
fund_id_list_earn = [i + "_earn" for i in fund_id_list]
fund_id_list_amount = [i + "_amount" for i in fund_id_list]
profit_df = cur_folio_result_cnav_data[fund_id_list_earn]
resample_df = resample(cur_folio_result_cnav_data, self.trade_cal, 2)
# 组合收益率
return_ratio_serise = self.combination_yield(cur_folio_result_cnav_data, fund_id_list)
# 总成本
total_cost = float(cur_folio_order_data[cur_folio_order_data["order_type"] == 1]["confirm_amount"].sum() - \
cur_folio_order_data[cur_folio_order_data["order_type"] == 2]["confirm_amount"].sum())
# 累积盈利
cumulative_profit = profit_df.sum().sum()
# 年化收益
return_ratio_year = 0
"""*************************年化收益*******************************"""
# 期末资产
ending_assets = cumulative_profit + total_cost
# 本月收益
cur_month_profit_df = profit_df.loc[self.month_start_date:self.end_date+datetime.timedelta(days=1), fund_id_list_earn]
cur_month_profit = cur_month_profit_df.sum().sum()
# 本月累积收益率
cur_month_profit_ratio = return_ratio_serise.loc[self.month_start_date:].sum()
# 今年累积收益
cur_year_date = pd.to_datetime(str(datetime.date(year=self.end_date.year, month=1, day=1)))
cur_year_profit_df = profit_df.loc[cur_year_date:self.end_date + datetime.timedelta(days=1), fund_id_list_earn]
cur_year_profit = cur_year_profit_df.sum().sum()
# 今年累积收益率
cur_year_profit_ratio = return_ratio_serise.loc[cur_year_date:]
# 月度回报
def year_month(x):
a = x.year
b = x.month
return str(a) + "/" + str(b)
profit_df_cp = profit_df.copy()
profit_df_cp["date"] = profit_df_cp.index
grouped = profit_df_cp.groupby(profit_df_cp["date"].apply(year_month))
sum_group = grouped.agg(np.sum)
month_sum = sum_group.sum(axis=1)
# 累积收益率
profit_df_cp["cumulative_return"] = return_ratio_serise.cumsum()
grouped_cumulative = profit_df_cp["cumulative_return"].groupby(profit_df_cp["date"].apply(year_month))
month_cumulative_return = grouped_cumulative.last()
# 单个组合基金净值数据
def signal_fund_info_data(self, p_fund_id_list, p_order_df):
pass pass
# 组合数据
# 组合数据
def get_group_data(self): def get_group_data(self):
pass pass
def performance_reward(self, order_info, ):
pass
@staticmethod
def combination_yield(p_combina_df, fund_id_list):
fund_id_list_amount = [i + "_amount" for i in fund_id_list]
fund_id_list_profit_ratio = [i + "_profit_ratio" for i in fund_id_list]
nav_amount_df = p_combina_df[fund_id_list + fund_id_list_amount+fund_id_list_profit_ratio].copy()
nav_amount_df["sum_amount"] = nav_amount_df[fund_id_list_amount].sum(axis=1).apply(lambda x: Decimal.from_float(x))
for amount_name in fund_id_list:
nav_amount_df[amount_name+"_amount_ratio"] = nav_amount_df[amount_name+"_amount"]/nav_amount_df["sum_amount"]
nav_amount_df[amount_name+"_profit_ratio_weight"] = nav_amount_df[amount_name+"_amount_ratio"] * nav_amount_df[amount_name+"_profit_ratio"]
fund_id_list_profit_ratio_weight = [i + "_profit_ratio_weight" for i in fund_id_list]
nav_profit_ratio_weight = nav_amount_df[fund_id_list_profit_ratio_weight].copy().fillna(method='ffill')
# 收益率
return_ratio = nav_profit_ratio_weight.sum(axis=1)
return return_ratio
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