Python Scipy使用数据帧优化最大化

Python Scipy使用数据帧优化最大化,python,pandas,scipy,scipy-optimize,Python,Pandas,Scipy,Scipy Optimize,我有一个由每月股价组成的df。我希望找到最佳的买入价和卖出价,以最大化收益(收入-成本)。从研究中可以看出,Scipy Optimize是最好的工具,但是我看到的所有示例都没有显示它与数据帧一起使用 以前的一种方式涵盖了这一点。但我无法让它为我工作,因为我的买卖数量将根据价格而变化。这意味着我需要重新校准df字段 任何帮助都将不胜感激 import pandas as pd import numpy as np import math import datetime from scipy.opt

我有一个由每月股价组成的df。我希望找到最佳的买入价和卖出价,以最大化收益(收入-成本)。从研究中可以看出,Scipy Optimize是最好的工具,但是我看到的所有示例都没有显示它与数据帧一起使用

以前的一种方式涵盖了这一点。但我无法让它为我工作,因为我的买卖数量将根据价格而变化。这意味着我需要重新校准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']
将熊猫作为pd导入
将numpy作为np导入
输入数学
导入日期时间
从scipy.optimize导入最小化
df=pd.DataFrame({
“时间”:[0,1,2,3,4,5,6,7,8,9],
‘价格’:[44100,40110,77109,65,93,89,73]})
#创建空列
df[['Qty'、'Buy'、'Sell'、'Cost'、'Rev']]=pd.DataFrame([[0.00,0.00,0.00,0.00]],index=df.index)
#初始值
购买价格=50
售价=100
#在时间0设置值
df.在[0,'数量']=0
在[0'购买']=np.其中(在[0'价格']<购买价格,最小值(30-在[0'数量']],10),0)处的df
在[0'卖出']=np.式中(在[0'价格']>卖出价格,最小值(在[0'数量'],10]卖出),0)
df.at[0,'成本']=df.at[0,'购买']*df.at[0,'价格']
df.at[0,'修订']=df.at[0,'出售']*df.at[0,'价格']
#设置剩余值
对于范围(1,len(df))内的t:
在[t'数量']=在[t-1'数量']+在[t-1'购买']-在[t-1'出售']
在[t'购买']=np.式中(在[t'价格']<购买价格,最小值(30-在[t'数量'],10),0)
在[t,'出售']=np.式中(在[t,'价格']>出售价格,最小值(在[t,'数量'],10),0)
df.at[t,'成本']=df.at[t,'购买']*df.at[t,'价格']
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())
将熊猫作为pd导入
将numpy作为np导入
导入scipy.optimize作为优化
df=pd.DataFrame({
“时间”:[0,1,2,3,4,5,6,7,8,9],
‘价格’:[44100,40110,77109,65,93,89,49]})
#创建空列
df[['Qty'、'Buy'、'Sell'、'Cost'、'Rev']]=pd.DataFrame([[0.00,0.00,0.00,0.00]],index=df.index)
类谓词:
定义初始化(自):
self.prev_time=-1
自上次数量=0
self.prev_buy=0
self.prev_sell=0
自身数量=0
self.Buy=0
self.Sell=0
自身成本=0
self.Rev=0
定义调用(self,x):
如果x.Time==self.prev_Time:#apply运行第一行/第一列两次,因此
x、 数量=自身上一个数量
x、 购买=自我。上一次购买
x、 Sell=self.prev\u Sell
x、 成本=x.购买*x.价格
x、 Rev=x.卖出*x.价格
其他:
x、 数量=自上次数量+自上次购买-自上次出售
x、 购买=np.式中(x.价格<购买价格,最小值(30-x.数量,10),0)
x、 销售=np.其中(x.价格>销售价格,最小值(x.数量,10),0)
x、 成本=x.购买*x.价格
x、 Rev=x.卖出*x.价格
self.prev_buy=x.buy
自上次数量=x数量
self.prev_sell=x.sell
self.prev_time=x.time
返回x
#定义要最小化的函数
def版本(参数):
全球买入价
全球销售价格
买入价、卖出价=参数
df2=df.apply(谓词(),轴=1)
返回-1*(df2['Rev'].sum()-df2['Cost'].sum())
#运行优化
初始猜测=[40,90]
结果=优化。基准点(func=rev,x0=initial_guess,niter=1000,步长=10)
打印(result.x)
#运行最终结果
结果.x=买入价,卖出价
df=df.apply(谓词(),轴=1)
打印(df)
打印(df['Rev'].sum()-df['Cost'].sum())

for loop可以完成i@WeNYoBen,谢谢您的回复。请你再详细说明一下好吗?我不知道如何合并for循环,我是否应该首先创建一个函数,将字段(数量、购买、销售、成本、修订)添加到我的df和returns-1*(收入-成本)。然后在我的scipy最小化优化中使用它。