【问题标题】:Solving Functions with Gekko in Python在 Python 中使用 Gekko 求解函数
【发布时间】:2021-11-20 23:50:29
【问题描述】:

我正在考虑使用 gekko 来解决基于时间的财务分析的优化问题,我一直在使用蛮力循环来解决这个问题,但这很困难,尤其是当变量的数量变得更加复杂时。 这是我正在尝试做的一个非常简单的示例: 函数 ema_cross_strat(x1,x2) 计算时间序列的两个 ema(也可以传递但当前没有传递)然后确定快速 ema 是否高于慢速 ema 并根据该位置计算时间序列的回报.

在 Gekko 中是否有办法做到这一点,以便您可以针对快速和慢速平均线优化最佳移动平均线组合。

closes['SPY'].tail()
 
date
2021-07-22    434.069275
2021-07-23    438.534973
2021-07-26    439.611511
2021-07-27    437.607941
2021-07-28    437.428497
Name: SPY, dtype: float32

def ema_cross_strat(x1,x2):
    f=x1
    s=x2

    ts = closes['SPY']
    ema_fast = ts.ewm(span = f).mean()
    ema_slow = ts.ewm(span = s).mean()
    strat_position = (ema_fast > ema_slow).astype(float)
       
    strategy = ts.pct_change() * strat_position.shift()
    equity = (strategy+1).cumprod()[-1]

    return -equity

#initialise model
m = GEKKO()

# Integer constraints for x1 and x2
#x1 is the fast EMA, x2 is the slow ema
x1 = m.Var(value=3,lb=3,ub=30,integer=True)
x2 = m.Var(value=30,lb=30,ub=200,integer=True)

#Equations
#slow ema needs to be higher than the fast ema.
m.Equation(x2-x1>0)
#m.Equation(x1**2+x2**2+x3**2+x4**2==eq)
#Objective
m.Minimize(ema_cross_strat(x1,x2))
#Set global options
m.Minimize(f(x))
m.options.SOLVER=1
m.solve()

这目前会产生一个错误,表明变量没有被正确传递,但我不清楚为什么基于其他示例,或者这种类型的东西是否适用于 gekko。已尝试将 x 与 x1,x2 的数组一起传递,但结果是相同的。

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-76-6fa879b27b94> in <module>
     12 
     13 #Objective
---> 14 m.Minimize(ema_cross_strat(x1,x2))
     15 #Set global options
     16 m.Minimize(f(x))

<ipython-input-71-caf179a766b9> in ema_cross_strat(x1, x2)
      4 
      5     ts = closes['SPY']
----> 6     ema_fast = ts.ewm(span = f).mean()
      7     ema_slow = ts.ewm(span = s).mean()
      8     strat_position = (ema_fast > ema_slow).astype(float)

C:\Anaconda3\envs\env_zip36\lib\site-packages\pandas\core\generic.py in ewm(self, com, span, halflife, alpha, min_periods, freq, adjust, ignore_na, axis)
   7084             return rwindow.ewm(self, com=com, span=span, halflife=halflife,
   7085                                alpha=alpha, min_periods=min_periods, freq=freq,
-> 7086                                adjust=adjust, ignore_na=ignore_na, axis=axis)
   7087 
   7088         cls.ewm = ewm

C:\Anaconda3\envs\env_zip36\lib\site-packages\pandas\core\window.py in ewm(obj, **kwds)
   2087         raise TypeError('invalid type: %s' % type(obj))
   2088 
-> 2089     return EWM(obj, **kwds)
   2090 
   2091 

C:\Anaconda3\envs\env_zip36\lib\site-packages\pandas\core\window.py in __init__(self, obj, com, span, halflife, alpha, min_periods, freq, adjust, ignore_na, axis)
   1682                  axis=0):
   1683         self.obj = obj
-> 1684         self.com = _get_center_of_mass(com, span, halflife, alpha)
   1685         self.min_periods = min_periods
   1686         self.freq = freq

C:\Anaconda3\envs\env_zip36\lib\site-packages\pandas\core\window.py in _get_center_of_mass(com, span, halflife, alpha)
   1986             raise ValueError("com must satisfy: com >= 0")
   1987     elif span is not None:
-> 1988         if span < 1:
   1989             raise ValueError("span must satisfy: span >= 1")
   1990         com = (span - 1) / 2.

C:\Anaconda3\envs\env_zip36\lib\site-packages\gekko\gk_operators.py in __len__(self)
     23         return self.name
     24     def __len__(self):
---> 25         return len(self.value)
     26     def __getitem__(self,key):
     27         return self.value[key]

C:\Anaconda3\envs\env_zip36\lib\site-packages\gekko\gk_operators.py in __len__(self)
    142 
    143     def __len__(self):
--> 144         return len(self.value)
    145 
    146     def __getitem__(self,key):

TypeError: object of type 'int' has no len()

【问题讨论】:

    标签: python gekko


    【解决方案1】:

    Gekko 创建一次模型,然后将其传递给求解器。任何函数都需要以符号表示问题的方式定义,这样就不需要重新评估。要尝试的一件事是Scipy.optimize.minimize() 并创建某种方式使决策变量连续(例如仅具有下一个数字的一​​小部分的平均值)。这是Scipy.optimize.minimize and Gekko for optimization的信息。

    Scipy

    import numpy as np
    from scipy.optimize import minimize
    
    def objective(x):
        return x[0]*x[3]*(x[0]+x[1]+x[2])+x[2]
    
    def constraint1(x):
        return x[0]*x[1]*x[2]*x[3]-25.0
    
    def constraint2(x):
        sum_eq = 40.0
        for i in range(4):
            sum_eq = sum_eq - x[i]**2
        return sum_eq
    
    # initial guesses
    n = 4
    x0 = np.zeros(n)
    x0[0] = 1.0
    x0[1] = 5.0
    x0[2] = 5.0
    x0[3] = 1.0
    
    # show initial objective
    print('Initial Objective: ' + str(objective(x0)))
    
    # optimize
    b = (1.0,5.0)
    bnds = (b, b, b, b)
    con1 = {'type': 'ineq', 'fun': constraint1} 
    con2 = {'type': 'eq', 'fun': constraint2}
    cons = ([con1,con2])
    solution = minimize(objective,x0,method='SLSQP',\
                        bounds=bnds,constraints=cons)
    x = solution.x
    
    # show final objective
    print('Final Objective: ' + str(objective(x)))
    
    # print solution
    print('Solution')
    print('x1 = ' + str(x[0]))
    print('x2 = ' + str(x[1]))
    print('x3 = ' + str(x[2]))
    print('x4 = ' + str(x[3]))
    

    壁虎

    from gekko import GEKKO    
    import numpy as np
    
    #Initialize Model
    m = GEKKO()
    
    #help(m)
    
    #define parameter
    eq = m.Param(value=40)
    
    #initialize variables
    x1,x2,x3,x4 = [m.Var(lb=1,ub=5) for i in range(4)]
    
    #initial values
    x1.value = 1
    x2.value = 5
    x3.value = 5
    x4.value = 1
    
    m.Equation(x1*x2*x3*x4>=25)
    m.Equation(x1**2+x2**2+x3**2+x4**2==eq)
    
    m.Minimize(x1*x4*(x1+x2+x3)+x3)
    
    m.solve()
    
    print('Results')
    print('x1: ' + str(x1.value))
    print('x2: ' + str(x2.value))
    print('x3: ' + str(x3.value))
    print('x4: ' + str(x4.value))
    

    如果您想使用 Gekko,请考虑根据平均值和值的数量之间的关系从平均值到 create a cubic spline (cspline) 的连续函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      • 1970-01-01
      • 1970-01-01
      • 2020-03-17
      相关资源
      最近更新 更多