Skip to content

Commit cb43b68

Browse files
committed
fix example
1 parent 09fba08 commit cb43b68

File tree

1 file changed

+45
-49
lines changed

1 file changed

+45
-49
lines changed

examples/option_valuation.py

Lines changed: 45 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,30 @@
2020
NPV of the American Option without dividend: 17.9647
2121
2222
"""
23-
from __future__ import print_function
24-
2523
from quantlib.settings import Settings
2624
from quantlib.compounding import Simple
25+
from quantlib.cashflows.dividend import DividendSchedule
2726
from quantlib.currency.api import USDCurrency
2827
from quantlib.indexes.api import Libor
2928
from quantlib.indexes.swap_index import SwapIndex
30-
from quantlib.instruments.option import EuropeanExercise, AmericanExercise
31-
from quantlib.instruments.option import VanillaOption, DividendVanillaOption, Call
29+
from quantlib.instruments.exercise import EuropeanExercise, AmericanExercise
30+
from quantlib.instruments.option import VanillaOption, VanillaOption, OptionType
3231
from quantlib.instruments.payoffs import PlainVanillaPayoff
32+
from quantlib.math.interpolation import Linear
3333
from quantlib.pricingengines.api import AnalyticDividendEuropeanEngine
34-
from quantlib.pricingengines.api import FDDividendAmericanEngine
34+
from quantlib.pricingengines.api import FdBlackScholesVanillaEngine
3535
from quantlib.pricingengines.api import AnalyticEuropeanEngine
36-
from quantlib.pricingengines.api import FDAmericanEngine
3736
from quantlib.processes.black_scholes_process import BlackScholesProcess
3837
from quantlib.quotes import SimpleQuote
3938
from quantlib.time.api import (
40-
Date, Days, Period, Actual360, Months, Jan, ModifiedFollowing, Years, Feb
39+
Date, Days, Period, Actual360, Months, Jan, ModifiedFollowing, Years, Feb, pydate_from_qldate
4140
)
41+
from quantlib.methods.finitedifferences.solvers.fdmbackwardsolver import FdmSchemeDesc
4242
from quantlib.time.calendars.united_states import UnitedStates
4343
from quantlib.termstructures.yields.api import (
44-
PiecewiseYieldCurve, DepositRateHelper, Interpolator, BootstrapTrait
44+
PiecewiseYieldCurve, DepositRateHelper, BootstrapTrait, HandleYieldTermStructure
4545
)
46-
from quantlib.termstructures.volatility.equityfx.black_vol_term_structure import BlackConstantVol
46+
from quantlib.termstructures.volatility.api import BlackConstantVol
4747
from quantlib.termstructures.yields.api import SwapRateHelper
4848

4949
def dividendOption():
@@ -61,7 +61,7 @@ def dividendOption():
6161
todaysDate, period=Period(settlement_days, Days)
6262
)
6363
dayCounter = Actual360() # INPUT
64-
currency = USDCurrency() # INPUT
64+
currency = USDCurrency() # INPUT
6565

6666
print("Date of the evaluation: ", todaysDate)
6767
print("Calendar used: ", calendar.name)
@@ -88,28 +88,28 @@ def dividendOption():
8888

8989
# We suppose the vol constant : his term structure is flat --> BlackConstantVol object
9090
flatVolTS = BlackConstantVol(settlementDate, calendar, underlying_vol, dayCounter)
91-
91+
9292
# ++++++++++++++++++++ Description of Yield Term Structure
93-
94-
# Libor data record
93+
94+
# Libor data record
9595
print("**********************************")
96-
print("Description of the Libor used for the Yield Curve construction")
97-
96+
print("Description of the Libor used for the Yield Curve construction")
97+
9898
Libor_dayCounter = Actual360();
9999

100100
liborRates = []
101101
liborRatesTenor = []
102102
# INPUT : all the following data are input : the rate and the corresponding tenor
103103
# You could make the choice of more or less data
104104
# --> However you have tho choice the instruments with different maturities
105-
liborRates = [ 0.002763, 0.004082, 0.005601, 0.006390, 0.007125, 0.007928, 0.009446,
105+
liborRates = [ 0.002763, 0.004082, 0.005601, 0.006390, 0.007125, 0.007928, 0.009446,
106106
0.01110]
107107
liborRatesTenor = [Period(tenor, Months) for tenor in [1,2,3,4,5,6,9,12]]
108-
108+
109109
for tenor, rate in zip(liborRatesTenor, liborRates):
110110
print(tenor, "\t\t\t", rate)
111111

112-
# Swap data record
112+
# Swap data record
113113

114114
# description of the fixed leg of the swap
115115
Swap_fixedLegTenor = Period(12, Months) # INPUT
@@ -134,19 +134,19 @@ def dividendOption():
134134
swapRates = [0.005681, 0.006970, 0.009310, 0.012010, 0.014628, 0.016881, 0.018745,
135135
0.020260, 0.021545]
136136
swapRatesTenor = [Period(i, Years) for i in range(2, 11)]
137-
137+
138138
for tenor, rate in zip(swapRatesTenor, swapRates):
139139
print(tenor, "\t\t\t", rate)
140-
140+
141141
# ++++++++++++++++++++ Creation of the vector of RateHelper (need for the Yield Curve construction)
142-
# ++++++++++++++++++++ Libor
142+
# ++++++++++++++++++++ Libor
143143
LiborFamilyName = currency.name + "Libor"
144144
instruments = []
145145
for rate, tenor in zip(liborRates, liborRatesTenor):
146146
# Index description ___ creation of a Libor index
147147
liborIndex = Libor(LiborFamilyName, tenor, settlement_days, currency, calendar,
148148
Libor_dayCounter)
149-
# Initialize rate helper ___ the DepositRateHelper link the recording rate with the Libor index
149+
# Initialize rate helper ___ the DepositRateHelper link the recording rate with the Libor index
150150
instruments.append(DepositRateHelper(rate, index=liborIndex))
151151

152152
# +++++++++++++++++++++ Swap
@@ -158,39 +158,38 @@ def dividendOption():
158158
Swap_iborIndex)
159159
# Initialize rate helper __ the SwapRateHelper links the swap index width his rate
160160
instruments.append(SwapRateHelper.from_index(rate, swapIndex))
161-
161+
162162
# ++++++++++++++++++ Now the creation of the yield curve
163163

164-
riskFreeTS = PiecewiseYieldCurve.from_reference_date(BootstrapTrait.ZeroYield,
165-
Interpolator.Linear, settlementDate, instruments, dayCounter)
164+
riskFreeTS = PiecewiseYieldCurve[BootstrapTrait.ZeroYield, Linear].from_reference_date(settlementDate, instruments, dayCounter)
166165

167166

168-
# ++++++++++++++++++ build of the underlying process : with a Black-Scholes model
167+
# ++++++++++++++++++ build of the underlying process : with a Black-Scholes model
169168

170169
print('Creating process')
171170

172-
bsProcess = BlackScholesProcess(underlying_priceH, riskFreeTS, flatVolTS)
171+
bsProcess = BlackScholesProcess(underlying_priceH, HandleYieldTermStructure(riskFreeTS), flatVolTS)
173172

174173

175174
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
176175
# ++++++++++++++++++++ Description of the option +++++++++++++++++++++++++++++++++++++++
177176
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
178-
177+
179178
Option_name = "IBM Option"
180179
maturity = Date(26, Jan, 2013)
181180
strike = 190
182-
option_type = Call
181+
option_type = OptionType.Call
183182

184183
# Here, as an implementation example, we make the test with borth american and european exercise
185184
europeanExercise = EuropeanExercise(maturity)
186185
# The emericanExercise need also the settlement date, as his right to exerce the buy or call start at the settlement date!
187186
#americanExercise = AmericanExercise(settlementDate, maturity)
188187
americanExercise = AmericanExercise(maturity, settlementDate)
189-
188+
190189
print("**********************************")
191190
print("Description of the option: ", Option_name)
192191
print("Date of maturity: ", maturity)
193-
print("Type of the option: ", option_type)
192+
print("Type of the option: ", option_type.name)
194193
print("Strike of the option: ", strike)
195194

196195

@@ -199,7 +198,7 @@ def dividendOption():
199198
# INPUT You have to determine the frequence and rates of the discrete dividend. Here is a sollution, but she's not the only one.
200199
# Last know dividend:
201200
dividend = 0.75 #//0.75
202-
next_dividend_date = Date(10,Feb,2012)
201+
next_dividend_date = Date(10, Feb, 2012)
203202
# HERE we have make the assumption that the dividend will grow with the quarterly croissance:
204203
dividendCroissance = 1.03
205204
dividendfrequence = Period(3, Months)
@@ -209,26 +208,24 @@ def dividendOption():
209208

210209
d = next_dividend_date
211210
while d <= maturity:
212-
dividendDates.append(d)
211+
dividendDates.append(pydate_from_qldate(d))
213212
dividends.append(dividend)
214-
d = d + dividendfrequence
213+
d += dividendfrequence
215214
dividend *= dividendCroissance
216215

217216
print("Discrete dividends ")
218217
print("Dates Dividends ")
219218
for date, div in zip(dividendDates, dividends):
220219
print(date, " ", div)
221220

222-
# ++++++++++++++++++ Description of the final payoff
221+
# ++++++++++++++++++ Description of the final payoff
223222
payoff = PlainVanillaPayoff(option_type, strike)
224223

225224
# ++++++++++++++++++ The OPTIONS : (American and European) with their dividends description:
226-
dividendEuropeanOption = DividendVanillaOption(
227-
payoff, europeanExercise, dividendDates, dividends
228-
)
229-
dividendAmericanOption = DividendVanillaOption(
230-
payoff, americanExercise, dividendDates, dividends
231-
)
225+
dividendEuropeanOption = VanillaOption(
226+
payoff, europeanExercise)
227+
dividendAmericanOption = VanillaOption(
228+
payoff, americanExercise)
232229

233230

234231
# just too test
@@ -238,33 +235,33 @@ def dividendOption():
238235
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
239236
# ++++++++++++++++++++ Description of the pricing +++++++++++++++++++++++++++++++++++++
240237
# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
241-
238+
242239
# For the european options we have a closed analytic formula: The Black Scholes:
243-
dividendEuropeanEngine = AnalyticDividendEuropeanEngine(bsProcess)
240+
dividendEuropeanEngine = AnalyticDividendEuropeanEngine(bsProcess, DividendSchedule(dividendDates, dividends))
244241

245242
# For the american option we have make the choice of the finite difference model with the CrankNicolson scheme
246243
# this model need to precise the time and space step
247244
# More they are greater, more the calul will be precise.
248245
americanGirdPoints = 600
249246
americanTimeSteps = 600
250-
dividendAmericanEngine = FDDividendAmericanEngine('CrankNicolson', bsProcess,americanTimeSteps, americanGirdPoints)
247+
dividendAmericanEngine = FdBlackScholesVanillaEngine(bsProcess, americanTimeSteps, americanGirdPoints, scheme=FdmSchemeDesc.CrankNicolson(), dividends=DividendSchedule(dividendDates, dividends))
251248

252249
# just to test
253250
europeanEngine = AnalyticEuropeanEngine(bsProcess)
254-
americanEngine = FDAmericanEngine('CrankNicolson', bsProcess,americanTimeSteps, americanGirdPoints)
251+
americanEngine = FdBlackScholesVanillaEngine(bsProcess, americanTimeSteps, americanGirdPoints, scheme=FdmSchemeDesc.CrankNicolson())
255252

256253

257254
# ++++++++++++++++++++ Valorisation ++++++++++++++++++++++++++++++++++++++++
258-
255+
259256
# Link the pricing Engine to the option
260257
dividendEuropeanOption.set_pricing_engine(dividendEuropeanEngine)
261258
dividendAmericanOption.set_pricing_engine(dividendAmericanEngine)
262-
259+
263260
# just to test
264261
europeanOption.set_pricing_engine(europeanEngine)
265262
americanOption.set_pricing_engine(americanEngine)
266263

267-
# Now we make all the needing calcul
264+
# Now we make all the needing calcul
268265
# ... and final results
269266
print("NPV of the European Option with discrete dividends=0: {:.4f}".format(dividendEuropeanOption.npv))
270267
print("NPV of the European Option without dividend: {:.4f}".format(europeanOption.npv))
@@ -279,4 +276,3 @@ def dividendOption():
279276
if __name__ == '__main__':
280277

281278
dividendOption()
282-

0 commit comments

Comments
 (0)