Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Sign in
Toggle navigation
F
fund_report
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
彭熊
fund_report
Commits
4597d1de
Commit
4597d1de
authored
Nov 27, 2020
by
赵杰
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
增加对应指数的结果数据
parent
a7967f6b
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
114 additions
and
54 deletions
+114
-54
data_service.py
app/service/data_service.py
+6
-4
result_service.py
app/service/result_service.py
+59
-47
draw.py
app/utils/draw.py
+2
-2
week_evaluation.py
app/utils/week_evaluation.py
+47
-1
No files found.
app/service/data_service.py
View file @
4597d1de
...
...
@@ -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
...
...
app/service/result_service.py
View file @
4597d1de
...
...
@@ -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
app/utils/draw.py
View file @
4597d1de
...
...
@@ -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
...
...
app/utils/week_evaluation.py
View file @
4597d1de
...
...
@@ -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
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment