Optimization
We are going to introduce scipy.optimize. What we need to do is first create a function we want to download. We will try to minimize (x-5)
2
. We use scipy.optimize.minimize() for this, and we feed it a function and a guess at what we think the answer is.
import scipy.optimize
def ourFunction(x):
return (x-5)**2
print(scipy.optimize.minimize(ourFunction,1))
We get a large amount of output, but for our purposes we want x, the value which minimizes. We get x back as an array which we can find by indexing with [“x”].
x = scipy.optimize.minimize(ourFunction,1)["x"]
print(x)
x = x[0]
print(ourFunction(x))
But how do we maximize? There actually isn’t an equation to do this, but instead you minimize the negative of your function. Let’s make another function that we want to find the max of. The equation 20-(x-5)
2
can be maximized if we put a negative in front of it.
def ourFunction(x):
return -(20-(x-5)**2)
x = scipy.optimize.minimize(ourFunction,1)["x"][0]
print(x)
print(ourFunction(x)*-1)
When we find the max value we have to multiply by -1 because the function gives the negative of the value.
The final topic we want to cover for this is constraints. We need to be able to constrain x values very often, so this is an important topic.
For our constraints we need to define two things, a type and a function. For type, we can say “eq” or “ineq”. The first forces the function to be equal to 0, the second one forces the function to be greater than or equal to 0. As for function, we feed in whatever function we want to use. For this, we are going to want the weight in asset 1 to be less than or equal to 100%, so we set it as an inequality -(x-100). The reson we do 100 is because the way we set up the function was to divide the x value by 100. We will do this with the lambda command, which allows you to make a temporary function. The way it works is you specify lambda x: followed by the function you want. The reason we need the negative is because we don’t want the function to be greater than or equal to 0, we want it to be less than or equal to. We can specify a function x to make sure the weights are greater than or equal to 0.
con1 = {'type': 'ineq',
'fun': lambda x: -(x-1)}
con2 = {'type': 'ineq',
'fun': lambda x: x}
Now, to include our constraints we add the argument constraints = ourConstraints to the optimization. Something to note is that since we plotted the graph as the percent in asset 1, we want 100%-x.
Challenge