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
68c1d166
Commit
68c1d166
authored
Dec 09, 2020
by
李宗熹
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修改objective
parent
9447fd90
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
88 additions
and
17 deletions
+88
-17
portfolio_diagnose.py
portfolio_diagnose.py
+88
-17
No files found.
portfolio_diagnose.py
View file @
68c1d166
...
...
@@ -335,7 +335,7 @@ tamp_fund = get_tamp_fund()
class
PortfolioDiagnose
(
object
):
def
__init__
(
self
,
client_type
,
portfolio
,
invest_amount
,
expect_return
=
0.1
5
,
def
__init__
(
self
,
client_type
,
portfolio
,
invest_amount
,
expect_return
=
0.1
,
expect_drawdown
=
0.15
,
index_id
=
'000905.SH'
,
invest_type
=
'private'
,
start_date
=
None
,
end_date
=
None
):
"""基金诊断
...
...
@@ -543,7 +543,7 @@ class PortfolioDiagnose(object):
else
:
prod
.
drop
(
columns
=
proposal
,
inplace
=
True
)
prod
.
bfill
(
inplace
=
True
)
prod
.
dropna
(
how
=
'all'
,
inplace
=
True
)
self
.
new_correlation
=
self
.
new_correlation
.
fillna
(
1
)
.
round
(
2
)
self
.
new_correlation
.
columns
=
self
.
new_correlation
.
columns
.
map
(
lambda
x
:
get_fund_name
(
x
)
.
values
[
0
][
0
])
self
.
new_correlation
.
index
=
self
.
new_correlation
.
index
.
map
(
lambda
x
:
get_fund_name
(
x
)
.
values
[
0
][
0
])
...
...
@@ -605,13 +605,12 @@ class PortfolioDiagnose(object):
try
:
ef
=
EfficientFrontier
(
mu
,
S
,
weight_bounds
=
[
w_low
,
1
],
expected_drawdown
=
dd
)
# ef = EfficientFrontier(mu, S, weight_bounds=[0, 1], expected_drawdown=dd)
#
ef.add_sector_constraints(propose_risk_mapper, risk_lower, risk_upper)
ef
.
add_sector_constraints
(
propose_risk_mapper
,
risk_lower
,
risk_upper
)
ef
.
efficient_return
(
target_return
=
self
.
expect_return
,
target_drawdown
=
self
.
expect_drawdown
)
clean_weights
=
ef
.
clean_weights
()
ef
.
portfolio_performance
(
verbose
=
True
)
self
.
new_weights
=
np
.
array
(
list
(
clean_weights
.
values
()))
except
Exception
as
e
:
print
(
e
)
except
:
self
.
new_weights
=
np
.
asarray
([
1
/
len
(
self
.
propose_portfolio
.
columns
)]
*
len
(
self
.
propose_portfolio
.
columns
))
print
(
self
.
new_weights
)
...
...
@@ -708,9 +707,12 @@ class PortfolioDiagnose(object):
# 覆盖的基金名称
strategy_name_evaluate
=
""
.
join
(
uniqe_strategy_name
)[:
-
1
]
if
len
(
uniqe_strategy
)
/
float
(
len
(
strategy_list
))
>
0.6
:
strategy_distribution_evaluate
=
"策略上有一定分散"
else
:
try
:
if
len
(
uniqe_strategy
)
/
float
(
len
(
strategy_list
))
>
0.6
:
strategy_distribution_evaluate
=
"策略上有一定分散"
else
:
strategy_distribution_evaluate
=
"策略分散程度不高"
except
ZeroDivisionError
:
strategy_distribution_evaluate
=
"策略分散程度不高"
# 相关性
if
len
(
self
.
abandon_fund_corr
)
>
0
:
...
...
@@ -750,7 +752,73 @@ class PortfolioDiagnose(object):
ret
=
[]
for
k
,
v
in
data
.
items
():
ret
.
append
(
sentence
[
k
]
.
format
(
*
data
[
k
])
.
replace
(
",;"
,
";"
))
return
ret
# 旧组合累积收益df
group_result_data
=
group_result
[
group_name
]
hold_info
=
group_result_data
[
"group_hoding_info"
]
hold_info_df
=
pd
.
DataFrame
(
hold_info
)
group_order_df
=
data_adaptor
.
user_customer_order_df
[
data_adaptor
.
user_customer_order_df
[
"folio_name"
]
==
group_name
]
group_order_start_date
=
pd
.
to_datetime
(
group_order_df
[
"confirm_share_date"
]
.
min
())
freq_max
=
group_order_df
[
"freq"
]
.
max
()
n_freq
=
freq_days
(
int
(
freq_max
))
old_return_df
=
group_result_data
[
"return_df"
]
old_return_df
[
"cum_return_ratio"
]
=
old_return_df
[
"cum_return_ratio"
]
-
1
# 原组合总市值, 区间收益, 年化收益, 波动率, 最大回撤, 夏普比率
total_asset
=
round
(
hold_info_df
[
"market_values"
]
.
sum
(),
2
)
old_return
=
group_result_data
[
"cumulative_return"
]
old_return_ratio_year
=
group_result_data
[
"return_ratio_year"
]
old_volatility
=
group_result_data
[
"volatility"
]
old_max_drawdown
=
group_result_data
[
"max_drawdown"
]
old_sharpe
=
group_result_data
[
"sharpe"
]
# 指数收益
index_data
=
get_index_daily
(
self
.
index_id
,
self
.
start_date
)
index_data
=
pd
.
merge
(
index_data
,
self
.
propose_portfolio
,
how
=
'inner'
,
left_index
=
True
,
right_index
=
True
)
index_return
=
index_data
.
iloc
[:,
:]
/
index_data
.
iloc
[
0
,
:]
-
1
# 指数收益
index_return
=
index_return
[
index_return
.
index
>=
group_order_start_date
]
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_ratio
=
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_volatility
=
volatility
(
index_return
[
"new_index_return"
]
+
1
,
n_freq
)
index_drawdown
=
max_drawdown
(
index_return
[
"new_index_return"
]
+
1
)
index_sim
=
simple_return
(
index_return
[
"new_index_return"
]
+
1
)
index_exc
=
excess_return
(
index_sim
,
BANK_RATE
,
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"
]],
right_index
=
True
,
left_index
=
True
)
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
.
iloc
[
1
:
-
1
,
:][
"date"
]
=
""
old_return_compare_result
=
{
"index"
:
{
"name"
:
"中证500"
,
"data"
:
return_compare_df
[
"new_index_return"
]
.
values
*
100
},
"origin_combination"
:
{
"name"
:
"原组合"
,
"data"
:
return_compare_df
[
"cum_return_ratio"
]
.
values
*
100
},
"xlabels"
:
return_compare_df
[
"date"
]
.
values
}
# 指标对比
old_indicator
=
{
"group_name"
:
"现有持仓组合"
,
"return_ratio"
:
round
((
old_return
-
1
)
*
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
)}
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
)}
old_indicator_compare
=
[
old_indicator
,
index_indicator
]
return
ret
,
old_return_compare_result
,
old_indicator_compare
def
new_evaluation
(
self
,
group_name
,
group_result
,
data_adaptor
):
try
:
...
...
@@ -793,7 +861,6 @@ class PortfolioDiagnose(object):
"substrategy"
:
propose_fund_id_strategy_name_list
[
i
],
"asset"
:
propose_fund_asset
[
i
]}
for
i
in
range
(
len
(
propose_fund_id_list
))}
# 调仓建议
suggestions_result
=
{}
old_hold_fund_name_list
=
list
(
hold_info_df
[
"fund_name"
])
...
...
@@ -857,7 +924,7 @@ class PortfolioDiagnose(object):
index_return_ratio_year
=
annual_return
(
index_return
[
"new_index_return"
]
.
values
[
-
1
],
index_return
[
"new_index_return"
],
n_freq
)
index_volatility
=
volatility
(
index_return
[
"new_index_return"
]
+
1
,
n_freq
)
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
(
index_return
[
"new_index
_return"
]
+
1
)
index_exc
=
excess_return
(
index_sim
,
BANK_RATE
,
n_freq
)
index_sharpe
=
sharpe_ratio
(
index_exc
,
index_sim
,
n_freq
)
...
...
@@ -870,9 +937,9 @@ class PortfolioDiagnose(object):
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_result
=
{
"new_combination"
:
{
"name"
:
"新组合"
,
"data"
:
return_compare_df
[
"new_return"
]
.
values
},
"index"
:
{
"name"
:
"中证500"
,
"data"
:
return_compare_df
[
"new_index_return"
]
.
values
},
"origin_combination"
:
{
"name"
:
"原组合"
,
"data"
:
return_compare_df
[
"cum_return_ratio"
]
.
values
},
"new_combination"
:
{
"name"
:
"新组合"
,
"data"
:
return_compare_df
[
"new_return"
]
.
values
*
100
},
"index"
:
{
"name"
:
"中证500"
,
"data"
:
return_compare_df
[
"new_index_return"
]
.
values
*
100
},
"origin_combination"
:
{
"name"
:
"原组合"
,
"data"
:
return_compare_df
[
"cum_return_ratio"
]
.
values
*
100
},
"xlabels"
:
return_compare_df
[
"date"
]
.
values
}
...
...
@@ -885,6 +952,7 @@ class PortfolioDiagnose(object):
"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
]
# 在保留{}的基础上,建议赎回{},并增配{}后,整体组合波动率大幅降低,最大回撤从{}降到不足{},年化收益率提升{}个点
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
]
...
...
@@ -913,7 +981,7 @@ class PortfolioDiagnose(object):
repr
(
e
)
return
None
,
None
,
None
,
None
,
None
def
single_evaluation
(
self
,
fund_id
,
objective
):
def
single_evaluation
(
self
,
fund_id
,
objective
=
False
):
"""
1、该基金整体表现优秀/良好/一般,收益能力优秀/良好/合格/较差,回撤控制能力优秀/良好/合格/较差,风险收益比例较高/一般/较低;
2、在收益方面,该基金年化收益能力高于/持平/低于同类基金平均水平,有x
%
区间跑赢大盘/指数,绝对收益能力优秀/一般;
...
...
@@ -1038,19 +1106,22 @@ class PortfolioDiagnose(object):
pass
evaluation_dict
=
{
'name'
:
fund_name
,
'data'
:
ret
}
if
objective
:
if
fund_id
in
self
.
abandon_fund_score
+
self
.
abandon_fund_corr
:
evaluation_dict
[
'status'
]
=
"换仓"
elif
fund_id
in
self
.
portfolio
:
evaluation_dict
[
'status'
]
=
"保留"
else
:
evaluation_dict
[
'status'
]
=
""
return
evaluation_dict
def
old_portfolio_evaluation
(
self
,
):
def
old_portfolio_evaluation
(
self
,
objective
=
False
):
try
:
result
=
[]
for
fund
in
self
.
portfolio
:
try
:
result
.
append
(
self
.
single_evaluation
(
fund
))
result
.
append
(
self
.
single_evaluation
(
fund
,
objective
))
except
IndexError
:
continue
return
result
...
...
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