'Adding a column to a Pandas dataframe that results from a call to a class method that uses row values

I have a csv file that looks as follows:

,calculation_date,opt_type,strike_price,maturity_date,underlying_price,risk_free_rate,implied_volatility,dividend_rate
0,2022-01-10 01:24:00,Call,90000,2022-12-30,41693.21,0.01,0.804194,0.01
1,2022-01-10 01:24:00,Call,90000,2022-12-30,41693.21,0.01,0.840400,0.01
2,2022-01-10 01:25:00,Put,15000,2022-06-24,41684.7,0.01,0.863425,0.01
3,2022-01-10 01:25:00,Put,15000,2022-06-24,41684.7,0.01,0.878962,0.01
4,2022-01-10 01:25:00,Put,20000,2022-06-24,41684.7,0.01,0.806613,0.01

The resulting Pandas dataframe looks as follows:

df = pd.read_csv('options.csv',
                 header=0,
                 names=['idx',
                        'calculation_date',
                        'opt_type',
                        'strike_price', 
                        'maturity_date', 
                        'underlying_price', 
                        'risk_free_rate', 
                        'implied_vol', 
                        'dividend_rate'],
                 parse_dates=True
                )

df

    idx calculation_date     opt_type   strike_price    maturity_date   underlying_price    risk_free_rate  implied_vol dividend_rate   
0   0   2022-01-10 01:24:00  Call       90000           2022-12-30      41693.21            0.01            0.804194    0.01
1   1   2022-01-10 01:24:00  Call       90000           2022-12-30      41693.21            0.01            0.840400    0.01
2   2   2022-01-10 01:25:00  Put        15000           2022-06-24      41684.70            0.01            0.863425    0.01
3   3   2022-01-10 01:25:00  Put        15000           2022-06-24      41684.70            0.01            0.878962    0.01
4   4   2022-01-10 01:25:00  Put        20000           2022-06-24      41684.70            0.01            0.806613    0.01

Next, I have a class that looks as follows:

import QuantLib as ql

class European_Option:

    day_count = ql.Actual365Fixed()
    calendar = ql.UnitedStates()

    def __init__(
        self,
        underlying_price,
        strike_price,
        maturity_date,
        risk_free_rate,
        implied_volatility,
        calculation_date,
        dividend_rate,
    ):
        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")
        self.dividend_rate = dividend_rate

        self.option_type = ql.Option.Call

        self.payoff = ql.PlainVanillaPayoff(self.option_type, self.strike_price)

        self.exercise = ql.EuropeanExercise(self.maturity_date)
        self.european_option = ql.VanillaOption(self.payoff, self.exercise)

        self.spot_handle = ql.QuoteHandle(ql.SimpleQuote(self.underlying_price))

        self.flat_ts = ql.YieldTermStructureHandle(
            ql.FlatForward(self.calculation_date, self.risk_free_rate, self.day_count)
        )

        self.dividend_yield = ql.YieldTermStructureHandle(
            ql.FlatForward(self.calculation_date, self.dividend_rate, self.day_count)
        )

        self.flat_vol_ts = ql.BlackVolTermStructureHandle(
            ql.BlackConstantVol(
                self.calculation_date,
                self.calendar,
                self.implied_volatility,
                self.day_count,
            )
        )

        self.bsm_process = ql.BlackScholesMertonProcess(
            self.spot_handle, self.dividend_yield, self.flat_ts, self.flat_vol_ts
        )

    def get_bs_price(self):
        self.european_option.setPricingEngine(ql.AnalyticEuropeanEngine(self.bsm_process))
        bs_price = self.european_option.NPV() / self.underlying_price
        return bs_price

    def get_delta(self):
        delta = self.european_option.delta()
        return delta

    def get_gamma(self):
        gamma = self.european_option.gamma()
        return gamma

    def get_vega(self):
        vega = self.european_option.vega()
        return vega

    def get_theta(self):
        theta = self.european_option.theta()
        return theta

With this class, we can use methods such as get_bs_price() and get_delta to get information about each row such as bs_price and delta, respectively.

For example, using the first row in the df, we can call:

foo = European_Option('Call',
                      41693.21,
                      90000,
                      '30-12-2022',
                      0.01,
                      0.804194,
                      '10-01-2022',
                      0.01
                        )

foo.get_bs_price()
0.09646261334373059

foo.get_delta()
0.279722212144296

Question: how do we pass the relevant values in each row to the get_bs_price() and get_delta() methods to return the resulting values of these functions as new columns?

(I believe we can use apply() or map(), but I'm not sure how to instantiate each row)

The desired df would look as follows:

    idx calculation_date     opt_type   strike_price    maturity_date   underlying_price    risk_free_rate  implied_vol dividend_rate   bs_price                delta
0   0   2022-01-10 01:24:00  Call       90000           2022-12-30      41693.21            0.01            0.804194    0.01            0.09646261334373059     0.279722212144296
1   1   2022-01-10 01:24:00  Call       90000           2022-12-30      41693.21            0.01            0.840400    0.01
2   2   2022-01-10 01:25:00  Put        15000           2022-06-24      41684.70            0.01            0.863425    0.01
3   3   2022-01-10 01:25:00  Put        15000           2022-06-24      41684.70            0.01            0.878962    0.01
4   4   2022-01-10 01:25:00  Put        20000           2022-06-24      41684.70            0.01            0.806613    0.01


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source