Commit 4597d1de authored by 赵杰's avatar 赵杰

增加对应指数的结果数据

parent a7967f6b
......@@ -32,13 +32,14 @@ class UserCustomerDataAdaptor:
self.compare_index_id = index_id
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)
# 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(str(p_end_date))
# self.end_date = pd.to_datetime("2020-11-23")
p_start_date = datetime.date(year=p_end_date.year, month=p_end_date.month, day=1)
self.month_start_date = pd.to_datetime("2020-11-16")
self.month_start_date = p_start_date
# self.month_start_date = pd.to_datetime("2020-11-16")
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.get_customer_index_nav_data()
self.index_df = self.get_customer_index_nav_data()
self.total_customer_order_cnav_df = self.total_combine_data()
self.group_operate()
......@@ -129,6 +130,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.index_df = index_df
return index_df
......
......@@ -13,57 +13,12 @@ from decimal import Decimal
from app.service.data_service import UserCustomerDataAdaptor
from app.utils.week_evaluation import *
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
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):
total_result_data = {}
group_result_data = {}
def __init__(self, user_id, customer_id, end_date=str(datetime.date.today())):
# super().__init__()
super().__init__(user_id, customer_id, end_date)
# 组合结果数据
......@@ -157,6 +112,12 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
folio_report_data["group_nav_info"] = result_fund_nav_info
folio_report_data["group_hoding_info"] = result_fund_hoding_info
# 对应指数数据
index_df = self.get_customer_index_nav_data()
index_result = self.signal_fund_profit_result(index_df[index_df.index >= pd.to_datetime(first_trade_date)],
"index")
folio_report_data["index_result"] = index_result
self.group_result_data[folio] = folio_report_data
return self.group_result_data
......@@ -273,6 +234,11 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
cumulative_return = return_ratio_df["cum_return_ratio"].values[-1]
report_data["contribution_decomposition"] = float(cumulative_return)
# 对应指数数据
index_df = self.get_customer_index_nav_data()
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.total_result_data = report_data
return report_data
......@@ -362,8 +328,52 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
return cum_return_ratio_df
@staticmethod
def signal_fund_profit_result():
pass
def signal_fund_profit_result(p_fund_nav_df, cur_fund_id):
result = {"fund_id": cur_fund_id}
fund_nav_df = p_fund_nav_df.copy()
profit = fund_nav_df[cur_fund_id].dropna() - fund_nav_df[cur_fund_id].dropna().shift(1)
fund_nav_df[cur_fund_id + "_profit"] = profit
fund_nav_df[cur_fund_id + "_profit_ratio"] = profit / fund_nav_df[cur_fund_id].dropna().shift(1)
# 累积收益率
return_ratio_list = list(fund_nav_df[cur_fund_id + "_profit_ratio"].astype("float64").values)
cum_return_ratio = []
last_ratio = 0
for i in range(len(return_ratio_list)):
if i == 0:
last_ratio = 1 + return_ratio_list[i] if str(return_ratio_list[0]) != 'nan' else 1
cum_return_ratio.append(last_ratio)
continue
cur_ratio = (1 + return_ratio_list[i]) * last_ratio
cum_return_ratio.append(cur_ratio)
last_ratio = cur_ratio
fund_nav_df['cum_return_ratio'] = cum_return_ratio
# 区间收益率
result["return_ratio"] = cum_return_ratio[-1]
# 区间年化收益
n_freq = freq_days(1)
return_ratio_year = annual_return((fund_nav_df["cum_return_ratio"].values[-1] - 1), fund_nav_df, n_freq)
result["return_ratio_year"] = float(return_ratio_year)
# 波动率
volatility_ = volatility(fund_nav_df["cum_return_ratio"], n_freq)
result["volatility"] = float(volatility_)
# 最大回撤
drawdown = max_drawdown(fund_nav_df["cum_return_ratio"])
result["max_drawdown"] = drawdown
# 夏普比率
sim = simple_return(fund_nav_df["cum_return_ratio"])
exc = excess_return(sim, BANK_RATE, n_freq)
sharpe = sharpe_ratio(exc, sim, n_freq)
result["sharpe"] = float(sharpe)
return result
def get_month_return_chart(self):
res = self.total_result_data["month_return"]
......@@ -378,3 +388,5 @@ class UserCustomerResultAdaptor(UserCustomerDataAdaptor):
def get_total_basic_data(self):
return self.total_result_data
def get_group_data(self):
return self.group_result_data
......@@ -14,7 +14,7 @@ from matplotlib.ticker import FuncFormatter
from matplotlib.font_manager import FontProperties
# 中文字体初始化
plt.rcParams['font.sans-serif']=['Heiti TC']
plt.rcParams['font.sans-serif']=['SimSun']
def to_percent(temp, position):
......@@ -31,7 +31,7 @@ def draw_month_return_chart(xlabels, product_list, cumulative):
fontsize = 20
# 初始化
fig = plt.figure(figsize=figsize)
ax1 = fig.add_subplot()
ax1 = fig.add_subplot(111)
ax2 = ax1.twinx()
max_x_count = max([x['data'].size for x in product_list])
loc = np.arange(max_x_count) # the x locations for the groups
......
......@@ -11,6 +11,13 @@ 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: '其他策略'}
BANK_RATE = 0.015
def simple_return(net_worth):
"""
简单收益率
......@@ -273,3 +280,42 @@ def freq_days(fav_freq):
else:
N = 250 # 没有设置freq默认是天更
return N
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
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