def test_FinFXVanillaOptionBloombergExample(): # Example Bloomberg Pricing at # https://stackoverflow.com/questions/48778712/fx-vanilla-call-price-in-quantlib-doesnt-match-bloomberg valueDate = FinDate(13, 2, 2018) expiryDate = FinDate(15, 2, 2019) # In BS the FX rate is the price in domestic of one unit of foreign # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR # DOM = USD , FOR = EUR forName = "EUR" domName = "USD" forDepoRate = 0.05 # EUR domDepoRate = 0.02 # USD currencyPair = forName + domName # Always FORDOM spotFXRate = 1.30 strikeFXRate = 1.3650 volatility = 0.20 spotDays = 0 settlementDate = valueDate.addWorkDays(spotDays) maturityDate = settlementDate.addMonths(12) notional = 1000000.0 notionalCurrency = "EUR" calendarType = FinCalendarTypes.TARGET depos = [] fras = [] swaps = [] depo = FinLiborDeposit(settlementDate, maturityDate, domDepoRate, FinDayCountTypes.ACT_360, notional, calendarType) depos.append(depo) domDiscountCurve = FinLiborCurve(forName, settlementDate, depos, fras, swaps) depos = [] fras = [] swaps = [] depo = FinLiborDeposit(settlementDate, maturityDate, forDepoRate, FinDayCountTypes.ACT_360, notional, calendarType) depos.append(depo) forDiscountCurve = FinLiborCurve(domName, settlementDate, depos, fras, swaps) model = FinFXModelBlackScholes(volatility) callOption = FinFXVanillaOption(expiryDate, strikeFXRate, currencyPair, FinOptionTypes.EUROPEAN_CALL, notional, notionalCurrency, 2) value = callOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) delta = callOption.delta(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) testCases.header("value", "delta") testCases.print(value, delta)
def test_FinFXVanillaOptionWystupExample2(): # Example Bloomberg Pricing at # https://stackoverflow.com/questions/48778712/fx-vanilla-call-price-in-quantlib-doesnt-match-bloomberg valueDate = FinDate(13, 2, 2018) expiryDate = FinDate(13, 2, 2019) # In BS the FX rate is the price in domestic of one unit of foreign # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR # DOM = USD , FOR = EUR ccy1 = "EUR" ccy2 = "USD" ccy1CCRate = 0.0396 # EUR ccy2CCRate = 0.0357 # USD currencyPair = ccy1 + ccy2 # Always ccy1ccy2 spotFXRate = 0.9090 strikeFXRate = 0.9090 volatility = 0.12 notional = 1000000.0 domDiscountCurve = FinDiscountCurveFlat(valueDate, ccy2CCRate) forDiscountCurve = FinDiscountCurveFlat(valueDate, ccy1CCRate) model = FinFXModelBlackScholes(volatility) # Two examples to show that changing the notional currency and notional # keeps the value unchanged notional = 1000000.0 callOption = FinFXVanillaOption(expiryDate, strikeFXRate, currencyPair, FinOptionTypes.EUROPEAN_PUT, notional, "EUR", 2) value = callOption.value( valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) delta = callOption.delta( valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) testCases.header("value", "delta") testCases.print(value, delta)
def test_FinFXVanillaOptionWystupExample1(): # Example from Book extract by Uwe Wystup with results in Table 1.2 # https://mathfinance.com/wp-content/uploads/2017/06/FXOptionsStructuredProducts2e-Extract.pdf # Not exactly T=1.0 but close so don't exact exact agreement # (in fact I do not get exact agreement even if I do set T=1.0) valueDate = FinDate(13, 2, 2018) expiryDate = FinDate(13, 2, 2019) # In BS the FX rate is the price in domestic of one unit of foreign # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR # DOM = USD , FOR = EUR ccy1 = "EUR" ccy2 = "USD" ccy1CCRate = 0.030 # EUR ccy2CCRate = 0.025 # USD currencyPair = ccy1 + ccy2 # Always ccy1ccy2 spotFXRate = 1.20 strikeFXRate = 1.250 volatility = 0.10 spotDays = 0 settlementDate = valueDate.addWorkDays(spotDays) maturityDate = settlementDate.addMonths(12) notional = 1000000.0 notionalCurrency = "EUR" calendarType = FinCalendarTypes.TARGET domDiscountCurve = FinFlatCurve(valueDate, ccy2CCRate) forDiscountCurve = FinFlatCurve(valueDate, ccy1CCRate) model = FinFXModelBlackScholes(volatility) # Two examples to show that changing the notional currency and notional # keeps the value unchanged notional = 1000000.0 callOption = FinFXVanillaOption(expiryDate, strikeFXRate, currencyPair, FinOptionTypes.EUROPEAN_CALL, notional, "EUR", 2) value = callOption.value(1.0, spotFXRate, domDiscountCurve, forDiscountCurve, model) notional = 1250000.0 callOption = FinFXVanillaOption(expiryDate, strikeFXRate, currencyPair, FinOptionTypes.EUROPEAN_CALL, notional, "USD", 2) value = callOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) delta = callOption.delta(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) testCases.header("value", "delta") testCases.print(value, delta)
def test_FinFXOptionSABR(): # UNFINISHED # There is no FXAmericanOption class. It is embedded in the FXVanillaOption # class. This test just compares it to the European valueDate = FinDate(13, 2, 2018) expiryDate = FinDate(13, 2, 2019) # In BS the FX rate is the price in domestic of one unit of foreign # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR # DOM = USD , FOR = EUR ccy1CCRate = 0.030 # EUR ccy2CCRate = 0.025 # USD spotFXRate = 1.20 strikeFXRate = 1.250 volatility = 0.10 notional = 1000000.0 domDiscountCurve = FinDiscountCurveFlat(valueDate, ccy2CCRate) forDiscountCurve = FinDiscountCurveFlat(valueDate, ccy1CCRate) model = FinFXModelBlackScholes(volatility) # Two examples to show that changing the notional currency and notional # keeps the value unchanged notional = 1000000.0 spotFXRates = np.arange(50, 200, 10) / 100.0 testCases.header("OPTION", "FX_RATE", "VALUE_BS", "VOL_IN", "DIFF") for spotFXRate in spotFXRates: callOption = FinFXVanillaOption(expiryDate, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_CALL, notional, "USD") valueEuropean = callOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model)['v'] callOption = FinFXVanillaOption(expiryDate, strikeFXRate, "EURUSD", FinOptionTypes.AMERICAN_CALL, 1000000, "USD") valueAmerican = callOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model)['v'] diff = (valueAmerican - valueEuropean) testCases.print("CALL:", "%9.6f" % spotFXRate, "%9.7f" % valueEuropean, "%9.7f" % valueAmerican, "%9.7f" % diff) testCases.header("OPTION", "FX_RATE", "VALUE_BS", "VOL_IN", "DIFF") for spotFXRate in spotFXRates: callOption = FinFXVanillaOption(expiryDate, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_PUT, 1000000, "USD") valueEuropean = callOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model)['v'] callOption = FinFXVanillaOption(expiryDate, strikeFXRate, "EURUSD", FinOptionTypes.AMERICAN_PUT, 1000000, "USD") valueAmerican = callOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model)['v'] diff = (valueAmerican - valueEuropean) testCases.print("PUT:", "%9.6f" % spotFXRate, "%9.7f" % valueEuropean, "%9.7f" % valueAmerican, "%9.7f" % diff)
def test_FinFXAmericanOption(): # There is no FXAmericanOption class. It is embedded in the FXVanillaOption # class. This test just compares it to the European valueDate = FinDate(13, 2, 2018) expiryDate = FinDate(13, 2, 2019) # In BS the FX rate is the price in domestic of one unit of foreign # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR # DOM = USD , FOR = EUR ccy1 = "EUR" ccy2 = "USD" ccy1CCRate = 0.030 # EUR ccy2CCRate = 0.025 # USD currencyPair = ccy1 + ccy2 # Always ccy1ccy2 spotFXRate = 1.20 strikeFXRate = 1.250 volatility = 0.10 spotDays = 0 settlementDate = valueDate.addWorkDays(spotDays) maturityDate = settlementDate.addMonths(12) notional = 1000000.0 notionalCurrency = "EUR" calendarType = FinCalendarTypes.TARGET domDiscountCurve = FinFlatCurve(valueDate, ccy2CCRate) forDiscountCurve = FinFlatCurve(valueDate, ccy1CCRate) model = FinFXModelBlackScholes(volatility) # Two examples to show that changing the notional currency and notional # keeps the value unchanged notional = 1000000.0 testCases.header("SPOT FX RATE", "VALUE_BS", "VOL_IN", "IMPLD_VOL") spotFXRates = np.arange(50, 200, 10) / 100.0 for spotFXRate in spotFXRates: callOption = FinFXVanillaOption(expiryDate, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_CALL, 1000000, "USD") valueEuropean = callOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model)['v'] callOption = FinFXVanillaOption(expiryDate, strikeFXRate, "EURUSD", FinOptionTypes.AMERICAN_CALL, 1000000, "USD") valueAmerican = callOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model)['v'] diff = (valueAmerican - valueEuropean) print("CALL %9.6f %9.6f %9.7f %10.8f" % (spotFXRate, valueEuropean, valueAmerican, diff)) for spotFXRate in spotFXRates: callOption = FinFXVanillaOption(expiryDate, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_PUT, 1000000, "USD") valueEuropean = callOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model)['v'] callOption = FinFXVanillaOption(expiryDate, strikeFXRate, "EURUSD", FinOptionTypes.AMERICAN_PUT, 1000000, "USD") valueAmerican = callOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model)['v'] diff = (valueAmerican - valueEuropean) print("PUT %9.6f %9.6f %9.7f %10.8f" % (spotFXRate, valueEuropean, valueAmerican, diff))
def test_FinFXVanillaOptionHullExample(): # Example from Hull 4th edition page 284 valuation_date = Date(1, 1, 2015) expiry_date = valuation_date.addMonths(4) spotFXRate = 1.60 volatility = 0.1411 domInterestRate = 0.08 forInterestRate = 0.11 model = FinModelBlackScholes(volatility) domDiscountCurve = DiscountCurveFlat(valuation_date, domInterestRate) forDiscountCurve = DiscountCurveFlat(valuation_date, forInterestRate) num_pathsList = [10000, 20000, 40000, 80000, 160000, 320000] testCases.header("NUMPATHS", "VALUE_BS", "VALUE_MC", "TIME") strikeFXRate = 1.60 for num_paths in num_pathsList: callOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_CALL, 1000000, "USD") value = callOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) start = time.time() valueMC = callOption.valueMC(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model, num_paths) end = time.time() duration = end - start testCases.print(num_paths, value, valueMC, duration) ########################################################################## spotFXRates = np.arange(100, 200, 10) spotFXRates = spotFXRates / 100.0 num_paths = 100000 testCases.header("NUMPATHS", "CALL_VALUE_BS", "CALL_VALUE_MC", "TIME") for spotFXRate in spotFXRates: callOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_CALL, 1000000, "USD") value = callOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) start = time.time() valueMC = callOption.valueMC(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model, num_paths) end = time.time() duration = end - start testCases.print(num_paths, value, valueMC, duration) ########################################################################## spotFXRates = np.arange(100, 200, 10) / 100.0 num_paths = 100000 testCases.header("SPOT FX RATE", "PUT_VALUE_BS", "PUT_VALUE_MC", "TIME") for spotFXRate in spotFXRates: putOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_PUT, 1000000, "USD") value = putOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) start = time.time() valueMC = putOption.valueMC(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model, num_paths) end = time.time() duration = end - start testCases.print(spotFXRate, value, valueMC, duration) ########################################################################## spotFXRates = np.arange(100, 200, 10) / 100.0 testCases.header("SPOT FX RATE", "CALL_VALUE_BS", "DELTA_BS", "VEGA_BS", "THETA_BS", "RHO_BS") for spotFXRate in spotFXRates: callOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_CALL, 1000000, "USD") value = callOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) delta = callOption.delta(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) vega = callOption.vega(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) theta = callOption.theta(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) # callOption.rho(valuation_date,stock_price, interestRate, # dividendYield, modelType, modelParams) rho = 999 testCases.print(spotFXRate, value, delta, vega, theta, rho) testCases.header("SPOT FX RATE", "PUT_VALUE_BS", "DELTA_BS", "VEGA_BS", "THETA_BS", "RHO_BS") for spotFXRate in spotFXRates: putOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_PUT, 1000000, "USD") value = putOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) delta = putOption.delta(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) vega = putOption.vega(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) theta = putOption.theta(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model) # putOption.rho(valuation_date,stock_price, interestRate, dividendYield, # modelType, modelParams) rho = 999 testCases.print(spotFXRate, value, delta, vega, theta, rho) ########################################################################## testCases.header("SPOT FX RATE", "VALUE_BS", "VOL_IN", "IMPLD_VOL") spotFXRates = np.arange(100, 200, 10) / 100.0 for spotFXRate in spotFXRates: callOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_CALL, 1000000, "USD") value = callOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model)['v'] impliedVol = callOption.impliedVolatility(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, value) testCases.print(spotFXRate, value, volatility, impliedVol)
def _price_option(contract_type_, contract_type_fin_): for i in range(len(expiry_date)): built_vol_surface = False # If we have a "key strike" need to fit the vol surface if isinstance(strike[i], str): if not (built_vol_surface): fx_vol_surface.build_vol_surface(horizon_date[i]) fx_vol_surface.extract_vol_surface( num_strike_intervals=None) built_vol_surface = True # Delta neutral strike/or whatever strike is quoted as ATM # usually this is ATM delta neutral strike, but can sometimes be ATMF for some Latam # Take the vol directly quoted, rather than getting it from building vol surface if strike[i] == 'atm': strike[i] = fx_vol_surface.get_atm_strike(tenor) vol[i] = fx_vol_surface.get_atm_quoted_vol( tenor) / 100.0 # vol[i] = fx_vol_surface.get_atm_vol(tenor) / 100.0 # interpolated elif strike[i] == 'atms': strike[i] = fx_vol_surface.get_spot( ) # Interpolate vol later elif strike[i] == 'atmf': # Quoted tenor, no need to interpolate strike[i] = float(fx_vol_surface.get_all_market_data()[cross + ".close"][horizon_date[i]]) \ + (float(fx_vol_surface.get_all_market_data()[cross + tenor + ".close"][horizon_date[i]]) \ / self._fx_forwards_pricer.get_forwards_divisor(cross[3:6])) # Interpolate vol later elif strike[i] == '25d-otm': if 'call' in contract_type_: strike[i] = fx_vol_surface.get_25d_call_strike( tenor) vol[i] = fx_vol_surface.get_25d_call_vol( tenor) / 100.0 elif 'put' in contract_type_: strike[i] = fx_vol_surface.get_25d_put_strike( tenor) vol[i] = fx_vol_surface.get_25d_put_vol( tenor) / 100.0 elif strike[i] == '10d-otm': if 'call' in contract_type_: strike[i] = fx_vol_surface.get_10d_call_strike( tenor) vol[i] = fx_vol_surface.get_10d_call_vol( tenor) / 100.0 elif 'put' in contract_type_: strike[i] = fx_vol_surface.get_10d_put_strike( tenor) vol[i] = fx_vol_surface.get_10d_put_vol( tenor) / 100.0 if not (built_vol_surface): try: fx_vol_surface.build_vol_surface(horizon_date[i]) except: logger.warn("Failed to build vol surface for " + str(horizon_date) + ", won't be able to interpolate vol") # fx_vol_surface.extract_vol_surface(num_strike_intervals=None) # If an implied vol hasn't been provided, interpolate that one, fit the vol surface (if hasn't already been # done) if np.isnan(vol[i]): if tenor is None: vol[i] = fx_vol_surface.calculate_vol_for_strike_expiry( strike[i], expiry_date=expiry_date[i], tenor=None) else: vol[i] = fx_vol_surface.calculate_vol_for_strike_expiry( strike[i], expiry_date=None, tenor=tenor) model = FinModelBlackScholes(float(vol[i])) logger.info("Pricing " + contract_type_ + " option, horizon date = " + str(horizon_date[i]) + ", expiry date = " + str(expiry_date[i])) option = FinFXVanillaOption(self._findate(expiry_date[i]), strike[i], cross, contract_type_fin_, notional, cross[0:3]) spot[i] = fx_vol_surface.get_spot() """ FinancePy will return the value in the following dictionary for values {'v': vdf, "cash_dom": cash_dom, "cash_for": cash_for, "pips_dom": pips_dom, "pips_for": pips_for, "pct_dom": pct_dom, "pct_for": pct_for, "not_dom": notional_dom, "not_for": notional_for, "ccy_dom": self._domName, "ccy_for": self._forName} """ option_values[i] = option_values[i] + option.value( self._findate(horizon_date[i]), spot[i], fx_vol_surface.get_dom_discount_curve(), fx_vol_surface.get_for_discount_curve(), model)[premium_output.replace('-', '_')] intrinsic_values[i] = intrinsic_values[i] + option.value( self._findate(expiry_date[i]), spot[i], fx_vol_surface.get_dom_discount_curve(), fx_vol_surface.get_for_discount_curve(), model)[premium_output.replace('-', '_')] """FinancePy returns this dictionary for deltas {"pips_spot_delta": pips_spot_delta, "pips_fwd_delta": pips_fwd_delta, "pct_spot_delta_prem_adj": pct_spot_delta_prem_adj, "pct_fwd_delta_prem_adj": pct_fwd_delta_prem_adj} """ delta[i] = delta[i] + option.delta( self._findate(horizon_date[i]), spot[i], fx_vol_surface.get_dom_discount_curve(), fx_vol_surface.get_for_discount_curve(), model)[delta_output.replace('-', '_')]
def test_FinFXAmericanOption(): # There is no FXAmericanOption class. It is embedded in the FXVanillaOption # class. This test just compares it to the European valuation_date = Date(13, 2, 2018) expiry_date = Date(13, 2, 2019) # In BS the FX rate is the price in domestic of one unit of foreign # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR # DOM = USD , FOR = EUR ccy1 = "EUR" ccy2 = "USD" ccy1CCRate = 0.030 # EUR ccy2CCRate = 0.025 # USD currencyPair = ccy1 + ccy2 # Always ccy1ccy2 spotFXRate = 1.20 strikeFXRate = 1.250 volatility = 0.10 domDiscountCurve = DiscountCurveFlat(valuation_date, ccy2CCRate) forDiscountCurve = DiscountCurveFlat(valuation_date, ccy1CCRate) model = FinModelBlackScholes(volatility) # Two examples to show that changing the notional currency and notional # keeps the value unchanged testCases.header("SPOT FX RATE", "VALUE_BS", "VOL_IN", "IMPLD_VOL") spotFXRates = np.arange(50, 200, 10) / 100.0 for spotFXRate in spotFXRates: callOption = FinFXVanillaOption(expiry_date, strikeFXRate, currencyPair, FinOptionTypes.EUROPEAN_CALL, 1000000, "USD") valueEuropean = callOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model)['v'] callOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD", FinOptionTypes.AMERICAN_CALL, 1000000, "USD") valueAmerican = callOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model)['v'] diff = (valueAmerican - valueEuropean) testCases.print(spotFXRate, valueEuropean, valueAmerican, diff) for spotFXRate in spotFXRates: callOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_PUT, 1000000, "USD") valueEuropean = callOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model)['v'] callOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD", FinOptionTypes.AMERICAN_PUT, 1000000, "USD") valueAmerican = callOption.value(valuation_date, spotFXRate, domDiscountCurve, forDiscountCurve, model)['v'] diff = (valueAmerican - valueEuropean) testCases.print(spotFXRate, valueEuropean, valueAmerican, diff)
def _price_option(contract_type_, contract_type_fin_): for i in range(len(expiry_date)): built_vol_surface = False # If we have a "key strike" need to fit the vol surface if isinstance(strike[i], str): if not (built_vol_surface): fx_vol_surface.build_vol_surface(horizon_date[i]) fx_vol_surface.extract_vol_surface( num_strike_intervals=None) built_vol_surface = True if strike[i] == 'atm': strike[i] = fx_vol_surface.get_atm_strike(tenor) vol[i] = fx_vol_surface.get_atm_vol(tenor) / 100.0 elif strike[i] == 'atms': strike[i] = fx_vol_surface.get_spot() elif strike[i] == 'atmf': delivery_date = self._calendar.get_delivery_date_from_horizon_date( horizon_date[i], cal=cross) strike[i] = self._fx_forwards_price.price_instrument( cross, delivery_date, market_df=fx_vol_surface.get_all_market_data()) elif strike[i] == '25d-otm': if 'call' in contract_type_: strike[i] = fx_vol_surface.get_25d_call_strike( tenor) vol[i] = fx_vol_surface.get_25d_call_strike( tenor) / 100.0 elif 'put' in contract_type_: strike[i] = fx_vol_surface.get_25d_put_strike( tenor) vol[i] = fx_vol_surface.get_25d_put_strike( tenor) / 100.0 elif strike[i] == '10d-otm': if 'call' in contract_type_: strike[i] = fx_vol_surface.get_10d_call_strike( tenor) vol[i] = fx_vol_surface.get_10d_call_strike( tenor) / 100.0 elif 'put' in contract_type_: strike[i] = fx_vol_surface.get_10d_put_strike( tenor) vol[i] = fx_vol_surface.get_10d_put_strike( tenor) / 100.0 if not (built_vol_surface): fx_vol_surface.build_vol_surface(horizon_date[i]) # fx_vol_surface.extract_vol_surface(num_strike_intervals=None) # If an implied vol hasn't been provided, interpolate that one, fit the vol surface (if hasn't already been # done) if np.isnan(vol[i]): if tenor is None: vol[i] = fx_vol_surface.calculate_vol_for_strike_expiry( strike[i], expiry_date=expiry_date[i], tenor=None) else: vol[i] = fx_vol_surface.calculate_vol_for_strike_expiry( strike[i], expiry_date=None, tenor=tenor) model = FinModelBlackScholes(float(vol[i])) logger.info("Pricing " + contract_type_ + " option, horizon date = " + str(horizon_date[i]) + ", expiry date = " + str(expiry_date[i])) option = FinFXVanillaOption(self._findate(expiry_date[i]), strike[i], cross, contract_type_fin_, notional, cross[0:3]) spot[i] = fx_vol_surface.get_spot() """ FinancePy will return the value in the following dictionary for values {'v': vdf, "cash_dom": cash_dom, "cash_for": cash_for, "pips_dom": pips_dom, "pips_for": pips_for, "pct_dom": pct_dom, "pct_for": pct_for, "not_dom": notional_dom, "not_for": notional_for, "ccy_dom": self._domName, "ccy_for": self._forName} """ option_values[i] = option_values[i] + option.value( self._findate(horizon_date[i]), spot[i], fx_vol_surface.get_dom_discount_curve(), fx_vol_surface.get_for_discount_curve(), model)[premium_output.replace('-', '_')] intrinsic_values[i] = intrinsic_values[i] + option.value( self._findate(expiry_date[i]), spot[i], fx_vol_surface.get_dom_discount_curve(), fx_vol_surface.get_for_discount_curve(), model)[premium_output.replace('-', '_')] """FinancePy returns this dictionary for deltas {"pips_spot_delta": pips_spot_delta, "pips_fwd_delta": pips_fwd_delta, "pct_spot_delta_prem_adj": pct_spot_delta_prem_adj, "pct_fwd_delta_prem_adj": pct_fwd_delta_prem_adj} """ delta[i] = delta[i] + option.delta( self._findate(horizon_date[i]), spot[i], fx_vol_surface.get_dom_discount_curve(), fx_vol_surface.get_for_discount_curve(), model)[delta_output.replace('-', '_')]