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
561e1046
Commit
561e1046
authored
Feb 08, 2018
by
Dr.李
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update model api
parent
eac7bef8
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
109 additions
and
85 deletions
+109
-85
composer.py
alphamind/model/composer.py
+46
-34
modelbase.py
alphamind/model/modelbase.py
+2
-1
allocations.py
alphamind/portfolio/allocations.py
+43
-50
test_modelbase.py
alphamind/tests/model/test_modelbase.py
+16
-0
test_suite.py
alphamind/tests/test_suite.py
+2
-0
No files found.
alphamind/model/composer.py
View file @
561e1046
...
@@ -43,6 +43,48 @@ class DataMeta(object):
...
@@ -43,6 +43,48 @@ class DataMeta(object):
self
.
warm_start
=
warm_start
self
.
warm_start
=
warm_start
def
train_model
(
ref_date
:
str
,
alpha_model
:
ModelBase
,
data_meta
:
DataMeta
):
train_data
=
fetch_train_phase
(
data_meta
.
engine
,
data_meta
.
alpha_factors
,
ref_date
,
data_meta
.
freq
,
data_meta
.
universe
,
data_meta
.
batch
,
data_meta
.
neutralized_risk
,
data_meta
.
risk_model
,
data_meta
.
pre_process
,
data_meta
.
post_process
,
data_meta
.
warm_start
)
x_values
=
train_data
[
'train'
][
'x'
]
y_values
=
train_data
[
'train'
][
'y'
]
alpha_model
.
fit
(
x_values
,
y_values
)
return
copy
.
deepcopy
(
alpha_model
)
def
predict_by_model
(
ref_date
:
str
,
alpha_model
:
ModelBase
,
data_meta
):
predict_data
=
fetch_predict_phase
(
data_meta
.
engine
,
data_meta
.
alpha_factors
,
ref_date
,
data_meta
.
freq
,
data_meta
.
universe
,
data_meta
.
batch
,
data_meta
.
neutralized_risk
,
data_meta
.
risk_model
,
data_meta
.
pre_process
,
data_meta
.
post_process
,
data_meta
.
warm_start
)
x_values
=
predict_data
[
'predict'
][
'x'
]
codes
=
predict_data
[
'predict'
][
'code'
]
return
pd
.
DataFrame
(
alpha_model
.
predict
(
x_values
)
.
flatten
(),
index
=
codes
)
class
ModelComposer
(
object
):
class
ModelComposer
(
object
):
def
__init__
(
self
,
def
__init__
(
self
,
alpha_model
:
ModelBase
,
alpha_model
:
ModelBase
,
...
@@ -55,47 +97,17 @@ class ModelComposer(object):
...
@@ -55,47 +97,17 @@ class ModelComposer(object):
self
.
sorted_keys
=
None
self
.
sorted_keys
=
None
def
train
(
self
,
ref_date
:
str
):
def
train
(
self
,
ref_date
:
str
):
train_data
=
fetch_train_phase
(
self
.
data_meta
.
engine
,
self
.
models
[
ref_date
]
=
train_model
(
ref_date
,
self
.
alpha_model
,
self
.
data_meta
)
self
.
data_meta
.
alpha_factors
,
ref_date
,
self
.
data_meta
.
freq
,
self
.
data_meta
.
universe
,
self
.
data_meta
.
batch
,
self
.
data_meta
.
neutralized_risk
,
self
.
data_meta
.
risk_model
,
self
.
data_meta
.
pre_process
,
self
.
data_meta
.
post_process
,
self
.
data_meta
.
warm_start
)
x_values
=
train_data
[
'train'
][
'x'
]
y_values
=
train_data
[
'train'
][
'y'
]
self
.
alpha_model
.
fit
(
x_values
,
y_values
)
self
.
models
[
ref_date
]
=
copy
.
deepcopy
(
self
.
alpha_model
)
self
.
is_updated
=
False
self
.
is_updated
=
False
def
predict
(
self
,
ref_date
:
str
,
x
:
pd
.
DataFrame
=
None
)
->
pd
.
DataFrame
:
def
predict
(
self
,
ref_date
:
str
,
x
:
pd
.
DataFrame
=
None
)
->
pd
.
DataFrame
:
model
=
self
.
_fetch_latest_model
(
ref_date
)
if
x
is
None
:
if
x
is
None
:
predict_data
=
fetch_predict_phase
(
self
.
data_meta
.
engine
,
return
predict_by_model
(
ref_date
,
model
,
self
.
data_meta
)
self
.
data_meta
.
alpha_factors
,
ref_date
,
self
.
data_meta
.
freq
,
self
.
data_meta
.
universe
,
self
.
data_meta
.
batch
,
self
.
data_meta
.
neutralized_risk
,
self
.
data_meta
.
risk_model
,
self
.
data_meta
.
pre_process
,
self
.
data_meta
.
post_process
,
self
.
data_meta
.
warm_start
)
x_values
=
predict_data
[
'predict'
][
'x'
]
codes
=
predict_data
[
'predict'
][
'code'
]
else
:
else
:
x_values
=
x
.
values
x_values
=
x
.
values
codes
=
x
.
index
codes
=
x
.
index
return
pd
.
DataFrame
(
model
.
predict
(
x_values
)
.
flatten
(),
index
=
codes
)
model
=
self
.
_fetch_latest_model
(
ref_date
)
return
pd
.
DataFrame
(
model
.
predict
(
x_values
)
.
flatten
(),
index
=
codes
)
def
_fetch_latest_model
(
self
,
ref_date
)
->
ModelBase
:
def
_fetch_latest_model
(
self
,
ref_date
)
->
ModelBase
:
if
self
.
is_updated
:
if
self
.
is_updated
:
...
...
alphamind/model/modelbase.py
View file @
561e1046
...
@@ -12,13 +12,14 @@ import numpy as np
...
@@ -12,13 +12,14 @@ import numpy as np
from
alphamind.utilities
import
alpha_logger
from
alphamind.utilities
import
alpha_logger
from
alphamind.utilities
import
encode
from
alphamind.utilities
import
encode
from
alphamind.utilities
import
decode
from
alphamind.utilities
import
decode
from
alphamind.data.transformer
import
Transformer
class
ModelBase
(
metaclass
=
abc
.
ABCMeta
):
class
ModelBase
(
metaclass
=
abc
.
ABCMeta
):
def
__init__
(
self
,
features
:
list
=
None
,
formulas
:
dict
=
None
):
def
__init__
(
self
,
features
:
list
=
None
,
formulas
:
dict
=
None
):
if
features
is
not
None
:
if
features
is
not
None
:
self
.
features
=
list
(
features
)
self
.
features
=
Transformer
(
features
)
.
names
else
:
else
:
self
.
features
=
None
self
.
features
=
None
self
.
impl
=
None
self
.
impl
=
None
...
...
alphamind/portfolio/allocations.py
View file @
561e1046
...
@@ -16,9 +16,9 @@ class Allocation(object):
...
@@ -16,9 +16,9 @@ class Allocation(object):
def
__init__
(
self
,
def
__init__
(
self
,
code
:
int
,
code
:
int
,
minimum
:
int
=
0
,
minimum
:
int
=
0
,
maximum
:
int
=
inf
,
maximum
:
int
=
inf
,
current
:
int
=
0
):
current
:
int
=
0
):
self
.
code
=
code
self
.
code
=
code
self
.
minimum
=
minimum
self
.
minimum
=
minimum
self
.
maximum
=
maximum
self
.
maximum
=
maximum
...
@@ -62,39 +62,32 @@ class Portfolio(object):
...
@@ -62,39 +62,32 @@ class Portfolio(object):
class
Execution
(
object
):
class
Execution
(
object
):
def
__init__
(
self
,
def
__init__
(
self
,
name
:
str
,
code
:
int
,
code
:
int
,
qty
:
int
,
qty
:
int
,
comment
:
str
=
None
):
cpty
:
str
=
'external'
,
comment
:
str
=
None
):
self
.
name
=
name
self
.
code
=
code
self
.
code
=
code
self
.
qty
=
qty
self
.
qty
=
qty
self
.
cpty
=
cpty
self
.
comment
=
comment
self
.
comment
=
comment
def
__repr__
(
self
):
def
__repr__
(
self
):
return
"Execution(code={0}, qty={1}, comment={2})"
.
format
(
self
.
code
,
return
"Execution(name={0}, code={1}, qty={2}, cpty={3}, comment={4})"
.
format
(
self
.
name
,
self
.
qty
,
self
.
code
,
self
.
comment
)
self
.
qty
,
self
.
cpty
,
self
.
comment
)
class
Executions
(
object
):
def
__init__
(
self
,
name
,
executions
:
List
[
Execution
]
=
None
):
self
.
name
=
name
self
.
executions
=
executions
def
__repr__
(
self
):
return
"Executions(name={0}, executions={1})"
.
format
(
self
.
name
,
self
.
executions
)
class
Asset
(
object
):
class
Asset
(
object
):
def
__init__
(
self
,
def
__init__
(
self
,
code
:
int
,
code
:
int
,
name
:
str
=
None
,
name
:
str
=
None
,
priority
:
List
[
str
]
=
None
,
priority
:
List
[
str
]
=
None
,
forbidden
:
List
[
str
]
=
None
):
forbidden
:
List
[
str
]
=
None
):
self
.
code
=
code
self
.
code
=
code
self
.
name
=
name
self
.
name
=
name
if
priority
:
if
priority
:
...
@@ -119,11 +112,11 @@ class Asset(object):
...
@@ -119,11 +112,11 @@ class Asset(object):
self
.
forbidden
)
self
.
forbidden
)
class
Target
Positions
(
object
):
class
Positions
(
object
):
def
__init__
(
self
,
def
__init__
(
self
,
assets
:
List
[
Asset
]
=
None
,
assets
:
List
[
Asset
]
=
None
,
qtys
:
List
[
int
]
=
None
):
qtys
:
List
[
int
]
=
None
):
if
assets
:
if
assets
:
self
.
targets
=
{
asset
.
code
:
(
asset
,
qty
)
for
asset
,
qty
in
zip
(
assets
,
qtys
)}
self
.
targets
=
{
asset
.
code
:
(
asset
,
qty
)
for
asset
,
qty
in
zip
(
assets
,
qtys
)}
...
@@ -133,9 +126,9 @@ class TargetPositions(object):
...
@@ -133,9 +126,9 @@ class TargetPositions(object):
def
add_asset
(
self
,
def
add_asset
(
self
,
asset
:
Asset
,
asset
:
Asset
,
qty
:
int
):
qty
:
int
):
if
asset
.
code
in
self
.
targets
:
code
=
asset
.
code
raise
ValueError
(
)
pyFinAssert
(
code
not
in
self
.
targets
,
ValueError
,
"code {0} is already in positions"
.
format
(
code
)
)
self
.
targets
[
asset
.
code
]
=
(
asset
,
qty
)
self
.
targets
[
code
]
=
(
asset
,
qty
)
def
__getitem__
(
self
,
code
:
int
)
->
Tuple
[
Asset
,
int
]:
def
__getitem__
(
self
,
code
:
int
)
->
Tuple
[
Asset
,
int
]:
return
self
.
targets
[
code
]
return
self
.
targets
[
code
]
...
@@ -148,10 +141,10 @@ class TargetPositions(object):
...
@@ -148,10 +141,10 @@ class TargetPositions(object):
return
"TargetPositions(assets={0}, qtys={1})"
.
format
(
*
zip
(
*
self
.
targets
.
values
()))
return
"TargetPositions(assets={0}, qtys={1})"
.
format
(
*
zip
(
*
self
.
targets
.
values
()))
def
handle_one_asset
(
pre_allocation
:
Allocation
,
def
handle_one_asset
(
p_name
:
str
,
pre_allocation
:
Allocation
,
asset
:
Asset
,
asset
:
Asset
,
qty
:
int
)
->
Tuple
[
Execution
,
Allocation
,
int
]:
qty
:
int
)
->
Tuple
[
Execution
,
Allocation
,
int
]:
minimum
=
pre_allocation
.
minimum
minimum
=
pre_allocation
.
minimum
maximum
=
pre_allocation
.
maximum
maximum
=
pre_allocation
.
maximum
current
=
pre_allocation
.
current
current
=
pre_allocation
.
current
...
@@ -161,14 +154,20 @@ def handle_one_asset(pre_allocation: Allocation,
...
@@ -161,14 +154,20 @@ def handle_one_asset(pre_allocation: Allocation,
raise
ValueError
(
"{0}'s target {1} is smaller than minimum amount {2}"
.
format
(
asset
.
code
,
qty
,
pre_allocation
))
raise
ValueError
(
"{0}'s target {1} is smaller than minimum amount {2}"
.
format
(
asset
.
code
,
qty
,
pre_allocation
))
elif
qty
<
maximum
:
elif
qty
<
maximum
:
# need to buy / sell
# need to buy / sell
ex
=
Execution
(
code
,
qty
-
current
)
ex
=
Execution
(
name
=
p_name
,
code
=
code
,
qty
=
qty
-
current
,
cpty
=
'external'
)
allocation
=
Allocation
(
code
,
allocation
=
Allocation
(
code
,
minimum
=
minimum
,
minimum
=
minimum
,
maximum
=
maximum
,
maximum
=
maximum
,
current
=
qty
)
current
=
qty
)
qty
=
0
qty
=
0
else
:
else
:
ex
=
Execution
(
code
,
maximum
-
current
)
ex
=
Execution
(
name
=
p_name
,
code
=
code
,
qty
=
maximum
-
current
,
cpty
=
'external'
)
allocation
=
Allocation
(
code
,
allocation
=
Allocation
(
code
,
minimum
=
minimum
,
minimum
=
minimum
,
maximum
=
maximum
,
maximum
=
maximum
,
...
@@ -177,41 +176,40 @@ def handle_one_asset(pre_allocation: Allocation,
...
@@ -177,41 +176,40 @@ def handle_one_asset(pre_allocation: Allocation,
return
ex
,
allocation
,
qty
return
ex
,
allocation
,
qty
def
pass_through
(
target_pos
:
TargetPositions
,
def
pass_through
(
target_pos
:
Positions
,
portfolio
:
Portfolio
)
->
Tuple
[
Executions
,
Portfolio
,
TargetPositions
]:
portfolio
:
Portfolio
)
->
Tuple
[
List
[
Execution
],
Portfolio
,
Positions
]:
p_name
=
portfolio
.
name
p_name
=
portfolio
.
name
new_target_pos
=
Target
Positions
()
new_target_pos
=
Positions
()
allocations
=
[]
allocations
=
[]
executions
=
[]
executions
=
[]
for
code
in
target_pos
.
codes
:
for
code
in
target_pos
.
codes
:
asset
,
qty
=
target_pos
[
code
]
asset
,
qty
=
target_pos
[
code
]
if
asset
.
priority
:
pyFinAssert
(
not
asset
.
priority
,
raise
ValueError
(
"asset ({0})'s priority pool {1} is not checked yet"
.
format
(
code
,
asset
.
priority
))
ValueError
,
"asset ({0})'s priority pool {1} is not checked yet"
.
format
(
code
,
asset
.
priority
))
if
p_name
in
asset
.
forbidden
:
if
p_name
in
asset
.
forbidden
:
ex
=
Execution
(
code
,
0
,
"{0} is forbidden for {1}"
.
format
(
code
,
p_name
))
allocation
=
copy
.
deepcopy
(
portfolio
[
code
])
allocation
=
copy
.
deepcopy
(
portfolio
[
code
])
new_target_pos
.
add_asset
(
asset
,
qty
)
new_target_pos
.
add_asset
(
asset
,
qty
)
else
:
else
:
prev_allocation
=
portfolio
[
code
]
prev_allocation
=
portfolio
[
code
]
ex
,
allocation
,
qty
=
handle_one_asset
(
prev_allocation
,
asset
,
qty
)
ex
,
allocation
,
qty
=
handle_one_asset
(
p
_name
,
p
rev_allocation
,
asset
,
qty
)
new_target_pos
.
add_asset
(
asset
,
qty
)
new_target_pos
.
add_asset
(
asset
,
qty
)
if
ex
.
qty
!=
0
:
executions
.
append
(
ex
)
allocations
.
append
(
allocation
)
allocations
.
append
(
allocation
)
executions
.
append
(
ex
)
return
Executions
(
p_name
,
executions
)
,
Portfolio
(
p_name
,
allocations
),
new_target_pos
return
executions
,
Portfolio
(
p_name
,
allocations
),
new_target_pos
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
asset1
=
Asset
(
1
,
'a'
)
asset1
=
Asset
(
1
,
'a'
)
asset2
=
Asset
(
2
,
'b'
)
asset2
=
Asset
(
2
,
'b'
)
asset3
=
Asset
(
3
,
'b'
)
asset3
=
Asset
(
3
,
'b'
)
target_pos
=
Target
Positions
([
asset1
,
asset2
,
asset3
],
[
200
,
300
,
100
])
target_pos
=
Positions
([
asset1
,
asset2
,
asset3
],
[
200
,
300
,
100
])
allc1
=
Allocation
(
1
,
0
,
100
,
0
)
allc1
=
Allocation
(
1
,
0
,
100
,
0
)
allc2
=
Allocation
(
2
,
0
,
400
,
100
)
allc2
=
Allocation
(
2
,
0
,
400
,
100
)
...
@@ -219,8 +217,3 @@ if __name__ == '__main__':
...
@@ -219,8 +217,3 @@ if __name__ == '__main__':
portfolio
=
Portfolio
(
'test1'
,
[
allc1
,
allc2
])
portfolio
=
Portfolio
(
'test1'
,
[
allc1
,
allc2
])
executions
,
portfolio
,
target_pos
=
pass_through
(
target_pos
,
portfolio
)
executions
,
portfolio
,
target_pos
=
pass_through
(
target_pos
,
portfolio
)
alphamind/tests/model/test_modelbase.py
0 → 100644
View file @
561e1046
# -*- coding: utf-8 -*-
"""
Created on 2018-2-8
@author: cheng.li
"""
import
unittest
from
alphamind.model.linearmodel
import
ConstLinearModel
class
TestModelBase
(
unittest
.
TestCase
):
def
test_simple_model_features
(
self
):
model
=
ConstLinearModel
(
features
=
[
'c'
,
'b'
,
'a'
])
self
.
assertListEqual
([
'a'
,
'b'
,
'c'
],
model
.
features
)
\ No newline at end of file
alphamind/tests/test_suite.py
View file @
561e1046
...
@@ -27,6 +27,7 @@ from alphamind.tests.analysis.test_riskanalysis import TestRiskAnalysis
...
@@ -27,6 +27,7 @@ from alphamind.tests.analysis.test_riskanalysis import TestRiskAnalysis
from
alphamind.tests.analysis.test_perfanalysis
import
TestPerformanceAnalysis
from
alphamind.tests.analysis.test_perfanalysis
import
TestPerformanceAnalysis
from
alphamind.tests.analysis.test_factoranalysis
import
TestFactorAnalysis
from
alphamind.tests.analysis.test_factoranalysis
import
TestFactorAnalysis
from
alphamind.tests.analysis.test_quantilieanalysis
import
TestQuantileAnalysis
from
alphamind.tests.analysis.test_quantilieanalysis
import
TestQuantileAnalysis
from
alphamind.tests.model.test_modelbase
import
TestModelBase
from
alphamind.tests.model.test_linearmodel
import
TestLinearModel
from
alphamind.tests.model.test_linearmodel
import
TestLinearModel
from
alphamind.tests.model.test_treemodel
import
TestTreeModel
from
alphamind.tests.model.test_treemodel
import
TestTreeModel
from
alphamind.tests.model.test_loader
import
TestLoader
from
alphamind.tests.model.test_loader
import
TestLoader
...
@@ -54,6 +55,7 @@ if __name__ == '__main__':
...
@@ -54,6 +55,7 @@ if __name__ == '__main__':
TestPerformanceAnalysis
,
TestPerformanceAnalysis
,
TestFactorAnalysis
,
TestFactorAnalysis
,
TestQuantileAnalysis
,
TestQuantileAnalysis
,
TestModelBase
,
TestLinearModel
,
TestLinearModel
,
TestTreeModel
,
TestTreeModel
,
TestLoader
,
TestLoader
,
...
...
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