簡體   English   中英

在 Python 中使用 Gekko 求解函數

[英]Solving Functions with Gekko in Python

我正在考慮使用 gekko 來解決基於時間的財務分析的優化問題,我一直在使用蠻力循環來解決這個問題,但這很困難,尤其是當變量的數量變得更加復雜時。 這是我正在嘗試做的一個非常簡單的示例:函數 ema_cross_strat(x1,x2) 計算時間序列的兩個 emas(也可以傳遞但當前不是)然后確定快速 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()

Gekko 創建模型一次,然后將其傳遞給求解器。 任何函數都需要以象征性表達問題的方式定義,以便不需要重新評估。 可以嘗試的一件事是Scipy.optimize.minimize()並創建某種使決策變量連續的方法(例如只有下一個數字的一​​小部分的平均值)。 這里是關於Scipy.optimize.minimize 和 Gekko for optimization 的信息

西比

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,請考慮根據平均值創建一個連續函數,以根據平均值和值數量之間的關系創建三次樣條 (cspline)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM