Search code examples
pythonpython-multiprocessingpool

Passing a variable from another function in a class to Pool


The below code simulates a stock price and calculates its payoff. I am trying to use multiprocessing to speed up the simulations. The problem is that in CallUpAndOut where I have pool.map, I am not sure how to access total from simulations

I have tried several things like self.Simulations.Total or self.total but it doesn't work.

import numpy as np
from multiprocessing import Pool
import time

class PricingSimulatedBarrierOption:
    def __init__(self, spot, strike, barrier, rate, sigma, time, sims, steps):
        self.spot = spot
        self.strike = strike
        self.barrier = barrier
        self.rate = rate
        self.sigma = sigma
        self.time = time
        self.sims = sims
        self.steps = steps
        self.dt = self.time / self.steps

    def Simulations(self):

        total = np.zeros((self.sims,self.steps+1),float)
        pathwiseS= np.zeros((self.steps+1),float)
        for j in range(self.sims):
            pathwiseS[0] =self.spot
            total[j,0] = self.spot
            for i in range(1,self.steps+1):
                phi = np.random.normal()
                pathwiseS[i] = pathwiseS[i-1]*(1+self.rate*self.dt+self.sigma*phi*np.sqrt(self.dt))
                total[j,i]= pathwiseS[i]

        return total.reshape(self.sims, self.steps+1)

    def CallUpAndOut(self):

        start_time = time.time()
        p = Pool()
        getpayoff = p.map(self.Simulations(),self.total) ###How to pass total here?
        p.close()
        p.join()
        end_time = time.time()-start_time
        print(end_time)
#        getpayoff = self.Simulations()
        callpayoff = np.zeros((self.sims),float)
        for j in range(self.sims):
            if max(getpayoff[j,])>=self.barrier:
                callpayoff[j] = 0
            else:
                callpayoff[j] = max(getpayoff[j,self.steps-1]-self.strike,0)  

        return np.exp(-self.rate*self.time)*np.average(callpayoff)

c = PricingSimulatedBarrierOption(100,100,170,0.05,0.2,1,10000,252)
print(c.CallUpAndOut())

Solution

  • To work this I had to move the declaration outside. Below code is now able to accept variable in the Pool function.

    import numpy as np
    from multiprocessing import Pool
    import time
    
    class PricingSimulatedBarrierOption:
        def __init__(self, spot, strike, barrier, rate, sigma, time, sims, steps):
            self.spot = spot
            self.strike = strike
            self.barrier = barrier
            self.rate = rate
            self.sigma = sigma
            self.time = time
            self.sims = sims
            self.steps = steps
            self.dt = self.time / self.steps
            self.pathwiseS= np.zeros((self.steps+1),float)
    
    def Simulations(self):
    
        print("Called")
        total = np.zeros((self.sims,self.steps+1),float)
        self.pathwiseS= np.zeros((self.steps+1),float)
        for j in range(self.sims):
            self.pathwiseS[0] =self.spot
            total[j,0] = self.spot
            for i in range(1,self.steps+1):
                phi = np.random.normal()
                self.pathwiseS[i] = self.pathwiseS[i-1]*(1+self.rate*self.dt+self.sigma*phi*np.sqrt(self.dt))
                total[j,i]= self.pathwiseS[i]
    
        return total.reshape(self.sims, self.steps+1)
    
    def CallUpAndOut(self):
    
        start_time = time.time()
        p = Pool()
        getpayoff = p.map(self.Simulations(),self.pathwiseS)
        p.close()
        p.join()
        end_time = time.time()-start_time
        print(end_time)
    #        getpayoff = self.Simulations()
        callpayoff = np.zeros((self.sims),float)
        for j in range(self.sims):
            if max(getpayoff[j,])>=self.barrier:
                callpayoff[j] = 0
            else:
                callpayoff[j] = max(getpayoff[j,self.steps-1]-self.strike,0)  
    
        return np.exp(-self.rate*self.time)*np.average(callpayoff)