Scipy 使用数据框优化最大化
Scipy Optimize Maximize with a dataframe
我有一个由每月股价组成的 df。我希望找到最佳买入价和卖出价以最大化收益(收入 - 成本)。根据研究,Scipy 优化似乎是最好的工具,但是我看到的所有示例都没有显示它与数据框一起使用。
之前的 已经涵盖了这一点。但我无法让它为我工作,因为我的买卖数量会根据价格而变化。这意味着我需要重新计算 df 字段。
如有任何帮助,我们将不胜感激!
import pandas as pd
import numpy as np
import math
import datetime
from scipy.optimize import minimize
df = pd.DataFrame({
'Time': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
'Price': [44, 100, 40, 110, 77, 109, 65, 93, 89, 73]})
# Create Empty Columns
df[['Qty', 'Buy', 'Sell', 'Cost', 'Rev']] = pd.DataFrame([[0.00, 0.00, 0.00, 0.00, 0.00]], index=df.index)
# Initial Values
buy_price = 50
sell_price = 100
# Set Values at Time 0
df.at[0, 'Qty'] = 0
df.at[0, 'Buy'] = np.where(df.at[0, 'Price'] < buy_price, min(30 - df.at[0, 'Qty'], 10), 0)
df.at[0, 'Sell'] = np.where(df.at[0, 'Price'] > sell_price, min(df.at[0, 'Qty'], 10), 0)
df.at[0, 'Cost'] = df.at[0, 'Buy'] * df.at[0, 'Price']
df.at[0, 'Rev'] = df.at[0, 'Sell'] * df.at[0, 'Price']
# Set Remaining Values
for t in range(1, len(df)):
df.at[t, 'Qty'] = df.at[t-1, 'Qty'] + df.at[t-1, 'Buy'] - df.at[t-1, 'Sell']
df.at[t, 'Buy'] = np.where(df.at[t, 'Price'] < buy_price, min(30 - df.at[t, 'Qty'], 10), 0)
df.at[t, 'Sell'] = np.where(df.at[t, 'Price'] > sell_price, min(df.at[t, 'Qty'], 10), 0)
df.at[t, 'Cost'] = df.at[t, 'Buy'] * df.at[t, 'Price']
df.at[t, 'Rev'] = df.at[t, 'Sell'] * df.at[t, 'Price']
所以我最终找到了一种使用 scipy 优化我的数据集的方法。
我写了一个谓词,可以让我解决我的领域计算。然后我在另一个用于 scipy 优化的函数中调用它。
这不是一个很好的优化解决方案,因为我似乎与我最初的猜测相去不远。但它至少解决了我在这里提出的问题。
import pandas as pd
import numpy as np
import scipy.optimize as optimize
df = pd.DataFrame({
'Time': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
'Price': [44, 100, 40, 110, 77, 109, 65, 93, 89, 49]})
# Create Empty Columns
df[['Qty', 'Buy', 'Sell', 'Cost', 'Rev']] = pd.DataFrame([[0.00, 0.00, 0.00, 0.00, 0.00]], index=df.index)
class Predicate:
def __init__(self):
self.prev_time = -1
self.prev_qty = 0
self.prev_buy = 0
self.prev_sell = 0
self.Qty = 0
self.Buy = 0
self.Sell = 0
self.Cost = 0
self.Rev = 0
def __call__(self, x):
if x.Time == self.prev_time: # apply runs first row/column twice, hence this
x.Qty = self.prev_qty
x.Buy = self.prev_buy
x.Sell = self.prev_sell
x.Cost = x.Buy * x.Price
x.Rev = x.Sell * x.Price
else:
x.Qty = self.prev_qty + self.prev_buy - self.prev_sell
x.Buy = np.where(x.Price < buy_price, min(30 - x.Qty, 10), 0)
x.Sell = np.where(x.Price > sell_price, min(x.Qty, 10), 0)
x.Cost = x.Buy * x.Price
x.Rev = x.Sell * x.Price
self.prev_buy = x.Buy
self.prev_qty = x.Qty
self.prev_sell = x.Sell
self.prev_time = x.Time
return x
# Define function to minimize
def rev(params):
global buy_price
global sell_price
buy_price, sell_price = params
df2 = df.apply(Predicate(), axis=1)
return -1 * (df2['Rev'].sum() - df2['Cost'].sum())
# Run optimization
initial_guess = [40, 90]
result = optimize.basinhopping(func=rev, x0=initial_guess, niter=1000, stepsize=10)
print(result.x)
# Run the final results
result.x = buy_price, sell_price
df = df.apply(Predicate(), axis=1)
print(df)
print(df['Rev'].sum() - df['Cost'].sum())
我有一个由每月股价组成的 df。我希望找到最佳买入价和卖出价以最大化收益(收入 - 成本)。根据研究,Scipy 优化似乎是最好的工具,但是我看到的所有示例都没有显示它与数据框一起使用。
之前的
如有任何帮助,我们将不胜感激!
import pandas as pd
import numpy as np
import math
import datetime
from scipy.optimize import minimize
df = pd.DataFrame({
'Time': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
'Price': [44, 100, 40, 110, 77, 109, 65, 93, 89, 73]})
# Create Empty Columns
df[['Qty', 'Buy', 'Sell', 'Cost', 'Rev']] = pd.DataFrame([[0.00, 0.00, 0.00, 0.00, 0.00]], index=df.index)
# Initial Values
buy_price = 50
sell_price = 100
# Set Values at Time 0
df.at[0, 'Qty'] = 0
df.at[0, 'Buy'] = np.where(df.at[0, 'Price'] < buy_price, min(30 - df.at[0, 'Qty'], 10), 0)
df.at[0, 'Sell'] = np.where(df.at[0, 'Price'] > sell_price, min(df.at[0, 'Qty'], 10), 0)
df.at[0, 'Cost'] = df.at[0, 'Buy'] * df.at[0, 'Price']
df.at[0, 'Rev'] = df.at[0, 'Sell'] * df.at[0, 'Price']
# Set Remaining Values
for t in range(1, len(df)):
df.at[t, 'Qty'] = df.at[t-1, 'Qty'] + df.at[t-1, 'Buy'] - df.at[t-1, 'Sell']
df.at[t, 'Buy'] = np.where(df.at[t, 'Price'] < buy_price, min(30 - df.at[t, 'Qty'], 10), 0)
df.at[t, 'Sell'] = np.where(df.at[t, 'Price'] > sell_price, min(df.at[t, 'Qty'], 10), 0)
df.at[t, 'Cost'] = df.at[t, 'Buy'] * df.at[t, 'Price']
df.at[t, 'Rev'] = df.at[t, 'Sell'] * df.at[t, 'Price']
所以我最终找到了一种使用 scipy 优化我的数据集的方法。
我写了一个谓词,可以让我解决我的领域计算。然后我在另一个用于 scipy 优化的函数中调用它。
这不是一个很好的优化解决方案,因为我似乎与我最初的猜测相去不远。但它至少解决了我在这里提出的问题。
import pandas as pd
import numpy as np
import scipy.optimize as optimize
df = pd.DataFrame({
'Time': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
'Price': [44, 100, 40, 110, 77, 109, 65, 93, 89, 49]})
# Create Empty Columns
df[['Qty', 'Buy', 'Sell', 'Cost', 'Rev']] = pd.DataFrame([[0.00, 0.00, 0.00, 0.00, 0.00]], index=df.index)
class Predicate:
def __init__(self):
self.prev_time = -1
self.prev_qty = 0
self.prev_buy = 0
self.prev_sell = 0
self.Qty = 0
self.Buy = 0
self.Sell = 0
self.Cost = 0
self.Rev = 0
def __call__(self, x):
if x.Time == self.prev_time: # apply runs first row/column twice, hence this
x.Qty = self.prev_qty
x.Buy = self.prev_buy
x.Sell = self.prev_sell
x.Cost = x.Buy * x.Price
x.Rev = x.Sell * x.Price
else:
x.Qty = self.prev_qty + self.prev_buy - self.prev_sell
x.Buy = np.where(x.Price < buy_price, min(30 - x.Qty, 10), 0)
x.Sell = np.where(x.Price > sell_price, min(x.Qty, 10), 0)
x.Cost = x.Buy * x.Price
x.Rev = x.Sell * x.Price
self.prev_buy = x.Buy
self.prev_qty = x.Qty
self.prev_sell = x.Sell
self.prev_time = x.Time
return x
# Define function to minimize
def rev(params):
global buy_price
global sell_price
buy_price, sell_price = params
df2 = df.apply(Predicate(), axis=1)
return -1 * (df2['Rev'].sum() - df2['Cost'].sum())
# Run optimization
initial_guess = [40, 90]
result = optimize.basinhopping(func=rev, x0=initial_guess, niter=1000, stepsize=10)
print(result.x)
# Run the final results
result.x = buy_price, sell_price
df = df.apply(Predicate(), axis=1)
print(df)
print(df['Rev'].sum() - df['Cost'].sum())