Coverage for rivapy/pricing/pricing_request.py: 39%

293 statements  

« prev     ^ index     » next       coverage.py v7.8.2, created at 2025-06-05 14:27 +0000

1# -*- coding: utf-8 -*- 

2 

3 

4from datetime import date, datetime 

5from typing import List as _List, Union as _Union 

6from rivapy.tools.interfaces import FactoryObject 

7from rivapy.tools.datetools import _date_to_datetime as datetime_to_date, _datetime_to_date_list as datetime_to_date_list 

8 

9 

10class PricingRequestBase(FactoryObject): 

11 

12 _keys = ['theo_val', 'paths_udl', 'cf_expected', 'cf_paths'] 

13 

14 def __init__(self, **kwargs): 

15 #validate the given keys 

16 for key in kwargs.keys(): 

17 if key not in PricingRequestBase._keys: 

18 raise ValueError("Unknown key '{}'".format(key)) 

19 #set the attributes 

20 setattr(self, key, kwargs[key]) 

21 

22 def _to_dict(self) -> dict: 

23 return self.__dict__ 

24 

25class GreenPPAPricingRequest(PricingRequestBase): 

26 def __init__(self, theo_val: bool, cf_paths: bool=False, cf_expected: bool=False): 

27 """PricingRequest for Green PPA pricing. 

28 

29 Args: 

30 price (bool): If True, the :term:`Theoretical Value` is calculated. 

31 cf_expected (bool, optional): If True, the paths of the simulated :term:`Cash flow` is returned. Defaults to False. 

32 """ 

33 super().__init__(theo_val=theo_val, cf_expected=cf_expected, cf_paths=cf_paths) 

34 

35 

36class PricingRequest: 

37 # def __init__(self, calc_delta_gamma: bool = False, calc_cross_gamma: bool = True, calc_clean_price: bool = False, 

38 # calc_rho: bool = False, rho_scale: float = 0.0001, calc_vega: bool = False, vega_scale: float = 0.01, 

39 # calc_cross_volga: bool = False, calc_vanna: bool = False, calc_theta: bool = False, 

40 # theta_scale: float = 1.0, calc_spline: bool = False, calc_grid_sizes: bool = False, 

41 # calc_implied_volatility: bool = False, management_delta_limit: float = 0.01, 

42 # calc_pricing_data: bool = False, calc_expected_cashflows: bool = False, 

43 # calc_simulation_data: bool = False, calc_additional_information: bool = False, 

44 # calc_z_spread: bool = False, calc_yield_to_maturity: bool = False, calc_convexity: bool = False, 

45 # max_expected_cashflow_date: _Union[date, datetime] = None, 

46 # cashflow_times: _List[_Union[date, datetime]] = None, calc_macaulay_duration: bool = False): 

47 # """ 

48 # Defines the set of information, e.g. sensitivities, cashflow information, etc., to be calculated together with 

49 # the instrument's price in the context of pricing. For some sensitivities the shift parameter for calculating 

50 # the difference quotient (rather than the sensitivity in closed formula) is also stored in the pricing request 

51 # object. 

52 # 

53 # Args: TODO: Read carefully and double-check if these guessed descriptions are valid! 

54 # calc_delta_gamma (bool, optional): Flag determining if the change of the instrument's price associated with 

55 # small changes of the underlying's price shall be calculated to first (and 

56 # second) order within the pricing routine. Defaults to False. 

57 # TODO: also second order? delta_scale=? 

58 # calc_cross_gamma (bool, optional): Flag determining if the change of the instrument's price associated with 

59 # small changes of two underlyings' prices (both at fist order) shall be 

60 # calculated within the pricing routine. Defaults to True. 

61 # TODO: why defaults to True? 

62 # calc_clean_price (bool, optional): Flag determining if the instrument's clean price shall be calculated 

63 # additional to its dirty price within the pricing routine. 

64 # Defaults to False. 

65 # calc_rho (bool, optional): Flag determining if the change of the instrument's price associated with small 

66 # changes of the zero rate curve shall be calculated to first order within the 

67 # pricing routine. Defaults to False. 

68 # rho_scale (float, optional): Size of zero rate shift in the calculation of the change of the instrument's 

69 # price associated with zero rate curve shifts as difference quotient. 

70 # Defaults to 0.0001 (= 1 basis point). 

71 # calc_vega (bool, optional): Flag determining if the change of the instrument's price associated with small 

72 # changes of the implied volatility surface shall be calculated to first order 

73 # within the pricing routine. Defaults to False. 

74 # vega_scale (float, optional): Size of implied volatility shift in the calculation of the change of the 

75 # instrument's price associated with implied volatility surface shifts as 

76 # difference quotient. Defaults to 0.01. 

77 # calc_cross_volga (bool, optional): Flag determining if the change of the instrument's price associated with 

78 # small changes of two implied volatility surfaces (both at first order) 

79 # shall be calculated within the pricing routine. Defaults to True. 

80 # TODO: why defaults to True? 

81 # calc_vanna (bool, optional): Flag determining if the change of the instrument's price associated with small 

82 # changes of the underlying's price and the implied volatility surface (both at 

83 # first order) shall be calculated within the pricing routine. Defaults to False. 

84 # TODO: why defaults to False in contrast to cross Gamma/Volga? 

85 # calc_theta (bool, optional): Flag determining if the change of the instrument's price associated with small 

86 # changes of the instrument's maturity shall be calculated to first order within 

87 # the pricing routine. Defaults to False. 

88 # theta_scale (float, optional): Size of maturity shift in the calculation of the change of the instrument's 

89 # price associated with maturity shifts as difference quotient. Defaults to 1.0 

90 # calc_spline (bool, optional): 

91 # calc_grid_sizes (bool, optional): 

92 # calc_implied_volatility (bool, optional): 

93 # management_delta_limit (float, optional): 

94 # calc_pricing_data (bool, optional): 

95 # calc_expected_cashflows (bool, optional): 

96 # calc_simulation_data (bool, optional): 

97 # calc_additional_information (bool, optional): 

98 # calc_z_spread (bool, optional): Flag determining if the instrument's z-spread shall be calculated within the 

99 # pricing routine. Defaults to False. 

100 # calc_yield_to_maturity (bool, optional): Flag determining if the instrument's yield-to-maturity shall be 

101 # calculated within the pricing routine. Defaults to False. 

102 # calc_convexity (bool, optional): Flag determining if the change of the instrument's price associated with 

103 # small changes of the zero rate curve shall be calculated to second order 

104 # within the pricing routine. Defaults to False. 

105 # max_expected_cashflow_date (_Union[date, datetime], optional): 

106 # cashflow_times (_List[_Union[date, datetime]], optional): 

107 # calc_macaulay_duration (bool, optional): Flag determining if the instrument's Macaulay duration shall be 

108 # calculated within the pricing routine. Defaults to False. 

109 # """ 

110 def __init__(self, calc_delta_gamma: bool = None, calc_cross_gamma: bool = None, calc_clean_price: bool = None, 

111 calc_rho: bool = None, rho_scale: float = None, calc_vega: bool = None, vega_scale: float = None, 

112 calc_cross_volga: bool = None, calc_vanna: bool = None, calc_theta: bool = None, 

113 theta_scale: float = None, calc_spline: bool = None, calc_grid_sizes: bool = None, 

114 calc_implied_volatility: bool = None, management_delta_limit: float = None, 

115 calc_pricing_data: bool = None, calc_expected_cashflows: bool = None, 

116 calc_simulation_data: bool = None, calc_additional_information: bool = None, 

117 calc_z_spread: bool = None, calc_yield_to_maturity: bool = None, calc_convexity: bool = None, 

118 max_expected_cashflow_date: _Union[date, datetime] = None, 

119 cashflow_times: _List[_Union[date, datetime]] = None, calc_macaulay_duration: bool = None): 

120 """ 

121 Defines the set of information, e.g. sensitivities, cashflow information, etc., to be calculated together with 

122 the instrument's price in the context of pricing. For some sensitivities the shift parameter for calculating 

123 the difference quotient (rather than the sensitivity in closed formula) is also stored in the pricing request 

124 object. 

125 

126 Args: TODO: Read carefully and double-check if these guessed descriptions are valid! 

127 calc_delta_gamma (bool, optional): Flag determining if the change of the instrument's price associated with 

128 small changes of the underlying's price shall be calculated to first (and 

129 second) order within the pricing routine. Defaults to None. 

130 TODO: also second order? delta_scale=? 

131 calc_cross_gamma (bool, optional): Flag determining if the change of the instrument's price associated with 

132 small changes of two underlyings' prices (both at fist order) shall be 

133 calculated within the pricing routine. Defaults to None. 

134 calc_clean_price (bool, optional): Flag determining if the instrument's clean price shall be calculated 

135 additional to its dirty price within the pricing routine. 

136 Defaults to None. 

137 calc_rho (bool, optional): Flag determining if the change of the instrument's price associated with small 

138 changes of the zero rate curve shall be calculated to first order within the 

139 pricing routine. Defaults to None. 

140 rho_scale (float, optional): Size of zero rate shift in the calculation of the change of the instrument's 

141 price associated with zero rate curve shifts as difference quotient. 

142 Defaults to None. 

143 calc_vega (bool, optional): Flag determining if the change of the instrument's price associated with small 

144 changes of the implied volatility surface shall be calculated to first order 

145 within the pricing routine. Defaults to None. 

146 vega_scale (float, optional): Size of implied volatility shift in the calculation of the change of the 

147 instrument's price associated with implied volatility surface shifts as 

148 difference quotient. Defaults to None. 

149 calc_cross_volga (bool, optional): Flag determining if the change of the instrument's price associated with 

150 small changes of two implied volatility surfaces (both at first order) 

151 shall be calculated within the pricing routine. Defaults to None. 

152 calc_vanna (bool, optional): Flag determining if the change of the instrument's price associated with small 

153 changes of the underlying's price and the implied volatility surface (both at 

154 first order) shall be calculated within the pricing routine. Defaults to None. 

155 calc_theta (bool, optional): Flag determining if the change of the instrument's price associated with small 

156 changes of the instrument's maturity shall be calculated to first order within 

157 the pricing routine. Defaults to None. 

158 theta_scale (float, optional): Size of maturity shift in the calculation of the change of the instrument's 

159 price associated with maturity shifts as difference quotient. 

160 Defaults to None 

161 calc_spline (bool, optional): 

162 calc_grid_sizes (bool, optional): 

163 calc_implied_volatility (bool, optional): 

164 management_delta_limit (float, optional): 

165 calc_pricing_data (bool, optional): 

166 calc_expected_cashflows (bool, optional): 

167 calc_simulation_data (bool, optional): 

168 calc_additional_information (bool, optional): 

169 calc_z_spread (bool, optional): Flag determining if the instrument's z-spread shall be calculated within the 

170 pricing routine. Defaults to None. 

171 calc_yield_to_maturity (bool, optional): Flag determining if the instrument's yield-to-maturity shall be 

172 calculated within the pricing routine. Defaults to None. 

173 calc_convexity (bool, optional): Flag determining if the change of the instrument's price associated with 

174 small changes of the zero rate curve shall be calculated to second order 

175 within the pricing routine. Defaults to None. 

176 max_expected_cashflow_date (_Union[date, datetime], optional): 

177 cashflow_times (_List[_Union[date, datetime]], optional): 

178 calc_macaulay_duration (bool, optional): Flag determining if the instrument's Macaulay duration shall be 

179 calculated within the pricing routine. Defaults to None. 

180 """ 

181 self._calc_delta_gamma = calc_delta_gamma 

182 self._calc_cross_gamma = calc_cross_gamma 

183 self._calc_clean_price = calc_clean_price 

184 self._calc_rho = calc_rho 

185 self._rho_scale = rho_scale 

186 self._calc_vega = calc_vega 

187 self._vega_scale = vega_scale 

188 self._calc_cross_volga = calc_cross_volga 

189 self._calc_vanna = calc_vanna 

190 self._calc_theta = calc_theta 

191 self._theta_scale = theta_scale 

192 self._calc_spline = calc_spline 

193 self._calc_grid_sizes = calc_grid_sizes 

194 self._calc_implied_volatility = calc_implied_volatility 

195 self._management_delta_limit = management_delta_limit 

196 self._calc_pricing_data = calc_pricing_data 

197 self._calc_expected_cashflows = calc_expected_cashflows 

198 self._calc_simulation_data = calc_simulation_data 

199 self._calc_additional_information = calc_additional_information 

200 self._calc_z_spread = calc_z_spread 

201 self._calc_yield_to_maturity = calc_yield_to_maturity 

202 self._calc_convexity = calc_convexity 

203 self._max_expected_cashflow_date = max_expected_cashflow_date 

204 self._cashflow_times = cashflow_times 

205 self._calc_macaulay_duration = calc_macaulay_duration 

206 

207 @property 

208 def _calc_delta_gamma(self): 

209 return self.__calc_delta_gamma 

210 

211 @_calc_delta_gamma.setter 

212 def _calc_delta_gamma(self, calc_delta_gamma: bool): 

213 if calc_delta_gamma is not None: 

214 if isinstance(calc_delta_gamma, bool): 

215 self.__calc_delta_gamma = calc_delta_gamma 

216 else: 

217 raise TypeError("'" + str(calc_delta_gamma) + "' must be of type bool!") 

218 

219 @property 

220 def _calc_cross_gamma(self): 

221 return self.__calc_cross_gamma 

222 

223 @_calc_cross_gamma.setter 

224 def _calc_cross_gamma(self, calc_cross_gamma: bool): 

225 if calc_cross_gamma is not None: 

226 if isinstance(calc_cross_gamma, bool): 

227 self.__calc_cross_gamma = calc_cross_gamma 

228 if self._calc_cross_gamma: 

229 self.calc_delta_gamma = True 

230 else: 

231 raise TypeError("'" + str(calc_cross_gamma) + "' must be of type bool!") 

232 

233 @property 

234 def _calc_clean_price(self): 

235 return self.__calc_clean_price 

236 

237 @_calc_clean_price.setter 

238 def _calc_clean_price(self, calc_clean_price: bool): 

239 if calc_clean_price is not None: 

240 if isinstance(calc_clean_price, bool): 

241 self.__calc_clean_price = calc_clean_price 

242 else: 

243 raise TypeError("'" + str(calc_clean_price) + "' must be of type bool!") 

244 

245 @property 

246 def _calc_rho(self): 

247 return self.__calc_rho 

248 

249 @_calc_rho.setter 

250 def _calc_rho(self, calc_rho: bool): 

251 if calc_rho is not None: 

252 if isinstance(calc_rho, bool): 

253 self.__calc_rho = calc_rho 

254 if self._calc_rho & ~hasattr(self, 'rho_scale'): 

255 self.rho_scale = 0.0001 

256 else: 

257 raise TypeError("'" + str(calc_rho) + "' must be of type bool!") 

258 

259 @property 

260 def _rho_scale(self): 

261 return self.__rho_scale 

262 

263 @_rho_scale.setter 

264 def _rho_scale(self, rho_scale: float): 

265 if rho_scale is not None: 

266 if isinstance(rho_scale, float): 

267 self.__rho_scale = rho_scale 

268 self.calc_rho = True 

269 else: 

270 raise TypeError("'" + str(rho_scale) + "' must be of type float!") 

271 

272 @property 

273 def _calc_vega(self): 

274 return self.__calc_vega 

275 

276 @_calc_vega.setter 

277 def _calc_vega(self, calc_vega: bool): 

278 if calc_vega is not None: 

279 if isinstance(calc_vega, bool): 

280 self.__calc_vega = calc_vega 

281 if self._calc_vega & ~hasattr(self, 'vega_scale'): 

282 self.vega_scale = 0.01 

283 else: 

284 raise TypeError("'" + str(calc_vega) + "' must be of type bool!") 

285 

286 @property 

287 def _vega_scale(self): 

288 return self.__vega_scale 

289 

290 @_vega_scale.setter 

291 def _vega_scale(self, vega_scale: float): 

292 if vega_scale is not None: 

293 if isinstance(vega_scale, float): 

294 self.__vega_scale = vega_scale 

295 self.calc_vega = True 

296 else: 

297 raise TypeError("'" + str(vega_scale) + "' must be of type float!") 

298 

299 @property 

300 def _calc_cross_volga(self): 

301 return self.__calc_cross_volga 

302 

303 @_calc_cross_volga.setter 

304 def _calc_cross_volga(self, calc_cross_volga: bool): 

305 if calc_cross_volga is not None: 

306 if isinstance(calc_cross_volga, bool): 

307 self.__calc_cross_volga = calc_cross_volga 

308 if self._calc_cross_volga: 

309 self.calc_vega = True 

310 if not hasattr(self, 'vega_scale'): 

311 self.vega_scale = 0.01 

312 else: 

313 raise TypeError("'" + str(calc_cross_volga) + "' must be of type bool!") 

314 

315 @property 

316 def _calc_vanna(self): 

317 return self.__calc_vanna 

318 

319 @_calc_vanna.setter 

320 def _calc_vanna(self, calc_vanna: bool): 

321 if calc_vanna is not None: 

322 if isinstance(calc_vanna, bool): 

323 self.__calc_vanna = calc_vanna 

324 if self._calc_vanna: 

325 self.calc_vega = True 

326 if not hasattr(self, 'vega_scale'): 

327 self.vega_scale = 0.01 

328 else: 

329 raise TypeError("'" + str(calc_vanna) + "' must be of type bool!") 

330 

331 @property 

332 def _calc_theta(self): 

333 return self.__calc_theta 

334 

335 @_calc_theta.setter 

336 def _calc_theta(self, calc_theta: bool): 

337 if calc_theta is not None: 

338 if isinstance(calc_theta, bool): 

339 self.__calc_theta = calc_theta 

340 if self._calc_theta & ~hasattr(self, 'theta_scale'): 

341 self.theta_scale = 1.0 

342 else: 

343 raise TypeError("'" + str(calc_theta) + "' must be of type bool!") 

344 

345 @property 

346 def _theta_scale(self): 

347 return self.__theta_scale 

348 

349 @_theta_scale.setter 

350 def _theta_scale(self, theta_scale: float): 

351 if theta_scale is not None: 

352 if isinstance(theta_scale, float): 

353 self.__theta_scale = theta_scale 

354 self.calc_theta = True 

355 else: 

356 raise TypeError("'" + str(theta_scale) + "' must be of type float!") 

357 

358 @property 

359 def _calc_spline(self): 

360 return self.__calc_spline 

361 

362 @_calc_spline.setter 

363 def _calc_spline(self, calc_spline: bool): 

364 if calc_spline is not None: 

365 if isinstance(calc_spline, bool): 

366 self.__calc_spline = calc_spline 

367 else: 

368 raise TypeError("'" + str(calc_spline) + "' must be of type bool!") 

369 

370 @property 

371 def _calc_grid_sizes(self): 

372 return self.__calc_grid_sizes 

373 

374 @_calc_grid_sizes.setter 

375 def _calc_grid_sizes(self, calc_grid_sizes: bool): 

376 if calc_grid_sizes is not None: 

377 if isinstance(calc_grid_sizes, bool): 

378 self.__calc_grid_sizes = calc_grid_sizes 

379 else: 

380 raise TypeError("'" + str(calc_grid_sizes) + "' must be of type bool!") 

381 

382 @property 

383 def _calc_implied_volatility(self): 

384 return self.__calc_implied_volatility 

385 

386 @_calc_implied_volatility.setter 

387 def _calc_implied_volatility(self, calc_implied_volatility: bool): 

388 if calc_implied_volatility is not None: 

389 if isinstance(calc_implied_volatility, bool): 

390 self.__calc_implied_volatility = calc_implied_volatility 

391 else: 

392 raise TypeError("'" + str(calc_implied_volatility) + "' must be of type bool!") 

393 

394 @property 

395 def _management_delta_limit(self): 

396 return self.__management_delta_limit 

397 

398 @_management_delta_limit.setter 

399 def _management_delta_limit(self, management_delta_limit: float): 

400 self.__management_delta_limit = management_delta_limit 

401 

402 @property 

403 def _calc_pricing_data(self): 

404 return self.__calc_pricing_data 

405 

406 @_calc_pricing_data.setter 

407 def _calc_pricing_data(self, calc_pricing_data: bool): 

408 if calc_pricing_data is not None: 

409 if isinstance(calc_pricing_data, float): 

410 self.__calc_pricing_data = calc_pricing_data 

411 else: 

412 raise TypeError("'" + str(calc_pricing_data) + "' must be of type float!") 

413 

414 @property 

415 def _calc_expected_cashflows(self): 

416 return self.__calc_expected_cashflows 

417 

418 @_calc_expected_cashflows.setter 

419 def _calc_expected_cashflows(self, calc_expected_cashflows: bool): 

420 if calc_expected_cashflows is not None: 

421 if isinstance(calc_expected_cashflows, bool): 

422 self.__calc_expected_cashflows = calc_expected_cashflows 

423 else: 

424 raise TypeError("'" + str(calc_expected_cashflows) + "' must be of type bool!") 

425 

426 @property 

427 def _calc_simulation_data(self): 

428 return self.__calc_simulation_data 

429 

430 @_calc_simulation_data.setter 

431 def _calc_simulation_data(self, calc_simulation_data: bool): 

432 if calc_simulation_data is not None: 

433 if isinstance(calc_simulation_data, bool): 

434 self.__calc_simulation_data = calc_simulation_data 

435 else: 

436 raise TypeError("'" + str(calc_simulation_data) + "' must be of type bool!") 

437 

438 @property 

439 def _calc_additional_information(self): 

440 return self.__calc_additional_information 

441 

442 @_calc_additional_information.setter 

443 def _calc_additional_information(self, calc_additional_information: bool): 

444 if calc_additional_information is not None: 

445 if isinstance(calc_additional_information, bool): 

446 self.__calc_additional_information = calc_additional_information 

447 else: 

448 raise TypeError("'" + str(calc_additional_information) + "' must be of type bool!") 

449 

450 @property 

451 def _calc_z_spread(self): 

452 return self.__calc_z_spread 

453 

454 @_calc_z_spread.setter 

455 def _calc_z_spread(self, calc_z_spread: bool): 

456 if calc_z_spread is not None: 

457 if isinstance(calc_z_spread, bool): 

458 self.__calc_z_spread = calc_z_spread 

459 else: 

460 raise TypeError("'" + str(calc_z_spread) + "' must be of type bool!") 

461 

462 @property 

463 def _calc_yield_to_maturity(self): 

464 return self.__calc_yield_to_maturity 

465 

466 @_calc_yield_to_maturity.setter 

467 def _calc_yield_to_maturity(self, calc_yield_to_maturity: bool): 

468 if calc_yield_to_maturity is not None: 

469 if isinstance(calc_yield_to_maturity, bool): 

470 self.__calc_yield_to_maturity = calc_yield_to_maturity 

471 else: 

472 raise TypeError("'" + str(calc_yield_to_maturity) + "' must be of type bool!") 

473 

474 @property 

475 def _calc_convexity(self): 

476 return self.__calc_convexity 

477 

478 @_calc_convexity.setter 

479 def _calc_convexity(self, calc_convexity: bool): 

480 if calc_convexity is not None: 

481 if isinstance(calc_convexity, bool): 

482 self.__calc_convexity = calc_convexity 

483 if self._calc_convexity: 

484 self.calc_rho = True 

485 if not hasattr(self, 'rho_scale'): 

486 self.rho_scale = 0.0001 

487 else: 

488 raise TypeError("'" + str(calc_convexity) + "' must be of type bool!") 

489 

490 @property 

491 def _max_expected_cashflow_date(self): 

492 return self.__max_expected_cashflow_date 

493 

494 @_max_expected_cashflow_date.setter 

495 def _max_expected_cashflow_date(self, max_expected_cashflow_date: _Union[date, datetime]): 

496 if max_expected_cashflow_date is not None: 

497 if isinstance(max_expected_cashflow_date, datetime) | isinstance(max_expected_cashflow_date, date): 

498 self.__max_expected_cashflow_date = datetime_to_date(max_expected_cashflow_date) 

499 else: 

500 raise TypeError("'" + str(max_expected_cashflow_date) + "' must be of type datetime or date!") 

501 

502 @property 

503 def _cashflow_times(self): 

504 return self.__cashflow_times 

505 

506 @_cashflow_times.setter 

507 def _cashflow_times(self, cashflow_times: _List[_Union[date, datetime]]): 

508 if cashflow_times is not None: 

509 if isinstance(cashflow_times, list) & ( 

510 isinstance(cashflow_times[0], datetime) | isinstance(cashflow_times[0], date) 

511 ): 

512 self.__cashflow_times = datetime_to_date_list(cashflow_times) 

513 else: 

514 raise TypeError("'" + str(cashflow_times) + "' must be of type list of datetime or date!") 

515 

516 @property 

517 def _calc_macaulay_duration(self): 

518 return self.__calc_macaulay_duration 

519 

520 @_calc_macaulay_duration.setter 

521 def _calc_macaulay_duration(self, calc_macaulay_duration: bool): 

522 if calc_macaulay_duration is not None: 

523 if isinstance(calc_macaulay_duration, bool): 

524 self.__calc_macaulay_duration = calc_macaulay_duration 

525 else: 

526 raise TypeError("'" + str(calc_macaulay_duration) + "' must be of type bool!") 

527 

528 

529class BondPricingRequest(PricingRequest): 

530 def __init__(self, calc_clean_price: bool = False, calc_rho: bool = False, rho_scale: float = None, 

531 calc_theta: bool = False, theta_scale: float = None, calc_yield_to_maturity: bool = False, 

532 calc_convexity: bool = False, calc_macaulay_duration: bool = False): # TODO: clarify why no z-spread 

533 """ 

534 Configuration of set of information to be calculated together with the bond's dirty price. In restricts the 

535 general PricingRequest to the sub-set relevant for the pricing of bonds. 

536 """ 

537 PricingRequest.__init__(self, calc_clean_price=calc_clean_price, calc_rho=calc_rho, rho_scale=rho_scale, 

538 calc_theta=calc_theta, theta_scale=theta_scale, 

539 calc_yield_to_maturity=calc_yield_to_maturity, calc_convexity=calc_convexity, 

540 calc_macaulay_duration=calc_macaulay_duration) 

541 

542 

543if __name__ == '__main__': 

544 bond_pricing_request = BondPricingRequest()