如何最大化收入-Python

如何最大化收入-Python,python,python-3.x,pulp,scipy-optimize,scipy-optimize-minimize,Python,Python 3.x,Pulp,Scipy Optimize,Scipy Optimize Minimize,我有一个由小时股价组成的大df。我希望找到最佳的买入价和卖出价,以最大化收益(收入-成本)。我不知道最大化的买入/卖出价格会是什么,因此我最初的猜测是在黑暗中瞎猜 我尝试使用Scipy的“最小化”和“盆地跳跃”。当我运行脚本时,我似乎被困在了当地的井中,结果与我最初的猜测几乎没有什么不同 有没有办法解决这个问题?是否有更好的方法来编写代码,或者使用更好的方法 下面是示例代码 import pandas as pd import numpy as np import scipy.optimize

我有一个由小时股价组成的大df。我希望找到最佳的买入价和卖出价,以最大化收益(收入-成本)。我不知道最大化的买入/卖出价格会是什么,因此我最初的猜测是在黑暗中瞎猜

我尝试使用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)


# Create Predicate to add fields
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:
            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 max_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.minimize(fun=max_rev, x0=initial_guess, method='BFGS')
# result = optimize.basinhopping(func=max_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_时间:
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]
结果=优化。最小化(乐趣=最大值,x0=初始猜测,方法='BFGS')
#结果=优化。基本海平面(func=最大海平面,x0=初始海平面,niter=1000,步长=10)
打印(result.x)
#运行最终结果
结果.x=买入价,卖出价
df=df.apply(谓词(),轴=1)
打印(df)
打印(df['Rev'].sum()-df['Cost'].sum())

你没有给出很多细节,但我假设你认为“完美的预见性”收益最大化问题-即你知道在开始时价格会如何在地平线上演化。 这个问题很容易解决,但据我目前所知,你的问题是不受约束的——你可以通过以低价购买无限数量的单元,然后以高价出售它们来获得任意大的收入

你需要增加一个限制条件,即你只能从有限的现金开始,而且你只能出售你自己的股票(严格来说,这不是真的,你可以“卖空”你现在出售的东西,期望它的价值会下降(当你以后不得不再次购买时)

忽略卖空骗局,您可以将优化问题表述为线性规划,如下所示:

import pandas as pd
import numpy as np
from pulp import *

# Problem Data
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]})

times = list(df.Time)
times_plus_1 = times + [times[-1] + 1]

# Instantiate maximisation problem
prob = LpProblem("numpy_constraints", LpMaximize)

# Create the problem vairables
# Cash in bank and stock-level at start of each interval
Cash = pulp.LpVariable.dicts("Cash", times_plus_1, cat='Continuous', lowBound=0)
Stock = pulp.LpVariable.dicts("Stock", times_plus_1, cat='Continuous', lowBound=0)

# Amount bought during interval
Buy = pulp.LpVariable.dicts("Buy", times, cat='Continuous')

# Add Objective to problem - cash at end of period modelled
prob += Cash[times_plus_1[-1]]

# Add constraints
# Start with a single dollar in the bank & no stock
prob += Cash[times[0]] == 1.0
prob += Stock[times[0]] == 0.0

# Cash & stock update rules
for t in times:
    prob += Cash[t+1] == Cash[t] - Buy[t]*df.Price[t]
    prob += Stock[t+1] == Stock[t] + Buy[t]

# Solve
prob.solve()

# Check when we bought when:
Buy_soln = np.array([Buy[t].varValue for t in times])
print("Buy_soln:")
print(Buy_soln)

Stock_soln = np.array([Stock[t].varValue for t in times_plus_1])
print("Stock_soln:")
print(Stock_soln)

Cash_soln = np.array([Cash[t].varValue for t in times_plus_1])
print("Cash_soln:")
print(Cash_soln)
其结果如下:

Buy_soln:
[ 0.02272727 -0.02272727  0.05681818 -0.05681818  0.08116883 -0.08116883
  0.13611389 -0.13611389  0.          0.        ]
Stock_soln:
[0.         0.02272727 0.         0.05681818 0.         0.08116883
 0.         0.13611389 0.         0.         0.        ]
Cash_soln:
[ 1.         0.         2.2727273  0.         6.25       0.
  8.8474026  0.        12.658591  12.658591  12.658591 ]

不是特别有趣——正如预期的那样,使用所有可用的现金来利用股价的任何上涨(买入低卖出高)。

< P>你没有给出很多细节,但我假设你认为“完美的预见性”收益最大化问题-即你知道价格在地平线上会如何演变。 这个问题很容易解决,但据我目前所知,你的问题是不受约束的——你可以通过以低价购买无限数量的单元,然后以高价出售它们来获得任意大的收入

你需要增加一个限制条件,即你只能从有限的现金开始,而且你只能出售你自己的股票(严格来说,这不是真的,你可以“卖空”你现在出售的东西,期望它的价值会下降(当你以后不得不再次购买时)

忽略卖空骗局,您可以将优化问题表述为线性规划,如下所示:

import pandas as pd
import numpy as np
from pulp import *

# Problem Data
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]})

times = list(df.Time)
times_plus_1 = times + [times[-1] + 1]

# Instantiate maximisation problem
prob = LpProblem("numpy_constraints", LpMaximize)

# Create the problem vairables
# Cash in bank and stock-level at start of each interval
Cash = pulp.LpVariable.dicts("Cash", times_plus_1, cat='Continuous', lowBound=0)
Stock = pulp.LpVariable.dicts("Stock", times_plus_1, cat='Continuous', lowBound=0)

# Amount bought during interval
Buy = pulp.LpVariable.dicts("Buy", times, cat='Continuous')

# Add Objective to problem - cash at end of period modelled
prob += Cash[times_plus_1[-1]]

# Add constraints
# Start with a single dollar in the bank & no stock
prob += Cash[times[0]] == 1.0
prob += Stock[times[0]] == 0.0

# Cash & stock update rules
for t in times:
    prob += Cash[t+1] == Cash[t] - Buy[t]*df.Price[t]
    prob += Stock[t+1] == Stock[t] + Buy[t]

# Solve
prob.solve()

# Check when we bought when:
Buy_soln = np.array([Buy[t].varValue for t in times])
print("Buy_soln:")
print(Buy_soln)

Stock_soln = np.array([Stock[t].varValue for t in times_plus_1])
print("Stock_soln:")
print(Stock_soln)

Cash_soln = np.array([Cash[t].varValue for t in times_plus_1])
print("Cash_soln:")
print(Cash_soln)
其结果如下:

Buy_soln:
[ 0.02272727 -0.02272727  0.05681818 -0.05681818  0.08116883 -0.08116883
  0.13611389 -0.13611389  0.          0.        ]
Stock_soln:
[0.         0.02272727 0.         0.05681818 0.         0.08116883
 0.         0.13611389 0.         0.         0.        ]
Cash_soln:
[ 1.         0.         2.2727273  0.         6.25       0.
  8.8474026  0.        12.658591  12.658591  12.658591 ]

不太有趣-正如预期的那样,使用所有可用现金来利用股价上涨(低买高卖)。

我认为这可能不是“最小化”或“跳跃”的问题,而是一个经典的动态规划问题。我自己对方法有点模糊,但可能不需要scipy。如果需要使用scipy,请务必这样说。我认为这可能不是“最小化”或“盆地跳跃”的问题,而是一个经典的动态规划问题。我自己对方法有点模糊,但可能不需要scipy。如果你需要使用scipy,那么一定要这么说。非常感谢你的回答。这很有魅力。我只是有一个简单的问题。我在我的原始版本中有一些限制。x.买&x.卖e限制在任何时候买入/卖出10股,x.数量限制在最多30股。有没有办法改变你对这些股票所做的版本中的限制?嗨,Bobby。是的,这很容易做到。只需在
股票
买入
变量中添加上下限。非常感谢你的回复。这就像魅力。我只是有一个简单的问题。我在我的原始版本中设置了一些限制。x.买入和卖出限制在任何时候买入/卖出10股,x.数量限制在最多30股。有没有办法改变你对这些股票的版本中的限制?嗨,博比。是的,这很容易做到。只需添加较低和较高的boun