Optimizer creation¶
Suppose we want to create a custom optimizer for a StocksSet. How can we do it? In this tutorial the structure of the optimizers will be shown, naming every definition needed for an optimizer to work. The tutorial then will finish with a creation of a dummy optimizer.
Lets see then how does an optimizer works.
The first thing to consider its the base class of every optimizer. There is a class named OptimizerABC that has the following method:
[1]:
def optimize(self, ss):
weights, metadata = self._calculate_weights(ss)
return ss.copy(weights=weights, optimizer=metadata)
Given this, we determine the need to implement a _calculate_weights function that provides the necessary data to create a new StocksSet instance with updated weights. That method is the core method of every optimizer. The weights definition.
Say for example that we want to create a new optimizer that only returns a normalized vector of weights. We can do that by making something like this.
[2]:
from garpar.optimize.opt_base import OptimizerABC
import numpy as np
class MyOptimizer(OptimizerABC):
family = "MyFamily"
def _calculate_weights(self, ss):
return np.ones(len(ss.weights))/len(ss.weights), {"name": "my_model"}
Note that we have defined an attribute named family, which represents the set of models it belongs to. For example, in this context, mean-variance is a family.
Now that we have defined an optimizer, let’s examine its output for a StocksSet instance.
[3]:
from garpar.datasets import make_risso_normal
opt = MyOptimizer()
ss = make_risso_normal(random_state=42, stocks=5, days=10)
opt.optimize(ss)
[3]:
| Stocks | S0[W 0.2, H 0.5] | S1[W 0.2, H 0.5] | S2[W 0.2, H 0.5] | S3[W 0.2, H 0.5] | S4[W 0.2, H 0.5] |
|---|---|---|---|---|---|
| Days | |||||
| 0 | 100.000000 | 100.000000 | 100.000000 | 100.000000 | 100.000000 |
| 1 | 98.805864 | 100.935769 | 99.326480 | 100.900464 | 100.649803 |
| 2 | 99.723073 | 99.709073 | 98.300671 | 99.884634 | 101.809271 |
| 3 | 100.481068 | 98.845525 | 99.570943 | 98.878556 | 100.721910 |
| 4 | 99.870674 | 97.846148 | 100.461281 | 99.783308 | 99.528206 |
| 5 | 101.124337 | 96.897283 | 101.310699 | 98.637364 | 100.581171 |
| 6 | 102.006936 | 95.770467 | 100.074504 | 99.746865 | 101.208367 |
| 7 | 103.332098 | 94.844957 | 101.280570 | 100.450735 | 100.356336 |
| 8 | 104.518001 | 94.306958 | 102.217987 | 99.473017 | 101.303750 |
| 9 | 105.458859 | 93.176509 | 100.824345 | 100.715559 | 100.136298 |
| 10 | 106.641517 | 92.403867 | 101.862962 | 99.497536 | 99.235579 |
As expected, this optimizer assings weights with equal values.
Thank you for visiting the tutorials for Garpar! We recommend to look in the API section for any documentation you might need.