Fixing QuantLib Option Class State and Method Scope
Summary
The document presents a Python class intended to price European options and return their Greeks through QuantLib. The reported error occurs when a method tries to access an option object created as a local variable inside the initializer. Local variables belong to the function that created them, so another instance method cannot refer to that name directly.
The answer explains the object-oriented fix: store the option as an attribute on the class instance and access that same attribute from methods. The same principle applies to other objects needed later, such as the pricing process or engine. This addresses the stated name-resolution error and helps structure a reusable pricing object for processing many options. The discussion does not review the full implementation or validate the pricing calculations; other issues in the shown methods may need separate debugging before the class can reliably produce prices and Greeks.
Key ideas
- Variables created locally in an initializer are not automatically available to other methods.
- Store reusable pricing objects as instance attributes so methods can access the same state.
- Refer to instance attributes consistently from each method that needs them.
- Resolving the scope error alone does not verify that prices and Greeks are calculated correctly.
Tags
Full text
# Error in class when pricing vanilla European options using QuantLib
# Error in class when pricing vanilla European options using QuantLib
I'm brand new to QuantLib and have the following class that I'm using to price European options:
```
import QuantLib as ql
class European_Option:
def __init__(self, underlying_price, strike_price, maturity_date, risk_free_rate, implied_volatility, calculation_date):
self.underlying_price = underlying_price
self.strike_price = strike_price
self.maturity_date = ql.Date(maturity_date, '%d-%m-%Y')
self.risk_free_rate = risk_free_rate
self.implied_volatility = implied_volatility
self.calculation_date = ql.Date(calculation_date, '%d-%m-%Y')
day_count = ql.Actual365Fixed()
calendar = ql.UnitedStates()
dividend_rate = 0.01
option_type = ql.Option.Call
payoff = ql.PlainVanillaPayoff(option_type, self.strike_price)
exercise = ql.EuropeanExercise(self.maturity_date)
european_option = ql.VanillaOption(payoff, exercise)
spot_handle = ql.QuoteHandle(
ql.SimpleQuote(self.underlying_price))
flat_ts = ql.YieldTermStructureHandle(
ql.FlatForward(self.calculation_date,
self.risk_free_rate,
day_count))
dividend_yield = ql.YieldTermStructureHandle(
ql.FlatForward(self.calculation_date,
dividend_rate,
day_count))
flat_vol_ts = ql.BlackVolTermStructureHandle(
ql.BlackConstantVol(self.calculation_date,
calendar,
self.implied_volatility,
day_count))
bsm_process = ql.BlackScholesMertonProcess(spot_handle,
dividend_yield,
flat_ts,
flat_vol_ts)
def get_price(self):
european_option.setPricingEngine(ql.AnalyticEuropeanEngine(bsm_process))
bs_price = european_option.NPV() / spot_price
return bs_price
def get_delta(self):
delta = european_option.delta()
return delta
def get_gamma(self):
gamma = european_option.gamma()
return gamma
def get_vega(self):
vega = european_option.vega()
return gamma
def get_theta(self):
theta = european_option.theta()
```
Next, I instantiate an object named `foo` as follows:
```
foo = European_Option(400,
500,
'15-06-2022',
0.01,
0.375,
'20-01-2022'
)
```
Then, I call the `get_delta()` method:
```
foo.get_delta()
```
I'm seeing the following error:
```
NameError: name 'european_option' is not defined
```
I have `european_option` defined as:
```
european_option = ql.VanillaOption(payoff, exercise)
```
So, I'm confused as to what's happening here.
My goal is to be able to use this class to be able to get the price and Greeks of thousands of options in a csv file (by creating a Pandas dataframe and then adding columns to the dataframe with the price and Greeks).
Can anyone help me with this?
Thanks!
## Answer by David Duarte (score 1)
https://quant.stackexchange.com/a/69632
This is not really a QuantLib related error.
You defined `european_option` locally in your `__init__` function and then you are trying to access `european_option` locally in your `get_delta()` function, so they are not the same variable.
Use `self.european_option = ql.VanillaOption(payoff, exercise)` to define this variable in the scope of the class instance and then refer to it as `self.european_option` in your functions.Shown in full with attribution under the source's licence. Licence: CC BY-SA 4.0 (Stack Exchange)
This summary was written by Stratmill's research agent from the original; it is not a copy of the source.