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_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 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_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_OIS(): startDate = FinDate(2018, 11, 30) endDate = FinDate(2028, 6, 20) endDate = startDate.addMonths(60) oisRate = 0.04 isPayer = True fixedFreq = FinFrequencyTypes.ANNUAL fixedDayCount = FinDayCountTypes.ACT_ACT_ISDA floatFreq = FinFrequencyTypes.ANNUAL floatDayCount = FinDayCountTypes.ACT_ACT_ISDA notional = ONE_MILLION ois = FinOIS(startDate, endDate, oisRate, fixedFreq, fixedDayCount, floatFreq, floatDayCount, isPayer, notional) valueDate = FinDate(2018, 11, 30) marketRate = 0.05 indexCurve = FinFlatCurve(valueDate, marketRate, 1) ois.print(valueDate, indexCurve) v = ois.value(startDate, indexCurve) testCases.header("LABEL", "VALUE") testCases.print("SWAP_VALUE", v)
def test_FinEquityVarianceSwap(): startDate = FinDate(2018, 3, 20) tenor = "3M" strike = 0.3 * 0.3 volSwap = FinEquityVarianceSwap(startDate, tenor, strike) valuationDate = FinDate(2018, 3, 20) stockPrice = 100.0 dividendYield = 0.0 maturityDate = startDate.addMonths(3) atmVol = 0.20 atmK = 100.0 skew = -0.02 / 5.0 # defined as dsigma/dK strikes = np.linspace(50.0, 135.0, 18) vols = volSkew(strikes, atmVol, atmK, skew) volCurve = FinVolatilityCurve(valuationDate, maturityDate, strikes, vols) strikeSpacing = 5.0 numCallOptions = 10 numPutOptions = 10 r = 0.05 discountCurve = FinFlatCurve(valuationDate, r) useForward = False testCases.header("LABEL", "VALUE") k1 = volSwap.fairStrike(valuationDate, stockPrice, dividendYield, volCurve, numCallOptions, numPutOptions, strikeSpacing, discountCurve, useForward) testCases.print("REPLICATION VARIANCE:", k1) # volSwap.print() k2 = volSwap.fairStrikeApprox(valuationDate, stockPrice, strikes, vols) testCases.print("DERMAN SKEW APPROX for K:", k2)
def testFinEquityAmericanOption(): valueDate = FinDate(2016, 1, 1) expiryDate = FinDate(2017, 1, 1) stockPrice = 50.0 interestRate = 0.06 dividendYield = 0.04 volatility = 0.40 strikePrice = 50.0 model = FinEquityModelBlackScholes(volatility) discountCurve = FinFlatCurve(valueDate, interestRate) numStepsList = [1000, 2000] testCases.banner("================== EUROPEAN PUT =======================") putOption = FinEquityVanillaOption( expiryDate, strikePrice, FinEquityOptionTypes.EUROPEAN_PUT) value = putOption.value( valueDate, stockPrice, discountCurve, dividendYield, model) delta = putOption.delta( valueDate, stockPrice, discountCurve, dividendYield, model) gamma = putOption.gamma( valueDate, stockPrice, discountCurve, dividendYield, model) theta = putOption.theta( valueDate, stockPrice, discountCurve, dividendYield, model) testCases.header("OPTION_TYPE", "VALUE", "DELTA", "GAMMA", "THETA") testCases.print("EUROPEAN_PUT_BS", value, delta, gamma, theta) option = FinEquityAmericanOption( expiryDate, strikePrice, FinEquityOptionTypes.EUROPEAN_PUT) testCases.header( "OPTION_TYPE", "NUMSTEPS", "VALUE DELTA GAMMA THETA", "TIME") for numSteps in numStepsList: start = time.time() results = option.value( valueDate, stockPrice, discountCurve, dividendYield, model, numSteps) end = time.time() duration = end - start testCases.print("EUROPEAN_PUT_TREE", numSteps, results, duration) testCases.banner("================== AMERICAN PUT =======================") option = FinEquityAmericanOption( expiryDate, strikePrice, FinEquityOptionTypes.AMERICAN_PUT) testCases.header( "OPTION_TYPE", "NUMSTEPS", "VALUE DELTA GAMMA THETA", "TIME") for numSteps in numStepsList: start = time.time() results = option.value( valueDate, stockPrice, discountCurve, dividendYield, model, numSteps) end = time.time() duration = end - start testCases.print("AMERICAN_PUT", numSteps, results, duration) testCases.banner( "================== EUROPEAN CALL =======================") callOption = FinEquityVanillaOption( expiryDate, strikePrice, FinEquityOptionTypes.EUROPEAN_CALL) value = callOption.value( valueDate, stockPrice, discountCurve, dividendYield, model) delta = callOption.delta( valueDate, stockPrice, discountCurve, dividendYield, model) gamma = callOption.gamma( valueDate, stockPrice, discountCurve, dividendYield, model) theta = callOption.theta( valueDate, stockPrice, discountCurve, dividendYield, model) testCases.header("OPTION_TYPE", "VALUE", "DELTA", "GAMMA", "THETA") testCases.print("EUROPEAN_CALL_BS", value, delta, gamma, theta) option = FinEquityAmericanOption( expiryDate, strikePrice, FinEquityOptionTypes.EUROPEAN_CALL) testCases.header( "OPTION_TYPE", "NUMSTEPS", "VALUE DELTA GAMMA THETA", "TIME") for numSteps in numStepsList: start = time.time() results = option.value( valueDate, stockPrice, discountCurve, dividendYield, model, numSteps) end = time.time() duration = end - start testCases.print("EUROPEAN_CALL", numSteps, results, duration) testCases.banner( "================== AMERICAN CALL =======================") testCases.header( "OPTION_TYPE", "NUMSTEPS", "VALUE DELTA GAMMA THETA", "TIME") option = FinEquityAmericanOption( expiryDate, strikePrice, FinEquityOptionTypes.AMERICAN_CALL) for numSteps in numStepsList: start = time.time() results = option.value( valueDate, stockPrice, discountCurve, dividendYield, model, numSteps) end = time.time() duration = end - start testCases.print("AMERICAN_CALL", numSteps, results, duration)
def test_FinFXVanillaOptionHullExample(): # Example from Hull 4th edition page 284 valueDate = FinDate(2015, 1, 1) expiryDate = valueDate.addMonths(4) spotFXRate = 1.60 volatility = 0.1411 domInterestRate = 0.08 forInterestRate = 0.11 model = FinFXModelBlackScholes(volatility) domDiscountCurve = FinFlatCurve(valueDate, domInterestRate) forDiscountCurve = FinFlatCurve(valueDate, forInterestRate) numPathsList = [10000, 20000, 40000, 80000, 160000, 320000] testCases.header("NUMPATHS", "VALUE_BS", "VALUE_MC", "TIME") strikeFXRate = 1.60 for numPaths in numPathsList: callOption = FinFXVanillaOption(expiryDate, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_CALL, 1000000, "USD") value = callOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) start = time.time() valueMC = callOption.valueMC(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model, numPaths) end = time.time() duration = end - start testCases.print(numPaths, value, valueMC, duration) ########################################################################## spotFXRates = np.arange(100, 200, 10) spotFXRates = spotFXRates / 100.0 numPaths = 100000 testCases.header("NUMPATHS", "CALL_VALUE_BS", "CALL_VALUE_MC", "TIME") for spotFXRate in spotFXRates: callOption = FinFXVanillaOption(expiryDate, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_CALL, 1000000, "USD") value = callOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) start = time.time() valueMC = callOption.valueMC(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model, numPaths) end = time.time() duration = end - start testCases.print(numPaths, value, valueMC, duration) ########################################################################## spotFXRates = np.arange(100, 200, 10) / 100.0 numPaths = 100000 testCases.header("SPOT FX RATE", "PUT_VALUE_BS", "PUT_VALUE_MC", "TIME") for spotFXRate in spotFXRates: putOption = FinFXVanillaOption(expiryDate, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_PUT, 1000000, "USD") value = putOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) start = time.time() valueMC = putOption.valueMC(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model, numPaths) 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(expiryDate, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_CALL, 1000000, "USD") value = callOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) delta = callOption.delta(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) vega = callOption.vega(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) theta = callOption.theta(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) # callOption.rho(valueDate,stockPrice, 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(expiryDate, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_PUT, 1000000, "USD") value = putOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) delta = putOption.delta(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) vega = putOption.vega(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) theta = putOption.theta(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model) # putOption.rho(valueDate,stockPrice, 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(expiryDate, strikeFXRate, "EURUSD", FinOptionTypes.EUROPEAN_CALL, 1000000, "USD") value = callOption.value(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, model)['v'] impliedVol = callOption.impliedVolatility(valueDate, spotFXRate, domDiscountCurve, forDiscountCurve, value) testCases.print(spotFXRate, value, volatility, impliedVol)
def test_FinBondConvertible(): settlementDate = FinDate(2003, 12, 31) startConvertDate = FinDate(2003, 12, 31) maturityDate = FinDate(2022, 3, 15) conversionRatio = 38.4615 # adjust for face coupon = 0.0575 frequencyType = FinFrequencyTypes.SEMI_ANNUAL accrualBasis = FinDayCountTypes.ACT_365_FIXED face = 1000.0 callPrice = 1100 callDates = [ FinDate(2007, 3, 20), FinDate(2012, 3, 15), FinDate(2017, 3, 15) ] callPrices = np.array([callPrice, callPrice, callPrice]) putPrice = 90 putDates = [ FinDate(2007, 3, 20), FinDate(2012, 3, 15), FinDate(2017, 3, 15) ] putPrices = np.array([putPrice, putPrice, putPrice]) bond = FinBondConvertible(maturityDate, coupon, frequencyType, startConvertDate, conversionRatio, callDates, callPrices, putDates, putPrices, accrualBasis, face) dividendDates = [ FinDate(2007, 3, 20), FinDate(2008, 3, 15), FinDate(2009, 3, 15), FinDate(2010, 3, 15), FinDate(2011, 3, 15), FinDate(2012, 3, 15), FinDate(2013, 3, 15), FinDate(2014, 3, 15), FinDate(2015, 3, 15), FinDate(2016, 3, 15), FinDate(2017, 3, 15), FinDate(2018, 3, 15), FinDate(2019, 3, 15), FinDate(2020, 3, 15), FinDate(2021, 3, 15), FinDate(2022, 3, 15) ] dividendYields = [0.00] * 16 stockPrice = 28.5 stockVolatility = 0.370 rate = 0.04 discountCurve = FinFlatCurve(settlementDate, rate, -1) creditSpread = 0.00 recoveryRate = 0.40 numStepsPerYear = 20 testCases.header("LABEL") testCases.print("NO CALLS OR PUTS") testCases.header("PERIOD", "NUMSTEPS", "PRICE", "FIXEDINCOME", "DELTA") for numStepsPerYear in [5, 10, 20, 40, 80]: start = time.time() res = bond.value(settlementDate, stockPrice, stockVolatility, dividendDates, dividendYields, discountCurve, creditSpread, recoveryRate, numStepsPerYear) end = time.time() period = end - start testCases.print(period, numStepsPerYear, res) print(res) dividendYields = [0.02] * 16 testCases.header("LABEL") testCases.print("DIVIDENDS") testCases.header("PERIOD", "NUMSTEPS", "PRICE", "FIXEDINCOME", "DELTA") for numStepsPerYear in [5, 10, 20, 40, 80]: start = time.time() res = bond.value(settlementDate, stockPrice, stockVolatility, dividendDates, dividendYields, discountCurve, creditSpread, recoveryRate, numStepsPerYear) end = time.time() period = end - start testCases.print(period, numStepsPerYear, res) print(res)
def test_FinBond(): import pandas as pd bondDataFrame = pd.read_csv('./data/giltbondprices.txt', sep='\t') bondDataFrame['mid'] = 0.5*(bondDataFrame['bid'] + bondDataFrame['ask']) frequencyType = FinFrequencyTypes.SEMI_ANNUAL settlement = FinDate(2012, 9, 19) for accrualType in FinDayCountTypes: testCases.header("MATURITY", "COUPON", "CLEAN_PRICE", "ACCD_DAYS", "ACCRUED", "YTM") for index, bond in bondDataFrame.iterrows(): dateString = bond['maturity'] matDatetime = dt.datetime.strptime(dateString, '%d-%b-%y') maturityDt = FinDate.fromDatetime(matDatetime) coupon = bond['coupon']/100.0 cleanPrice = bond['mid'] bond = FinBond(maturityDt, coupon, frequencyType, accrualType) ytm = bond.yieldToMaturity(settlement, cleanPrice) accd = bond._accrued accd_days = bond._accruedDays testCases.print("%18s" % maturityDt, "%8.4f" % coupon, "%10.4f" % cleanPrice, "%6.0f" % accd_days, "%10.4f" % accd, "%8.4f" % ytm) # EXAMPLE FROM http://bondtutor.com/btchp4/topic6/topic6.htm accrualConvention = FinDayCountTypes.ACT_ACT_ICMA y = 0.062267 settlementDate = FinDate(1994, 4, 19) maturityDate = FinDate(1997, 7, 15) coupon = 0.085 face = 1.0 freqType = FinFrequencyTypes.SEMI_ANNUAL bond = FinBond(maturityDate, coupon, freqType, accrualConvention, face) testCases.header("FIELD", "VALUE") fullPrice = bond.fullPriceFromYield(settlementDate, y) testCases.print("Full Price = ", fullPrice) cleanPrice = bond.cleanPriceFromYield(settlementDate, y) testCases.print("Clean Price = ", cleanPrice) accd = bond._accrued testCases.print("Accrued = ", accd) ytm = bond.yieldToMaturity(settlementDate, cleanPrice) testCases.print("Yield to Maturity = ", ytm) bump = 1e-4 priceBumpedUp = bond.fullPriceFromYield(settlementDate, y + bump) testCases.print("Price Bumped Up:", priceBumpedUp) priceBumpedDn = bond.fullPriceFromYield(settlementDate, y - bump) testCases.print("Price Bumped Dn:", priceBumpedDn) durationByBump = -(priceBumpedUp - fullPrice) / bump testCases.print("Duration by Bump = ", durationByBump) duration = bond.dollarDuration(settlementDate, y) testCases.print("Dollar Duration = ", duration) testCases.print("Duration Difference:", duration - durationByBump) modifiedDuration = bond.modifiedDuration(settlementDate, y) testCases.print("Modified Duration = ", modifiedDuration) macauleyDuration = bond.macauleyDuration(settlementDate, y) testCases.print("Macauley Duration = ", macauleyDuration) conv = bond.convexityFromYield(settlementDate, y) testCases.print("Convexity = ", conv) # ASSET SWAP SPREAD # When the libor curve is the flat bond curve then the ASW is zero by # definition flatCurve = FinFlatCurve(settlementDate, ytm, 2) testCases.header("FIELD", "VALUE") cleanPrice = bond.cleanPriceFromYield(settlementDate, ytm) asw = bond.assetSwapSpread(settlementDate, cleanPrice, flatCurve) testCases.print("Discounted on Bond Curve ASW:", asw * 10000) # When the libor curve is the Libor curve then the ASW is positive liborCurve = buildLiborCurve(settlementDate) asw = bond.assetSwapSpread(settlementDate, cleanPrice, liborCurve) oas = bond.optionAdjustedSpread(settlementDate, cleanPrice, liborCurve) testCases.print("Discounted on LIBOR Curve ASW:", asw * 10000) testCases.print("Discounted on LIBOR Curve OAS:", oas * 10000) p = 0.90 asw = bond.assetSwapSpread(settlementDate, p, liborCurve) oas = bond.optionAdjustedSpread(settlementDate, p, liborCurve) testCases.print("Deep discount bond at 90 ASW:", asw * 10000) testCases.print("Deep discount bond at 90 OAS:", oas * 10000) p = 1.00 asw = bond.assetSwapSpread(settlementDate, p, liborCurve) oas = bond.optionAdjustedSpread(settlementDate, p, liborCurve) testCases.print("Par bond at 100 ASW:", asw * 10000) testCases.print("Par bond at 100 OAS:", oas * 10000) p = 1.20 asw = bond.assetSwapSpread(settlementDate, p, liborCurve) oas = bond.optionAdjustedSpread(settlementDate, p, liborCurve) testCases.print("Above par bond at 120 ASW:", asw * 10000) testCases.print("Above par bond at 120 OAS:", oas * 10000) ########################################################################## # https://data.bloomberglp.com/bat/sites/3/2017/07/SF-2017_Paul-Fjeldsted.pdf # Page 10 TREASURY NOTE SCREENSHOT ########################################################################## testCases.banner("BLOOMBERG US TREASURY EXAMPLE") settlementDate = FinDate(2017, 7, 21) maturityDate = FinDate(2027, 5, 15) coupon = 0.02375 freqType = FinFrequencyTypes.SEMI_ANNUAL accrualType = FinDayCountTypes.ACT_ACT_ICMA face = 100.0 bond = FinBond(maturityDate, coupon, freqType, accrualType, face) testCases.header("FIELD", "VALUE") cleanPrice = 99.780842 yld = bond.currentYield(cleanPrice) testCases.print("Current Yield = ", yld) ytm = bond.yieldToMaturity(settlementDate, cleanPrice, FinYieldConventions.UK_DMO) testCases.print("UK DMO Yield To Maturity = ", ytm) ytm = bond.yieldToMaturity(settlementDate, cleanPrice, FinYieldConventions.US_STREET) testCases.print("US STREET Yield To Maturity = ", ytm) ytm = bond.yieldToMaturity(settlementDate, cleanPrice, FinYieldConventions.US_TREASURY) testCases.print("US TREASURY Yield To Maturity = ", ytm) fullPrice = bond.fullPriceFromYield(settlementDate, ytm) testCases.print("Full Price = ", fullPrice) cleanPrice = bond.cleanPriceFromYield(settlementDate, ytm) testCases.print("Clean Price = ", cleanPrice) accd = bond._accrued testCases.print("Accrued = ", accd) accddays = bond._accruedDays testCases.print("Accrued Days = ", accddays) duration = bond.dollarDuration(settlementDate, ytm) testCases.print("Dollar Duration = ", duration) modifiedDuration = bond.modifiedDuration(settlementDate, ytm) testCases.print("Modified Duration = ", modifiedDuration) macauleyDuration = bond.macauleyDuration(settlementDate, ytm) testCases.print("Macauley Duration = ", macauleyDuration) conv = bond.convexityFromYield(settlementDate, ytm) testCases.print("Convexity = ", conv) ########################################################################## # Page 11 APPLE NOTE SCREENSHOT ########################################################################## testCases.banner("BLOOMBERG APPLE CORP BOND EXAMPLE") settlementDate = FinDate(2017, 7, 21) maturityDate = FinDate(2022, 5, 13) coupon = 0.027 freqType = FinFrequencyTypes.SEMI_ANNUAL accrualType = FinDayCountTypes.ACT_ACT_ICMA face = 100.0 bond = FinBond(maturityDate, coupon, freqType, accrualType, face) testCases.header("FIELD", "VALUE") cleanPrice = 101.581564 yld = bond.currentYield(cleanPrice) testCases.print("Current Yield = ", yld) ytm = bond.yieldToMaturity(settlementDate, cleanPrice, FinYieldConventions.UK_DMO) testCases.print("UK DMO Yield To Maturity = ", ytm) ytm = bond.yieldToMaturity(settlementDate, cleanPrice, FinYieldConventions.US_STREET) testCases.print("US STREET Yield To Maturity = ", ytm) ytm = bond.yieldToMaturity(settlementDate, cleanPrice, FinYieldConventions.US_TREASURY) testCases.print("US TREASURY Yield To Maturity = ", ytm) fullPrice = bond.fullPriceFromYield(settlementDate, ytm) testCases.print("Full Price = ", fullPrice) cleanPrice = bond.cleanPriceFromYield(settlementDate, ytm) testCases.print("Clean Price = ", cleanPrice) # I GET 69 DAYS BUT BBG GETS 68 - CANNOT EXPLAIN!! accddays = bond._accruedDays testCases.print("Accrued Days = ", accddays) accd = bond._accrued testCases.print("Accrued = ", accd) duration = bond.dollarDuration(settlementDate, ytm) testCases.print("Dollar Duration = ", duration) modifiedDuration = bond.modifiedDuration(settlementDate, ytm) testCases.print("Modified Duration = ", modifiedDuration) macauleyDuration = bond.macauleyDuration(settlementDate, ytm) testCases.print("Macauley Duration = ", macauleyDuration) conv = bond.convexityFromYield(settlementDate, ytm) testCases.print("Convexity = ", conv)
def test_FinRainbowOption(): # import matplotlib.pyplot as plt valueDate = FinDate(2015, 1, 1) expiryDate = FinDate(2016, 1, 1) interestRate = 0.05 discountCurve = FinFlatCurve(valueDate, interestRate) numAssets = 2 volatilities = np.ones(numAssets) * 0.3 dividendYields = np.ones(numAssets) * 0.01 stockPrices = np.ones(numAssets) * 100 numPathsList = [10000] corrList = np.linspace(0.0, 0.999999, 6) strike = 100.0 testCases.banner( "===================================================================") testCases.banner(" CALL ON MAXIMUM") testCases.banner( "===================================================================") payoffType = FinEquityRainbowOptionTypes.CALL_ON_MAXIMUM payoffParams = [strike] rainbowOption = FinEquityRainbowOption(expiryDate, payoffType, payoffParams, numAssets) rainboxOptionValues = [] rainbowOptionValuesMC = [] testCases.header("NUMPATHS", "CORRELATION", "VALUE", "VALUE_MC", "TIME") for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) for numPaths in numPathsList: start = time.time() v = rainbowOption.value(valueDate, expiryDate, stockPrices, discountCurve, dividendYields, volatilities, betas) v_MC = rainbowOption.valueMC(valueDate, expiryDate, stockPrices, discountCurve, dividendYields, volatilities, betas, numPaths) end = time.time() duration = end - start testCases.print(numPaths, correlation, v, v_MC, duration) rainboxOptionValues.append(v) rainbowOptionValuesMC.append(v_MC) # plt.figure(figsize=(10,8)) # plt.plot(corrList, rainboxOptionValues, color = 'r', label = "CALL ON MAX Rainbow Option Analytical") # plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "CALL ON MAX Rainbow Option MC") # plt.xlabel("Correlation") # plt.legend(loc='best') ########################################################################## testCases.banner( "===================================================================") testCases.banner(" CALL ON MINIMUM") testCases.banner( "===================================================================") payoffType = FinEquityRainbowOptionTypes.CALL_ON_MINIMUM payoffParams = [strike] rainbowOption = FinEquityRainbowOption(expiryDate, payoffType, payoffParams, numAssets) rainboxOptionValues = [] rainbowOptionValuesMC = [] testCases.header("NUMPATHS", "CORRELATION", "VALUE", "VALUE_MC", "TIME") for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) for numPaths in numPathsList: start = time.time() v = rainbowOption.value(valueDate, expiryDate, stockPrices, discountCurve, dividendYields, volatilities, betas) v_MC = rainbowOption.valueMC(valueDate, expiryDate, stockPrices, discountCurve, dividendYields, volatilities, betas, numPaths) end = time.time() duration = end - start testCases.print(numPaths, correlation, v, v_MC, duration) rainboxOptionValues.append(v) rainbowOptionValuesMC.append(v_MC) # plt.figure(figsize=(10,8)) # plt.plot(corrList, rainboxOptionValues, color = 'r', label = "CALL ON MIN Rainbow Option Analytical") # plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "CALL ON MIN Rainbow Option MC") # plt.xlabel("Correlation") # plt.legend(loc='best') ############################################################################### testCases.banner( "===================================================================") testCases.banner(" PUT ON MAXIMUM") testCases.banner( "===================================================================") payoffType = FinEquityRainbowOptionTypes.PUT_ON_MAXIMUM payoffParams = [strike] rainbowOption = FinEquityRainbowOption(expiryDate, payoffType, payoffParams, numAssets) rainboxOptionValues = [] rainbowOptionValuesMC = [] testCases.header("NUMPATHS", "CORRELATION", "VALUE", "VALUE_MC", "TIME") for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) for numPaths in numPathsList: start = time.time() v = rainbowOption.value(valueDate, expiryDate, stockPrices, discountCurve, dividendYields, volatilities, betas) v_MC = rainbowOption.valueMC(valueDate, expiryDate, stockPrices, discountCurve, dividendYields, volatilities, betas, numPaths) end = time.time() duration = end - start testCases.print(numPaths, correlation, v, v_MC, duration) rainboxOptionValues.append(v) rainbowOptionValuesMC.append(v_MC) # plt.figure(figsize=(10,8)) # plt.plot(corrList, rainboxOptionValues, color = 'r', label = "PUT ON MAX Rainbow Option Analytical") # plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "PUT ON MAX Rainbow Option MC") # plt.xlabel("Correlation") # plt.legend(loc='best') ########################################################################## testCases.banner( "===================================================================") testCases.banner(" PUT ON MINIMUM") testCases.banner( "===================================================================") payoffType = FinEquityRainbowOptionTypes.PUT_ON_MINIMUM payoffParams = [strike] rainbowOption = FinEquityRainbowOption(expiryDate, payoffType, payoffParams, numAssets) rainboxOptionValues = [] rainbowOptionValuesMC = [] testCases.header("NUMPATHS", "CORRELATION", "VALUE", "VALUE_MC", "TIME") for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) for numPaths in numPathsList: start = time.time() v = rainbowOption.value(valueDate, expiryDate, stockPrices, discountCurve, dividendYields, volatilities, betas) v_MC = rainbowOption.valueMC(valueDate, expiryDate, stockPrices, discountCurve, dividendYields, volatilities, betas, numPaths) end = time.time() duration = end - start testCases.print(numPaths, correlation, v, v_MC, duration) rainboxOptionValues.append(v) rainbowOptionValuesMC.append(v_MC) # plt.figure(figsize=(10,8)) # plt.plot(corrList, rainboxOptionValues, color = 'r', label = "PUT ON MIN Rainbow Option Analytical") # plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "PUT ON MIN Rainbow Option MC") # plt.xlabel("Correlation") # plt.legend(loc='best') ########################################################################## numAssets = 2 volatilities = np.ones(numAssets) * 0.3 dividendYields = np.ones(numAssets) * 0.01 stockPrices = np.ones(numAssets) * 100 strike = 100.0 correlation = 0.50 testCases.banner( "===================================================================") testCases.banner(" CALL ON 1st") testCases.banner( "===================================================================") rainboxOptionValues = [] rainbowOptionValuesMC = [] testCases.header("NUMPATHS", "CORRELATION", "VALUE", "VALUE_MC", "TIME") for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) for numPaths in numPathsList: payoffType1 = FinEquityRainbowOptionTypes.CALL_ON_MAXIMUM payoffParams1 = [strike] rainbowOption1 = FinEquityRainbowOption(expiryDate, payoffType1, payoffParams1, numAssets) payoffType2 = FinEquityRainbowOptionTypes.CALL_ON_NTH payoffParams2 = [1, strike] rainbowOption2 = FinEquityRainbowOption(expiryDate, payoffType2, payoffParams2, numAssets) start = time.time() v = rainbowOption1.value(valueDate, expiryDate, stockPrices, discountCurve, dividendYields, volatilities, betas) v_MC = rainbowOption2.valueMC(valueDate, expiryDate, stockPrices, discountCurve, dividendYields, volatilities, betas, numPaths) end = time.time() duration = end - start testCases.print(numPaths, correlation, v, v_MC, duration) rainboxOptionValues.append(v) rainbowOptionValuesMC.append(v_MC) # plt.figure(figsize=(10,8)) # plt.plot(corrList, rainboxOptionValues, color = 'r', label = "CALL ON MAX Rainbow Option Analytical") # plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "CALL ON 1st Rainbow Option MC") # plt.xlabel("Correlation") # plt.legend(loc='best') testCases.banner( "===================================================================") testCases.banner(" CALL ON 2nd") testCases.banner( "===================================================================") rainboxOptionValues = [] rainbowOptionValuesMC = [] testCases.header("NUMPATHS", "CORRELATION", "VALUE", "VALUE_MC", "TIME") for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) for numPaths in numPathsList: payoffType1 = FinEquityRainbowOptionTypes.CALL_ON_MINIMUM payoffParams1 = [strike] rainbowOption1 = FinEquityRainbowOption(expiryDate, payoffType1, payoffParams1, numAssets) payoffType2 = FinEquityRainbowOptionTypes.CALL_ON_NTH payoffParams2 = [2, strike] rainbowOption2 = FinEquityRainbowOption(expiryDate, payoffType2, payoffParams2, numAssets) start = time.time() v = rainbowOption1.value(valueDate, expiryDate, stockPrices, discountCurve, dividendYields, volatilities, betas) v_MC = rainbowOption2.valueMC(valueDate, expiryDate, stockPrices, discountCurve, dividendYields, volatilities, betas, numPaths) end = time.time() duration = end - start testCases.print(numPaths, correlation, v, v_MC, duration) rainboxOptionValues.append(v) rainbowOptionValuesMC.append(v_MC) # plt.figure(figsize=(10,8)) # plt.plot(corrList, rainboxOptionValues, color = 'r', label = "CALL ON MIN Rainbow Option Analytical") # plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "CALL ON 2nd Rainbow Option MC") # plt.xlabel("Correlation") # plt.legend(loc='best') testCases.banner( "===================================================================") testCases.banner(" CALL ON 1-5") testCases.banner( "===================================================================") rainboxOptionValues = [] rainbowOptionValuesMC = [] numPaths = 10000 numAssets = 5 volatilities = np.ones(numAssets) * 0.3 dividendYields = np.ones(numAssets) * 0.01 stockPrices = np.ones(numAssets) * 100 # plt.figure(figsize=(10,8)) testCases.header("NUMPATHS", "CORRELATION", "NTD", "VALUE", "VALUE_MC", "TIME") for n in [1, 2, 3, 4, 5]: rainboxOptionValues = [] rainbowOptionValuesMC = [] payoffType2 = FinEquityRainbowOptionTypes.CALL_ON_NTH payoffParams2 = [n, strike] rainbowOption2 = FinEquityRainbowOption(expiryDate, payoffType2, payoffParams2, numAssets) for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) start = time.time() v_MC = rainbowOption2.valueMC(valueDate, expiryDate, stockPrices, discountCurve, dividendYields, volatilities, betas, numPaths) end = time.time() duration = end - start testCases.print(numPaths, correlation, n, v, v_MC, duration) rainbowOptionValuesMC.append(v_MC) # plt.plot(corrList, rainbowOptionValuesMC, 'o-', label = "CALL Rainbow Option MC NTH = " + str(n)) # plt.xlabel("Correlation") # plt.legend(loc='best') testCases.banner( "===================================================================") testCases.banner(" PUT ON 1-5") testCases.banner( "===================================================================") rainboxOptionValues = [] rainbowOptionValuesMC = [] numPaths = 10000 numAssets = 5 volatilities = np.ones(numAssets) * 0.3 dividendYields = np.ones(numAssets) * 0.01 stockPrices = np.ones(numAssets) * 100 # plt.figure(figsize=(10,8)) testCases.header("NUMPATHS", "CORRELATION", "NTD", "VALUE", "VALUE_MC", "TIME") for n in [1, 2, 3, 4, 5]: rainboxOptionValues = [] rainbowOptionValuesMC = [] payoffType2 = FinEquityRainbowOptionTypes.PUT_ON_NTH payoffParams2 = [n, strike] rainbowOption2 = FinEquityRainbowOption(expiryDate, payoffType2, payoffParams2, numAssets) for correlation in corrList: betas = np.ones(numAssets) * sqrt(correlation) start = time.time() v_MC = rainbowOption2.valueMC(valueDate, expiryDate, stockPrices, discountCurve, dividendYields, volatilities, betas, numPaths) end = time.time() duration = end - start testCases.print(numPaths, correlation, n, v, v_MC, duration) rainbowOptionValuesMC.append(v_MC)
cleanPrice = bond.cleanPriceFromYield(settlementDate, ytm) print("Clean Price = ", cleanPrice) accd = bond._accrued print("Accrued = ", accd) accddays = bond._accruedDays print("Accrued Days = ", accddays) duration = bond.dollarDuration(settlementDate, ytm) print("Dollar Duration = ", duration) modifiedDuration = bond.modifiedDuration(settlementDate, ytm) print("Modified Duration = ", modifiedDuration) macauleyDuration = bond.macauleyDuration(settlementDate, ytm) print("Macauley Duration = ", macauleyDuration) conv = bond.convexityFromYield(settlementDate, ytm) print("Convexity = ", conv) discountRate = 0.0275 flatCurve = FinFlatCurve(settlementDate, discountRate, FinCompoundingMethods.SEMI_ANNUAL) asw = bond.assetSwapSpread(settlementDate, cleanPrice, flatCurve) print("Discounted on LIBOR Curve ASW (bp):", asw * 10000) oas = bond.optionAdjustedSpread(settlementDate, cleanPrice, flatCurve) print("Discounted on LIBOR Curve OAS (bp):", oas * 10000)
def test_FinFlatCurve(): curveDate = FinDate(2019, 2, 2) times = np.linspace(0.0, 1.0, 5) testCases.header("COMPOUNDING", "DFS") compounding = -1 flatCurve = FinFlatCurve(curveDate, 0.05, compounding) dfs = flatCurve.df(times) testCases.print(compounding, dfs) compounding = 1 flatCurve = FinFlatCurve(curveDate, 0.05, compounding) dfs = flatCurve.df(times) testCases.print(compounding, dfs) compounding = 2 flatCurve = FinFlatCurve(curveDate, 0.05, compounding) dfs = flatCurve.df(times) testCases.print(compounding, dfs) compounding = 4 flatCurve = FinFlatCurve(curveDate, 0.05, compounding) dfs = flatCurve.df(times) testCases.print(compounding, dfs) compounding = 12 flatCurve = FinFlatCurve(curveDate, 0.05, compounding) dfs = flatCurve.df(times) testCases.print(compounding, dfs) compounding = 0 flatCurve = FinFlatCurve(curveDate, 0.05, compounding) dfs = flatCurve.df(times) testCases.print(compounding, dfs)
def test_FinEquityBarrierOption(): valueDate = FinDate(2015, 1, 1) expiryDate = FinDate(2016, 1, 1) stockPrice = 100.0 volatility = 0.20 interestRate = 0.05 dividendYield = 0.02 optionType = FinEquityBarrierTypes.DOWN_AND_OUT_CALL drift = interestRate - dividendYield scheme = FinGBMNumericalScheme.NORMAL processType = FinProcessTypes.GBM discountCurve = FinFlatCurve(valueDate, interestRate) model = FinEquityModelBlackScholes(volatility) ####################################################################### import time start = time.time() numObservationsPerYear = 100 testCases.header("Type", "K", "B", "S:", "Value:", "ValueMC", "Diff", "TIME") for optionType in FinEquityBarrierTypes: for stockPrice in range(80, 120, 10): B = 110.0 K = 100.0 option = FinEquityBarrierOption(expiryDate, K, optionType, B, numObservationsPerYear) value = option.value(valueDate, stockPrice, discountCurve, dividendYield, model) start = time.time() modelParams = (stockPrice, drift, volatility, scheme) valueMC = option.valueMC(valueDate, stockPrice, discountCurve, processType, modelParams) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print(optionType, K, B, stockPrice, value, valueMC, diff, timeElapsed) testCases.header("Type", "K", "B", "S:", "Value:", "ValueMC", "Diff", "TIME") for stockPrice in range(80, 120, 10): B = 100.0 K = 110.0 option = FinEquityBarrierOption(expiryDate, K, optionType, B, numObservationsPerYear) value = option.value(valueDate, stockPrice, discountCurve, dividendYield, model) start = time.time() modelParams = (stockPrice, drift, volatility, scheme) valueMC = option.valueMC(valueDate, stockPrice, discountCurve, processType, modelParams) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print(optionType, K, B, stockPrice, value, valueMC, diff, timeElapsed) end = time.time() ########################################################################## stockPrices = range(50, 150, 10) B = 105.0 testCases.header("Type", "K", "B", "S:", "Value", "Delta", "Vega", "Theta") for optionType in FinEquityBarrierTypes: for stockPrice in stockPrices: barrierOption = FinEquityBarrierOption(expiryDate, 100.0, optionType, B, numObservationsPerYear) value = barrierOption.value(valueDate, stockPrice, discountCurve, dividendYield, model) delta = barrierOption.delta(valueDate, stockPrice, discountCurve, dividendYield, model) vega = barrierOption.vega(valueDate, stockPrice, discountCurve, dividendYield, model) theta = barrierOption.theta(valueDate, stockPrice, discountCurve, dividendYield, model) testCases.print(optionType, K, B, stockPrice, value, delta, vega, theta)
def testTimeEvolution(): startAveragingDate = FinDate(2015, 1, 1) expiryDate = FinDate(2016, 1, 1) stockPrice = 100.0 volatility = 0.20 interestRate = 0.30 dividendYield = 0.10 numObservations = 100 # weekly as we have a year accruedAverage = None K = 100 seed = 1976 model = FinEquityModelBlackScholes(volatility) asianOption = FinEquityAsianOption(startAveragingDate, expiryDate, K, FinEquityOptionTypes.EUROPEAN_CALL, numObservations) testCases.header("Date", "Geometric", "Turnbull_Wakeman", "Curran", "FastMC", "FastMC_CV") valuesTurnbull = [] valuesCurran = [] valuesGeometric = [] valuesMC_fast = [] valuesMC_CV = [] valueDates = [] valueDates.append(FinDate(2014, 4, 1)) valueDates.append(FinDate(2014, 6, 1)) valueDates.append(FinDate(2014, 8, 1)) valueDates.append(FinDate(2015, 2, 1)) valueDates.append(FinDate(2015, 4, 1)) valueDates.append(FinDate(2015, 6, 1)) valueDates.append(FinDate(2015, 8, 1)) numPaths = 10000 for valueDate in valueDates: accruedAverage = stockPrice * 0.9 discountCurve = FinFlatCurve(valueDate, interestRate) valueMC_fast = asianOption.valueMC_fast(valueDate, stockPrice, discountCurve, dividendYield, model, numPaths, seed, accruedAverage) valueMC_CV = asianOption.valueMC_fast_CV(valueDate, stockPrice, discountCurve, dividendYield, model, numPaths, seed, accruedAverage) valueGeometric = asianOption.value(valueDate, stockPrice, discountCurve, dividendYield, model, "GEOMETRIC", accruedAverage) valueTurnbullWakeman = asianOption.value(valueDate, stockPrice, discountCurve, dividendYield, model, "TURNBULL_WAKEMAN", accruedAverage) valueCurran = asianOption.value(valueDate, stockPrice, discountCurve, dividendYield, model, "CURRAN", accruedAverage) valuesGeometric.append(valueGeometric) valuesTurnbull.append(valueTurnbullWakeman) valuesCurran.append(valueCurran) valuesMC_fast.append(valueMC_fast) valuesMC_CV.append(valueMC_CV) testCases.print(str(valueDate), valueGeometric, valueTurnbullWakeman, valueCurran, valueMC_fast, valueMC_CV)
def testMCTimings(): valueDate = FinDate(2014, 1, 1) startAveragingDate = FinDate(2014, 6, 1) expiryDate = FinDate(2015, 1, 1) stockPrice = 100.0 volatility = 0.20 interestRate = 0.30 dividendYield = 0.10 numObservations = 120 # daily as we have a half year accruedAverage = None K = 100 seed = 1976 model = FinEquityModelBlackScholes(volatility) discountCurve = FinFlatCurve(valueDate, interestRate) asianOption = FinEquityAsianOption(startAveragingDate, expiryDate, K, FinEquityOptionTypes.EUROPEAN_CALL, numObservations) testCases.header("NUMPATHS", "VALUE", "TIME", "VALUE_MC", "TIME", "VALUE_MC_CV", "TIME") valuesMC = [] valuesMC_fast = [] valuesMC_fast_CV = [] tvaluesMC = [] tvaluesMC_fast = [] tvaluesMC_fast_CV = [] numPathsList = [5000] for numPaths in numPathsList: accruedAverage = stockPrice * 1.1 start = time.time() valueMC = asianOption.valueMC(valueDate, stockPrice, discountCurve, dividendYield, model, numPaths, seed, accruedAverage) end = time.time() t_MC = end - start start = time.time() valueMC_fast = asianOption.valueMC_fast(valueDate, stockPrice, discountCurve, dividendYield, model, numPaths, seed, accruedAverage) end = time.time() t_MC_fast = end - start start = time.time() valueMC_fast_CV = asianOption.valueMC_fast_CV(valueDate, stockPrice, discountCurve, dividendYield, model, numPaths, seed, accruedAverage) end = time.time() t_MC_fast_CV = end - start valuesMC.append(valueMC) valuesMC_fast.append(valueMC_fast) valuesMC_fast_CV.append(valueMC_fast_CV) tvaluesMC.append(t_MC) tvaluesMC_fast.append(t_MC_fast) tvaluesMC_fast_CV.append(t_MC_fast_CV) testCases.print(numPaths, valueMC, t_MC, valueMC_fast, t_MC_fast, valueMC_fast_CV, t_MC_fast_CV)
def test_FinEquityVanillaOption(): valueDate = FinDate(2015, 1, 1) expiryDate = FinDate(2015, 7, 1) stockPrice = 100 volatility = 0.30 interestRate = 0.05 dividendYield = 0.01 model = FinEquityModelBlackScholes(volatility) discountCurve = FinFlatCurve(valueDate, interestRate) numPathsList = [10000, 20000, 40000, 80000, 160000, 320000] testCases.header("NUMPATHS", "VALUE_BS", "VALUE_MC", "TIME") for numPaths in numPathsList: callOption = FinEquityVanillaOption( expiryDate, 100.0, FinEquityOptionTypes.EUROPEAN_CALL) value = callOption.value( valueDate, stockPrice, discountCurve, dividendYield, model) start = time.time() valueMC = callOption.valueMC( valueDate, stockPrice, discountCurve, dividendYield, model, numPaths) end = time.time() duration = end - start testCases.print(numPaths, value, valueMC, duration) ########################################################################## stockPrices = range(80, 120, 2) numPaths = 100000 testCases.header("NUMPATHS", "VALUE_BS", "VALUE_MC", "TIME") for stockPrice in stockPrices: callOption = FinEquityVanillaOption( expiryDate, 100.0, FinEquityOptionTypes.EUROPEAN_CALL) value = callOption.value( valueDate, stockPrice, discountCurve, dividendYield, model) start = time.time() valueMC = callOption.valueMC( valueDate, stockPrice, discountCurve, dividendYield, model, numPaths) end = time.time() duration = end - start testCases.print(numPaths, value, valueMC, duration) ########################################################################## stockPrices = range(80, 120, 2) numPaths = 100000 testCases.header("STOCK PRICE", "VALUE_BS", "VALUE_MC", "TIME") for stockPrice in stockPrices: putOption = FinEquityVanillaOption( expiryDate, 100.0, FinEquityOptionTypes.EUROPEAN_PUT) value = putOption.value( valueDate, stockPrice, discountCurve, dividendYield, model) start = time.time() valueMC = putOption.valueMC( valueDate, stockPrice, discountCurve, dividendYield, model, numPaths) end = time.time() duration = end - start testCases.print(stockPrice, value, valueMC, duration) ########################################################################## stockPrices = range(80, 120, 2) testCases.header( "STOCK PRICE", "VALUE_BS", "DELTA_BS", "VEGA_BS", "THETA_BS", "RHO_BS") for stockPrice in stockPrices: callOption = FinEquityVanillaOption( expiryDate, 100.0, FinEquityOptionTypes.EUROPEAN_CALL) value = callOption.value( valueDate, stockPrice, discountCurve, dividendYield, model) delta = callOption.delta( valueDate, stockPrice, discountCurve, dividendYield, model) vega = callOption.vega( valueDate, stockPrice, discountCurve, dividendYield, model) theta = callOption.theta( valueDate, stockPrice, discountCurve, dividendYield, model) # callOption.rho(valueDate,stockPrice, interestRate, dividendYield, modelType, modelParams) rho = 999 testCases.print(stockPrice, value, delta, vega, theta, rho) testCases.header( "STOCK PRICE", "VALUE_BS", "DELTA_BS", "VEGA_BS", "THETA_BS", "RHO_BS") for stockPrice in stockPrices: putOption = FinEquityVanillaOption( expiryDate, 100.0, FinEquityOptionTypes.EUROPEAN_PUT) value = putOption.value( valueDate, stockPrice, discountCurve, dividendYield, model) delta = putOption.delta( valueDate, stockPrice, discountCurve, dividendYield, model) vega = putOption.vega( valueDate, stockPrice, discountCurve, dividendYield, model) theta = putOption.theta( valueDate, stockPrice, discountCurve, dividendYield, model) # putOption.rho(valueDate,stockPrice, interestRate, dividendYield, # modelType, modelParams) rho = 999 testCases.print(stockPrice, value, delta, vega, theta, rho) ########################################################################## testCases.header("STOCK PRICE", "VALUE_BS", "VOL_IN", "IMPLD_VOL") stockPrices = range(60, 150, 2) for stockPrice in stockPrices: callOption = FinEquityVanillaOption( expiryDate, 100.0, FinEquityOptionTypes.EUROPEAN_CALL) value = callOption.value( valueDate, stockPrice, discountCurve, dividendYield, model) impliedVol = callOption.impliedVolatility( valueDate, stockPrice, discountCurve, dividendYield, value) testCases.print(stockPrice, value, volatility, impliedVol)
def test_FinEquityLookBackOption(): valueDate = FinDate(2015, 1, 1) expiryDate = FinDate(2016, 1, 1) stockPrice = 100.0 volatility = 0.3 interestRate = 0.05 dividendYield = 0.01 numPathsRange = [10000] stockPriceRange = range(90, 110, 2) numStepsPerYear = 252 discountCurve = FinFlatCurve(valueDate, interestRate) ############################################################################### testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "SMIN", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinEquityFloatLookbackOptionTypes.FLOATING_CALL for stockPrice in stockPriceRange: for numPaths in numPathsRange: option = FinEquityFloatLookbackOption(expiryDate, optionType) stockMin = stockPrice value = option.value( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMin) start = time.time() valueMC = option.valueMC( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMin, numPaths, numStepsPerYear) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( numPaths, optionType, stockPrice, stockMin, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "SMIN", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinEquityFloatLookbackOptionTypes.FLOATING_CALL for stockPrice in stockPriceRange: for numPaths in numPathsRange: option = FinEquityFloatLookbackOption(expiryDate, optionType) stockMin = stockPrice - 10 value = option.value( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMin) start = time.time() valueMC = option.valueMC( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMin, numPaths, numStepsPerYear) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( numPaths, optionType, stockPrice, stockMin, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "SMAX", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinEquityFloatLookbackOptionTypes.FLOATING_PUT for stockPrice in stockPriceRange: for numPaths in numPathsRange: option = FinEquityFloatLookbackOption(expiryDate, optionType) stockMax = stockPrice value = option.value( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMax) start = time.time() valueMC = option.valueMC( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMax, numPaths, numStepsPerYear) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( numPaths, optionType, stockPrice, stockMax, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "SMAX", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinEquityFloatLookbackOptionTypes.FLOATING_PUT for stockPrice in stockPriceRange: for numPaths in numPathsRange: option = FinEquityFloatLookbackOption(expiryDate, optionType) stockMax = stockPrice + 10 value = option.value( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMax) start = time.time() valueMC = option.valueMC( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMax, numPaths, numStepsPerYear) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( numPaths, optionType, stockPrice, stockMax, value, valueMC, diff, timeElapsed) ############################################################################### ############################################################################### stockPriceRange = range(90, 110, 2) numStepsPerYear = 252 testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "K", "SMAX", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinEquityFixedLookbackOptionTypes.FIXED_CALL k = 95.0 for stockPrice in stockPriceRange: for numPaths in numPathsRange: option = FinEquityFixedLookbackOption(expiryDate, optionType, k) stockMax = stockPrice value = option.value( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMax) start = time.time() valueMC = option.valueMC( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMax, numPaths, numStepsPerYear) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( numPaths, optionType, stockPrice, k, stockMax, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "K", "SMAX", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinEquityFixedLookbackOptionTypes.FIXED_CALL k = 100.0 for stockPrice in stockPriceRange: for numPaths in numPathsRange: option = FinEquityFixedLookbackOption(expiryDate, optionType, k) stockMax = stockPrice value = option.value( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMax) start = time.time() valueMC = option.valueMC( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMax, numPaths, numStepsPerYear) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( numPaths, optionType, stockPrice, k, stockMax, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "K", "SMAX", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinEquityFixedLookbackOptionTypes.FIXED_CALL k = 105.0 for stockPrice in stockPriceRange: for numPaths in numPathsRange: option = FinEquityFixedLookbackOption(expiryDate, optionType, k) stockMax = stockPrice + 10.0 value = option.value( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMax) start = time.time() valueMC = option.valueMC( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMax, numPaths, numStepsPerYear) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( numPaths, optionType, stockPrice, k, stockMax, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "K", "SMIN", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinEquityFixedLookbackOptionTypes.FIXED_PUT k = 95.0 for stockPrice in stockPriceRange: for numPaths in numPathsRange: option = FinEquityFixedLookbackOption(expiryDate, optionType, k) stockMin = stockPrice value = option.value( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMin) start = time.time() valueMC = option.valueMC( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMin, numPaths, numStepsPerYear) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( numPaths, optionType, stockPrice, k, stockMin, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "K", "SMIN", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinEquityFixedLookbackOptionTypes.FIXED_PUT k = 100.0 for stockPrice in stockPriceRange: for numPaths in numPathsRange: option = FinEquityFixedLookbackOption(expiryDate, optionType, k) stockMin = stockPrice value = option.value( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMin) start = time.time() valueMC = option.valueMC( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMin, numPaths, numStepsPerYear) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( numPaths, optionType, stockPrice, k, stockMin, value, valueMC, diff, timeElapsed) testCases.header( "NUMPATHS", "OPTION_TYPE", "S", "K", "SMIN", "VALUE", "VALUE_MC", "DIFF", "TIME") optionType = FinEquityFixedLookbackOptionTypes.FIXED_PUT k = 105.0 for stockPrice in stockPriceRange: for numPaths in numPathsRange: option = FinEquityFixedLookbackOption(expiryDate, optionType, k) stockMin = stockPrice - 10.0 value = option.value( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMin) start = time.time() valueMC = option.valueMC( valueDate, stockPrice, discountCurve, dividendYield, volatility, stockMin, numPaths, numStepsPerYear) end = time.time() timeElapsed = round(end - start, 3) diff = valueMC - value testCases.print( numPaths, optionType, stockPrice, k, stockMin, value, valueMC, diff, timeElapsed)
def test_FinBinomialTree(): stockPrice = 50.0 riskFreeRate = 0.06 dividendYield = 0.04 volatility = 0.40 valueDate = FinDate(2016, 1, 1) expiryDate = FinDate(2017, 1, 1) model = FinEquityModelBlackScholes(volatility) discountCurve = FinFlatCurve(valueDate, riskFreeRate) numStepsList = [100, 500, 1000, 2000, 5000] strikePrice = 50.0 testCases.banner("================== EUROPEAN PUT =======================") putOption = FinEquityVanillaOption(expiryDate, strikePrice, FinEquityOptionTypes.EUROPEAN_PUT) value = putOption.value(valueDate, stockPrice, discountCurve, dividendYield, model) delta = putOption.delta(valueDate, stockPrice, discountCurve, dividendYield, model) gamma = putOption.gamma(valueDate, stockPrice, discountCurve, dividendYield, model) theta = putOption.theta(valueDate, stockPrice, discountCurve, dividendYield, model) testCases.header("BS Value", "BS Delta", "BS Gamma", "BS Theta") testCases.print(value, delta, gamma, theta) payoff = FinEquityTreePayoffTypes.VANILLA_OPTION exercise = FinEquityTreeExerciseTypes.EUROPEAN params = np.array([-1, strikePrice]) testCases.header("NumSteps", "Results", "TIME") for numSteps in numStepsList: start = time.time() tree = FinEquityBinomialTree() results = tree.value(stockPrice, discountCurve, dividendYield, volatility, numSteps, valueDate, payoff, expiryDate, payoff, exercise, params) end = time.time() duration = end - start testCases.print(numSteps, results, duration) testCases.banner("================== AMERICAN PUT =======================") payoff = FinEquityTreePayoffTypes.VANILLA_OPTION exercise = FinEquityTreeExerciseTypes.AMERICAN params = np.array([-1, strikePrice]) testCases.header("NumSteps", "Results", "TIME") for numSteps in numStepsList: start = time.time() tree = FinEquityBinomialTree() results = tree.value(stockPrice, discountCurve, dividendYield, volatility, numSteps, valueDate, payoff, expiryDate, payoff, exercise, params) end = time.time() duration = end - start testCases.print(numSteps, results, duration) testCases.banner( "================== EUROPEAN CALL =======================") callOption = FinEquityVanillaOption(expiryDate, strikePrice, FinEquityOptionTypes.EUROPEAN_CALL) value = callOption.value(valueDate, stockPrice, discountCurve, dividendYield, model) delta = callOption.delta(valueDate, stockPrice, discountCurve, dividendYield, model) gamma = callOption.gamma(valueDate, stockPrice, discountCurve, dividendYield, model) theta = callOption.theta(valueDate, stockPrice, discountCurve, dividendYield, model) testCases.header("BS Value", "BS Delta", "BS Gamma", "BS Theta") testCases.print(value, delta, gamma, theta) payoff = FinEquityTreePayoffTypes.VANILLA_OPTION exercise = FinEquityTreeExerciseTypes.EUROPEAN params = np.array([1.0, strikePrice]) testCases.header("NumSteps", "Results", "TIME") for numSteps in numStepsList: start = time.time() tree = FinEquityBinomialTree() results = tree.value(stockPrice, discountCurve, dividendYield, volatility, numSteps, valueDate, payoff, expiryDate, payoff, exercise, params) end = time.time() duration = end - start testCases.print(numSteps, results, duration) testCases.banner( "================== AMERICAN CALL =======================") payoff = FinEquityTreePayoffTypes.VANILLA_OPTION exercise = FinEquityTreeExerciseTypes.AMERICAN params = np.array([1.0, strikePrice]) testCases.header("NumSteps", "Results", "TIME") for numSteps in numStepsList: start = time.time() tree = FinEquityBinomialTree() results = tree.value(stockPrice, discountCurve, dividendYield, volatility, numSteps, valueDate, payoff, expiryDate, payoff, exercise, params) end = time.time() duration = end - start testCases.print(numSteps, results, duration)
def test_FinBasketOption(): import time valueDate = FinDate(2015, 1, 1) expiryDate = FinDate(2016, 1, 1) volatility = 0.30 interestRate = 0.05 discountCurve = FinFlatCurve(valueDate, interestRate) ########################################################################## # Homogeneous Basket ########################################################################## numAssets = 5 volatilities = np.ones(numAssets) * volatility dividendYields = np.ones(numAssets) * 0.01 stockPrices = np.ones(numAssets) * 100 betaList = np.linspace(0.0, 0.999999, 11) testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME") for beta in betaList: for numPaths in [10000]: callOption = FinEquityBasketOption( expiryDate, 100.0, FinEquityOptionTypes.EUROPEAN_CALL, numAssets) betas = np.ones(numAssets) * beta start = time.time() v = callOption.value( valueDate, stockPrices, discountCurve, dividendYields, volatilities, betas) vMC = callOption.valueMC( valueDate, stockPrices, discountCurve, dividendYields, volatilities, betas, numPaths) end = time.time() duration = end - start testCases.print(numPaths, beta, v, vMC, duration) ########################################################################## # INHomogeneous Basket ########################################################################## numAssets = 5 volatilities = np.array([0.3, 0.2, 0.25, 0.22, 0.4]) dividendYields = np.array([0.01, 0.02, 0.04, 0.01, 0.02]) stockPrices = np.array([100, 105, 120, 100, 90]) betaList = np.linspace(0.0, 0.999999, 11) testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME") for beta in betaList: for numPaths in [10000]: callOption = FinEquityBasketOption( expiryDate, 100.0, FinEquityOptionTypes.EUROPEAN_CALL, numAssets) betas = np.ones(numAssets) * beta start = time.time() v = callOption.value( valueDate, stockPrices, discountCurve, dividendYields, volatilities, betas) vMC = callOption.valueMC( valueDate, stockPrices, discountCurve, dividendYields, volatilities, betas, numPaths) end = time.time() duration = end - start testCases.print(numPaths, beta, v, vMC, duration) ########################################################################## # Homogeneous Basket ########################################################################## numAssets = 5 volatilities = np.ones(numAssets) * volatility dividendYields = np.ones(numAssets) * 0.01 stockPrices = np.ones(numAssets) * 100 betaList = np.linspace(0.0, 0.999999, 11) testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME") for beta in betaList: for numPaths in [10000]: callOption = FinEquityBasketOption( expiryDate, 100.0, FinEquityOptionTypes.EUROPEAN_PUT, numAssets) betas = np.ones(numAssets) * beta start = time.time() v = callOption.value( valueDate, stockPrices, discountCurve, dividendYields, volatilities, betas) vMC = callOption.valueMC( valueDate, stockPrices, discountCurve, dividendYields, volatilities, betas, numPaths) end = time.time() duration = end - start testCases.print(numPaths, beta, v, vMC, duration) ########################################################################## # INHomogeneous Basket ########################################################################## numAssets = 5 volatilities = np.array([0.3, 0.2, 0.25, 0.22, 0.4]) dividendYields = np.array([0.01, 0.02, 0.04, 0.01, 0.02]) stockPrices = np.array([100, 105, 120, 100, 90]) betaList = np.linspace(0.0, 0.999999, 11) testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME") for beta in betaList: for numPaths in [10000]: callOption = FinEquityBasketOption( expiryDate, 100.0, FinEquityOptionTypes.EUROPEAN_PUT, numAssets) betas = np.ones(numAssets) * beta start = time.time() v = callOption.value( valueDate, stockPrices, discountCurve, dividendYields, volatilities, betas) vMC = callOption.valueMC( valueDate, stockPrices, discountCurve, dividendYields, volatilities, betas, numPaths) end = time.time() duration = end - start testCases.print(numPaths, beta, v, vMC, duration)
def testConvergence(): valueDate = FinDate(2014, 1, 1) startAveragingDate = FinDate(2014, 6, 1) expiryDate = FinDate(2015, 1, 1) stockPrice = 100.0 volatility = 0.20 interestRate = 0.30 dividendYield = 0.10 numObservations = 120 # daily as we have a half year accruedAverage = None K = 100 seed = 1976 model = FinEquityModelBlackScholes(volatility) discountCurve = FinFlatCurve(valueDate, interestRate) asianOption = FinEquityAsianOption(startAveragingDate, expiryDate, K, FinEquityOptionTypes.EUROPEAN_CALL, numObservations) testCases.header("K", "Geometric", "Turnbull_Wakeman", "Curran", "FastMC", "FastMC_CV") valuesTurnbull = [] valuesCurran = [] valuesGeometric = [] valuesMC_fast = [] valuesMC_CV = [] numPathsList = [5000] for numPaths in numPathsList: accruedAverage = stockPrice * 1.1 valueMC_fast = asianOption.valueMC_fast(valueDate, stockPrice, discountCurve, dividendYield, model, numPaths, seed, accruedAverage) valueMC_CV = asianOption.valueMC_fast_CV(valueDate, stockPrice, discountCurve, dividendYield, model, numPaths, seed, accruedAverage) valueGeometric = asianOption.value(valueDate, stockPrice, discountCurve, dividendYield, model, "GEOMETRIC", accruedAverage) valueTurnbullWakeman = asianOption.value(valueDate, stockPrice, discountCurve, dividendYield, model, "TURNBULL_WAKEMAN", accruedAverage) valueCurran = asianOption.value(valueDate, stockPrice, discountCurve, dividendYield, model, "CURRAN", accruedAverage) valuesGeometric.append(valueGeometric) valuesTurnbull.append(valueTurnbullWakeman) valuesCurran.append(valueCurran) valuesMC_fast.append(valueMC_fast) valuesMC_CV.append(valueMC_CV) testCases.print(numPaths, valueGeometric, valueTurnbullWakeman, valueCurran, valueMC_fast, valueMC_CV)
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_FinEquityDigitalOption(): valueDate = FinDate(2015, 1, 1) expiryDate = FinDate(2016, 1, 1) stockPrice = 100.0 volatility = 0.30 interestRate = 0.05 dividendYield = 0.01 discountCurve = FinFlatCurve(valueDate, interestRate) model = FinEquityModelBlackScholes(volatility) import time callOptionValues = [] callOptionValuesMC = [] numPathsList = [ 10000, 20000, 40000, 80000, 160000, 320000, 640000, 1280000, 2560000 ] testCases.header("NumLoops", "ValueBS", "ValueMC", "TIME") for numPaths in numPathsList: callOption = FinEquityDigitalOption(expiryDate, 100.0, FinEquityOptionTypes.DIGITAL_CALL) value = callOption.value(valueDate, stockPrice, discountCurve, dividendYield, model) start = time.time() valueMC = callOption.valueMC(valueDate, stockPrice, discountCurve, dividendYield, model, numPaths) end = time.time() duration = end - start testCases.print(numPaths, value, valueMC, duration) callOptionValues.append(value) callOptionValuesMC.append(valueMC) # plt.figure(figsize=(10,8)) # plt.plot(numPathsList, callOptionValues, color = 'b', label="Call Option") # plt.plot(numPathsList, callOptionValuesMC, color = 'r', label = "Call Option MC") # plt.xlabel("Num Loops") # plt.legend(loc='best') ########################################################################## stockPrices = range(50, 150) callOptionValues = [] callOptionDeltas = [] callOptionVegas = [] callOptionThetas = [] for stockPrice in stockPrices: callOption = FinEquityDigitalOption(expiryDate, 100.0, FinEquityOptionTypes.DIGITAL_CALL) value = callOption.value(valueDate, stockPrice, discountCurve, dividendYield, model) delta = callOption.delta(valueDate, stockPrice, discountCurve, dividendYield, model) vega = callOption.vega(valueDate, stockPrice, discountCurve, dividendYield, model) theta = callOption.theta(valueDate, stockPrice, discountCurve, dividendYield, model) callOptionValues.append(value) callOptionDeltas.append(delta) callOptionVegas.append(vega) callOptionThetas.append(theta) putOptionValues = [] putOptionDeltas = [] putOptionVegas = [] putOptionThetas = [] for stockPrice in stockPrices: putOption = FinEquityDigitalOption(expiryDate, 100.0, FinEquityOptionTypes.DIGITAL_PUT) value = putOption.value(valueDate, stockPrice, discountCurve, dividendYield, model) delta = putOption.delta(valueDate, stockPrice, discountCurve, dividendYield, model) vega = putOption.vega(valueDate, stockPrice, discountCurve, dividendYield, model) theta = putOption.theta(valueDate, stockPrice, discountCurve, dividendYield, model) putOptionValues.append(value) putOptionDeltas.append(delta) putOptionVegas.append(vega) putOptionThetas.append(theta)