recusive objective function in scipy.minimize - Bellmann equation

33 Views Asked by At

I am working on an optimal execution problem in python but I do not know dynamic programming. Therefore I am trying to write down a recursive minimization problem.

v is the arrays of the shares traded each period q is the arrays of the hedging portfolio. It starts with q[0] which is known, while the other entries are defined recursively as q[i+1] = q[i] + v[i]*dt prices is the array of share' price. The final value is either N or 0 depending on the value of the stock at final period

V is a constant J is the max time period while i is the time period considered at each iteration.

As you can see there are 2 objective functions, I differentiate it because I know the final value at J of theta, which is given by the function "payoff_wcost" . While for the previous value I need to rely on the optimization results themselves.

However, my code is dependent on the initial guess that I make creating arrays v and q, while I want to define v and q exactly as the result of the overall minimization process.

def objective(v, V, J,i, q, prices):
  
    obj = np.exp(J-(i+1)*dt)*gamma *( (q[i])*prices[i]*(np.exp(dt)-1) + L(v/V, eta, phi) * V *dt  - (q[i]+v*dt)*(mu*dt + sigma*dt**(0.5)*epsilon[i]) + payoff_wcost("physical", N, prices[i], K, q[i], T,i*dt, V  ))
    #obj = np.log((np.exp(J-(i+1)*dt))*gamma *( (q[i])*prices[i]*(np.exp(dt)-1) + L(v/V, eta, phi) * V *dt  - (q[i]+v*dt)*(mu*dt) + payoff_wcost("physical", N, prices[i], K, q[i], T,J*dt, V  ) ))
    return obj

    
def theta_obj(v, V, J,i, q, prices):
    
    #obj = np.exp(J-(i+1)*dt)*gamma *( (q[i])*prices[i]*(np.exp(dt)-1) + L(v/V, eta, phi) * V *dt  - (q[i]+v)*(mu*dt + sigma*dt**(0.5)*epsilon[i]) + theta[i+1] )
    obj = np.exp(J-(i+1)*dt)*gamma *( (q[i])*prices[i]*(np.exp(dt)-1) + L(v/V, eta, phi) * V *dt  - (q[i]+v*dt)*(mu*dt + sigma*dt**(0.5)*epsilon[i]) + theta[i+1] )

    #obj = np.log((np.exp(J-(i+1)*dt))*gamma *( (q[i])*prices[i]*(np.exp(dt)-1) + L(v/V, eta, phi) * V *dt  - (q[i]+v*dt)*(mu*dt ) + theta[i+1] ))
    return obj


from scipy.optimize import minimize
from scipy.optimize import LinearConstraint

# LinearConstraint([[1, 0, 0, 0, 0, 0], [0, 1, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1]], [0.00001, 0.00001, 0.00001, 0.00001, 0.00001], [np.inf, np.inf, np.inf, np.inf, np.inf])
linear_constraint = LinearConstraint([[1]], [-rho*V], [rho*V])

v_tree = np.zeros(len(vb))
theta = np.zeros(J)

result = minimize(objective, v[-1], args=(V, J,J-1,q, prices) , method= "trust-constr" , bounds=[(-rho*V, rho*V)])   #,constraints=linear_constraint)
optimal_v = result.x
v_tree[-1] = optimal_v
theta[-1] =  payoff_wcost("physical", N, prices[-1], K, q[-1], T,J*dt, V  )

for i in reversed(range(0,J-1)):
    result = minimize(theta_obj, v[i], args=(V, J,i,q, prices) , method= "trust-constr",constraints=linear_constraint)
    optimal_v = result.x
    v_tree[i] = optimal_v
    
    theta[i] = optimal_v / gamma



q_tree = np.zeros(len(qB))
q_tree[0] = qB[0]   
for i in range(1,J):
    q_tree[i] = q_tree[i-1] + (v_tree[i-1]*dt)/2

plt.plot(time_points, q_tree/N)


I also tried to replicate the bellman recursive structure in the following way but it make my kernel to crush:

 Bellman recursion for the value function
def bellman_recursion(q, S, i):
    
    def objective(v):
        # Next stock price movement, assuming a simple model for illustration
     
        # Cost of trading
        
        # Recursive part of the Bellman equation
        return -np.exp( J-(i+1)*dt)*gamma *( q*prices[i]*(np.exp(dt)-1) + \
                L(v/V, eta, phi) * V *dt  - \
                (q+v*dt)*(mu*dt + sigma*dt**(0.5)*epsilon[i]) + \
                (bellman_recursion(q + v *dt, prices[i+1], i + 1) ))
    
    optimal_trading_speed = []
    
    for i in range(0, J):
        if i == J-1:
            # Terminal conditio
            return payoff_wcost("physical", N, S, K, q, T, i, V )
    # Objective function for the optimization at each time step
    
       # Optimization step to find the optimal trading speed v
        result = minimize(objective, x0=0, bounds=[(-rho*V, rho*V)])
        optimal_trading_speed.append(result.x[0])
        print(i)
        
    return optimal_trading_speed

# Example usage
initial_position = 0.5 * N
initial_stock_price = S0
optimal_strategy = bellman_recursion(initial_position, initial_stock_price, i=0)
print("Optimal strategy:", optimal_strategy)

Any suggestions to implement it?

0

There are 0 best solutions below