[英]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.