skfolio 0.0.7__py3-none-any.whl → 0.0.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- skfolio/model_selection/_combinatorial.py +2 -2
- skfolio/optimization/_base.py +1 -1
- skfolio/optimization/cluster/_nco.py +5 -5
- skfolio/optimization/cluster/hierarchical/_base.py +7 -7
- skfolio/optimization/cluster/hierarchical/_herc.py +17 -14
- skfolio/optimization/cluster/hierarchical/_hrp.py +13 -12
- skfolio/optimization/convex/_base.py +10 -10
- skfolio/optimization/convex/_distributionally_robust.py +9 -9
- skfolio/optimization/convex/_maximum_diversification.py +10 -10
- skfolio/optimization/convex/_mean_risk.py +10 -10
- skfolio/optimization/convex/_risk_budgeting.py +11 -11
- skfolio/optimization/ensemble/_stacking.py +6 -4
- skfolio/prior/_black_litterman.py +2 -2
- skfolio/prior/_factor_model.py +2 -2
- {skfolio-0.0.7.dist-info → skfolio-0.0.9.dist-info}/METADATA +75 -52
- {skfolio-0.0.7.dist-info → skfolio-0.0.9.dist-info}/RECORD +19 -19
- {skfolio-0.0.7.dist-info → skfolio-0.0.9.dist-info}/LICENSE +0 -0
- {skfolio-0.0.7.dist-info → skfolio-0.0.9.dist-info}/WHEEL +0 -0
- {skfolio-0.0.7.dist-info → skfolio-0.0.9.dist-info}/top_level.txt +0 -0
@@ -44,7 +44,7 @@ class CombinatorialPurgedCV(BaseCombinatorialCV):
|
|
44
44
|
Provides train/test indices to split time series data samples based on
|
45
45
|
Combinatorial Purged Cross-Validation [1]_.
|
46
46
|
|
47
|
-
Compared to `KFold
|
47
|
+
Compared to `KFold`, which splits the data into `k` folds with `1` fold for the test
|
48
48
|
set and `k - 1` folds for the training set, `CombinatorialPurgedCV` uses `k - p`
|
49
49
|
folds for the training set with `p > 1` being the number of test folds.
|
50
50
|
|
@@ -57,7 +57,7 @@ class CombinatorialPurgedCV(BaseCombinatorialCV):
|
|
57
57
|
overlapped in time with those labels included in the testing set.
|
58
58
|
|
59
59
|
Embargoing consist of removing from the training set all observations that
|
60
|
-
immediately follow an observation in the testing set since financial features
|
60
|
+
immediately follow an observation in the testing set, since financial features
|
61
61
|
often incorporate series that exhibit serial correlation (like ARMA processes).
|
62
62
|
|
63
63
|
Parameters
|
skfolio/optimization/_base.py
CHANGED
@@ -16,7 +16,7 @@ from skfolio.portfolio import Portfolio
|
|
16
16
|
|
17
17
|
|
18
18
|
class BaseOptimization(skb.BaseEstimator, ABC):
|
19
|
-
"""Base class for all
|
19
|
+
"""Base class for all portfolio optimizations in skfolio.
|
20
20
|
|
21
21
|
portfolio_params : dict, optional
|
22
22
|
Portfolio parameters passed to the portfolio evaluated by the `predict` and
|
@@ -40,12 +40,12 @@ class NestedClustersOptimization(BaseOptimization):
|
|
40
40
|
.. note ::
|
41
41
|
|
42
42
|
The original paper uses KMeans as the clustering algorithm, minimum Variance for
|
43
|
-
the inner-estimator and equal-
|
44
|
-
it to all `sklearn` and `skfolio` clustering
|
45
|
-
KMeans,
|
46
|
-
and risk measures (Variance, CVaR
|
43
|
+
the inner-estimator and equal-weighted for the outer-estimator. Here we
|
44
|
+
generalize it to all `sklearn` and `skfolio` clustering algorithms
|
45
|
+
(HierarchicalClustering, KMeans, etc.), all portfolio optimizations
|
46
|
+
(Mean-Variance, HRP, etc.) and risk measures (Variance, CVaR, etc.).
|
47
47
|
To avoid data leakage at the outer-estimator, we use out-of-sample estimates to
|
48
|
-
fit the outer
|
48
|
+
fit the outer estimator.
|
49
49
|
|
50
50
|
Parameters
|
51
51
|
----------
|
@@ -93,7 +93,7 @@ class BaseHierarchicalOptimization(BaseOptimization, ABC):
|
|
93
93
|
allowed. If a float is provided, it is applied to each asset. `None` is
|
94
94
|
equivalent to `+np.Inf` (no upper bound). If a dictionary is provided, its
|
95
95
|
(key/value) pair must be the (asset name/asset maximum weight) and the input `X`
|
96
|
-
of the `fit`
|
96
|
+
of the `fit` method must be a DataFrame with the assets names in columns. When
|
97
97
|
using a dictionary, assets values that are not provided are assigned a minimum
|
98
98
|
weight of `1.0`. The default is 1.0 (each asset is below 100%).
|
99
99
|
|
@@ -112,7 +112,7 @@ class BaseHierarchicalOptimization(BaseOptimization, ABC):
|
|
112
112
|
|
113
113
|
with :math:`c_{i}` the transaction cost of asset i, :math:`w_{i}` its weight
|
114
114
|
and :math:`w\_prev_{i}` its previous weight (defined in `previous_weights`).
|
115
|
-
The float :math:`total\_cost` is
|
115
|
+
The float :math:`total\_cost` is impacting the portfolio expected return in the optimization:
|
116
116
|
|
117
117
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_cost
|
118
118
|
|
@@ -121,7 +121,7 @@ class BaseHierarchicalOptimization(BaseOptimization, ABC):
|
|
121
121
|
|
122
122
|
If a float is provided, it is applied to each asset.
|
123
123
|
If a dictionary is provided, its (key/value) pair must be the
|
124
|
-
(asset name/asset cost) and the input `X` of the `fit`
|
124
|
+
(asset name/asset cost) and the input `X` of the `fit` method must be a
|
125
125
|
DataFrame with the assets names in columns.
|
126
126
|
The default value is `0.0`.
|
127
127
|
|
@@ -130,7 +130,7 @@ class BaseHierarchicalOptimization(BaseOptimization, ABC):
|
|
130
130
|
Based on the above formula, the periodicity of the transaction costs
|
131
131
|
needs to be homogenous to the periodicity of :math:`\mu`. For example, if
|
132
132
|
the input `X` is composed of **daily** returns, the `transaction_costs` need
|
133
|
-
to be expressed
|
133
|
+
to be expressed as **daily** costs.
|
134
134
|
(See :ref:`sphx_glr_auto_examples_1_mean_risk_plot_6_transaction_costs.py`)
|
135
135
|
|
136
136
|
management_fees : float | dict[str, float] | array-like of shape (n_assets, ), default=0.0
|
@@ -140,7 +140,7 @@ class BaseHierarchicalOptimization(BaseOptimization, ABC):
|
|
140
140
|
.. math:: total\_fee = \sum_{i=1}^{N} f_{i} \times w_{i}
|
141
141
|
|
142
142
|
with :math:`f_{i}` the management fee of asset i and :math:`w_{i}` its weight.
|
143
|
-
The float :math:`total\_fee` is
|
143
|
+
The float :math:`total\_fee` is impacting the portfolio expected return in the optimization:
|
144
144
|
|
145
145
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_fee
|
146
146
|
|
@@ -149,7 +149,7 @@ class BaseHierarchicalOptimization(BaseOptimization, ABC):
|
|
149
149
|
|
150
150
|
If a float is provided, it is applied to each asset.
|
151
151
|
If a dictionary is provided, its (key/value) pair must be the
|
152
|
-
(asset name/asset fee) and the input `X` of the `fit`
|
152
|
+
(asset name/asset fee) and the input `X` of the `fit` method must be a
|
153
153
|
DataFrame with the assets names in columns.
|
154
154
|
The default value is `0.0`.
|
155
155
|
|
@@ -172,7 +172,7 @@ class BaseHierarchicalOptimization(BaseOptimization, ABC):
|
|
172
172
|
Previous weights of the assets. Previous weights are used to compute the
|
173
173
|
portfolio total cost. If a float is provided, it is applied to each asset.
|
174
174
|
If a dictionary is provided, its (key/value) pair must be the
|
175
|
-
(asset name/asset previous weight) and the input `X` of the `fit`
|
175
|
+
(asset name/asset previous weight) and the input `X` of the `fit` method must
|
176
176
|
be a DataFrame with the assets names in columns.
|
177
177
|
The default (`None`) means no previous weights.
|
178
178
|
|
@@ -27,19 +27,20 @@ class HierarchicalEqualRiskContribution(BaseHierarchicalOptimization):
|
|
27
27
|
developed by Thomas Raffinot [2]_.
|
28
28
|
|
29
29
|
This algorithm uses a distance matrix to compute hierarchical clusters using the
|
30
|
-
Hierarchical Tree Clustering algorithm then computes, for each cluster, the
|
31
|
-
cluster risk of an inverse-risk allocation.
|
32
|
-
|
33
|
-
|
30
|
+
Hierarchical Tree Clustering algorithm. It then computes, for each cluster, the
|
31
|
+
total cluster risk of an inverse-risk allocation.
|
32
|
+
|
33
|
+
The final step is the top-down recursive division of the dendrogram, where the
|
34
|
+
assets weights are updated using a naive risk parity within clusters.
|
34
35
|
|
35
36
|
It differs from the Hierarchical Risk Parity by exploiting the dendrogram shape
|
36
37
|
during the top-down recursive division instead of bisecting it.
|
37
38
|
|
38
39
|
.. note ::
|
39
40
|
|
40
|
-
The default linkage method is set to the Ward
|
41
|
-
|
42
|
-
|
41
|
+
The default linkage method is set to the Ward variance minimization algorithm,
|
42
|
+
which is more stable and has better properties than the single-linkage
|
43
|
+
method [4]_.
|
43
44
|
|
44
45
|
Parameters
|
45
46
|
----------
|
@@ -113,7 +114,7 @@ class HierarchicalEqualRiskContribution(BaseHierarchicalOptimization):
|
|
113
114
|
allowed. If a float is provided, it is applied to each asset. `None` is
|
114
115
|
equivalent to `+np.Inf` (no upper bound). If a dictionary is provided, its
|
115
116
|
(key/value) pair must be the (asset name/asset maximum weight) and the input `X`
|
116
|
-
of the `fit`
|
117
|
+
of the `fit` method must be a DataFrame with the assets names in columns. When
|
117
118
|
using a dictionary, assets values that are not provided are assigned a minimum
|
118
119
|
weight of `1.0`. The default is 1.0 (each asset is below 100%).
|
119
120
|
|
@@ -132,7 +133,8 @@ class HierarchicalEqualRiskContribution(BaseHierarchicalOptimization):
|
|
132
133
|
|
133
134
|
with :math:`c_{i}` the transaction cost of asset i, :math:`w_{i}` its weight
|
134
135
|
and :math:`w\_prev_{i}` its previous weight (defined in `previous_weights`).
|
135
|
-
The float :math:`total\_cost` is
|
136
|
+
The float :math:`total\_cost` is impacting the portfolio expected return in the
|
137
|
+
optimization:
|
136
138
|
|
137
139
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_cost
|
138
140
|
|
@@ -141,7 +143,7 @@ class HierarchicalEqualRiskContribution(BaseHierarchicalOptimization):
|
|
141
143
|
|
142
144
|
If a float is provided, it is applied to each asset.
|
143
145
|
If a dictionary is provided, its (key/value) pair must be the
|
144
|
-
(asset name/asset cost) and the input `X` of the `fit`
|
146
|
+
(asset name/asset cost) and the input `X` of the `fit` method must be a
|
145
147
|
DataFrame with the assets names in columns.
|
146
148
|
The default value is `0.0`.
|
147
149
|
|
@@ -150,7 +152,7 @@ class HierarchicalEqualRiskContribution(BaseHierarchicalOptimization):
|
|
150
152
|
Based on the above formula, the periodicity of the transaction costs
|
151
153
|
needs to be homogenous to the periodicity of :math:`\mu`. For example, if
|
152
154
|
the input `X` is composed of **daily** returns, the `transaction_costs` need
|
153
|
-
to be expressed
|
155
|
+
to be expressed as **daily** costs.
|
154
156
|
(See :ref:`sphx_glr_auto_examples_1_mean_risk_plot_6_transaction_costs.py`)
|
155
157
|
|
156
158
|
management_fees : float | dict[str, float] | array-like of shape (n_assets, ), default=0.0
|
@@ -160,7 +162,8 @@ class HierarchicalEqualRiskContribution(BaseHierarchicalOptimization):
|
|
160
162
|
.. math:: total\_fee = \sum_{i=1}^{N} f_{i} \times w_{i}
|
161
163
|
|
162
164
|
with :math:`f_{i}` the management fee of asset i and :math:`w_{i}` its weight.
|
163
|
-
The float :math:`total\_fee` is
|
165
|
+
The float :math:`total\_fee` is impacting the portfolio expected return in the
|
166
|
+
optimization:
|
164
167
|
|
165
168
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_fee
|
166
169
|
|
@@ -169,7 +172,7 @@ class HierarchicalEqualRiskContribution(BaseHierarchicalOptimization):
|
|
169
172
|
|
170
173
|
If a float is provided, it is applied to each asset.
|
171
174
|
If a dictionary is provided, its (key/value) pair must be the
|
172
|
-
(asset name/asset fee) and the input `X` of the `fit`
|
175
|
+
(asset name/asset fee) and the input `X` of the `fit` method must be a
|
173
176
|
DataFrame with the assets names in columns.
|
174
177
|
The default value is `0.0`.
|
175
178
|
|
@@ -192,7 +195,7 @@ class HierarchicalEqualRiskContribution(BaseHierarchicalOptimization):
|
|
192
195
|
Previous weights of the assets. Previous weights are used to compute the
|
193
196
|
portfolio total cost. If a float is provided, it is applied to each asset.
|
194
197
|
If a dictionary is provided, its (key/value) pair must be the
|
195
|
-
(asset name/asset previous weight) and the input `X` of the `fit`
|
198
|
+
(asset name/asset previous weight) and the input `X` of the `fit` method must
|
196
199
|
be a DataFrame with the assets names in columns.
|
197
200
|
The default (`None`) means no previous weights.
|
198
201
|
|
@@ -26,12 +26,13 @@ class HierarchicalRiskParity(BaseHierarchicalOptimization):
|
|
26
26
|
Lopez de Prado [2]_.
|
27
27
|
|
28
28
|
This algorithm uses a distance matrix to compute hierarchical clusters using the
|
29
|
-
Hierarchical Tree Clustering algorithm then
|
30
|
-
in the dendrogram minimizing the distance between leafs.
|
29
|
+
Hierarchical Tree Clustering algorithm. It then employs seriation to rearrange the
|
30
|
+
assets in the dendrogram, minimizing the distance between leafs.
|
31
|
+
|
31
32
|
The final step is the recursive bisection where each cluster is split between two
|
32
33
|
sub-clusters by starting with the topmost cluster and traversing in a top-down
|
33
|
-
manner. For each sub-cluster we compute the total cluster risk of an inverse-risk
|
34
|
-
allocation. A weighting factor is then computed from these two sub-cluster risks
|
34
|
+
manner. For each sub-cluster, we compute the total cluster risk of an inverse-risk
|
35
|
+
allocation. A weighting factor is then computed from these two sub-cluster risks,
|
35
36
|
which is used to update the cluster weight.
|
36
37
|
|
37
38
|
.. note ::
|
@@ -39,7 +40,7 @@ class HierarchicalRiskParity(BaseHierarchicalOptimization):
|
|
39
40
|
method for the Hierarchical Tree Clustering algorithm. Here we generalize it to
|
40
41
|
multiple risk measures and linkage methods.
|
41
42
|
The default linkage method is set to the Ward
|
42
|
-
variance minimization algorithm which is more stable and
|
43
|
+
variance minimization algorithm, which is more stable and has better properties
|
43
44
|
than the single-linkage method [4]_.
|
44
45
|
|
45
46
|
Parameters
|
@@ -114,7 +115,7 @@ class HierarchicalRiskParity(BaseHierarchicalOptimization):
|
|
114
115
|
allowed. If a float is provided, it is applied to each asset. `None` is
|
115
116
|
equivalent to `+np.Inf` (no upper bound). If a dictionary is provided, its
|
116
117
|
(key/value) pair must be the (asset name/asset maximum weight) and the input `X`
|
117
|
-
of the `fit`
|
118
|
+
of the `fit` method must be a DataFrame with the assets names in columns. When
|
118
119
|
using a dictionary, assets values that are not provided are assigned a minimum
|
119
120
|
weight of `1.0`. The default is 1.0 (each asset is below 100%).
|
120
121
|
|
@@ -133,7 +134,7 @@ class HierarchicalRiskParity(BaseHierarchicalOptimization):
|
|
133
134
|
|
134
135
|
with :math:`c_{i}` the transaction cost of asset i, :math:`w_{i}` its weight
|
135
136
|
and :math:`w\_prev_{i}` its previous weight (defined in `previous_weights`).
|
136
|
-
The float :math:`total\_cost` is
|
137
|
+
The float :math:`total\_cost` is impacting the portfolio expected return in the optimization:
|
137
138
|
|
138
139
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_cost
|
139
140
|
|
@@ -142,7 +143,7 @@ class HierarchicalRiskParity(BaseHierarchicalOptimization):
|
|
142
143
|
|
143
144
|
If a float is provided, it is applied to each asset.
|
144
145
|
If a dictionary is provided, its (key/value) pair must be the
|
145
|
-
(asset name/asset cost) and the input `X` of the `fit`
|
146
|
+
(asset name/asset cost) and the input `X` of the `fit` method must be a
|
146
147
|
DataFrame with the assets names in columns.
|
147
148
|
The default value is `0.0`.
|
148
149
|
|
@@ -151,7 +152,7 @@ class HierarchicalRiskParity(BaseHierarchicalOptimization):
|
|
151
152
|
Based on the above formula, the periodicity of the transaction costs
|
152
153
|
needs to be homogenous to the periodicity of :math:`\mu`. For example, if
|
153
154
|
the input `X` is composed of **daily** returns, the `transaction_costs` need
|
154
|
-
to be expressed
|
155
|
+
to be expressed as **daily** costs.
|
155
156
|
(See :ref:`sphx_glr_auto_examples_1_mean_risk_plot_6_transaction_costs.py`)
|
156
157
|
|
157
158
|
management_fees : float | dict[str, float] | array-like of shape (n_assets, ), default=0.0
|
@@ -161,7 +162,7 @@ class HierarchicalRiskParity(BaseHierarchicalOptimization):
|
|
161
162
|
.. math:: total\_fee = \sum_{i=1}^{N} f_{i} \times w_{i}
|
162
163
|
|
163
164
|
with :math:`f_{i}` the management fee of asset i and :math:`w_{i}` its weight.
|
164
|
-
The float :math:`total\_fee` is
|
165
|
+
The float :math:`total\_fee` is impacting the portfolio expected return in the optimization:
|
165
166
|
|
166
167
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_fee
|
167
168
|
|
@@ -170,7 +171,7 @@ class HierarchicalRiskParity(BaseHierarchicalOptimization):
|
|
170
171
|
|
171
172
|
If a float is provided, it is applied to each asset.
|
172
173
|
If a dictionary is provided, its (key/value) pair must be the
|
173
|
-
(asset name/asset fee) and the input `X` of the `fit`
|
174
|
+
(asset name/asset fee) and the input `X` of the `fit` method must be a
|
174
175
|
DataFrame with the assets names in columns.
|
175
176
|
The default value is `0.0`.
|
176
177
|
|
@@ -193,7 +194,7 @@ class HierarchicalRiskParity(BaseHierarchicalOptimization):
|
|
193
194
|
Previous weights of the assets. Previous weights are used to compute the
|
194
195
|
portfolio total cost. If a float is provided, it is applied to each asset.
|
195
196
|
If a dictionary is provided, its (key/value) pair must be the
|
196
|
-
(asset name/asset previous weight) and the input `X` of the `fit`
|
197
|
+
(asset name/asset previous weight) and the input `X` of the `fit` method must
|
197
198
|
be a DataFrame with the assets names in columns.
|
198
199
|
The default (`None`) means no previous weights.
|
199
200
|
|
@@ -100,7 +100,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
100
100
|
If a float is provided, it is applied to each asset.
|
101
101
|
`None` is equivalent to `-np.Inf` (no lower bound).
|
102
102
|
If a dictionary is provided, its (key/value) pair must be the
|
103
|
-
(asset name/asset minium weight) and the input `X` of the `fit`
|
103
|
+
(asset name/asset minium weight) and the input `X` of the `fit` method must
|
104
104
|
be a DataFrame with the assets names in columns.
|
105
105
|
When using a dictionary, assets values that are not provided are assigned
|
106
106
|
a minimum weight of `0.0`.
|
@@ -119,7 +119,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
119
119
|
If a float is provided, it is applied to each asset.
|
120
120
|
`None` is equivalent to `+np.Inf` (no upper bound).
|
121
121
|
If a dictionary is provided, its (key/value) pair must be the
|
122
|
-
(asset name/asset maximum weight) and the input `X` of the `fit`
|
122
|
+
(asset name/asset maximum weight) and the input `X` of the `fit` method must
|
123
123
|
be a DataFrame with the assets names in columns.
|
124
124
|
When using a dictionary, assets values that are not provided are assigned
|
125
125
|
a minimum weight of `1.0`.
|
@@ -172,7 +172,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
172
172
|
|
173
173
|
with :math:`c_{i}` the transaction cost of asset i, :math:`w_{i}` its weight
|
174
174
|
and :math:`w\_prev_{i}` its previous weight (defined in `previous_weights`).
|
175
|
-
The float :math:`total\_cost` is
|
175
|
+
The float :math:`total\_cost` is impacting the portfolio expected return in the optimization:
|
176
176
|
|
177
177
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_cost
|
178
178
|
|
@@ -181,7 +181,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
181
181
|
|
182
182
|
If a float is provided, it is applied to each asset.
|
183
183
|
If a dictionary is provided, its (key/value) pair must be the
|
184
|
-
(asset name/asset cost) and the input `X` of the `fit`
|
184
|
+
(asset name/asset cost) and the input `X` of the `fit` method must be a
|
185
185
|
DataFrame with the assets names in columns.
|
186
186
|
The default value is `0.0`.
|
187
187
|
|
@@ -190,7 +190,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
190
190
|
Based on the above formula, the periodicity of the transaction costs
|
191
191
|
needs to be homogenous to the periodicity of :math:`\mu`. For example, if
|
192
192
|
the input `X` is composed of **daily** returns, the `transaction_costs` need
|
193
|
-
to be expressed
|
193
|
+
to be expressed as **daily** costs.
|
194
194
|
(See :ref:`sphx_glr_auto_examples_1_mean_risk_plot_6_transaction_costs.py`)
|
195
195
|
|
196
196
|
management_fees : float | dict[str, float] | array-like of shape (n_assets, ), default=0.0
|
@@ -200,7 +200,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
200
200
|
.. math:: total\_fee = \sum_{i=1}^{N} f_{i} \times w_{i}
|
201
201
|
|
202
202
|
with :math:`f_{i}` the management fee of asset i and :math:`w_{i}` its weight.
|
203
|
-
The float :math:`total\_fee` is
|
203
|
+
The float :math:`total\_fee` is impacting the portfolio expected return in the optimization:
|
204
204
|
|
205
205
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_fee
|
206
206
|
|
@@ -209,7 +209,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
209
209
|
|
210
210
|
If a float is provided, it is applied to each asset.
|
211
211
|
If a dictionary is provided, its (key/value) pair must be the
|
212
|
-
(asset name/asset fee) and the input `X` of the `fit`
|
212
|
+
(asset name/asset fee) and the input `X` of the `fit` method must be a
|
213
213
|
DataFrame with the assets names in columns.
|
214
214
|
The default value is `0.0`.
|
215
215
|
|
@@ -233,7 +233,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
233
233
|
portfolio cost and the portfolio turnover.
|
234
234
|
If a float is provided, it is applied to each asset.
|
235
235
|
If a dictionary is provided, its (key/value) pair must be the
|
236
|
-
(asset name/asset previous weight) and the input `X` of the `fit`
|
236
|
+
(asset name/asset previous weight) and the input `X` of the `fit` method must
|
237
237
|
be a DataFrame with the assets names in columns.
|
238
238
|
The default (`None`) means no previous weights.
|
239
239
|
|
@@ -290,7 +290,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
290
290
|
|
291
291
|
With "ref1", "ref2" ... the assets names or the groups names provided
|
292
292
|
in the parameter `groups`. Assets names can be referenced without the need of
|
293
|
-
`groups` if the input `X` of the `fit`
|
293
|
+
`groups` if the input `X` of the `fit` method is a DataFrame with these
|
294
294
|
assets names in columns.
|
295
295
|
|
296
296
|
Examples:
|
@@ -304,7 +304,7 @@ class ConvexOptimization(BaseOptimization, ABC):
|
|
304
304
|
groups : dict[str, list[str]] or array-like of shape (n_groups, n_assets), optional
|
305
305
|
The assets groups referenced in `linear_constraints`.
|
306
306
|
If a dictionary is provided, its (key/value) pair must be the
|
307
|
-
(asset name/asset groups) and the input `X` of the `fit`
|
307
|
+
(asset name/asset groups) and the input `X` of the `fit` method must be a
|
308
308
|
DataFrame with the assets names in columns.
|
309
309
|
|
310
310
|
Examples:
|
@@ -19,16 +19,16 @@ class DistributionallyRobustCVaR(ConvexOptimization):
|
|
19
19
|
|
20
20
|
The Distributionally Robust CVaR model constructs a Wasserstein ball in the space of
|
21
21
|
multivariate and non-discrete probability distributions centered at the uniform
|
22
|
-
distribution on the training samples
|
23
|
-
of the worst-case distribution within this Wasserstein ball.
|
22
|
+
distribution on the training samples and finds the allocation that minimizes the
|
23
|
+
CVaR of the worst-case distribution within this Wasserstein ball.
|
24
24
|
Esfahani and Kuhn [1]_ proved that for piecewise linear objective functions,
|
25
25
|
which is the case of CVaR [2]_, the distributionally robust optimization problem
|
26
26
|
over a Wasserstein ball can be reformulated as finite convex programs.
|
27
27
|
|
28
|
-
Only piecewise linear
|
29
|
-
regularization are not permitted.
|
28
|
+
Only piecewise linear functions are supported, which means that transaction costs
|
29
|
+
and regularization are not permitted.
|
30
30
|
|
31
|
-
A solver like `Mosek` that can
|
31
|
+
A solver like `Mosek` that can handle a high number of constraints is preferred.
|
32
32
|
|
33
33
|
Parameters
|
34
34
|
----------
|
@@ -53,7 +53,7 @@ class DistributionallyRobustCVaR(ConvexOptimization):
|
|
53
53
|
If a float is provided, it is applied to each asset.
|
54
54
|
`None` is equivalent to `-np.Inf` (no lower bound).
|
55
55
|
If a dictionary is provided, its (key/value) pair must be the
|
56
|
-
(asset name/asset minium weight) and the input `X` of the `fit`
|
56
|
+
(asset name/asset minium weight) and the input `X` of the `fit` method must
|
57
57
|
be a DataFrame with the assets names in columns.
|
58
58
|
When using a dictionary, assets values that are not provided are assigned
|
59
59
|
a minimum weight of `0.0`.
|
@@ -72,7 +72,7 @@ class DistributionallyRobustCVaR(ConvexOptimization):
|
|
72
72
|
If a float is provided, it is applied to each asset.
|
73
73
|
`None` is equivalent to `+np.Inf` (no upper bound).
|
74
74
|
If a dictionary is provided, its (key/value) pair must be the
|
75
|
-
(asset name/asset maximum weight) and the input `X` of the `fit`
|
75
|
+
(asset name/asset maximum weight) and the input `X` of the `fit` method must
|
76
76
|
be a DataFrame with the assets names in columns.
|
77
77
|
When using a dictionary, assets values that are not provided are assigned
|
78
78
|
a minimum weight of `1.0`.
|
@@ -128,7 +128,7 @@ class DistributionallyRobustCVaR(ConvexOptimization):
|
|
128
128
|
|
129
129
|
With "ref1", "ref2" ... the assets names or the groups names provided
|
130
130
|
in the parameter `groups`. Assets names can be referenced without the need of
|
131
|
-
`groups` if the input `X` of the `fit`
|
131
|
+
`groups` if the input `X` of the `fit` method is a DataFrame with these
|
132
132
|
assets names in columns.
|
133
133
|
|
134
134
|
Examples:
|
@@ -142,7 +142,7 @@ class DistributionallyRobustCVaR(ConvexOptimization):
|
|
142
142
|
groups : dict[str, list[str]] or array-like of shape (n_groups, n_assets), optional
|
143
143
|
The assets groups referenced in `linear_constraints`.
|
144
144
|
If a dictionary is provided, its (key/value) pair must be the
|
145
|
-
(asset name/asset groups) and the input `X` of the `fit`
|
145
|
+
(asset name/asset groups) and the input `X` of the `fit` method must be a
|
146
146
|
DataFrame with the assets names in columns.
|
147
147
|
|
148
148
|
Examples:
|
@@ -37,7 +37,7 @@ class MaximumDiversification(MeanRisk):
|
|
37
37
|
If a float is provided, it is applied to each asset.
|
38
38
|
`None` is equivalent to `-np.Inf` (no lower bound).
|
39
39
|
If a dictionary is provided, its (key/value) pair must be the
|
40
|
-
(asset name/asset minium weight) and the input `X` of the `fit`
|
40
|
+
(asset name/asset minium weight) and the input `X` of the `fit` method must
|
41
41
|
be a DataFrame with the assets names in columns.
|
42
42
|
When using a dictionary, assets values that are not provided are assigned
|
43
43
|
a minimum weight of `0.0`.
|
@@ -56,7 +56,7 @@ class MaximumDiversification(MeanRisk):
|
|
56
56
|
If a float is provided, it is applied to each asset.
|
57
57
|
`None` is equivalent to `+np.Inf` (no upper bound).
|
58
58
|
If a dictionary is provided, its (key/value) pair must be the
|
59
|
-
(asset name/asset maximum weight) and the input `X` of the `fit`
|
59
|
+
(asset name/asset maximum weight) and the input `X` of the `fit` method must
|
60
60
|
be a DataFrame with the assets names in columns.
|
61
61
|
When using a dictionary, assets values that are not provided are assigned
|
62
62
|
a minimum weight of `1.0`.
|
@@ -109,7 +109,7 @@ class MaximumDiversification(MeanRisk):
|
|
109
109
|
|
110
110
|
with :math:`c_{i}` the transaction cost of asset i, :math:`w_{i}` its weight
|
111
111
|
and :math:`w\_prev_{i}` its previous weight (defined in `previous_weights`).
|
112
|
-
The float :math:`total\_cost` is
|
112
|
+
The float :math:`total\_cost` is impacting the portfolio expected return in the optimization:
|
113
113
|
|
114
114
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_cost
|
115
115
|
|
@@ -118,7 +118,7 @@ class MaximumDiversification(MeanRisk):
|
|
118
118
|
|
119
119
|
If a float is provided, it is applied to each asset.
|
120
120
|
If a dictionary is provided, its (key/value) pair must be the
|
121
|
-
(asset name/asset cost) and the input `X` of the `fit`
|
121
|
+
(asset name/asset cost) and the input `X` of the `fit` method must be a
|
122
122
|
DataFrame with the assets names in columns.
|
123
123
|
The default value is `0.0`.
|
124
124
|
|
@@ -127,7 +127,7 @@ class MaximumDiversification(MeanRisk):
|
|
127
127
|
Based on the above formula, the periodicity of the transaction costs
|
128
128
|
needs to be homogenous to the periodicity of :math:`\mu`. For example, if
|
129
129
|
the input `X` is composed of **daily** returns, the `transaction_costs` need
|
130
|
-
to be expressed
|
130
|
+
to be expressed as **daily** costs.
|
131
131
|
(See :ref:`sphx_glr_auto_examples_1_mean_risk_plot_6_transaction_costs.py`)
|
132
132
|
|
133
133
|
management_fees : float | dict[str, float] | array-like of shape (n_assets, ), default=0.0
|
@@ -137,7 +137,7 @@ class MaximumDiversification(MeanRisk):
|
|
137
137
|
.. math:: total\_fee = \sum_{i=1}^{N} f_{i} \times w_{i}
|
138
138
|
|
139
139
|
with :math:`f_{i}` the management fee of asset i and :math:`w_{i}` its weight.
|
140
|
-
The float :math:`total\_fee` is
|
140
|
+
The float :math:`total\_fee` is impacting the portfolio expected return in the optimization:
|
141
141
|
|
142
142
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_fee
|
143
143
|
|
@@ -146,7 +146,7 @@ class MaximumDiversification(MeanRisk):
|
|
146
146
|
|
147
147
|
If a float is provided, it is applied to each asset.
|
148
148
|
If a dictionary is provided, its (key/value) pair must be the
|
149
|
-
(asset name/asset fee) and the input `X` of the `fit`
|
149
|
+
(asset name/asset fee) and the input `X` of the `fit` method must be a
|
150
150
|
DataFrame with the assets names in columns.
|
151
151
|
The default value is `0.0`.
|
152
152
|
|
@@ -170,7 +170,7 @@ class MaximumDiversification(MeanRisk):
|
|
170
170
|
portfolio cost and the portfolio turnover.
|
171
171
|
If a float is provided, it is applied to each asset.
|
172
172
|
If a dictionary is provided, its (key/value) pair must be the
|
173
|
-
(asset name/asset previous weight) and the input `X` of the `fit`
|
173
|
+
(asset name/asset previous weight) and the input `X` of the `fit` method must
|
174
174
|
be a DataFrame with the assets names in columns.
|
175
175
|
The default (`None`) means no previous weights.
|
176
176
|
|
@@ -205,7 +205,7 @@ class MaximumDiversification(MeanRisk):
|
|
205
205
|
|
206
206
|
With "ref1", "ref2" ... the assets names or the groups names provided
|
207
207
|
in the parameter `groups`. Assets names can be referenced without the need of
|
208
|
-
`groups` if the input `X` of the `fit`
|
208
|
+
`groups` if the input `X` of the `fit` method is a DataFrame with these
|
209
209
|
assets names in columns.
|
210
210
|
|
211
211
|
Examples:
|
@@ -219,7 +219,7 @@ class MaximumDiversification(MeanRisk):
|
|
219
219
|
groups : dict[str, list[str]] or array-like of shape (n_groups, n_assets), optional
|
220
220
|
The assets groups referenced in `linear_constraints`.
|
221
221
|
If a dictionary is provided, its (key/value) pair must be the
|
222
|
-
(asset name/asset groups) and the input `X` of the `fit`
|
222
|
+
(asset name/asset groups) and the input `X` of the `fit` method must be a
|
223
223
|
DataFrame with the assets names in columns.
|
224
224
|
|
225
225
|
Examples:
|
@@ -145,7 +145,7 @@ class MeanRisk(ConvexOptimization):
|
|
145
145
|
If a float is provided, it is applied to each asset.
|
146
146
|
`None` is equivalent to `-np.Inf` (no lower bound).
|
147
147
|
If a dictionary is provided, its (key/value) pair must be the
|
148
|
-
(asset name/asset minium weight) and the input `X` of the `fit`
|
148
|
+
(asset name/asset minium weight) and the input `X` of the `fit` method must
|
149
149
|
be a DataFrame with the assets names in columns.
|
150
150
|
When using a dictionary, assets values that are not provided are assigned
|
151
151
|
a minimum weight of `0.0`.
|
@@ -164,7 +164,7 @@ class MeanRisk(ConvexOptimization):
|
|
164
164
|
If a float is provided, it is applied to each asset.
|
165
165
|
`None` is equivalent to `+np.Inf` (no upper bound).
|
166
166
|
If a dictionary is provided, its (key/value) pair must be the
|
167
|
-
(asset name/asset maximum weight) and the input `X` of the `fit`
|
167
|
+
(asset name/asset maximum weight) and the input `X` of the `fit` method must
|
168
168
|
be a DataFrame with the assets names in columns.
|
169
169
|
When using a dictionary, assets values that are not provided are assigned
|
170
170
|
a minimum weight of `1.0`.
|
@@ -217,7 +217,7 @@ class MeanRisk(ConvexOptimization):
|
|
217
217
|
|
218
218
|
with :math:`c_{i}` the transaction cost of asset i, :math:`w_{i}` its weight
|
219
219
|
and :math:`w\_prev_{i}` its previous weight (defined in `previous_weights`).
|
220
|
-
The float :math:`total\_cost` is
|
220
|
+
The float :math:`total\_cost` is impacting the portfolio expected return in the optimization:
|
221
221
|
|
222
222
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_cost
|
223
223
|
|
@@ -226,7 +226,7 @@ class MeanRisk(ConvexOptimization):
|
|
226
226
|
|
227
227
|
If a float is provided, it is applied to each asset.
|
228
228
|
If a dictionary is provided, its (key/value) pair must be the
|
229
|
-
(asset name/asset cost) and the input `X` of the `fit`
|
229
|
+
(asset name/asset cost) and the input `X` of the `fit` method must be a
|
230
230
|
DataFrame with the assets names in columns.
|
231
231
|
The default value is `0.0`.
|
232
232
|
|
@@ -235,7 +235,7 @@ class MeanRisk(ConvexOptimization):
|
|
235
235
|
Based on the above formula, the periodicity of the transaction costs
|
236
236
|
needs to be homogenous to the periodicity of :math:`\mu`. For example, if
|
237
237
|
the input `X` is composed of **daily** returns, the `transaction_costs` need
|
238
|
-
to be expressed
|
238
|
+
to be expressed as **daily** costs.
|
239
239
|
(See :ref:`sphx_glr_auto_examples_1_mean_risk_plot_6_transaction_costs.py`)
|
240
240
|
|
241
241
|
management_fees : float | dict[str, float] | array-like of shape (n_assets, ), default=0.0
|
@@ -245,7 +245,7 @@ class MeanRisk(ConvexOptimization):
|
|
245
245
|
.. math:: total\_fee = \sum_{i=1}^{N} f_{i} \times w_{i}
|
246
246
|
|
247
247
|
with :math:`f_{i}` the management fee of asset i and :math:`w_{i}` its weight.
|
248
|
-
The float :math:`total\_fee` is
|
248
|
+
The float :math:`total\_fee` is impacting the portfolio expected return in the optimization:
|
249
249
|
|
250
250
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_fee
|
251
251
|
|
@@ -254,7 +254,7 @@ class MeanRisk(ConvexOptimization):
|
|
254
254
|
|
255
255
|
If a float is provided, it is applied to each asset.
|
256
256
|
If a dictionary is provided, its (key/value) pair must be the
|
257
|
-
(asset name/asset fee) and the input `X` of the `fit`
|
257
|
+
(asset name/asset fee) and the input `X` of the `fit` method must be a
|
258
258
|
DataFrame with the assets names in columns.
|
259
259
|
The default value is `0.0`.
|
260
260
|
|
@@ -278,7 +278,7 @@ class MeanRisk(ConvexOptimization):
|
|
278
278
|
portfolio cost and the portfolio turnover.
|
279
279
|
If a float is provided, it is applied to each asset.
|
280
280
|
If a dictionary is provided, its (key/value) pair must be the
|
281
|
-
(asset name/asset previous weight) and the input `X` of the `fit`
|
281
|
+
(asset name/asset previous weight) and the input `X` of the `fit` method must
|
282
282
|
be a DataFrame with the assets names in columns.
|
283
283
|
The default (`None`) means no previous weights.
|
284
284
|
|
@@ -335,7 +335,7 @@ class MeanRisk(ConvexOptimization):
|
|
335
335
|
|
336
336
|
With "ref1", "ref2" ... the assets names or the groups names provided
|
337
337
|
in the parameter `groups`. Assets names can be referenced without the need of
|
338
|
-
`groups` if the input `X` of the `fit`
|
338
|
+
`groups` if the input `X` of the `fit` method is a DataFrame with these
|
339
339
|
assets names in columns.
|
340
340
|
|
341
341
|
Examples:
|
@@ -349,7 +349,7 @@ class MeanRisk(ConvexOptimization):
|
|
349
349
|
groups : dict[str, list[str]] or array-like of shape (n_groups, n_assets), optional
|
350
350
|
The assets groups referenced in `linear_constraints`.
|
351
351
|
If a dictionary is provided, its (key/value) pair must be the
|
352
|
-
(asset name/asset groups) and the input `X` of the `fit`
|
352
|
+
(asset name/asset groups) and the input `X` of the `fit` method must be a
|
353
353
|
DataFrame with the assets names in columns.
|
354
354
|
|
355
355
|
Examples:
|
@@ -84,7 +84,7 @@ class RiskBudgeting(ConvexOptimization):
|
|
84
84
|
risk_budget : dict[str, float] | array-like of shape (n_assets,), optional
|
85
85
|
Risk budget allocated to each asset.
|
86
86
|
If a dictionary is provided, its (key/value) pair must be the
|
87
|
-
(asset name/asset risk budget) and the input `X` of the `fit`
|
87
|
+
(asset name/asset risk budget) and the input `X` of the `fit` method must be a
|
88
88
|
DataFrame with the assets names in columns.
|
89
89
|
The default (`None`) is to use the identity vector, reducing the risk
|
90
90
|
budgeting to a risk-parity (each asset contributing equally to the total risk).
|
@@ -101,7 +101,7 @@ class RiskBudgeting(ConvexOptimization):
|
|
101
101
|
If a float is provided, it is applied to each asset.
|
102
102
|
`None` is equivalent to `-np.Inf` (no lower bound).
|
103
103
|
If a dictionary is provided, its (key/value) pair must be the
|
104
|
-
(asset name/asset minium weight) and the input `X` of the `fit`
|
104
|
+
(asset name/asset minium weight) and the input `X` of the `fit` method must
|
105
105
|
be a DataFrame with the assets names in columns.
|
106
106
|
When using a dictionary, assets values that are not provided are assigned
|
107
107
|
a minimum weight of `0.0`.
|
@@ -120,7 +120,7 @@ class RiskBudgeting(ConvexOptimization):
|
|
120
120
|
If a float is provided, it is applied to each asset.
|
121
121
|
`None` is equivalent to `+np.Inf` (no upper bound).
|
122
122
|
If a dictionary is provided, its (key/value) pair must be the
|
123
|
-
(asset name/asset maximum weight) and the input `X` of the `fit`
|
123
|
+
(asset name/asset maximum weight) and the input `X` of the `fit` method must
|
124
124
|
be a DataFrame with the assets names in columns.
|
125
125
|
When using a dictionary, assets values that are not provided are assigned
|
126
126
|
a minimum weight of `1.0`.
|
@@ -142,7 +142,7 @@ class RiskBudgeting(ConvexOptimization):
|
|
142
142
|
|
143
143
|
with :math:`c_{i}` the transaction cost of asset i, :math:`w_{i}` its weight
|
144
144
|
and :math:`w\_prev_{i}` its previous weight (defined in `previous_weights`).
|
145
|
-
The float :math:`total\_cost` is
|
145
|
+
The float :math:`total\_cost` is impacting the portfolio expected return in the optimization:
|
146
146
|
|
147
147
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_cost
|
148
148
|
|
@@ -151,7 +151,7 @@ class RiskBudgeting(ConvexOptimization):
|
|
151
151
|
|
152
152
|
If a float is provided, it is applied to each asset.
|
153
153
|
If a dictionary is provided, its (key/value) pair must be the
|
154
|
-
(asset name/asset cost) and the input `X` of the `fit`
|
154
|
+
(asset name/asset cost) and the input `X` of the `fit` method must be a
|
155
155
|
DataFrame with the assets names in columns.
|
156
156
|
The default value is `0.0`.
|
157
157
|
|
@@ -160,7 +160,7 @@ class RiskBudgeting(ConvexOptimization):
|
|
160
160
|
Based on the above formula, the periodicity of the transaction costs
|
161
161
|
needs to be homogenous to the periodicity of :math:`\mu`. For example, if
|
162
162
|
the input `X` is composed of **daily** returns, the `transaction_costs` need
|
163
|
-
to be expressed
|
163
|
+
to be expressed as **daily** costs.
|
164
164
|
(See :ref:`sphx_glr_auto_examples_1_mean_risk_plot_6_transaction_costs.py`)
|
165
165
|
|
166
166
|
management_fees : float | dict[str, float] | array-like of shape (n_assets, ), default=0.0
|
@@ -170,7 +170,7 @@ class RiskBudgeting(ConvexOptimization):
|
|
170
170
|
.. math:: total\_fee = \sum_{i=1}^{N} f_{i} \times w_{i}
|
171
171
|
|
172
172
|
with :math:`f_{i}` the management fee of asset i and :math:`w_{i}` its weight.
|
173
|
-
The float :math:`total\_fee` is
|
173
|
+
The float :math:`total\_fee` is impacting the portfolio expected return in the optimization:
|
174
174
|
|
175
175
|
.. math:: expected\_return = \mu^{T} \cdot w - total\_fee
|
176
176
|
|
@@ -179,7 +179,7 @@ class RiskBudgeting(ConvexOptimization):
|
|
179
179
|
|
180
180
|
If a float is provided, it is applied to each asset.
|
181
181
|
If a dictionary is provided, its (key/value) pair must be the
|
182
|
-
(asset name/asset fee) and the input `X` of the `fit`
|
182
|
+
(asset name/asset fee) and the input `X` of the `fit` method must be a
|
183
183
|
DataFrame with the assets names in columns.
|
184
184
|
The default value is `0.0`.
|
185
185
|
|
@@ -203,7 +203,7 @@ class RiskBudgeting(ConvexOptimization):
|
|
203
203
|
portfolio cost and the portfolio turnover.
|
204
204
|
If a float is provided, it is applied to each asset.
|
205
205
|
If a dictionary is provided, its (key/value) pair must be the
|
206
|
-
(asset name/asset previous weight) and the input `X` of the `fit`
|
206
|
+
(asset name/asset previous weight) and the input `X` of the `fit` method must
|
207
207
|
be a DataFrame with the assets names in columns.
|
208
208
|
The default (`None`) means no previous weights.
|
209
209
|
|
@@ -218,7 +218,7 @@ class RiskBudgeting(ConvexOptimization):
|
|
218
218
|
|
219
219
|
With "ref1", "ref2" ... the assets names or the groups names provided
|
220
220
|
in the parameter `groups`. Assets names can be referenced without the need of
|
221
|
-
`groups` if the input `X` of the `fit`
|
221
|
+
`groups` if the input `X` of the `fit` method is a DataFrame with these
|
222
222
|
assets names in columns.
|
223
223
|
|
224
224
|
Examples:
|
@@ -232,7 +232,7 @@ class RiskBudgeting(ConvexOptimization):
|
|
232
232
|
groups : dict[str, list[str]] or array-like of shape (n_groups, n_assets), optional
|
233
233
|
The assets groups referenced in `linear_constraints`.
|
234
234
|
If a dictionary is provided, its (key/value) pair must be the
|
235
|
-
(asset name/asset groups) and the input `X` of the `fit`
|
235
|
+
(asset name/asset groups) and the input `X` of the `fit` method must be a
|
236
236
|
DataFrame with the assets names in columns.
|
237
237
|
|
238
238
|
Examples:
|
@@ -26,11 +26,13 @@ class StackingOptimization(BaseOptimization, BaseComposition):
|
|
26
26
|
"""Stack of optimizations with a final optimization.
|
27
27
|
|
28
28
|
Stacking Optimization is an ensemble method that consists in stacking the output of
|
29
|
-
individual
|
29
|
+
individual portfolio optimizations with a final portfolio optimization.
|
30
30
|
|
31
|
-
The weights are the dot-product of individual
|
32
|
-
|
33
|
-
|
31
|
+
The weights are the dot-product of individual optimizations weights with the final
|
32
|
+
optimization weights.
|
33
|
+
|
34
|
+
Stacking allows to use the strength of each individual portfolio optimization by
|
35
|
+
using their output as input of a final portfolio optimization.
|
34
36
|
|
35
37
|
To avoid data leakage, out-of-sample estimates are used to fit the outer
|
36
38
|
optimization.
|
@@ -17,7 +17,7 @@ class BlackLitterman(BasePrior):
|
|
17
17
|
"""Black & Litterman Prior Model estimator.
|
18
18
|
|
19
19
|
The Black & Litterman model [1]_ takes a Bayesian approach by using a prior estimate
|
20
|
-
of the assets expected returns and covariance matrix which are updated using the
|
20
|
+
of the assets expected returns and covariance matrix, which are updated using the
|
21
21
|
analyst views to get a posterior estimate.
|
22
22
|
|
23
23
|
Parameters
|
@@ -44,7 +44,7 @@ class BlackLitterman(BasePrior):
|
|
44
44
|
groups : dict[str, list[str]] or array-like of strings of shape (n_groups, n_assets), optional
|
45
45
|
The assets groups to be referenced in `views`.
|
46
46
|
If a dictionary is provided, its (key/value) pair must be the
|
47
|
-
(asset name/asset groups) and the input `X` of the `fit`
|
47
|
+
(asset name/asset groups) and the input `X` of the `fit` method must be a
|
48
48
|
DataFrame with the assets names in columns.
|
49
49
|
|
50
50
|
Examples:
|
skfolio/prior/_factor_model.py
CHANGED
@@ -120,10 +120,10 @@ class FactorModel(BasePrior):
|
|
120
120
|
|
121
121
|
The purpose of Factor Models is to impose a structure on financial variables and
|
122
122
|
their covariance matrix by explaining them through a small number of common factors.
|
123
|
-
This can help
|
123
|
+
This can help overcome estimation error by reducing the number of parameters,
|
124
124
|
i.e. the dimensionality of the estimation problem, making portfolio optimization
|
125
125
|
more robust against noise in the data. Factor Models also provide a decomposition of
|
126
|
-
financial risk
|
126
|
+
financial risk into systematic and security-specific components.
|
127
127
|
|
128
128
|
Parameters
|
129
129
|
----------
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: skfolio
|
3
|
-
Version: 0.0.
|
3
|
+
Version: 0.0.9
|
4
4
|
Summary: Portfolio optimization built on top of scikit-learn
|
5
5
|
Author-email: Hugo Delatte <delatte.hugo@gmail.com>
|
6
6
|
Maintainer-email: Hugo Delatte <delatte.hugo@gmail.com>
|
@@ -73,7 +73,6 @@ Requires-Dist: kaleido ; extra == 'docs'
|
|
73
73
|
Requires-Dist: sphinx-copybutton ; extra == 'docs'
|
74
74
|
Requires-Dist: numpydoc ; extra == 'docs'
|
75
75
|
Requires-Dist: sphinx-togglebutton ; extra == 'docs'
|
76
|
-
Requires-Dist: jupyterlite-sphinx ; extra == 'docs'
|
77
76
|
Requires-Dist: sphinx-favicon ; extra == 'docs'
|
78
77
|
Requires-Dist: sphinx-prompt ; extra == 'docs'
|
79
78
|
Requires-Dist: sphinxext.opengraph ; extra == 'docs'
|
@@ -127,8 +126,10 @@ Requires-Dist: ruff ; extra == 'tests'
|
|
127
126
|
|
128
127
|
|
129
128
|
**skfolio** is a Python library for portfolio optimization built on top of scikit-learn.
|
130
|
-
It
|
131
|
-
cross-validate portfolio models.
|
129
|
+
It offers a unified interface and tools compatible with scikit-learn to build, fine-tune,
|
130
|
+
and cross-validate portfolio models.
|
131
|
+
|
132
|
+
It is distributed under the open source 3-Clause BSD license.
|
132
133
|
|
133
134
|
.. image:: https://raw.githubusercontent.com/skfolio/skfolio/master/docs/_static/expo.jpg
|
134
135
|
:target: https://skfolio.org/auto_examples/
|
@@ -145,7 +146,7 @@ Important links
|
|
145
146
|
Installation
|
146
147
|
~~~~~~~~~~~~
|
147
148
|
|
148
|
-
|
149
|
+
`skfolio` is available on PyPI and can be installed with::
|
149
150
|
|
150
151
|
pip install -U skfolio
|
151
152
|
|
@@ -154,7 +155,7 @@ To install skfolio::
|
|
154
155
|
Dependencies
|
155
156
|
~~~~~~~~~~~~
|
156
157
|
|
157
|
-
skfolio requires:
|
158
|
+
`skfolio` requires:
|
158
159
|
|
159
160
|
- python (>= |PythonMinVersion|)
|
160
161
|
- numpy (>= |NumpyMinVersion|)
|
@@ -167,30 +168,37 @@ skfolio requires:
|
|
167
168
|
|
168
169
|
Key Concepts
|
169
170
|
~~~~~~~~~~~~
|
170
|
-
Since the development of modern portfolio theory by Markowitz (1952), mean-variance
|
171
|
-
has received considerable attention.
|
172
|
-
|
173
|
-
|
174
|
-
|
171
|
+
Since the development of modern portfolio theory by Markowitz (1952), mean-variance
|
172
|
+
optimization (MVO) has received considerable attention.
|
173
|
+
|
174
|
+
Unfortunately, it faces a number of shortcomings, including high sensitivity to the
|
175
|
+
input parameters (expected returns and covariance), weight concentration, high turnover,
|
176
|
+
and poor out-of-sample performance.
|
177
|
+
|
178
|
+
It is well known that naive allocation (1/N, inverse-vol, etc.) tends to outperform
|
179
|
+
MVO out-of-sample (DeMiguel, 2007).
|
175
180
|
|
176
|
-
Numerous approaches have been developed to alleviate these shortcomings (shrinkage,
|
177
|
-
additional constraints, regularization, uncertainty set, higher moments,
|
178
|
-
left-tail risk optimization, distributionally robust
|
179
|
-
ensemble methods
|
181
|
+
Numerous approaches have been developed to alleviate these shortcomings (shrinkage,
|
182
|
+
additional constraints, regularization, uncertainty set, higher moments, Bayesian
|
183
|
+
approaches, coherent risk measures, left-tail risk optimization, distributionally robust
|
184
|
+
optimization, factor model, risk-parity, hierarchical clustering, ensemble methods,
|
185
|
+
pre-selection, etc.).
|
180
186
|
|
181
|
-
With this large number of methods, added to the fact that they can be composed together
|
182
|
-
|
183
|
-
and
|
187
|
+
With this large number of methods, added to the fact that they can be composed together,
|
188
|
+
there is a need for a unified framework with a machine learning approach to perform
|
189
|
+
model selection, validation, and parameter tuning while reducing the risk of data
|
190
|
+
leakage and overfitting.
|
191
|
+
|
192
|
+
This framework is built on scikit-learn's API.
|
184
193
|
|
185
194
|
Available models
|
186
195
|
~~~~~~~~~~~~~~~~
|
187
|
-
The current release contains:
|
188
196
|
|
189
|
-
* Optimization
|
197
|
+
* Portfolio Optimization:
|
190
198
|
* Naive:
|
191
199
|
* Equal-Weighted
|
192
200
|
* Inverse-Volatility
|
193
|
-
* Random (
|
201
|
+
* Random (Dirichlet)
|
194
202
|
* Convex:
|
195
203
|
* Mean-Risk
|
196
204
|
* Risk Budgeting
|
@@ -200,27 +208,27 @@ The current release contains:
|
|
200
208
|
* Hierarchical Risk Parity
|
201
209
|
* Hierarchical Equal Risk Contribution
|
202
210
|
* Nested Clusters Optimization
|
203
|
-
* Ensemble
|
211
|
+
* Ensemble Methods:
|
204
212
|
* Stacking Optimization
|
205
213
|
|
206
|
-
*
|
207
|
-
*
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
* Distance
|
214
|
+
* Expected Returns Estimator:
|
215
|
+
* Empirical
|
216
|
+
* Exponentially Weighted
|
217
|
+
* Equilibrium
|
218
|
+
* Shrinkage
|
219
|
+
|
220
|
+
* Covariance Estimator:
|
221
|
+
* Empirical
|
222
|
+
* Gerber
|
223
|
+
* Denoising
|
224
|
+
* Denoting
|
225
|
+
* Exponentially Weighted
|
226
|
+
* Ledoit-Wolf
|
227
|
+
* Oracle Approximating Shrinkage
|
228
|
+
* Shrunk Covariance
|
229
|
+
* Graphical Lasso CV
|
230
|
+
|
231
|
+
* Distance Estimator:
|
224
232
|
* Pearson Distance
|
225
233
|
* Kendall Distance
|
226
234
|
* Spearman Distance
|
@@ -228,12 +236,12 @@ The current release contains:
|
|
228
236
|
* Distance Correlation
|
229
237
|
* Variation of Information
|
230
238
|
|
231
|
-
* Prior
|
239
|
+
* Prior Estimator:
|
232
240
|
* Empirical
|
233
241
|
* Black & Litterman
|
234
242
|
* Factor Model
|
235
243
|
|
236
|
-
* Uncertainty Set
|
244
|
+
* Uncertainty Set Estimator:
|
237
245
|
* On Expected Returns:
|
238
246
|
* Empirical
|
239
247
|
* Circular Bootstrap
|
@@ -241,18 +249,18 @@ The current release contains:
|
|
241
249
|
* Empirical
|
242
250
|
* Circular bootstrap
|
243
251
|
|
244
|
-
* Pre-Selection
|
252
|
+
* Pre-Selection Transformer:
|
245
253
|
* Non-Dominated Selection
|
246
254
|
* Select K Extremes (Best or Worst)
|
247
255
|
* Drop Highly Correlated Assets
|
248
256
|
|
249
257
|
* Cross-Validation and Model Selection:
|
250
|
-
* Compatible with all `sklearn` methods (KFold,
|
258
|
+
* Compatible with all `sklearn` methods (KFold, etc.)
|
251
259
|
* Walk Forward
|
252
|
-
* Combinatorial Purged Cross-
|
260
|
+
* Combinatorial Purged Cross-Validation
|
253
261
|
|
254
262
|
* Hyper-Parameter Tuning:
|
255
|
-
* Compatible with all `sklearn` methods (GridSearchCV, RandomizedSearchCV
|
263
|
+
* Compatible with all `sklearn` methods (GridSearchCV, RandomizedSearchCV)
|
256
264
|
|
257
265
|
* Risk Measures:
|
258
266
|
* Variance
|
@@ -276,9 +284,24 @@ The current release contains:
|
|
276
284
|
* Skew
|
277
285
|
* Kurtosis
|
278
286
|
|
287
|
+
* Optimization Features:
|
288
|
+
* Minimize Risk
|
289
|
+
* Maximize Returns
|
290
|
+
* Maximize Utility
|
291
|
+
* Maximize Ratio
|
292
|
+
* Transaction Costs
|
293
|
+
* Management Fees
|
294
|
+
* L1 and L2 Regularization
|
295
|
+
* Weight Constraints
|
296
|
+
* Group Constraints
|
297
|
+
* Budget Constraints
|
298
|
+
* Tracking Error Constraints
|
299
|
+
* Turnover Constraints
|
300
|
+
|
279
301
|
Quickstart
|
280
302
|
~~~~~~~~~~
|
281
|
-
The code snippets below are designed to introduce
|
303
|
+
The code snippets below are designed to introduce the functionality of `skfolio` so you
|
304
|
+
can start using it quickly. It follows the same API as scikit-learn.
|
282
305
|
|
283
306
|
Imports
|
284
307
|
-------
|
@@ -590,9 +613,9 @@ Combinatorial Purged Cross-Validation
|
|
590
613
|
Recognition
|
591
614
|
~~~~~~~~~~~
|
592
615
|
|
593
|
-
We would like to
|
594
|
-
scikit-learn and cvxpy but also the contributors of the following packages that
|
595
|
-
|
616
|
+
We would like to thank all contributors behind our direct dependencies, such as
|
617
|
+
scikit-learn and cvxpy, but also the contributors of the following packages that were a
|
618
|
+
source of inspiration:
|
596
619
|
|
597
620
|
* PyPortfolioOpt
|
598
621
|
* Riskfolio-Lib
|
@@ -605,11 +628,11 @@ were a source of inspiration:
|
|
605
628
|
Citation
|
606
629
|
~~~~~~~~
|
607
630
|
|
608
|
-
If you use skfolio in a scientific publication, we would appreciate citations:
|
631
|
+
If you use `skfolio` in a scientific publication, we would appreciate citations:
|
609
632
|
|
610
633
|
Bibtex entry::
|
611
634
|
|
612
|
-
@misc{
|
635
|
+
@misc{skfolio,
|
613
636
|
author = {Hugo Delatte},
|
614
637
|
title = {skfolio},
|
615
638
|
year = {2023},
|
@@ -18,7 +18,7 @@ skfolio/measures/_measures.py,sha256=GyMeyJAK9m6OkAd6o6gKyoWnwM1kbpM14156JjPGitA
|
|
18
18
|
skfolio/metrics/__init__.py,sha256=MomHJ5_bgjq4qUwGS2bfhNmG_ld0oQ4wK6y0Yy_Eonc,75
|
19
19
|
skfolio/metrics/_scorer.py,sha256=f5JYeKWu6Xmr4kbuKnWNmrQGwUzFNif1JCooVD_wgyM,4048
|
20
20
|
skfolio/model_selection/__init__.py,sha256=QYYm5lYyioZuPnsTu-b3lz-tCcl3Gwrx-y9IIvep13A,453
|
21
|
-
skfolio/model_selection/_combinatorial.py,sha256=
|
21
|
+
skfolio/model_selection/_combinatorial.py,sha256=Bq9w7awDbx0DxqbD9X7YrST_TNRlv5gKkTNb_q8dFcc,14458
|
22
22
|
skfolio/model_selection/_validation.py,sha256=WkLBFtkj7plXbj4WYbbgWkVQNOx4UXM1Xf0Wz565T-A,7386
|
23
23
|
skfolio/model_selection/_walk_forward.py,sha256=Amg3c2yjIEZQgWqcZQHRfusx56Pt6quW2CHTWnCIid0,7282
|
24
24
|
skfolio/moments/__init__.py,sha256=vxm3b76SPjQgjsNsrR3DNY4FvKylGA7vDHMJwm5cR5U,746
|
@@ -29,22 +29,22 @@ skfolio/moments/expected_returns/__init__.py,sha256=NETEcKKYKsQvzUU4ZIq6mgT14zdr
|
|
29
29
|
skfolio/moments/expected_returns/_base.py,sha256=RCheYVmvi7W5XFliI0vvO42PQdyxYtQbVoRakxN1WsU,697
|
30
30
|
skfolio/moments/expected_returns/_expected_returns.py,sha256=BarbKe5JdvZSAzwPKYUnzTkuPL_QtAvw0WvF8m_KEiE,13131
|
31
31
|
skfolio/optimization/__init__.py,sha256=vXIbwWJL48zJ1jy7ZB2PPBVx7rZo0vVA8QQQuD-L6ts,1021
|
32
|
-
skfolio/optimization/_base.py,sha256
|
32
|
+
skfolio/optimization/_base.py,sha256=F7tEp5jlUTgn1TcrywYav823RLTb_AswUj6sD3vJa8k,5275
|
33
33
|
skfolio/optimization/cluster/__init__.py,sha256=M3xVdYhNKp4e9CB7hzb4yjTxkkNCHh7Mt_KGFFrkOgs,388
|
34
|
-
skfolio/optimization/cluster/_nco.py,sha256=
|
34
|
+
skfolio/optimization/cluster/_nco.py,sha256=SRJ1vHz7aHGCYfFLIKanKyephN8Y_GeQt-qef7LfSz8,14577
|
35
35
|
skfolio/optimization/cluster/hierarchical/__init__.py,sha256=YnfcPHvjwB6kcG4hoQqc0NqIJKaG7OjBtmXNbOxCq08,405
|
36
|
-
skfolio/optimization/cluster/hierarchical/_base.py,sha256=
|
37
|
-
skfolio/optimization/cluster/hierarchical/_herc.py,sha256=
|
38
|
-
skfolio/optimization/cluster/hierarchical/_hrp.py,sha256=
|
36
|
+
skfolio/optimization/cluster/hierarchical/_base.py,sha256=ClJaDJIFkr50Y-HI9TtExf9z27wGRSbSJpO9i2KG3hg,17036
|
37
|
+
skfolio/optimization/cluster/hierarchical/_herc.py,sha256=u6NUB3JfUHJ7czN644QMMI34a2nUvNJfalhq7XvMj6c,17057
|
38
|
+
skfolio/optimization/cluster/hierarchical/_hrp.py,sha256=JF3kbD7ABmG-LjOjkxod6VxM3vo6jYI1UaLBUcTA-A4,15941
|
39
39
|
skfolio/optimization/convex/__init__.py,sha256=F6BPFikTo0B-7JCKazqLGEwM3RkgTNbFm5GAGkaq9Uo,570
|
40
|
-
skfolio/optimization/convex/_base.py,sha256=
|
41
|
-
skfolio/optimization/convex/_distributionally_robust.py,sha256=
|
42
|
-
skfolio/optimization/convex/_maximum_diversification.py,sha256=
|
43
|
-
skfolio/optimization/convex/_mean_risk.py,sha256=
|
44
|
-
skfolio/optimization/convex/_risk_budgeting.py,sha256=
|
40
|
+
skfolio/optimization/convex/_base.py,sha256=Zj4fXHlqms-fWTD_cKPhXCm9WADb2W54nzG5-W7JBEk,75276
|
41
|
+
skfolio/optimization/convex/_distributionally_robust.py,sha256=LIPyWUseAfqq5cg1iBVUZeh42R1cgzMO2VTD7IisXlw,17287
|
42
|
+
skfolio/optimization/convex/_maximum_diversification.py,sha256=t8GZYcFfOMxTU4seecnobWp_o0zYbBPU8E9sx41yzTE,19114
|
43
|
+
skfolio/optimization/convex/_mean_risk.py,sha256=y_6H9IbcJR_Np3W2lvgju3BvF0ELYvvr1O--COnnZjI,42979
|
44
|
+
skfolio/optimization/convex/_risk_budgeting.py,sha256=EVYU1Fv2suiEM27eXCBlE0cEDez7TufZAIgzoDxAAZM,23469
|
45
45
|
skfolio/optimization/ensemble/__init__.py,sha256=8TXxcxH2_gG3C1xtgQj9OHHr0Le8lhdejtlURL6T3ZY,158
|
46
46
|
skfolio/optimization/ensemble/_base.py,sha256=yHQGOfI59lR5_Yd02M83eO6NTw-7D7s-ryuN74UOe2w,3271
|
47
|
-
skfolio/optimization/ensemble/_stacking.py,sha256
|
47
|
+
skfolio/optimization/ensemble/_stacking.py,sha256=d9sQEujDkH8jCBgtP8MUNGt_kOmx6KFO90oXHp-Hey4,12924
|
48
48
|
skfolio/optimization/naive/__init__.py,sha256=Dkr55R48urC-jfYN007NTbei16N91Na_EDYLVqzhGgQ,147
|
49
49
|
skfolio/optimization/naive/_naive.py,sha256=sadsU8TnNRf28EDLg-KZ4yJm2FvV204vdsb1MhVJyMQ,5561
|
50
50
|
skfolio/population/__init__.py,sha256=rsPPMUv95aTK7vmpPeQwF8NzFuBwk6RDo5g4HNaPzNM,80
|
@@ -59,9 +59,9 @@ skfolio/preprocessing/__init__.py,sha256=15A1bzfPsbfxxXgGP1gstf4R0E_347Wn18z5W5j
|
|
59
59
|
skfolio/preprocessing/_returns.py,sha256=mSheHksBPIuRd9cCFq1r4f3wyChdY6wMa-1j7NoBiFw,3819
|
60
60
|
skfolio/prior/__init__.py,sha256=jql8NTiWlykPKJUXTOPdqm531mP8Pul1QAR6hXTXA6c,446
|
61
61
|
skfolio/prior/_base.py,sha256=jjXioNBLCgNdDhAwU0ASPjKBLCjkO0vsh4slDBlF9FA,1906
|
62
|
-
skfolio/prior/_black_litterman.py,sha256=
|
62
|
+
skfolio/prior/_black_litterman.py,sha256=ejK-XWyuu6GsVTH8NtxUlU9cXED_ooh9NjgWQjCvlWQ,9175
|
63
63
|
skfolio/prior/_empirical.py,sha256=fo-29PZUBE5sXBnXktrfMlQe2HB0hBtOKkIyMG_S_wI,5718
|
64
|
-
skfolio/prior/_factor_model.py,sha256=
|
64
|
+
skfolio/prior/_factor_model.py,sha256=gA6l6yxOHUa8Bs_SpKq6-Vqskpa8KCYfoENMUpPc8tI,9351
|
65
65
|
skfolio/uncertainty_set/__init__.py,sha256=LlMHtYv9G9fgtM7m4sCSToS9et57Pm2Q2gGchTVrj6c,617
|
66
66
|
skfolio/uncertainty_set/_base.py,sha256=IMuDPhX6VszpLWDku11AQCVkoK_aSnUgWfTuSReX2Z8,3280
|
67
67
|
skfolio/uncertainty_set/_bootstrap.py,sha256=f2a0IqbtTpHcuoYXNIi-gxpo-MJtAK5TF2EkOrlqB2A,10044
|
@@ -72,8 +72,8 @@ skfolio/utils/equations.py,sha256=iaROYx9jEIGTlbout872OQ1SakvMxa0K1NdXM5sIvbg,11
|
|
72
72
|
skfolio/utils/sorting.py,sha256=DcnK37pXYjH3RRFjaz3cpL9f3ATtgRgUHL1HmeidcUc,3483
|
73
73
|
skfolio/utils/stats.py,sha256=x92lyfKacQSr4f_CL07kc5NSdL6BlBfV_whmFpj9H5U,12914
|
74
74
|
skfolio/utils/tools.py,sha256=h0vlk54dthRcHbiMcWAcRkIjeappLb88ZrlJXFREp7k,15177
|
75
|
-
skfolio-0.0.
|
76
|
-
skfolio-0.0.
|
77
|
-
skfolio-0.0.
|
78
|
-
skfolio-0.0.
|
79
|
-
skfolio-0.0.
|
75
|
+
skfolio-0.0.9.dist-info/LICENSE,sha256=F6Gi-ZJX5BlVzYK8R9NcvAkAsKa7KO29xB1OScbrH6Q,1526
|
76
|
+
skfolio-0.0.9.dist-info/METADATA,sha256=YeCCFWNF9famiXPJXF4T9bsNMbzQgexDzqnlShdZ6a4,18946
|
77
|
+
skfolio-0.0.9.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
78
|
+
skfolio-0.0.9.dist-info/top_level.txt,sha256=NXEaoS9Ms7t32gxkb867nV0OKlU0KmssL7IJBVo0fJs,8
|
79
|
+
skfolio-0.0.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|