Search code examples
pythonoptimizationgekkomixed-integer-programming

GEKKO optimization function gives no solution


I'm trying to figure out a list of integer solutions for the problem. I'm trying to maximize the function get_sharpe_ratio. When I run the program, the result is always zero.

Optimization function is inside the function calc_sharp_ratio

Is there any where I did wrong? How can I get the solution I want?

import numpy as np

from gekko import GEKKO

class WeightOptimalSolver:

def __init__(self, stocks, total_money, rf):

    self._stocks = stocks
    self._rf = rf/252
    self._total_money = total_money

def get_sharpe_ratio(self, hands):

    shares = []

    # Get shares
    for h in hands:
        shares.append(h * 100)

    # Get weigths
    required_money = 0

    for s in range(0,len(shares)):
        required_money += shares[s] * float(self._stocks[s].get_price())

    weights = []

    for s in range(0,len(shares)):
        weight = shares[s] * float(self._stocks[s].get_price()) / required_money
        weights.append(weight)

    Er = 0
    sd = 0

    for s in range(0,len(self._stocks)):
        Er += float(self._stocks[s].get_Er()) * weights[s]
        sd += float(self._stocks[s].get_sd()) * weights[s]

    inverse_sharpe_ratio =  -1 * ((Er - self._rf)/sd)

    return inverse_sharpe_ratio

def get_required_money(self, hands):

    required_money = 0

    for h in range(0,len(hands)):
        required_money += hands[h] * 100 * float(self._stocks[h].get_price())

    return required_money


def calc_sharp_ratio(self):

    m = GEKKO(remote = True)

    hands = [m.Var(integer = True, ub = 0) for h in range(len(self._stocks))]

    m.Equation(self.get_required_money(hands) >= -1 * self._total_money)
    m.Obj(self.get_sharpe_ratio(hands))
    m.options.SOLVER = 1
    m.solve()

    return hands

if __name__ == '__main__':

    import Stocks
    import datetime
    import WeightOptimalSolver

    Today = datetime.datetime.today()
    dateToday = Today.strftime('%Y-%m-%d')

    stocks = Stocks.Stocks('Data/' + dateToday + 'hedgeA' + '.csv').get_stocks()

    wos = WeightOptimalSolver.WeightOptimalSolver(stocks[0:2], 15000, 0.03)
    hands = wos.calc_sharp_ratio()

    print(hands)

The result is:

apm 70.191.46.236_gk_model0 <br><pre> ----------------------------------------------------------------
 APMonitor, Version 1.0.1
 APMonitor Optimization Suite
 ----------------------------------------------------------------
 
 
 Warning: there is insufficient data in CSV file 70.191.46.236_gk_model0.csv
 
 --------- APM Model Size ------------
 Each time step contains
   Objects      :            0
   Constants    :            0
   Variables    :            3
   Intermediates:            0
   Connections  :            0
   Equations    :            2
   Residuals    :            2
 
 Number of state variables:              3
 Number of total equations: -            1
 Number of slack variables: -            1
 ---------------------------------------
 Degrees of freedom       :              1
 
 ----------------------------------------------
 Steady State Optimization with APOPT Solver
 ----------------------------------------------
Iter:     1 I:  0 Tm:      0.00 NLPi:    2 Dpth:    0 Lvs:    0 Obj:       NaN Gap:  0.00E+00
 Successful solution
 
 ---------------------------------------------------
 Solver         :  APOPT (v1.0)
 Solution time  :   1.279999999678694E-002 sec
 Objective      :                      NaN
 Successful solution
 ---------------------------------------------------
 
[[0.0], [0.0]]

Solution

  • All gekko problems as defined as static equations and then compiled and sent to a solver. It appears that the definition of the equations changes each time the function is called. The solution is to either use a solver such as Scipy.optimize.minimize as shown here or else use Gekko functions to build the model. Scipy.optimize.minimize is a nonlinear programming solver so the solution may include fractional hands. Here is an example of a mixed integer solution with Gekko.

    from gekko import GEKKO
    m = GEKKO() # create GEKKO model
    # create integer variables
    x1 = m.Var(integer=True,lb=-5,ub=10) 
    x2 = m.Var(integer=True,lb=-1,ub=2)
    m.Minimize(4*x1**2-4*x2*x1**2+x2**2+x1**2-x1+1)
    m.options.SOLVER = 1 # APOPT solver
    m.solve()
    print('x1: ' + str(x1.value[0]))
    print('x2: ' + str(x2.value[0]))
    

    The problem you posted can't be tested because of missing packages Stocks and WeightOptimalSolver as well as the data file 'Data/' + dateToday + 'hedgeA' + '.csv'. If possible, try to share a problem that is reproducible for future questions.