Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
A
alpha-mind
Project
Project
Details
Activity
Releases
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
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Dr.李
alpha-mind
Commits
9256a8be
Commit
9256a8be
authored
Aug 21, 2017
by
Dr.李
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update factor_analysis implementation
parent
108d2d78
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
76 additions
and
61 deletions
+76
-61
factoranalysis.py
alphamind/analysis/factoranalysis.py
+34
-24
simplesettle.py
alphamind/settlement/simplesettle.py
+35
-12
test_simplesettle.py
alphamind/tests/settlement/test_simplesettle.py
+7
-25
No files found.
alphamind/analysis/factoranalysis.py
View file @
9256a8be
...
@@ -18,12 +18,12 @@ from alphamind.portfolio.percentbuilder import percent_build
...
@@ -18,12 +18,12 @@ from alphamind.portfolio.percentbuilder import percent_build
from
alphamind.portfolio.linearbuilder
import
linear_build
from
alphamind.portfolio.linearbuilder
import
linear_build
from
alphamind.portfolio.meanvariancebuilder
import
mean_variance_builder
from
alphamind.portfolio.meanvariancebuilder
import
mean_variance_builder
from
alphamind.analysis.utilities
import
FDataPack
from
alphamind.analysis.utilities
import
FDataPack
from
alphamind.settlement.simplesettle
import
simple_settle
def
build_portfolio
(
er
:
np
.
ndarray
,
def
build_portfolio
(
er
:
np
.
ndarray
,
builder
:
Optional
[
str
]
=
'long_short'
,
builder
:
Optional
[
str
]
=
'long_short'
,
**
kwargs
)
->
np
.
ndarray
:
**
kwargs
)
->
np
.
ndarray
:
builder
=
builder
.
lower
()
builder
=
builder
.
lower
()
if
builder
==
'ls'
or
builder
==
'long_short'
:
if
builder
==
'ls'
or
builder
==
'long_short'
:
...
@@ -49,16 +49,15 @@ def build_portfolio(er: np.ndarray,
...
@@ -49,16 +49,15 @@ def build_portfolio(er: np.ndarray,
def
factor_analysis
(
factors
:
pd
.
DataFrame
,
def
factor_analysis
(
factors
:
pd
.
DataFrame
,
factor_weights
:
np
.
ndarray
,
factor_weights
:
np
.
ndarray
,
industry
:
np
.
ndarray
,
industry
:
np
.
ndarray
,
d1returns
:
np
.
ndarray
=
None
,
d1returns
:
np
.
ndarray
=
None
,
detail_analysis
=
True
,
detail_analysis
=
True
,
benchmark
:
Optional
[
np
.
ndarray
]
=
None
,
benchmark
:
Optional
[
np
.
ndarray
]
=
None
,
risk_exp
:
Optional
[
np
.
ndarray
]
=
None
,
risk_exp
:
Optional
[
np
.
ndarray
]
=
None
,
is_tradable
:
Optional
[
np
.
ndarray
]
=
None
,
is_tradable
:
Optional
[
np
.
ndarray
]
=
None
,
constraints
:
Optional
[
Constraints
]
=
None
,
constraints
:
Optional
[
Constraints
]
=
None
,
method
=
'risk_neutral'
,
method
=
'risk_neutral'
,
do_neutralize
=
True
,
do_neutralize
=
True
,
**
kwargs
)
->
Tuple
[
pd
.
DataFrame
,
Optional
[
pd
.
DataFrame
]]:
**
kwargs
)
->
Tuple
[
pd
.
DataFrame
,
Optional
[
pd
.
DataFrame
]]:
data_pack
=
FDataPack
(
raw_factors
=
factors
.
values
,
data_pack
=
FDataPack
(
raw_factors
=
factors
.
values
,
groups
=
industry
,
groups
=
industry
,
benchmark
=
benchmark
,
benchmark
=
benchmark
,
...
@@ -79,8 +78,27 @@ def factor_analysis(factors: pd.DataFrame,
...
@@ -79,8 +78,27 @@ def factor_analysis(factors: pd.DataFrame,
er
=
data_pack
.
factor_processing
(
pre_process
,
post_process
,
do_neutralize
)
@
factor_weights
er
=
data_pack
.
factor_processing
(
pre_process
,
post_process
,
do_neutralize
)
@
factor_weights
def
create_constraints
(
benchmark
,
**
kwargs
):
return
er_analysis
(
er
,
industry
,
d1returns
,
constraints
,
detail_analysis
,
benchmark
,
is_tradable
,
method
,
**
kwargs
)
def
er_analysis
(
er
:
np
.
ndarray
,
industry
:
np
.
ndarray
,
dx_return
:
np
.
ndarray
,
constraints
:
Constraints
,
detail_analysis
=
True
,
benchmark
:
Optional
[
np
.
ndarray
]
=
None
,
is_tradable
:
Optional
[
np
.
ndarray
]
=
None
,
method
=
'risk_neutral'
,
**
kwargs
)
->
Tuple
[
pd
.
DataFrame
,
Optional
[
pd
.
DataFrame
]]:
def
create_constraints
(
benchmark
,
**
kwargs
):
if
'lbound'
in
kwargs
:
if
'lbound'
in
kwargs
:
lbound
=
kwargs
[
'lbound'
]
lbound
=
kwargs
[
'lbound'
]
del
kwargs
[
'lbound'
]
del
kwargs
[
'lbound'
]
...
@@ -92,21 +110,14 @@ def factor_analysis(factors: pd.DataFrame,
...
@@ -92,21 +110,14 @@ def factor_analysis(factors: pd.DataFrame,
del
kwargs
[
'ubound'
]
del
kwargs
[
'ubound'
]
else
:
else
:
ubound
=
0.01
+
benchmark
ubound
=
0.01
+
benchmark
if
is_tradable
is
not
None
:
if
is_tradable
is
not
None
:
ubound
[
~
is_tradable
]
=
np
.
minimum
(
lbound
,
ubound
)[
~
is_tradable
]
ubound
[
~
is_tradable
]
=
np
.
minimum
(
lbound
,
ubound
)[
~
is_tradable
]
if
constraints
:
risk_lbound
,
risk_ubound
=
constraints
.
risk_targets
()
risk_lbound
,
risk_ubound
=
constraints
.
risk_targets
()
cons_exp
=
constraints
.
risk_exp
cons_exp
=
constraints
.
risk_exp
else
:
cons_exp
=
risk_exp
risk_lbound
=
data_pack
.
benchmark_constraints
()
risk_ubound
=
data_pack
.
benchmark_constraints
()
return
lbound
,
ubound
,
cons_exp
,
risk_lbound
,
risk_ubound
return
lbound
,
ubound
,
cons_exp
,
risk_lbound
,
risk_ubound
if
benchmark
is
not
None
and
risk_exp
is
not
None
and
method
==
'risk_neutral'
:
if
benchmark
is
not
None
and
method
==
'risk_neutral'
:
lbound
,
ubound
,
cons_exp
,
risk_lbound
,
risk_ubound
=
create_constraints
(
benchmark
,
**
kwargs
)
lbound
,
ubound
,
cons_exp
,
risk_lbound
,
risk_ubound
=
create_constraints
(
benchmark
,
**
kwargs
)
status
,
_
,
weights
=
linear_build
(
er
,
status
,
_
,
weights
=
linear_build
(
er
,
risk_constraints
=
cons_exp
,
risk_constraints
=
cons_exp
,
...
@@ -143,11 +154,10 @@ def factor_analysis(factors: pd.DataFrame,
...
@@ -143,11 +154,10 @@ def factor_analysis(factors: pd.DataFrame,
raise
ValueError
(
"Unknown building tpe ({0})"
.
format
(
method
))
raise
ValueError
(
"Unknown building tpe ({0})"
.
format
(
method
))
if
detail_analysis
:
if
detail_analysis
:
analysis
=
data_pack
.
settle
(
weights
,
d1returns
)
analysis
=
simple_settle
(
weights
,
dx_return
,
industry
,
benchmark
)
else
:
else
:
analysis
=
None
analysis
=
None
return
pd
.
DataFrame
({
'weight'
:
weights
,
return
pd
.
DataFrame
({
'weight'
:
weights
,
'industry'
:
industry
,
'industry'
:
industry
,
'er'
:
er
},
'er'
:
er
}),
\
index
=
factors
.
index
),
\
analysis
analysis
alphamind/settlement/simplesettle.py
View file @
9256a8be
...
@@ -6,21 +6,44 @@ Created on 2017-4-28
...
@@ -6,21 +6,44 @@ Created on 2017-4-28
"""
"""
import
numpy
as
np
import
numpy
as
np
from
alphamind.utilities
import
group_mapping
import
pandas
as
pd
from
alphamind.utilities
import
aggregate
from
alphamind.utilities
import
simple_sum
def
simple_settle
(
weights
:
np
.
ndarray
,
ret_series
:
np
.
ndarray
,
groups
:
np
.
ndarray
=
None
)
->
np
.
ndarray
:
def
simple_settle
(
weights
:
np
.
ndarray
,
dx_return
:
np
.
ndarray
,
groups
:
np
.
ndarray
=
None
,
benchmark
:
np
.
ndarray
=
None
)
->
pd
.
DataFrame
:
if
ret_series
.
ndim
==
1
:
weights
=
weights
.
flatten
()
ret_series
=
ret_series
.
reshape
((
-
1
,
1
))
dx_return
=
dx_return
.
flatten
()
if
benchmark
is
not
None
:
net_pos
=
weights
-
benchmark
else
:
net_pos
=
weights
ret_arr
=
net_pos
*
dx_return
ret_mat
=
weights
*
ret_series
if
groups
is
not
None
:
if
groups
is
not
None
:
groups
=
group_mapping
(
groups
)
ret_agg
=
pd
.
Series
(
ret_arr
)
.
groupby
(
groups
)
.
sum
(
)
ret
urn
aggregate
(
groups
,
ret_mat
,
'sum'
)
ret
_agg
.
loc
[
'total'
]
=
ret_agg
.
sum
(
)
else
:
else
:
if
ret_mat
.
ndim
==
1
:
ret_agg
=
pd
.
Series
(
ret_arr
.
sum
(),
index
=
[
'total'
])
ret_mat
=
ret_mat
.
reshape
((
-
1
,
1
))
return
simple_sum
(
ret_mat
,
axis
=
0
)
ret_agg
.
index
.
name
=
'industry'
ret_agg
.
name
=
'er'
pos_table
=
pd
.
DataFrame
(
net_pos
,
columns
=
[
'weight'
])
pos_table
[
'ret'
]
=
dx_return
if
groups
is
not
None
:
ic_table
=
pos_table
.
groupby
(
groups
)
.
corr
()[
'ret'
]
.
loc
[(
slice
(
None
),
'weight'
)]
ic_table
.
loc
[
'total'
]
=
pos_table
.
corr
()
.
iloc
[
0
,
1
]
else
:
ic_table
=
pd
.
Series
(
pos_table
.
corr
()
.
iloc
[
0
,
1
],
index
=
[
'total'
])
return
pd
.
DataFrame
({
'er'
:
ret_agg
.
values
,
'ic'
:
ic_table
.
values
},
index
=
ret_agg
.
index
)
alphamind/tests/settlement/test_simplesettle.py
View file @
9256a8be
...
@@ -16,10 +16,8 @@ class TestSimpleSettle(unittest.TestCase):
...
@@ -16,10 +16,8 @@ class TestSimpleSettle(unittest.TestCase):
def
setUp
(
self
):
def
setUp
(
self
):
self
.
n_samples
=
3000
self
.
n_samples
=
3000
self
.
n_portfolio
=
3
self
.
n_groups
=
30
self
.
n_groups
=
30
self
.
weights
=
np
.
random
.
randn
(
self
.
n_samples
,
self
.
weights
=
np
.
random
.
randn
(
self
.
n_samples
)
self
.
n_portfolio
)
self
.
ret_series
=
np
.
random
.
randn
(
self
.
n_samples
)
self
.
ret_series
=
np
.
random
.
randn
(
self
.
n_samples
)
self
.
groups
=
np
.
random
.
randint
(
self
.
n_groups
,
size
=
self
.
n_samples
)
self
.
groups
=
np
.
random
.
randint
(
self
.
n_groups
,
size
=
self
.
n_samples
)
...
@@ -27,34 +25,18 @@ class TestSimpleSettle(unittest.TestCase):
...
@@ -27,34 +25,18 @@ class TestSimpleSettle(unittest.TestCase):
calc_ret
=
simple_settle
(
self
.
weights
,
self
.
ret_series
)
calc_ret
=
simple_settle
(
self
.
weights
,
self
.
ret_series
)
ret_series
=
self
.
ret_series
.
reshape
((
-
1
,
1
))
ret_series
=
self
.
ret_series
.
reshape
((
-
1
,
1
))
expected_ret
=
(
self
.
weights
*
ret_series
)
.
sum
(
axis
=
0
)
expected_ret
=
self
.
weights
@
ret_series
np
.
testing
.
assert_array_almost_equal
(
calc_ret
,
expected_ret
)
self
.
assertAlmostEqual
(
calc_ret
[
'er'
][
0
],
expected_ret
[
0
])
ret_series
=
np
.
random
.
randn
(
self
.
n_samples
,
1
)
calc_ret
=
simple_settle
(
self
.
weights
,
ret_series
)
expected_ret
=
(
self
.
weights
*
ret_series
)
.
sum
(
axis
=
0
)
np
.
testing
.
assert_array_almost_equal
(
calc_ret
,
expected_ret
)
def
test_simple_settle_with_group
(
self
):
def
test_simple_settle_with_group
(
self
):
calc_ret
=
simple_settle
(
self
.
weights
,
self
.
ret_series
,
self
.
groups
)
calc_ret
=
simple_settle
(
self
.
weights
,
self
.
ret_series
,
self
.
groups
)
ret_series
=
self
.
ret_series
.
reshape
((
-
1
,
1
))
ret_series
=
self
.
weights
*
self
.
ret_series
ret_mat
=
self
.
weights
*
ret_series
expected_ret
=
pd
.
Series
(
ret_series
)
.
groupby
(
self
.
groups
)
.
sum
()
.
values
expected_ret
=
pd
.
DataFrame
(
ret_mat
)
.
groupby
(
self
.
groups
)
.
sum
()
.
values
np
.
testing
.
assert_array_almost_equal
(
calc_ret
,
expected_ret
)
ret_series
=
np
.
random
.
randn
(
self
.
n_samples
,
1
)
calc_ret
=
simple_settle
(
self
.
weights
,
ret_series
,
self
.
groups
)
ret_mat
=
self
.
weights
*
ret_series
expected_ret
=
pd
.
DataFrame
(
ret_mat
)
.
groupby
(
self
.
groups
)
.
sum
()
.
values
np
.
testing
.
assert_array_almost_equal
(
calc_ret
,
expected_ret
)
np
.
testing
.
assert_array_almost_equal
(
calc_ret
[
'er'
]
.
values
[:
-
1
],
expected_ret
)
self
.
assertAlmostEqual
(
calc_ret
[
'er'
]
.
values
[
-
1
],
expected_ret
.
sum
())
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
...
...
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