I'm trying to code the Heston Model in Python. In my final stages, I have to integrate a bunch of integrands. The problem is arising in these lines.
integrands_list_1 and integrands_list_2 are lists of lambda functions of variable phi, I have to integrate these functions to get my final result. When I pass a df of a single row I get the desired result however the problem arises when I try to pass a df with multiple rows.
In this version of code, I created a list of functions and used a loop to iterate through these functions and then integrate them, however, I get the TypeError as stated in the heading.
The error occurs in the P1 line where I get the error as mentioned earlier.
for integrand1, integrand2 in zip(integrands_list_1, integrands_list_2):
P1 = 0.5 + (1/np.pi) * quad(integrand1, 0, 100)[0]
P2 = 0.5 + (1/np.pi) * quad(integrand2, 0, 100)[0]
results.append((P1, P2))
An example df is as follows:
| [QUOTE_DATE] | [UNDERLYING_LAST] | [EXPIRE_DATE] | [STRIKE] | [DTE] | [C_LAST] | [DTB3] |
|---|---|---|---|---|---|---|
| 2022-03-01 | 4305.46 | 2022-03-09 | 4000 | 8.0 | 379.71 | 0.0032 |
| 2022-03-01 | 4305.46 | 2022-03-09 | 4050 | 8.0 | 325.41 | 0.0032 |
| 2022-03-01 | 4305.46 | 2022-03-09 | 4140 | 8.0 | 171.22 | 0.0032 |
| 2022-03-01 | 4305.46 | 2022-03-09 | 4150 | 8.0 | 168.82 | 0.0032 |
The Full Error Message:
TypeError Traceback (most recent call last)
Cell In[24], line 1
----> 1 df_8['Heston Initial'] = Heston_Model.heston_price(df_8, v_0, theta, sigma, rho, kappa)
File ~/Desktop/Python/BS option pricing/Heston_Model.py:103, in heston_price(df, v_0, theta, sigma, rho, kappa)
101 print(type(integrand1))
102 print(integrand1)
--> 103 P1 = 0.5 + (1/np.pi) * quad(integrand1, 0, 100)[0]
104 P2 = 0.5 + (1/np.pi) * quad(integrand2, 0, 100)[0]
105 results.append((P1, P2))
TypeError: only size-1 arrays can be converted to Python scalars
Heston Price and Integrand Functions:
def heston_price(df, v_0, theta, sigma, rho, kappa):
St = df['[UNDERLYING_LAST]']
K = df['[STRIKE]']
r = df['[DTB3]']
t = df['[DTE]'] / 252 # Assuming [DTE] is in days
### Looping into List
integrands_list_1 = []
integrands_list_2 = []
results = []
for index, row in df.iterrows():
phi_values = np.linspace(1, 100, 1000)
integrands = heston_integrand(phi_values, df, v_0, theta, sigma, rho, kappa)
integrands_list_1.append(integrands[0])
integrands_list_2.append(integrands[1])
for integrand1, integrand2 in zip(integrands_list_1, integrands_list_2):
print(type(integrand1))
print(integrand1)
P1 = 0.5 + (1/np.pi) * quad(integrand1, 0, 100)[0]
P2 = 0.5 + (1/np.pi) * quad(integrand2, 0, 100)[0]
results.append((P1, P2))
C = St * P1 - K * np.exp(-r*t) * P2
return C
def heston_integrand(phi,df, v_0, theta, sigma, rho, kappa):
St = df['[UNDERLYING_LAST]']
K = df['[STRIKE]']
r = df['[DTB3]']
t = df['[DTE]'] / 252
integrand1 = lambda phi: np.real(np.exp(-1j * phi * np.log(K)) *
heston_char(St, v_0, t, r, kappa * theta, 0.5, kappa - rho * sigma, rho, sigma, phi) / (1j * phi))
integrand2 = lambda phi: np.real(np.exp(-1j * phi * np.log(K)) *
heston_char(St, v_0, t, r, kappa * theta, -0.5, kappa, rho, sigma, phi) / (1j * phi))
return integrand1, integrand2