def dividendOption(): # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++ General Parameter for all the computation +++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # declaration of the today's date (date where the records are done) todaysDate = Date(24 , Jan ,2012) # INPUT Settings.instance().evaluation_date = todaysDate #!\ IMPORTANT COMMAND REQUIRED FOR ALL VALUATIONS calendar = UnitedStates() # INPUT settlement_days = 2 # INPUT # Calcul of the settlement date : need to add a period of 2 days to the todays date settlementDate = calendar.advance( todaysDate, period=Period(settlement_days, Days) ) dayCounter = Actual360() # INPUT currency = USDCurrency() # INPUT print "Date of the evaluation: ", todaysDate print "Calendar used: ", calendar.name() print "Number of settlement Days: ", settlement_days print "Date of settlement: ", settlementDate print "Convention of day counter: ", dayCounter.name() print "Currency of the actual context:\t\t", currency.name # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++ Description of the underlying +++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ underlying_name = "IBM" underlying_price = 191.75 # INPUT underlying_vol = 0.2094 # INPUT print "**********************************" print "Name of the underlying: ", underlying_name print "Price of the underlying at t0: ", underlying_price print "Volatility of the underlying: ", underlying_vol # For a great managing of price and vol objects --> Handle underlying_priceH = SimpleQuote(underlying_price) # We suppose the vol constant : his term structure is flat --> BlackConstantVol object flatVolTS = BlackVolTermStructure( BlackConstantVol( settlementDate, calendar, underlying_vol, dayCounter ) ) # ++++++++++++++++++++ Description of Yield Term Structure # Libor data record print "**********************************" print "Description of the Libor used for the Yield Curve construction" Libor_dayCounter = Actual360(); liborRates = [] liborRatesTenor = [] # INPUT : all the following data are input : the rate and the corresponding tenor # You could make the choice of more or less data # --> However you have tho choice the instruments with different maturities liborRates = [ 0.002763, 0.004082, 0.005601, 0.006390, 0.007125, 0.007928, 0.009446, 0.01110] liborRatesTenor = [Period(tenor, Months) for tenor in [1,2,3,4,5,6,7,12]] for tenor, rate in zip(liborRatesTenor, liborRates): print tenor, "\t\t\t", rate # Swap data record # description of the fixed leg of the swap Swap_fixedLegTenor = Period(12, Months) # INPUT Swap_fixedLegConvention = ModifiedFollowing # INPUT Swap_fixedLegDayCounter = Actual360() # INPUT # description of the float leg of the swap Swap_iborIndex = Libor( "USDLibor", Period(3,Months), settlement_days, USDCurrency(), UnitedStates(), Actual360() ) print "Description of the Swap used for the Yield Curve construction" print "Tenor of the fixed leg: ", Swap_fixedLegTenor print "Index of the floated leg: ", Swap_iborIndex.name print "Maturity Rate " swapRates = [] swapRatesTenor = [] # INPUT : all the following data are input : the rate and the corresponding tenor # You could make the choice of more or less data # --> However you have tho choice the instruments with different maturities swapRates = [0.005681, 0.006970, 0.009310, 0.012010, 0.014628, 0.016881, 0.018745, 0.020260, 0.021545] swapRatesTenor = [Period(i, Years) for i in range(2, 11)] for tenor, rate in zip(swapRatesTenor, swapRates): print tenor, "\t\t\t", rate # ++++++++++++++++++++ Creation of the vector of RateHelper (need for the Yield Curve construction) # ++++++++++++++++++++ Libor LiborFamilyName = currency.name + "Libor" instruments = [] for rate, tenor in zip(liborRates, liborRatesTenor): # Index description ___ creation of a Libor index liborIndex = Libor(LiborFamilyName, tenor, settlement_days, currency, calendar, Libor_dayCounter) # Initialize rate helper ___ the DepositRateHelper link the recording rate with the Libor index instruments.append(DepositRateHelper(rate, index=liborIndex)) # +++++++++++++++++++++ Swap SwapFamilyName = currency.name + "swapIndex"; for tenor, rate in zip(swapRatesTenor, swapRates): # Rate description ___ record of the rate swapHandle = SimpleQuote(rate) # swap description ___ creation of a swap index. The floating leg is described in the index 'Swap_iborIndex' swapIndex = SwapIndex (SwapFamilyName, tenor, settlement_days, currency, calendar, Swap_fixedLegTenor, Swap_fixedLegConvention, Swap_fixedLegDayCounter, Swap_iborIndex) # Initialize rate helper __ the SwapRateHelper links the swap index width his rate instruments.append(SwapRateHelper(swapHandle,swapIndex)) # ++++++++++++++++++ Now the creation of the yield curve riskFreeTS = term_structure_factory('zero', 'linear', settlementDate, instruments, dayCounter) # ++++++++++++++++++ build of the underlying process : with a Black-Scholes model bsProcess = BlackScholesProcess(underlying_priceH, riskFreeTS, flatVolTS) # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++ Description of the option +++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Option_name = "IBM Option" maturity = Date(26, Jan,2013) strike = 190 type = Call # Here, as an implementation exemple, we make the test with borth american and european exercise europeanExercise = EuropeanExercise(maturity) # The emericanExercise need also the settlement date, as his right to exerce the buy or call start at the settlement date! americanExercise = AmericanExercise(settlementDate, maturity) print "**********************************" print "Description of the option: ", Option_name print "Date of maturity: ", maturity print "Type of the option: ", type print "Strike of the option: ", strike # ++++++++++++++++++ Description of the discrete dividends # INPUT You have to determine the frequece and rates of the discrete dividend. Here is a sollution, but she's not the only one. # Last know dividend: dividend = 0.0 #//0.75 nextDividendDate = Date(10,Feb,2012) # HERE we have make the assumption that the dividend will grow with the quarterly croissance: dividendCroissance = 1.03 dividendfrequence = 3 * Months dividendDates = [] dividends = [] d = nextDividentDate while d < maturity: dividendDates.append(d) dividend.append(dividend) d += dividendfrequence dividend *= dividendCroissance print "Discrete dividends " print "Dates Dividends " for date, div in zip(dividendDates, dividend): print date, " ", div # ++++++++++++++++++ Description of the final payoff payoff = PlainVanillaPayoff(type, strike) # ++++++++++++++++++ The OPTIONS : (American and European) with their dividends description: dividendEuropeanOption = DividendVanillaOption( payoff, europeanExercise, dividendDates, dividends ) dividendAmericanOption = DividendVanillaOption( payoff, americanExercise, dividendDates, dividends ) # just too test europeanOption = VanillaOption(payoff, europeanExercise) americanOption = VanillaOption(payoff, americanExercise) # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++ Description of the pricing +++++++++++++++++++++++++++++++++++++ # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ # For the european options we have a closed analytic formula: The Black Scholes: dividendEuropeanEngine = AnalyticDividendEuropeanEngine(bsProcess) # For the american option we have make the choice of the finite difference model with the CrankNicolson scheme # this model need to precise the time and space step # More they are greater, more the calul will be precise. americanGirdPoints = 600 americanTimeSteps = 600 dividendAmericanEngine = FDDividendAmericanEngine(CrankNicolson, bsProcess,americanTimeSteps, americanGirdPoints) # just to test europeanEngine = AnalyticEuropeanEngine(bsProcess) americanEngine = FDAmericanEngine(CrankNicolson, bsProcess,americanTimeSteps, americanGirdPoints) # ++++++++++++++++++++ Valorisation ++++++++++++++++++++++++++++++++++++++++ # Link the pricing Engine to the option dividendEuropeanOption.setPricingEngine(dividendEuropeanEngine) dividendAmericanOption.setPricingEngine(dividendAmericanEngine) # just to test europeanOption.setPricingEngine(europeanEngine) americanOption.setPricingEngine(americanEngine) # Now we make all the needing calcul # ... and final results print "NPV of the European Option with discrete dividends=0: ", dividendEuropeanOption.NPV() print "NPV of the European Option without dividend: ", europeanOption.NPV() print "NPV of the American Option with discrete dividends=0: ", dividendAmericanOption.NPV() print "NPV of the American Option without dividend: ", americanOption.NPV() # just a single test print "ZeroRate with a maturity at ", maturity, ": ", \ riskFreeTS.currentLink().zeroRate(maturity, dayCounter, Simple)
swapHelpers = [ SwapRateHelper(swaps[(n,unit)], Period(n,unit), calendar, fixedLegFrequency, fixedLegAdjustment, fixedLegDayCounter, Euribor6M()) for n, unit in swaps.keys() ] # term structure handles discountTermStructure = YieldTermStructure(relinkable=True) forecastTermStructure = YieldTermStructure(relinkable=True) # term-structure construction helpers = depositHelpers[:2] + futuresHelpers + swapHelpers[1:] depoFuturesSwapCurve = term_structure_factory( 'forward', 'loglinear',settlementDate, helpers, Actual360() ) helpers = depositHelpers[:3] + fraHelpers + swapHelpers depoFraSwapCurve = term_structure_factory( 'forward', 'loglinear', settlementDate, helpers, Actual360() ) # swaps to be priced swapEngine = DiscountingSwapEngine(discountTermStructure) nominal = 1000000 length = 5 maturity = calendar.advance(settlementDate,length,Years) payFixed = True