You can subscribe to this list here.
| 2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
(60) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2001 |
Jan
(18) |
Feb
(4) |
Mar
(6) |
Apr
(2) |
May
|
Jun
(12) |
Jul
(48) |
Aug
(6) |
Sep
(3) |
Oct
(24) |
Nov
(15) |
Dec
(18) |
| 2002 |
Jan
(39) |
Feb
(12) |
Mar
(80) |
Apr
(72) |
May
(46) |
Jun
(27) |
Jul
(23) |
Aug
(34) |
Sep
(65) |
Oct
(71) |
Nov
(19) |
Dec
(14) |
| 2003 |
Jan
(44) |
Feb
(59) |
Mar
(18) |
Apr
(62) |
May
(54) |
Jun
(27) |
Jul
(46) |
Aug
(15) |
Sep
(44) |
Oct
(36) |
Nov
(19) |
Dec
(12) |
| 2004 |
Jan
(26) |
Feb
(33) |
Mar
(47) |
Apr
(63) |
May
(36) |
Jun
(65) |
Jul
(80) |
Aug
(163) |
Sep
(65) |
Oct
(39) |
Nov
(36) |
Dec
(39) |
| 2005 |
Jan
(97) |
Feb
(78) |
Mar
(64) |
Apr
(64) |
May
(48) |
Jun
(55) |
Jul
(89) |
Aug
(57) |
Sep
(51) |
Oct
(111) |
Nov
(86) |
Dec
(76) |
| 2006 |
Jan
(84) |
Feb
(103) |
Mar
(143) |
Apr
(92) |
May
(55) |
Jun
(58) |
Jul
(71) |
Aug
(57) |
Sep
(74) |
Oct
(59) |
Nov
(8) |
Dec
(32) |
| 2007 |
Jan
(60) |
Feb
(40) |
Mar
(50) |
Apr
(26) |
May
(61) |
Jun
(120) |
Jul
(119) |
Aug
(48) |
Sep
(121) |
Oct
(66) |
Nov
(103) |
Dec
(43) |
| 2008 |
Jan
(60) |
Feb
(109) |
Mar
(92) |
Apr
(106) |
May
(82) |
Jun
(59) |
Jul
(67) |
Aug
(118) |
Sep
(131) |
Oct
(56) |
Nov
(37) |
Dec
(69) |
| 2009 |
Jan
(75) |
Feb
(76) |
Mar
(103) |
Apr
(78) |
May
(61) |
Jun
(35) |
Jul
(66) |
Aug
(69) |
Sep
(166) |
Oct
(46) |
Nov
(72) |
Dec
(65) |
| 2010 |
Jan
(48) |
Feb
(57) |
Mar
(93) |
Apr
(85) |
May
(123) |
Jun
(82) |
Jul
(98) |
Aug
(121) |
Sep
(146) |
Oct
(86) |
Nov
(72) |
Dec
(34) |
| 2011 |
Jan
(96) |
Feb
(55) |
Mar
(73) |
Apr
(57) |
May
(33) |
Jun
(74) |
Jul
(89) |
Aug
(71) |
Sep
(103) |
Oct
(76) |
Nov
(52) |
Dec
(61) |
| 2012 |
Jan
(48) |
Feb
(54) |
Mar
(78) |
Apr
(60) |
May
(75) |
Jun
(59) |
Jul
(33) |
Aug
(66) |
Sep
(43) |
Oct
(46) |
Nov
(75) |
Dec
(51) |
| 2013 |
Jan
(112) |
Feb
(72) |
Mar
(49) |
Apr
(48) |
May
(42) |
Jun
(44) |
Jul
(80) |
Aug
(19) |
Sep
(33) |
Oct
(37) |
Nov
(38) |
Dec
(98) |
| 2014 |
Jan
(113) |
Feb
(93) |
Mar
(49) |
Apr
(106) |
May
(97) |
Jun
(155) |
Jul
(87) |
Aug
(127) |
Sep
(85) |
Oct
(48) |
Nov
(41) |
Dec
(37) |
| 2015 |
Jan
(34) |
Feb
(50) |
Mar
(104) |
Apr
(80) |
May
(82) |
Jun
(66) |
Jul
(41) |
Aug
(84) |
Sep
(37) |
Oct
(65) |
Nov
(83) |
Dec
(52) |
| 2016 |
Jan
(68) |
Feb
(35) |
Mar
(42) |
Apr
(35) |
May
(54) |
Jun
(75) |
Jul
(45) |
Aug
(52) |
Sep
(60) |
Oct
(52) |
Nov
(36) |
Dec
(64) |
| 2017 |
Jan
(92) |
Feb
(59) |
Mar
(35) |
Apr
(53) |
May
(83) |
Jun
(43) |
Jul
(65) |
Aug
(68) |
Sep
(46) |
Oct
(75) |
Nov
(40) |
Dec
(49) |
| 2018 |
Jan
(68) |
Feb
(54) |
Mar
(48) |
Apr
(58) |
May
(51) |
Jun
(44) |
Jul
(40) |
Aug
(68) |
Sep
(35) |
Oct
(15) |
Nov
(7) |
Dec
(37) |
| 2019 |
Jan
(43) |
Feb
(7) |
Mar
(22) |
Apr
(21) |
May
(31) |
Jun
(39) |
Jul
(73) |
Aug
(45) |
Sep
(47) |
Oct
(89) |
Nov
(19) |
Dec
(69) |
| 2020 |
Jan
(52) |
Feb
(63) |
Mar
(45) |
Apr
(59) |
May
(42) |
Jun
(57) |
Jul
(30) |
Aug
(29) |
Sep
(75) |
Oct
(64) |
Nov
(96) |
Dec
(22) |
| 2021 |
Jan
(14) |
Feb
(24) |
Mar
(35) |
Apr
(58) |
May
(36) |
Jun
(15) |
Jul
(18) |
Aug
(31) |
Sep
(30) |
Oct
(33) |
Nov
(27) |
Dec
(16) |
| 2022 |
Jan
(35) |
Feb
(22) |
Mar
(14) |
Apr
(20) |
May
(44) |
Jun
(53) |
Jul
(25) |
Aug
(56) |
Sep
(11) |
Oct
(47) |
Nov
(22) |
Dec
(36) |
| 2023 |
Jan
(30) |
Feb
(17) |
Mar
(31) |
Apr
(48) |
May
(31) |
Jun
(7) |
Jul
(25) |
Aug
(26) |
Sep
(61) |
Oct
(66) |
Nov
(19) |
Dec
(21) |
| 2024 |
Jan
(37) |
Feb
(29) |
Mar
(26) |
Apr
(26) |
May
(34) |
Jun
(9) |
Jul
(27) |
Aug
(13) |
Sep
(15) |
Oct
(25) |
Nov
(13) |
Dec
(8) |
| 2025 |
Jan
(13) |
Feb
(1) |
Mar
(16) |
Apr
(17) |
May
(8) |
Jun
(6) |
Jul
(9) |
Aug
|
Sep
(6) |
Oct
(15) |
Nov
(6) |
Dec
|
| 2026 |
Jan
(6) |
Feb
(4) |
Mar
(20) |
Apr
(2) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: El Y. F. <fah...@gm...> - 2022-06-16 10:45:15
|
Hi, i am working on a library for pricing callable bonds, and I have a few questions: 1 - for fixed rate callable bonds, is there a way to know when it is called and when? because I am trying to approximate American calls with daily European calls? 2 - doesn quantlib support floating rate callable bonds? Thank you |
|
From: Diego D'A. <die...@gm...> - 2022-06-14 18:30:39
|
Got this working. There were a couple of mistakes in my code. On Mon, 13 Jun 2022, 10:51 Diego D'Alessandro, < die...@gm...> wrote: > Hi, > > I have been trying to bootstrap the inflation term structure with ZCIIS > quote using Quantlib. > > I am getting a "Runtime error: root not bracketed". Here is the code that > I have posted on StackOverflow: > > > https://stackoverflow.com/questions/72564838/python-quantlib-bootstrapping-the-inflation-term-structure-from-zciis-runtimee > > I am new to Quantlib and I have been following the existing examples made > by other users. However, I have noticed that the ql.ZeroCouponInflationSwapHelper() > and the ql.PiecewiseZeroInflation() objects have changed since the latest > posts. > > Could anyone explain why the interpolation fails for the ZCIIS that I have > provided? > > Many thanks, > Diego > |
|
From: Ashish B. <ash...@gm...> - 2022-06-14 14:08:32
|
Ok, understood. so you are saying even with DD=1 for a call it is anyways falling to BS model. I would rather use that. Could you also explain in short what is the difference between FDAmerican engine vs FD Black Scholes engine that I am getting difference in prices? Is there a way I could equate those? Ashish On Tue, 14 Jun 2022 at 18:53, Luigi Ballabio <lui...@gm...> wrote: > Dividend discount = 1 is a weird way to say that the dividend rate is 0, > that is, there are no dividends. > > An American call on a stock with no dividends is the same as a European > call, so the engine falls back to the Black-Scholes formula for European > options (which also provides Greeks). An American put (or an American call > on a stock with dividends) is not the same, so in that case the engine uses > the approximation formula and Greeks are not available. > > Luigi > > > > On Tue, Jun 14, 2022 at 3:16 PM Ashish Bansal <ash...@gm...> > wrote: > >> Not sure why is dividend discount is treated for Call only. I am running >> this for commodities where the dividend is 0. Although passing some >> dividend also gave the same error. >> >> Anyways, thanks for your help around it. Greatly appreciated. >> >> Regards, >> Ashish >> >> On Tue, 14 Jun 2022 at 16:29, Jonathan Sweemer <sw...@gm...> wrote: >> >>> Hi Ashish, >>> >>> The code[1] treats calls with a dividend discount of at least 1 the same >>> as European, so that's probably why you're seeing greeks for calls only. >>> >>> There was a similar question[2] on github recently and the suggestion >>> was to calculate a numerical delta by bumping spot up and down and >>> repricing. The other benefit of this approach is that it will incorporate >>> the effect of the smile into your delta if you switch to a non-BS vol model >>> one day. >>> >>> [1] >>> https://github.com/sweemer/QuantLib/blob/master/ql/pricingengines/vanilla/baroneadesiwhaleyengine.cpp#L162-L165 >>> [2] >>> https://github.com/lballabio/QuantLib/issues/1398#issuecomment-1146073964 >>> >>> On Tue, Jun 14, 2022 at 7:39 PM Ashish Bansal <ash...@gm...> >>> wrote: >>> >>>> Hi, >>>> >>>> I am analyzing BaroneAdesiWhaleyEngine for pricing the American option >>>> to replace old FDAmericanEngine we are using. I am getting the price and >>>> greeks when passing the call option in this engine but when I pass a put >>>> trade, I get <greek> not provided error for all greeks including Delta or >>>> Gamma. >>>> >>>> Is put not supported in BaroneAdesiWhaleyEngine? >>>> >>>> I noticed that the release notes suggested >>>> using FdBlackScholesVanillaEngine but that provides a price farther than >>>> the BAW engine which is closer to the FD American engine. >>>> >>>> Thanks >>>> Ashish >>>> _______________________________________________ >>>> QuantLib-users mailing list >>>> Qua...@li... >>>> https://lists.sourceforge.net/lists/listinfo/quantlib-users >>>> >>> _______________________________________________ >> QuantLib-users mailing list >> Qua...@li... >> https://lists.sourceforge.net/lists/listinfo/quantlib-users >> > |
|
From: Luigi B. <lui...@gm...> - 2022-06-14 13:23:55
|
Dividend discount = 1 is a weird way to say that the dividend rate is 0, that is, there are no dividends. An American call on a stock with no dividends is the same as a European call, so the engine falls back to the Black-Scholes formula for European options (which also provides Greeks). An American put (or an American call on a stock with dividends) is not the same, so in that case the engine uses the approximation formula and Greeks are not available. Luigi On Tue, Jun 14, 2022 at 3:16 PM Ashish Bansal <ash...@gm...> wrote: > Not sure why is dividend discount is treated for Call only. I am running > this for commodities where the dividend is 0. Although passing some > dividend also gave the same error. > > Anyways, thanks for your help around it. Greatly appreciated. > > Regards, > Ashish > > On Tue, 14 Jun 2022 at 16:29, Jonathan Sweemer <sw...@gm...> wrote: > >> Hi Ashish, >> >> The code[1] treats calls with a dividend discount of at least 1 the same >> as European, so that's probably why you're seeing greeks for calls only. >> >> There was a similar question[2] on github recently and the suggestion was >> to calculate a numerical delta by bumping spot up and down and repricing. >> The other benefit of this approach is that it will incorporate the effect >> of the smile into your delta if you switch to a non-BS vol model one day. >> >> [1] >> https://github.com/sweemer/QuantLib/blob/master/ql/pricingengines/vanilla/baroneadesiwhaleyengine.cpp#L162-L165 >> [2] >> https://github.com/lballabio/QuantLib/issues/1398#issuecomment-1146073964 >> >> On Tue, Jun 14, 2022 at 7:39 PM Ashish Bansal <ash...@gm...> >> wrote: >> >>> Hi, >>> >>> I am analyzing BaroneAdesiWhaleyEngine for pricing the American option >>> to replace old FDAmericanEngine we are using. I am getting the price and >>> greeks when passing the call option in this engine but when I pass a put >>> trade, I get <greek> not provided error for all greeks including Delta or >>> Gamma. >>> >>> Is put not supported in BaroneAdesiWhaleyEngine? >>> >>> I noticed that the release notes suggested >>> using FdBlackScholesVanillaEngine but that provides a price farther than >>> the BAW engine which is closer to the FD American engine. >>> >>> Thanks >>> Ashish >>> _______________________________________________ >>> QuantLib-users mailing list >>> Qua...@li... >>> https://lists.sourceforge.net/lists/listinfo/quantlib-users >>> >> _______________________________________________ > QuantLib-users mailing list > Qua...@li... > https://lists.sourceforge.net/lists/listinfo/quantlib-users > |
|
From: Ashish B. <ash...@gm...> - 2022-06-14 13:13:24
|
Not sure why is dividend discount is treated for Call only. I am running this for commodities where the dividend is 0. Although passing some dividend also gave the same error. Anyways, thanks for your help around it. Greatly appreciated. Regards, Ashish On Tue, 14 Jun 2022 at 16:29, Jonathan Sweemer <sw...@gm...> wrote: > Hi Ashish, > > The code[1] treats calls with a dividend discount of at least 1 the same > as European, so that's probably why you're seeing greeks for calls only. > > There was a similar question[2] on github recently and the suggestion was > to calculate a numerical delta by bumping spot up and down and repricing. > The other benefit of this approach is that it will incorporate the effect > of the smile into your delta if you switch to a non-BS vol model one day. > > [1] > https://github.com/sweemer/QuantLib/blob/master/ql/pricingengines/vanilla/baroneadesiwhaleyengine.cpp#L162-L165 > [2] > https://github.com/lballabio/QuantLib/issues/1398#issuecomment-1146073964 > > On Tue, Jun 14, 2022 at 7:39 PM Ashish Bansal <ash...@gm...> > wrote: > >> Hi, >> >> I am analyzing BaroneAdesiWhaleyEngine for pricing the American option to >> replace old FDAmericanEngine we are using. I am getting the price and >> greeks when passing the call option in this engine but when I pass a put >> trade, I get <greek> not provided error for all greeks including Delta or >> Gamma. >> >> Is put not supported in BaroneAdesiWhaleyEngine? >> >> I noticed that the release notes suggested >> using FdBlackScholesVanillaEngine but that provides a price farther than >> the BAW engine which is closer to the FD American engine. >> >> Thanks >> Ashish >> _______________________________________________ >> QuantLib-users mailing list >> Qua...@li... >> https://lists.sourceforge.net/lists/listinfo/quantlib-users >> > |
|
From: Jonathan S. <sw...@gm...> - 2022-06-14 10:59:35
|
Hi Ashish, The code[1] treats calls with a dividend discount of at least 1 the same as European, so that's probably why you're seeing greeks for calls only. There was a similar question[2] on github recently and the suggestion was to calculate a numerical delta by bumping spot up and down and repricing. The other benefit of this approach is that it will incorporate the effect of the smile into your delta if you switch to a non-BS vol model one day. [1] https://github.com/sweemer/QuantLib/blob/master/ql/pricingengines/vanilla/baroneadesiwhaleyengine.cpp#L162-L165 [2] https://github.com/lballabio/QuantLib/issues/1398#issuecomment-1146073964 On Tue, Jun 14, 2022 at 7:39 PM Ashish Bansal <ash...@gm...> wrote: > Hi, > > I am analyzing BaroneAdesiWhaleyEngine for pricing the American option to > replace old FDAmericanEngine we are using. I am getting the price and > greeks when passing the call option in this engine but when I pass a put > trade, I get <greek> not provided error for all greeks including Delta or > Gamma. > > Is put not supported in BaroneAdesiWhaleyEngine? > > I noticed that the release notes suggested > using FdBlackScholesVanillaEngine but that provides a price farther than > the BAW engine which is closer to the FD American engine. > > Thanks > Ashish > _______________________________________________ > QuantLib-users mailing list > Qua...@li... > https://lists.sourceforge.net/lists/listinfo/quantlib-users > |
|
From: Ashish B. <ash...@gm...> - 2022-06-14 10:35:08
|
Hi, I am analyzing BaroneAdesiWhaleyEngine for pricing the American option to replace old FDAmericanEngine we are using. I am getting the price and greeks when passing the call option in this engine but when I pass a put trade, I get <greek> not provided error for all greeks including Delta or Gamma. Is put not supported in BaroneAdesiWhaleyEngine? I noticed that the release notes suggested using FdBlackScholesVanillaEngine but that provides a price farther than the BAW engine which is closer to the FD American engine. Thanks Ashish |
|
From: Ashish B. <ash...@gm...> - 2022-06-14 07:33:56
|
Dear team, I need some guidance on the pricing of the barrier option using the FdBlackScholesBarrierEngine in the event that the barrier is hit: 1. for Down-Out, when I pass the spot less than the barrier, I get RunTimeerror for interpolation range. Should I block the pricing at all in this case? Can't the engine handle it? 2. For Down-in, I am getting the same error whereas the option gets activated and is still live then why is this not priced by the engine? Am I doing something wrong? What is the difference between FdBlackScholesBarrierEngine and AnalyticBarrierEngine? I compared a few results and found a slight difference in values. Any suggestion on which one to use? Any help would be appreciated. Thanks Ashish |
|
From: Diego D'A. <die...@gm...> - 2022-06-13 09:52:19
|
Hi, I have been trying to bootstrap the inflation term structure with ZCIIS quote using Quantlib. I am getting a "Runtime error: root not bracketed". Here is the code that I have posted on StackOverflow: https://stackoverflow.com/questions/72564838/python-quantlib-bootstrapping-the-inflation-term-structure-from-zciis-runtimee I am new to Quantlib and I have been following the existing examples made by other users. However, I have noticed that the ql.ZeroCouponInflationSwapHelper() and the ql.PiecewiseZeroInflation() objects have changed since the latest posts. Could anyone explain why the interpolation fails for the ZCIIS that I have provided? Many thanks, Diego |
|
From: Peter C. <pca...@gm...> - 2022-06-05 14:26:58
|
Hi friendly reminder / am I right in interpreting the silence as consent? Thanks Peter On Wed, 11 May 2022 at 09:55, Peter Caspers <pca...@gm...> wrote: > > Hi all > > When QuantLib is built with enabled QL_ENABLE_SESSIONS, users have to > provide an implementation of sessionId(). Usually the sessions are > used to enable thread-local singleton instances and consequently > sessionId() will be implemented such that the current thread id is > returned. More recent versions of QuantLib require C++11 as the > minimum language standard and with that we are able to simplify the > singleton implementation while always ensuring a thread-safe > initialization of singleton instances. The proposed change is this > > https://github.com/lballabio/QuantLib/pull/1377 > > and comes with a removal of the sessionId() and a hard-wired > assumption that there is a 1:1 relation between sessions and threads. > The question for you is whether there are other uses of sessions out > there which wouldn't be supported after the above change, i.e. where > you use sessions differently from what I described above. > > Thanks > Peter |
|
From: Ashish B. <ash...@gm...> - 2022-06-03 16:27:06
|
Will wait for July. May I request to release during early July? if no issues in that? Thanks for all the help and information. Thanks Ashish On Fri, Jun 3, 2022, 2:53 PM Luigi Ballabio <lui...@gm...> wrote: > Version 1.27 will be out sometime in July. The changes included so far > are at <https://github.com/lballabio/QuantLib/milestone/23?closed=1>. > The changes in previous releases are at < > https://github.com/lballabio/QuantLib/releases/>. > > Luigi > > > On Thu, Jun 2, 2022 at 7:23 AM Ashish Bansal <ash...@gm...> > wrote: > >> That is great news. I have been waiting for TW engine for a long time :) >> . Special thanks to Fredrick (@gbfredrik) for adding it. >> >> When is v1.27 planned to be released? Hoping that it will be released on >> SWIG at the same time. Where can I read about other changes in 1.27 so that >> we can plan accordingly? >> >> Thanks >> Ashish >> >> On Thu, 2 Jun 2022 at 01:35, Luigi Ballabio <lui...@gm...> >> wrote: >> >>> Hello, >>> it does mention it now -- the Turnbull-Wakeman engine was added to >>> the repository less than a month ago and will be in release 1.27. It >>> didn't exist in release 1.17. >>> >>> Luigi >>> >>> >>> On Wed, Jun 1, 2022 at 7:55 PM Ashish Bansal <ash...@gm...> >>> wrote: >>> >>>> Luigi, >>>> >>>> You had given me the following link sometime back. It does mention >>>> about the Turnbull Wakeman model based on 2 moment matching: >>>> >>>> https://github.com/lballabio/QuantLib/blob/master/test-suite/asianoptions.cpp >>>> <ql/pricingengines/asian/turnbullwakemanasianengine.hpp> >>>> >>>> [image: image.png] >>>> Even the example is given in the above file. Although the asianoption >>>> is part of test-suite but the Turnbull...engine is part of main QL. Is it >>>> not part of SWIG? i tried in it in python but could not find it. >>>> >>>> How can I use this in python with QL v1.17? >>>> >>>> Regards, >>>> Ashish >>>> >>>> On Mon, 30 May 2022 at 19:39, Ashish Bansal <ash...@gm...> >>>> wrote: >>>> >>>>> Thanks for the responses. I am trying various papers to find the >>>>> moment matching for the asian options. I did find the calculation based on >>>>> Turnbull-Wakeman model here: >>>>> >>>>> https://osf.io/efq6a/download >>>>> >>>>> >>>>> I tried this but did not get good results for options expiring in a >>>>> few months. I will try some other source probably. >>>>> >>>>> >>>>> One last question, does QL's FdBlackScholesAsianengine with DiscreteAveragingAsianOption >>>>> adjust the valuation for trade which are in between the averaging period; >>>>> as mentioned on slide # 9 and 10 of this deck? >>>>> >>>>> >>>>> Regards, >>>>> >>>>> Ashish >>>>> >>>>> On Thu, 26 May 2022 at 13:24, Luigi Ballabio <lui...@gm...> >>>>> wrote: >>>>> >>>>>> I mean that the two engines give the same price, i.e. 6.09. I don't >>>>>> have info on moment matching. >>>>>> >>>>>> On Wed, May 25, 2022 at 6:51 PM Ashish Bansal < >>>>>> ash...@gm...> wrote: >>>>>> >>>>>>> By same price, you mean same as exchange i.e. 4.57. or same as aRA >>>>>>> parameter i.e. 6.09? >>>>>>> >>>>>>> Any guidance on moment matching? I could not find anything online >>>>>>> about it. >>>>>>> >>>>>>> Regards >>>>>>> Ashish >>>>>>> >>>>>>> On Wed, May 25, 2022, 7:02 PM Luigi Ballabio < >>>>>>> lui...@gm...> wrote: >>>>>>> >>>>>>>> Hi, >>>>>>>> no, the engine doesn't do moment matching. I don't think we >>>>>>>> have something ready to use for that in the library. >>>>>>>> As for the accumulator: I confirm it's the sum. If you create a >>>>>>>> virtual Python environment and install the latest QuantLib in it, you can >>>>>>>> try your shortened code with the other constructor for the Asian option >>>>>>>> (the one taking the list of fixings). It returns the same price. >>>>>>>> >>>>>>>> Luigi >>>>>>>> >>>>>>>> >>>>>>>> On Wed, May 25, 2022 at 2:46 PM Ashish Bansal < >>>>>>>> ash...@gm...> wrote: >>>>>>>> >>>>>>>>> Hi Luigi, >>>>>>>>> >>>>>>>>> One question about the QL calculation: Does QL code for the Asian >>>>>>>>> option include *moment matching *of the volatility or do we need >>>>>>>>> to do that before passing to the DiscAvAsOption? >>>>>>>>> >>>>>>>>> Regarding the code, I had attached the full code from our system >>>>>>>>> in my previous email, attaching here too. The shortened version of the >>>>>>>>> code, containing only the QL interaction and excluding excess processing, >>>>>>>>> is also attached here. It includes the trade parameters we are using to >>>>>>>>> evaluate the Asian option. Strangely, the value is coming zero with >>>>>>>>> short-code but with full code in our system, we are getting the values. >>>>>>>>> >>>>>>>>> Following is the NPV that we are getting in our system (using full >>>>>>>>> code) for our trade which has averaging period from 1st March to 31st March >>>>>>>>> 2022 and the market traded premium of 4.56: >>>>>>>>> arithmeticRunningAccumulator NPV >>>>>>>>> 0 4.5711 >>>>>>>>> 1302.88 6.09 >>>>>>>>> >>>>>>>>> Thanks in advance for help. >>>>>>>>> >>>>>>>>> PS: We are using QL1.17 and the vols are sourced from Reuters >>>>>>>>> could be different from implied in the market traded premium. >>>>>>>>> >>>>>>>>> Regards, >>>>>>>>> Ashish >>>>>>>>> >>>>>>>>> On Mon, 23 May 2022 at 22:26, Luigi Ballabio < >>>>>>>>> lui...@gm...> wrote: >>>>>>>>> >>>>>>>>>> May you send sample code and the value of the fixings for one of >>>>>>>>>> those options? Thanks! >>>>>>>>>> >>>>>>>>>> Luigi >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Mon, May 23, 2022 at 8:32 AM Ashish Bansal < >>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>> >>>>>>>>>>> Luigi, >>>>>>>>>>> >>>>>>>>>>> We ran the asian code, which i sent earlier for a couple of >>>>>>>>>>> asian options traded on exchange. We got prices very close to traded prices >>>>>>>>>>> when we used the value of running accumulator as 1 for march option being >>>>>>>>>>> valued on 17th with past fixing count as 12. But when we used the sum of >>>>>>>>>>> past fixing prices i.e. 1302.88 we got a very different number like 6.09 >>>>>>>>>>> against 4.57 earlier and 14.11 against 12.39 earlier. >>>>>>>>>>> >>>>>>>>>>> Just want to confirm if i am missing something about running >>>>>>>>>>> accumulator and should it be really the sum of all past fixings? >>>>>>>>>>> >>>>>>>>>>> Thanks for help in advance. >>>>>>>>>>> Ashish >>>>>>>>>>> >>>>>>>>>>> On Fri, 20 May 2022 at 14:58, Ashish Bansal < >>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>> >>>>>>>>>>>> Ok understood. thanks. >>>>>>>>>>>> >>>>>>>>>>>> On Fri, 20 May 2022 at 14:46, Luigi Ballabio < >>>>>>>>>>>> lui...@gm...> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> It would be the sum of past fixings; for three past fixings of >>>>>>>>>>>>> 100.2, 101.3 and 94.6 it would be 296.1. >>>>>>>>>>>>> >>>>>>>>>>>>> Luigi >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Thu, May 19, 2022 at 12:37 PM Ashish Bansal < >>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Thanks, Luigi for the suggestion. After taking the running >>>>>>>>>>>>>> accumulator, we are able to generate the numbers. What exactly should be >>>>>>>>>>>>>> passed here? The average price of past fixings or just 1 when the trade is >>>>>>>>>>>>>> priced during averaging period? >>>>>>>>>>>>>> >>>>>>>>>>>>>> Thanks for help. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Wed, 18 May 2022 at 21:17, Luigi Ballabio < >>>>>>>>>>>>>> lui...@gm...> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> I don't have a 1.7 version to try it, but the check is the >>>>>>>>>>>>>>> one at < >>>>>>>>>>>>>>> https://github.com/lballabio/QuantLib/blob/QuantLib-v1.7/ql/pricingengines/asian/fdblackscholesasianengine.cpp#L51-L53>, >>>>>>>>>>>>>>> suggesting that your running accumulator should be 0 (which makes sense, >>>>>>>>>>>>>>> because you're using arithmetic average, i.e., a sum, and if you don't have >>>>>>>>>>>>>>> any fixings yet the sum should be 0.) >>>>>>>>>>>>>>> Your default seems to be 1 instead. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Luigi >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Wed, May 18, 2022 at 5:17 PM Ashish Bansal < >>>>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Luigi, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Our code is not too much but we are using >>>>>>>>>>>>>>>> deprecated functions like FDEuropeanEngine and FDAmericanEngine. >>>>>>>>>>>>>>>> Not sure if using new function called >>>>>>>>>>>>>>>> FdBlackScholesVanillaEngine has any change in the >>>>>>>>>>>>>>>> calculation that our code will have an impact. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Can we use the DiscreteAveragingAsianOption without the >>>>>>>>>>>>>>>> overloaded parameter of pastfixings under 1.7? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Wed, 18 May 2022 at 20:00, Luigi Ballabio < >>>>>>>>>>>>>>>> lui...@gm...> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi — it could be. Any particular reason you're still >>>>>>>>>>>>>>>>> using a version from 4 years ago? If you have a substantial amount of code >>>>>>>>>>>>>>>>> that depends on QuantLib, it might require some work to update because some >>>>>>>>>>>>>>>>> methods were deprecated and then removed in the meantime; and of course >>>>>>>>>>>>>>>>> you'll probably have some validation process in place when updating, so >>>>>>>>>>>>>>>>> that's work too. But on the other hand, you're missing 4 years worth of >>>>>>>>>>>>>>>>> bug fixings... >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Luigi >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Wed, May 18, 2022 at 4:19 PM Ashish Bansal < >>>>>>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> We tried again and got the same error. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Could it be due to the old version (1.7) we are using? I >>>>>>>>>>>>>>>>>> see in the release notes of Apr-2021 that the overload for past fixing was >>>>>>>>>>>>>>>>>> added: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> - Added an overloaded constructor for Asian options >>>>>>>>>>>>>>>>>> that takes all past fixings and thus allows to reprice them correctly when >>>>>>>>>>>>>>>>>> the evaluation date changes (thanks to Jack Gillett). >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Wed, 18 May 2022 at 19:14, Jack G < >>>>>>>>>>>>>>>>>> jac...@gm...> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi Ashish, >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> I have a better answer for you with a screenshot >>>>>>>>>>>>>>>>>>> awaiting moderation as it's quite large, but in the meantime, I was able to >>>>>>>>>>>>>>>>>>> run your code without problems using the python at the bottom of this email >>>>>>>>>>>>>>>>>>> (although I didn't check the numbers). >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> If there is something you're doing specifically to >>>>>>>>>>>>>>>>>>> generate the error, could you please attach a minimal reproduction of it? >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Best, >>>>>>>>>>>>>>>>>>> Jack >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> import QuantLib as ql >>>>>>>>>>>>>>>>>>> from copy import deepcopy >>>>>>>>>>>>>>>>>>> from datetime import datetime >>>>>>>>>>>>>>>>>>> from datetime import timedelta >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> # DEFAULT_PERIODS = [ql.Period(f"{i}d") for i in >>>>>>>>>>>>>>>>>>> range(0,31)] >>>>>>>>>>>>>>>>>>> DEFAULT_PERIODS = [ql.Period("6M"), ql.Period("12M"), >>>>>>>>>>>>>>>>>>> ql.Period("18M"), ql.Period("24M")] >>>>>>>>>>>>>>>>>>> DEFAULT_tGRID = 100 >>>>>>>>>>>>>>>>>>> DEFAULT_xGRID = 100 >>>>>>>>>>>>>>>>>>> DEFAULT_aGRID = 50 >>>>>>>>>>>>>>>>>>> DEFAULT_aRA = 1 # arithmeticRunningAccumulator >>>>>>>>>>>>>>>>>>> DEFAULT_PASTFIXINGS = 1 >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> class AsianOptionPrice: >>>>>>>>>>>>>>>>>>> def __init__(self, **x): >>>>>>>>>>>>>>>>>>> for k, v in x.items(): >>>>>>>>>>>>>>>>>>> setattr(self, k, v) >>>>>>>>>>>>>>>>>>> self.tGrid = x.get("tGrid", DEFAULT_tGRID) >>>>>>>>>>>>>>>>>>> self.xGrid = x.get("xGrid", DEFAULT_xGRID) >>>>>>>>>>>>>>>>>>> self.aGrid = x.get("aGrid", DEFAULT_aGRID) >>>>>>>>>>>>>>>>>>> self.periods = x.get("periods", DEFAULT_PERIODS) >>>>>>>>>>>>>>>>>>> self.pastFixings = x.get("pastFixings", >>>>>>>>>>>>>>>>>>> DEFAULT_PASTFIXINGS) >>>>>>>>>>>>>>>>>>> self.aRA = x.get("arithmeticRunningAccumulator", >>>>>>>>>>>>>>>>>>> DEFAULT_aRA) >>>>>>>>>>>>>>>>>>> self.keyList = [k for k, v in x.items()] >>>>>>>>>>>>>>>>>>> self.dist = 10**(-2) >>>>>>>>>>>>>>>>>>> self.date_format = "%d-%m-%Y" >>>>>>>>>>>>>>>>>>> self.value_date = ql.DateParser.parseFormatted( >>>>>>>>>>>>>>>>>>> self.valueDate, '%d-%m-%Y') >>>>>>>>>>>>>>>>>>> self.expiry_date = ql.DateParser.parseFormatted( >>>>>>>>>>>>>>>>>>> self.expiryDate, '%d-%m-%Y') >>>>>>>>>>>>>>>>>>> ql.Settings.instance().evaluationDate = >>>>>>>>>>>>>>>>>>> self.value_date >>>>>>>>>>>>>>>>>>> self.exDay = >>>>>>>>>>>>>>>>>>> ql.DateParser.parseFormatted(self.expiryDate, '%d-%m-%Y') >>>>>>>>>>>>>>>>>>> # Volatility input is required for running the >>>>>>>>>>>>>>>>>>> computing implied volatility function. This volatility is NOT used in the >>>>>>>>>>>>>>>>>>> implied volatility calculation. >>>>>>>>>>>>>>>>>>> self.vol_for_iv_calc = 0.10 >>>>>>>>>>>>>>>>>>> self.IV = None >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> def >>>>>>>>>>>>>>>>>>> generate_fixture_dates(self,start_date,end_date,period): >>>>>>>>>>>>>>>>>>> schedule = ql.MakeSchedule(start_date, end_date, >>>>>>>>>>>>>>>>>>> period) >>>>>>>>>>>>>>>>>>> fixture_dates = [_date for _date in schedule if >>>>>>>>>>>>>>>>>>> _date.weekday() not in [1,7]] >>>>>>>>>>>>>>>>>>> return fixture_dates >>>>>>>>>>>>>>>>>>> def asian(self): >>>>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>>>> arithmeticRunningAccumulator(aRA) >>>>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>>>> arithmeticRunningAccumulator = self.aRA >>>>>>>>>>>>>>>>>>> pastFixings = self.pastFixings >>>>>>>>>>>>>>>>>>> print(pastFixings) >>>>>>>>>>>>>>>>>>> option_type = self.optionType.lower() >>>>>>>>>>>>>>>>>>> if option_type not in ["call", "put"]: >>>>>>>>>>>>>>>>>>> raise Exception( >>>>>>>>>>>>>>>>>>> f"Option Type is Neither Call nor Put, >>>>>>>>>>>>>>>>>>> Option type is {option_type}") >>>>>>>>>>>>>>>>>>> option_type = ql.Option.Call if option_type == >>>>>>>>>>>>>>>>>>> "call" else ql.Option.Put >>>>>>>>>>>>>>>>>>> strike = self.strikePrice >>>>>>>>>>>>>>>>>>> today = self.value_date >>>>>>>>>>>>>>>>>>> print(today) >>>>>>>>>>>>>>>>>>> fixingStartDate >>>>>>>>>>>>>>>>>>> =ql.DateParser.parseFormatted(self.fixingStartDate, '%d-%m-%Y') >>>>>>>>>>>>>>>>>>> print("#"*40,fixingStartDate) >>>>>>>>>>>>>>>>>>> periods = self.periods >>>>>>>>>>>>>>>>>>> asianFutureFixingDates = >>>>>>>>>>>>>>>>>>> self.generate_fixture_dates(fixingStartDate,self.expiry_date,ql.Period("1d")) >>>>>>>>>>>>>>>>>>> print("#"*40,asianFutureFixingDates) >>>>>>>>>>>>>>>>>>> asianExpiryDate = self.expiry_date >>>>>>>>>>>>>>>>>>> vanillaPayoff = >>>>>>>>>>>>>>>>>>> ql.PlainVanillaPayoff(option_type, strike) >>>>>>>>>>>>>>>>>>> europeanExercise = >>>>>>>>>>>>>>>>>>> ql.EuropeanExercise(asianExpiryDate) >>>>>>>>>>>>>>>>>>> arithmeticAverage = ql.Average().Arithmetic >>>>>>>>>>>>>>>>>>> discreteArithmeticAsianOption = >>>>>>>>>>>>>>>>>>> ql.DiscreteAveragingAsianOption( >>>>>>>>>>>>>>>>>>> arithmeticAverage, >>>>>>>>>>>>>>>>>>> arithmeticRunningAccumulator, pastFixings, asianFutureFixingDates, >>>>>>>>>>>>>>>>>>> vanillaPayoff, europeanExercise) >>>>>>>>>>>>>>>>>>> return discreteArithmeticAsianOption >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> def create_arg_list(self, Option=None, >>>>>>>>>>>>>>>>>>> compute_implied_vol=None, implied_vol_am_put=None): >>>>>>>>>>>>>>>>>>> ''' >>>>>>>>>>>>>>>>>>> The arguments with disturbances added. Will >>>>>>>>>>>>>>>>>>> be used for calculation of Greeks >>>>>>>>>>>>>>>>>>> using numerical differentiation. >>>>>>>>>>>>>>>>>>> Creating a dictionary of arguments that will >>>>>>>>>>>>>>>>>>> be used for option price and greeks calculation. >>>>>>>>>>>>>>>>>>> ''' >>>>>>>>>>>>>>>>>>> self.riskFreeRate = self.riskFreeRate/100 >>>>>>>>>>>>>>>>>>> originalDict_ = {k: getattr(self, k) for k in >>>>>>>>>>>>>>>>>>> self.keyList} >>>>>>>>>>>>>>>>>>> ListDict = [] >>>>>>>>>>>>>>>>>>> for i in range(4): >>>>>>>>>>>>>>>>>>> ListDict.append(deepcopy(originalDict_)) >>>>>>>>>>>>>>>>>>> ListDict[1]['riskFreeRate'] = self.riskFreeRate >>>>>>>>>>>>>>>>>>> + self.dist >>>>>>>>>>>>>>>>>>> ListDict[2]['volatility'] = self.volatility + >>>>>>>>>>>>>>>>>>> self.dist >>>>>>>>>>>>>>>>>>> ListDict[3]['expiryDate'] = (datetime.strptime( >>>>>>>>>>>>>>>>>>> self.expiryDate, self.date_format) - >>>>>>>>>>>>>>>>>>> timedelta(days=1)).strftime(self.date_format) >>>>>>>>>>>>>>>>>>> print(ListDict) >>>>>>>>>>>>>>>>>>> return(ListDict) >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> def bs_process(self, create_process_for_iv=None, >>>>>>>>>>>>>>>>>>> use_IV=None): >>>>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>>>> Creating the Black-Scholes process for option >>>>>>>>>>>>>>>>>>> valuation. >>>>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>>>> riskFreeTS = ql.YieldTermStructureHandle( >>>>>>>>>>>>>>>>>>> ql.FlatForward(self.value_date, >>>>>>>>>>>>>>>>>>> self.riskFreeRate, ql.Actual365Fixed())) >>>>>>>>>>>>>>>>>>> dividendTS = ql.YieldTermStructureHandle( >>>>>>>>>>>>>>>>>>> ql.FlatForward(self.value_date, 0, >>>>>>>>>>>>>>>>>>> ql.Actual365Fixed())) >>>>>>>>>>>>>>>>>>> volatility = >>>>>>>>>>>>>>>>>>> ql.BlackVolTermStructureHandle(ql.BlackConstantVol( >>>>>>>>>>>>>>>>>>> self.value_date, ql.NullCalendar(), >>>>>>>>>>>>>>>>>>> self.volatility, ql.Actual365Fixed())) >>>>>>>>>>>>>>>>>>> initialValue = >>>>>>>>>>>>>>>>>>> ql.QuoteHandle(ql.SimpleQuote(self.underlyingPrice)) >>>>>>>>>>>>>>>>>>> process = ql.BlackScholesMertonProcess( >>>>>>>>>>>>>>>>>>> initialValue, dividendTS, riskFreeTS, >>>>>>>>>>>>>>>>>>> volatility) >>>>>>>>>>>>>>>>>>> return(process) >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> def evaluate(self, Option=None, >>>>>>>>>>>>>>>>>>> compute_implied_vol=None): >>>>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>>>> Call the relevant option based on the input. >>>>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>>>> self.riskFreeRate = self.riskFreeRate/100 >>>>>>>>>>>>>>>>>>> res = None >>>>>>>>>>>>>>>>>>> option = AsianOptionPrice.asian(self) >>>>>>>>>>>>>>>>>>> if compute_implied_vol == True: >>>>>>>>>>>>>>>>>>> # create Black Scholes process using IV. >>>>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>>>>>> use_IV=True) >>>>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>>>>>> process, tGrid=self.tGrid, >>>>>>>>>>>>>>>>>>> xGrid=self.xGrid, aGrid=self.aGrid) >>>>>>>>>>>>>>>>>>> option.setPricingEngine(engine) >>>>>>>>>>>>>>>>>>> res = {'value': option.NPV(), >>>>>>>>>>>>>>>>>>> 'impliedVolatility': self.IV} >>>>>>>>>>>>>>>>>>> else: >>>>>>>>>>>>>>>>>>> # Create Black Scholes process using HV. >>>>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>>>>>> use_IV=False) >>>>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>>>>>> process, tGrid=self.tGrid, >>>>>>>>>>>>>>>>>>> xGrid=self.xGrid, aGrid=self.aGrid) >>>>>>>>>>>>>>>>>>> option.setPricingEngine(engine) >>>>>>>>>>>>>>>>>>> res = {'value': option.NPV()} >>>>>>>>>>>>>>>>>>> return res >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> def evaluate_asian_npv(self): >>>>>>>>>>>>>>>>>>> Option = AsianOptionPrice.asian(self) >>>>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>>>>>> use_IV=False) >>>>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>>>>>> process, tGrid=self.tGrid, xGrid=self.xGrid, >>>>>>>>>>>>>>>>>>> aGrid=self.aGrid) >>>>>>>>>>>>>>>>>>> Option.setPricingEngine(engine) >>>>>>>>>>>>>>>>>>> res = Option.NPV() >>>>>>>>>>>>>>>>>>> return(res) >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> def calculate_greeks(self, Option=None, >>>>>>>>>>>>>>>>>>> compute_implied_vol=None): >>>>>>>>>>>>>>>>>>> today = self.value_date >>>>>>>>>>>>>>>>>>> Option = AsianOptionPrice.asian(self) >>>>>>>>>>>>>>>>>>> if compute_implied_vol == True: >>>>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>>>>>> use_IV=True) >>>>>>>>>>>>>>>>>>> else: >>>>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>>>>>> use_IV=False) >>>>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>>>>>> process, tGrid=self.tGrid, xGrid=self.xGrid, >>>>>>>>>>>>>>>>>>> aGrid=self.aGrid) >>>>>>>>>>>>>>>>>>> Option.setPricingEngine(engine) >>>>>>>>>>>>>>>>>>> option_greeks_ = {"delta": Option.delta(), >>>>>>>>>>>>>>>>>>> "gamma": Option.gamma( >>>>>>>>>>>>>>>>>>> )} >>>>>>>>>>>>>>>>>>> ArgmntList = AsianOptionPrice.create_arg_list( >>>>>>>>>>>>>>>>>>> self, Option, compute_implied_vol=True, >>>>>>>>>>>>>>>>>>> implied_vol_am_put=self.volatility) >>>>>>>>>>>>>>>>>>> DisturbedPrices = [] >>>>>>>>>>>>>>>>>>> arg_keys = ['Price', 'PRup', 'PVup', 'PTup'] >>>>>>>>>>>>>>>>>>> for i in range(4): >>>>>>>>>>>>>>>>>>> DisturbedPrices.append(eval( >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> "AsianOptionPrice(**ArgmntList[i]).evaluate_asian_npv()")) >>>>>>>>>>>>>>>>>>> print(DisturbedPrices) >>>>>>>>>>>>>>>>>>> PricesDistrbd = dict(zip(arg_keys, >>>>>>>>>>>>>>>>>>> DisturbedPrices)) >>>>>>>>>>>>>>>>>>> Rho = (PricesDistrbd['PRup'] - >>>>>>>>>>>>>>>>>>> PricesDistrbd['Price'])/(self.dist*100) >>>>>>>>>>>>>>>>>>> vega = (PricesDistrbd['PVup'] - >>>>>>>>>>>>>>>>>>> PricesDistrbd['Price'])/(self.dist*100) >>>>>>>>>>>>>>>>>>> thetaDay = (PricesDistrbd['PTup'] - >>>>>>>>>>>>>>>>>>> PricesDistrbd['Price']) >>>>>>>>>>>>>>>>>>> option_greeks_.update({'rho': Rho, 'vega': vega, >>>>>>>>>>>>>>>>>>> 'theta': thetaDay}) >>>>>>>>>>>>>>>>>>> return option_greeks_ >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> settings = { >>>>>>>>>>>>>>>>>>> "computeHistoricalVolatiltiy": False, >>>>>>>>>>>>>>>>>>> "tenantId": "380", >>>>>>>>>>>>>>>>>>> "gridPoints": 149, >>>>>>>>>>>>>>>>>>> "computeImpliedVolatiltiy": False, >>>>>>>>>>>>>>>>>>> "runId": 3735, >>>>>>>>>>>>>>>>>>> "timeSteps": 150, >>>>>>>>>>>>>>>>>>> "optionTrades": [ >>>>>>>>>>>>>>>>>>> { >>>>>>>>>>>>>>>>>>> "underlyingPrice": 98.69, >>>>>>>>>>>>>>>>>>> "refNo": "OPT-1135-GVA", >>>>>>>>>>>>>>>>>>> "underlyingPriceUnit": "US cents/LB", >>>>>>>>>>>>>>>>>>> "valueDate": "17-03-2022", >>>>>>>>>>>>>>>>>>> "fixingStartDate":"01-05-2022", >>>>>>>>>>>>>>>>>>> "pastFixings":0, >>>>>>>>>>>>>>>>>>> "volatility": 0.6015, >>>>>>>>>>>>>>>>>>> "openQuantity": 1, >>>>>>>>>>>>>>>>>>> "strikePriceUnit": "US cents/LB", >>>>>>>>>>>>>>>>>>> "optionType": "Call", >>>>>>>>>>>>>>>>>>> "expiryDate": "31-05-2022", >>>>>>>>>>>>>>>>>>> "exType": "asian", >>>>>>>>>>>>>>>>>>> "riskFreeRate": 0.8080374999999999, >>>>>>>>>>>>>>>>>>> "premium": 1, >>>>>>>>>>>>>>>>>>> "portfolioId": 18209, >>>>>>>>>>>>>>>>>>> "marketPremium": 11.42, >>>>>>>>>>>>>>>>>>> "longShort": "Long", >>>>>>>>>>>>>>>>>>> "optionInstrument": "EURO USD 1.105 Call", >>>>>>>>>>>>>>>>>>> "asset": "EURO USD 1.105 Call", >>>>>>>>>>>>>>>>>>> "portfolioName": "Option Trades", >>>>>>>>>>>>>>>>>>> "scenarioId": 8356, >>>>>>>>>>>>>>>>>>> "scenarioName": "Option Valuation - Greeks", >>>>>>>>>>>>>>>>>>> "strikePrice": 95, >>>>>>>>>>>>>>>>>>> "maturityInYears": 0.205479452 >>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>> ], >>>>>>>>>>>>>>>>>>> "userId": "5263", >>>>>>>>>>>>>>>>>>> "americanOptionsEngine": "CrankNicolson" >>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> opt = AsianOptionPrice(**settings["optionTrades"][0]) >>>>>>>>>>>>>>>>>>> opt.evaluate_asian_npv() >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Wed, May 18, 2022 at 9:25 PM Ashish Bansal < >>>>>>>>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Jack, >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Please find attached the Asian option python code and >>>>>>>>>>>>>>>>>>>> the option trade payload. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Thanks for your help, >>>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Wed, 18 May 2022 at 12:12, Jack G < >>>>>>>>>>>>>>>>>>>> jac...@gm...> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi Ashish, >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> I've just lifted the examples from your references >>>>>>>>>>>>>>>>>>>>> directly for a discrete arithmetic Asian using the FD Asian engine and it >>>>>>>>>>>>>>>>>>>>> is working for me - can you share the code you are using that breaks please? >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Best, >>>>>>>>>>>>>>>>>>>>> Jack >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Wed, 18 May 2022, 13:55 Ashish Bansal, < >>>>>>>>>>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Hi all, >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Could somebody help with the asian options? We are >>>>>>>>>>>>>>>>>>>>>> using FdBlackScholesAsianengine with DiscreteAveragingAsianOption. Online >>>>>>>>>>>>>>>>>>>>>> references are given below. In DiscreteAveragingAsianOption, we need to >>>>>>>>>>>>>>>>>>>>>> pass the past fixing which is suggested to be 0 for new trade. Whereas when >>>>>>>>>>>>>>>>>>>>>> we are passing it as 0, we are getting the following error: >>>>>>>>>>>>>>>>>>>>>> "QuantLib Error - Running average requires at least >>>>>>>>>>>>>>>>>>>>>> one past fixing" >>>>>>>>>>>>>>>>>>>>>> ref: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> https://quantlib-python-docs.readthedocs.io/en/latest/pricing_engines.html#fdblackscholesasianengine >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> https://quantlib-python-docs.readthedocs.io/en/latest/instruments/options.html?highlight=DiscreteAveragingAsianOption#ql.DiscreteAveragingAsianOption >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Queries: >>>>>>>>>>>>>>>>>>>>>> 1. What is to be passed here for new trade if not 0? >>>>>>>>>>>>>>>>>>>>>> 2. For trade which is mid of averaging and has few >>>>>>>>>>>>>>>>>>>>>> past fixings, do we need to pass the count of past fixing or the actual >>>>>>>>>>>>>>>>>>>>>> rates of the pastfixing as an array? >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Any help will be appreciated. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Thanks in advance >>>>>>>>>>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>>>>>>>>> QuantLib-users mailing list >>>>>>>>>>>>>>>>>>>>>> Qua...@li... >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> https://lists.sourceforge.net/lists/listinfo/quantlib-users >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>>>>> QuantLib-users mailing list >>>>>>>>>>>>>>>>>> Qua...@li... >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> https://lists.sourceforge.net/lists/listinfo/quantlib-users >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> |
|
From: Luigi B. <lui...@gm...> - 2022-06-03 09:23:57
|
Version 1.27 will be out sometime in July. The changes included so far are at <https://github.com/lballabio/QuantLib/milestone/23?closed=1>. The changes in previous releases are at < https://github.com/lballabio/QuantLib/releases/>. Luigi On Thu, Jun 2, 2022 at 7:23 AM Ashish Bansal <ash...@gm...> wrote: > That is great news. I have been waiting for TW engine for a long time :) > . Special thanks to Fredrick (@gbfredrik) for adding it. > > When is v1.27 planned to be released? Hoping that it will be released on > SWIG at the same time. Where can I read about other changes in 1.27 so that > we can plan accordingly? > > Thanks > Ashish > > On Thu, 2 Jun 2022 at 01:35, Luigi Ballabio <lui...@gm...> > wrote: > >> Hello, >> it does mention it now -- the Turnbull-Wakeman engine was added to >> the repository less than a month ago and will be in release 1.27. It >> didn't exist in release 1.17. >> >> Luigi >> >> >> On Wed, Jun 1, 2022 at 7:55 PM Ashish Bansal <ash...@gm...> >> wrote: >> >>> Luigi, >>> >>> You had given me the following link sometime back. It does mention about >>> the Turnbull Wakeman model based on 2 moment matching: >>> >>> https://github.com/lballabio/QuantLib/blob/master/test-suite/asianoptions.cpp >>> <ql/pricingengines/asian/turnbullwakemanasianengine.hpp> >>> >>> [image: image.png] >>> Even the example is given in the above file. Although the asianoption is >>> part of test-suite but the Turnbull...engine is part of main QL. Is it not >>> part of SWIG? i tried in it in python but could not find it. >>> >>> How can I use this in python with QL v1.17? >>> >>> Regards, >>> Ashish >>> >>> On Mon, 30 May 2022 at 19:39, Ashish Bansal <ash...@gm...> >>> wrote: >>> >>>> Thanks for the responses. I am trying various papers to find the moment >>>> matching for the asian options. I did find the calculation based on >>>> Turnbull-Wakeman model here: >>>> >>>> https://osf.io/efq6a/download >>>> >>>> >>>> I tried this but did not get good results for options expiring in a few >>>> months. I will try some other source probably. >>>> >>>> >>>> One last question, does QL's FdBlackScholesAsianengine with DiscreteAveragingAsianOption >>>> adjust the valuation for trade which are in between the averaging period; >>>> as mentioned on slide # 9 and 10 of this deck? >>>> >>>> >>>> Regards, >>>> >>>> Ashish >>>> >>>> On Thu, 26 May 2022 at 13:24, Luigi Ballabio <lui...@gm...> >>>> wrote: >>>> >>>>> I mean that the two engines give the same price, i.e. 6.09. I don't >>>>> have info on moment matching. >>>>> >>>>> On Wed, May 25, 2022 at 6:51 PM Ashish Bansal <ash...@gm...> >>>>> wrote: >>>>> >>>>>> By same price, you mean same as exchange i.e. 4.57. or same as aRA >>>>>> parameter i.e. 6.09? >>>>>> >>>>>> Any guidance on moment matching? I could not find anything online >>>>>> about it. >>>>>> >>>>>> Regards >>>>>> Ashish >>>>>> >>>>>> On Wed, May 25, 2022, 7:02 PM Luigi Ballabio < >>>>>> lui...@gm...> wrote: >>>>>> >>>>>>> Hi, >>>>>>> no, the engine doesn't do moment matching. I don't think we >>>>>>> have something ready to use for that in the library. >>>>>>> As for the accumulator: I confirm it's the sum. If you create a >>>>>>> virtual Python environment and install the latest QuantLib in it, you can >>>>>>> try your shortened code with the other constructor for the Asian option >>>>>>> (the one taking the list of fixings). It returns the same price. >>>>>>> >>>>>>> Luigi >>>>>>> >>>>>>> >>>>>>> On Wed, May 25, 2022 at 2:46 PM Ashish Bansal < >>>>>>> ash...@gm...> wrote: >>>>>>> >>>>>>>> Hi Luigi, >>>>>>>> >>>>>>>> One question about the QL calculation: Does QL code for the Asian >>>>>>>> option include *moment matching *of the volatility or do we need >>>>>>>> to do that before passing to the DiscAvAsOption? >>>>>>>> >>>>>>>> Regarding the code, I had attached the full code from our system in >>>>>>>> my previous email, attaching here too. The shortened version of the code, >>>>>>>> containing only the QL interaction and excluding excess processing, is also >>>>>>>> attached here. It includes the trade parameters we are using to evaluate >>>>>>>> the Asian option. Strangely, the value is coming zero with short-code but >>>>>>>> with full code in our system, we are getting the values. >>>>>>>> >>>>>>>> Following is the NPV that we are getting in our system (using full >>>>>>>> code) for our trade which has averaging period from 1st March to 31st March >>>>>>>> 2022 and the market traded premium of 4.56: >>>>>>>> arithmeticRunningAccumulator NPV >>>>>>>> 0 4.5711 >>>>>>>> 1302.88 6.09 >>>>>>>> >>>>>>>> Thanks in advance for help. >>>>>>>> >>>>>>>> PS: We are using QL1.17 and the vols are sourced from Reuters could >>>>>>>> be different from implied in the market traded premium. >>>>>>>> >>>>>>>> Regards, >>>>>>>> Ashish >>>>>>>> >>>>>>>> On Mon, 23 May 2022 at 22:26, Luigi Ballabio < >>>>>>>> lui...@gm...> wrote: >>>>>>>> >>>>>>>>> May you send sample code and the value of the fixings for one of >>>>>>>>> those options? Thanks! >>>>>>>>> >>>>>>>>> Luigi >>>>>>>>> >>>>>>>>> >>>>>>>>> On Mon, May 23, 2022 at 8:32 AM Ashish Bansal < >>>>>>>>> ash...@gm...> wrote: >>>>>>>>> >>>>>>>>>> Luigi, >>>>>>>>>> >>>>>>>>>> We ran the asian code, which i sent earlier for a couple of asian >>>>>>>>>> options traded on exchange. We got prices very close to traded prices when >>>>>>>>>> we used the value of running accumulator as 1 for march option being valued >>>>>>>>>> on 17th with past fixing count as 12. But when we used the sum of past >>>>>>>>>> fixing prices i.e. 1302.88 we got a very different number like 6.09 against >>>>>>>>>> 4.57 earlier and 14.11 against 12.39 earlier. >>>>>>>>>> >>>>>>>>>> Just want to confirm if i am missing something about running >>>>>>>>>> accumulator and should it be really the sum of all past fixings? >>>>>>>>>> >>>>>>>>>> Thanks for help in advance. >>>>>>>>>> Ashish >>>>>>>>>> >>>>>>>>>> On Fri, 20 May 2022 at 14:58, Ashish Bansal < >>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>> >>>>>>>>>>> Ok understood. thanks. >>>>>>>>>>> >>>>>>>>>>> On Fri, 20 May 2022 at 14:46, Luigi Ballabio < >>>>>>>>>>> lui...@gm...> wrote: >>>>>>>>>>> >>>>>>>>>>>> It would be the sum of past fixings; for three past fixings of >>>>>>>>>>>> 100.2, 101.3 and 94.6 it would be 296.1. >>>>>>>>>>>> >>>>>>>>>>>> Luigi >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Thu, May 19, 2022 at 12:37 PM Ashish Bansal < >>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Thanks, Luigi for the suggestion. After taking the running >>>>>>>>>>>>> accumulator, we are able to generate the numbers. What exactly should be >>>>>>>>>>>>> passed here? The average price of past fixings or just 1 when the trade is >>>>>>>>>>>>> priced during averaging period? >>>>>>>>>>>>> >>>>>>>>>>>>> Thanks for help. >>>>>>>>>>>>> >>>>>>>>>>>>> Ashish >>>>>>>>>>>>> >>>>>>>>>>>>> On Wed, 18 May 2022 at 21:17, Luigi Ballabio < >>>>>>>>>>>>> lui...@gm...> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> I don't have a 1.7 version to try it, but the check is the >>>>>>>>>>>>>> one at < >>>>>>>>>>>>>> https://github.com/lballabio/QuantLib/blob/QuantLib-v1.7/ql/pricingengines/asian/fdblackscholesasianengine.cpp#L51-L53>, >>>>>>>>>>>>>> suggesting that your running accumulator should be 0 (which makes sense, >>>>>>>>>>>>>> because you're using arithmetic average, i.e., a sum, and if you don't have >>>>>>>>>>>>>> any fixings yet the sum should be 0.) >>>>>>>>>>>>>> Your default seems to be 1 instead. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Luigi >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Wed, May 18, 2022 at 5:17 PM Ashish Bansal < >>>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Luigi, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Our code is not too much but we are using >>>>>>>>>>>>>>> deprecated functions like FDEuropeanEngine and FDAmericanEngine. >>>>>>>>>>>>>>> Not sure if using new function called >>>>>>>>>>>>>>> FdBlackScholesVanillaEngine has any change in the >>>>>>>>>>>>>>> calculation that our code will have an impact. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Can we use the DiscreteAveragingAsianOption without the >>>>>>>>>>>>>>> overloaded parameter of pastfixings under 1.7? >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Wed, 18 May 2022 at 20:00, Luigi Ballabio < >>>>>>>>>>>>>>> lui...@gm...> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi — it could be. Any particular reason you're still >>>>>>>>>>>>>>>> using a version from 4 years ago? If you have a substantial amount of code >>>>>>>>>>>>>>>> that depends on QuantLib, it might require some work to update because some >>>>>>>>>>>>>>>> methods were deprecated and then removed in the meantime; and of course >>>>>>>>>>>>>>>> you'll probably have some validation process in place when updating, so >>>>>>>>>>>>>>>> that's work too. But on the other hand, you're missing 4 years worth of >>>>>>>>>>>>>>>> bug fixings... >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Luigi >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Wed, May 18, 2022 at 4:19 PM Ashish Bansal < >>>>>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> We tried again and got the same error. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Could it be due to the old version (1.7) we are using? I >>>>>>>>>>>>>>>>> see in the release notes of Apr-2021 that the overload for past fixing was >>>>>>>>>>>>>>>>> added: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> - Added an overloaded constructor for Asian options >>>>>>>>>>>>>>>>> that takes all past fixings and thus allows to reprice them correctly when >>>>>>>>>>>>>>>>> the evaluation date changes (thanks to Jack Gillett). >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Wed, 18 May 2022 at 19:14, Jack G < >>>>>>>>>>>>>>>>> jac...@gm...> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Ashish, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> I have a better answer for you with a screenshot awaiting >>>>>>>>>>>>>>>>>> moderation as it's quite large, but in the meantime, I was able to run your >>>>>>>>>>>>>>>>>> code without problems using the python at the bottom of this email >>>>>>>>>>>>>>>>>> (although I didn't check the numbers). >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> If there is something you're doing specifically to >>>>>>>>>>>>>>>>>> generate the error, could you please attach a minimal reproduction of it? >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Best, >>>>>>>>>>>>>>>>>> Jack >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> import QuantLib as ql >>>>>>>>>>>>>>>>>> from copy import deepcopy >>>>>>>>>>>>>>>>>> from datetime import datetime >>>>>>>>>>>>>>>>>> from datetime import timedelta >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> # DEFAULT_PERIODS = [ql.Period(f"{i}d") for i in >>>>>>>>>>>>>>>>>> range(0,31)] >>>>>>>>>>>>>>>>>> DEFAULT_PERIODS = [ql.Period("6M"), ql.Period("12M"), >>>>>>>>>>>>>>>>>> ql.Period("18M"), ql.Period("24M")] >>>>>>>>>>>>>>>>>> DEFAULT_tGRID = 100 >>>>>>>>>>>>>>>>>> DEFAULT_xGRID = 100 >>>>>>>>>>>>>>>>>> DEFAULT_aGRID = 50 >>>>>>>>>>>>>>>>>> DEFAULT_aRA = 1 # arithmeticRunningAccumulator >>>>>>>>>>>>>>>>>> DEFAULT_PASTFIXINGS = 1 >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> class AsianOptionPrice: >>>>>>>>>>>>>>>>>> def __init__(self, **x): >>>>>>>>>>>>>>>>>> for k, v in x.items(): >>>>>>>>>>>>>>>>>> setattr(self, k, v) >>>>>>>>>>>>>>>>>> self.tGrid = x.get("tGrid", DEFAULT_tGRID) >>>>>>>>>>>>>>>>>> self.xGrid = x.get("xGrid", DEFAULT_xGRID) >>>>>>>>>>>>>>>>>> self.aGrid = x.get("aGrid", DEFAULT_aGRID) >>>>>>>>>>>>>>>>>> self.periods = x.get("periods", DEFAULT_PERIODS) >>>>>>>>>>>>>>>>>> self.pastFixings = x.get("pastFixings", >>>>>>>>>>>>>>>>>> DEFAULT_PASTFIXINGS) >>>>>>>>>>>>>>>>>> self.aRA = x.get("arithmeticRunningAccumulator", >>>>>>>>>>>>>>>>>> DEFAULT_aRA) >>>>>>>>>>>>>>>>>> self.keyList = [k for k, v in x.items()] >>>>>>>>>>>>>>>>>> self.dist = 10**(-2) >>>>>>>>>>>>>>>>>> self.date_format = "%d-%m-%Y" >>>>>>>>>>>>>>>>>> self.value_date = ql.DateParser.parseFormatted( >>>>>>>>>>>>>>>>>> self.valueDate, '%d-%m-%Y') >>>>>>>>>>>>>>>>>> self.expiry_date = ql.DateParser.parseFormatted( >>>>>>>>>>>>>>>>>> self.expiryDate, '%d-%m-%Y') >>>>>>>>>>>>>>>>>> ql.Settings.instance().evaluationDate = >>>>>>>>>>>>>>>>>> self.value_date >>>>>>>>>>>>>>>>>> self.exDay = >>>>>>>>>>>>>>>>>> ql.DateParser.parseFormatted(self.expiryDate, '%d-%m-%Y') >>>>>>>>>>>>>>>>>> # Volatility input is required for running the >>>>>>>>>>>>>>>>>> computing implied volatility function. This volatility is NOT used in the >>>>>>>>>>>>>>>>>> implied volatility calculation. >>>>>>>>>>>>>>>>>> self.vol_for_iv_calc = 0.10 >>>>>>>>>>>>>>>>>> self.IV = None >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> def >>>>>>>>>>>>>>>>>> generate_fixture_dates(self,start_date,end_date,period): >>>>>>>>>>>>>>>>>> schedule = ql.MakeSchedule(start_date, end_date, >>>>>>>>>>>>>>>>>> period) >>>>>>>>>>>>>>>>>> fixture_dates = [_date for _date in schedule if >>>>>>>>>>>>>>>>>> _date.weekday() not in [1,7]] >>>>>>>>>>>>>>>>>> return fixture_dates >>>>>>>>>>>>>>>>>> def asian(self): >>>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>>> arithmeticRunningAccumulator(aRA) >>>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>>> arithmeticRunningAccumulator = self.aRA >>>>>>>>>>>>>>>>>> pastFixings = self.pastFixings >>>>>>>>>>>>>>>>>> print(pastFixings) >>>>>>>>>>>>>>>>>> option_type = self.optionType.lower() >>>>>>>>>>>>>>>>>> if option_type not in ["call", "put"]: >>>>>>>>>>>>>>>>>> raise Exception( >>>>>>>>>>>>>>>>>> f"Option Type is Neither Call nor Put, >>>>>>>>>>>>>>>>>> Option type is {option_type}") >>>>>>>>>>>>>>>>>> option_type = ql.Option.Call if option_type == >>>>>>>>>>>>>>>>>> "call" else ql.Option.Put >>>>>>>>>>>>>>>>>> strike = self.strikePrice >>>>>>>>>>>>>>>>>> today = self.value_date >>>>>>>>>>>>>>>>>> print(today) >>>>>>>>>>>>>>>>>> fixingStartDate >>>>>>>>>>>>>>>>>> =ql.DateParser.parseFormatted(self.fixingStartDate, '%d-%m-%Y') >>>>>>>>>>>>>>>>>> print("#"*40,fixingStartDate) >>>>>>>>>>>>>>>>>> periods = self.periods >>>>>>>>>>>>>>>>>> asianFutureFixingDates = >>>>>>>>>>>>>>>>>> self.generate_fixture_dates(fixingStartDate,self.expiry_date,ql.Period("1d")) >>>>>>>>>>>>>>>>>> print("#"*40,asianFutureFixingDates) >>>>>>>>>>>>>>>>>> asianExpiryDate = self.expiry_date >>>>>>>>>>>>>>>>>> vanillaPayoff = >>>>>>>>>>>>>>>>>> ql.PlainVanillaPayoff(option_type, strike) >>>>>>>>>>>>>>>>>> europeanExercise = >>>>>>>>>>>>>>>>>> ql.EuropeanExercise(asianExpiryDate) >>>>>>>>>>>>>>>>>> arithmeticAverage = ql.Average().Arithmetic >>>>>>>>>>>>>>>>>> discreteArithmeticAsianOption = >>>>>>>>>>>>>>>>>> ql.DiscreteAveragingAsianOption( >>>>>>>>>>>>>>>>>> arithmeticAverage, >>>>>>>>>>>>>>>>>> arithmeticRunningAccumulator, pastFixings, asianFutureFixingDates, >>>>>>>>>>>>>>>>>> vanillaPayoff, europeanExercise) >>>>>>>>>>>>>>>>>> return discreteArithmeticAsianOption >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> def create_arg_list(self, Option=None, >>>>>>>>>>>>>>>>>> compute_implied_vol=None, implied_vol_am_put=None): >>>>>>>>>>>>>>>>>> ''' >>>>>>>>>>>>>>>>>> The arguments with disturbances added. Will >>>>>>>>>>>>>>>>>> be used for calculation of Greeks >>>>>>>>>>>>>>>>>> using numerical differentiation. >>>>>>>>>>>>>>>>>> Creating a dictionary of arguments that will >>>>>>>>>>>>>>>>>> be used for option price and greeks calculation. >>>>>>>>>>>>>>>>>> ''' >>>>>>>>>>>>>>>>>> self.riskFreeRate = self.riskFreeRate/100 >>>>>>>>>>>>>>>>>> originalDict_ = {k: getattr(self, k) for k in >>>>>>>>>>>>>>>>>> self.keyList} >>>>>>>>>>>>>>>>>> ListDict = [] >>>>>>>>>>>>>>>>>> for i in range(4): >>>>>>>>>>>>>>>>>> ListDict.append(deepcopy(originalDict_)) >>>>>>>>>>>>>>>>>> ListDict[1]['riskFreeRate'] = self.riskFreeRate + >>>>>>>>>>>>>>>>>> self.dist >>>>>>>>>>>>>>>>>> ListDict[2]['volatility'] = self.volatility + >>>>>>>>>>>>>>>>>> self.dist >>>>>>>>>>>>>>>>>> ListDict[3]['expiryDate'] = (datetime.strptime( >>>>>>>>>>>>>>>>>> self.expiryDate, self.date_format) - >>>>>>>>>>>>>>>>>> timedelta(days=1)).strftime(self.date_format) >>>>>>>>>>>>>>>>>> print(ListDict) >>>>>>>>>>>>>>>>>> return(ListDict) >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> def bs_process(self, create_process_for_iv=None, >>>>>>>>>>>>>>>>>> use_IV=None): >>>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>>> Creating the Black-Scholes process for option >>>>>>>>>>>>>>>>>> valuation. >>>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>>> riskFreeTS = ql.YieldTermStructureHandle( >>>>>>>>>>>>>>>>>> ql.FlatForward(self.value_date, >>>>>>>>>>>>>>>>>> self.riskFreeRate, ql.Actual365Fixed())) >>>>>>>>>>>>>>>>>> dividendTS = ql.YieldTermStructureHandle( >>>>>>>>>>>>>>>>>> ql.FlatForward(self.value_date, 0, >>>>>>>>>>>>>>>>>> ql.Actual365Fixed())) >>>>>>>>>>>>>>>>>> volatility = >>>>>>>>>>>>>>>>>> ql.BlackVolTermStructureHandle(ql.BlackConstantVol( >>>>>>>>>>>>>>>>>> self.value_date, ql.NullCalendar(), >>>>>>>>>>>>>>>>>> self.volatility, ql.Actual365Fixed())) >>>>>>>>>>>>>>>>>> initialValue = >>>>>>>>>>>>>>>>>> ql.QuoteHandle(ql.SimpleQuote(self.underlyingPrice)) >>>>>>>>>>>>>>>>>> process = ql.BlackScholesMertonProcess( >>>>>>>>>>>>>>>>>> initialValue, dividendTS, riskFreeTS, >>>>>>>>>>>>>>>>>> volatility) >>>>>>>>>>>>>>>>>> return(process) >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> def evaluate(self, Option=None, >>>>>>>>>>>>>>>>>> compute_implied_vol=None): >>>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>>> Call the relevant option based on the input. >>>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>>> self.riskFreeRate = self.riskFreeRate/100 >>>>>>>>>>>>>>>>>> res = None >>>>>>>>>>>>>>>>>> option = AsianOptionPrice.asian(self) >>>>>>>>>>>>>>>>>> if compute_implied_vol == True: >>>>>>>>>>>>>>>>>> # create Black Scholes process using IV. >>>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>>>>> use_IV=True) >>>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>>>>> process, tGrid=self.tGrid, >>>>>>>>>>>>>>>>>> xGrid=self.xGrid, aGrid=self.aGrid) >>>>>>>>>>>>>>>>>> option.setPricingEngine(engine) >>>>>>>>>>>>>>>>>> res = {'value': option.NPV(), >>>>>>>>>>>>>>>>>> 'impliedVolatility': self.IV} >>>>>>>>>>>>>>>>>> else: >>>>>>>>>>>>>>>>>> # Create Black Scholes process using HV. >>>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>>>>> use_IV=False) >>>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>>>>> process, tGrid=self.tGrid, >>>>>>>>>>>>>>>>>> xGrid=self.xGrid, aGrid=self.aGrid) >>>>>>>>>>>>>>>>>> option.setPricingEngine(engine) >>>>>>>>>>>>>>>>>> res = {'value': option.NPV()} >>>>>>>>>>>>>>>>>> return res >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> def evaluate_asian_npv(self): >>>>>>>>>>>>>>>>>> Option = AsianOptionPrice.asian(self) >>>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>>>>> use_IV=False) >>>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>>>>> process, tGrid=self.tGrid, xGrid=self.xGrid, >>>>>>>>>>>>>>>>>> aGrid=self.aGrid) >>>>>>>>>>>>>>>>>> Option.setPricingEngine(engine) >>>>>>>>>>>>>>>>>> res = Option.NPV() >>>>>>>>>>>>>>>>>> return(res) >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> def calculate_greeks(self, Option=None, >>>>>>>>>>>>>>>>>> compute_implied_vol=None): >>>>>>>>>>>>>>>>>> today = self.value_date >>>>>>>>>>>>>>>>>> Option = AsianOptionPrice.asian(self) >>>>>>>>>>>>>>>>>> if compute_implied_vol == True: >>>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>>>>> use_IV=True) >>>>>>>>>>>>>>>>>> else: >>>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>>>>> use_IV=False) >>>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>>>>> process, tGrid=self.tGrid, xGrid=self.xGrid, >>>>>>>>>>>>>>>>>> aGrid=self.aGrid) >>>>>>>>>>>>>>>>>> Option.setPricingEngine(engine) >>>>>>>>>>>>>>>>>> option_greeks_ = {"delta": Option.delta(), >>>>>>>>>>>>>>>>>> "gamma": Option.gamma( >>>>>>>>>>>>>>>>>> )} >>>>>>>>>>>>>>>>>> ArgmntList = AsianOptionPrice.create_arg_list( >>>>>>>>>>>>>>>>>> self, Option, compute_implied_vol=True, >>>>>>>>>>>>>>>>>> implied_vol_am_put=self.volatility) >>>>>>>>>>>>>>>>>> DisturbedPrices = [] >>>>>>>>>>>>>>>>>> arg_keys = ['Price', 'PRup', 'PVup', 'PTup'] >>>>>>>>>>>>>>>>>> for i in range(4): >>>>>>>>>>>>>>>>>> DisturbedPrices.append(eval( >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> "AsianOptionPrice(**ArgmntList[i]).evaluate_asian_npv()")) >>>>>>>>>>>>>>>>>> print(DisturbedPrices) >>>>>>>>>>>>>>>>>> PricesDistrbd = dict(zip(arg_keys, >>>>>>>>>>>>>>>>>> DisturbedPrices)) >>>>>>>>>>>>>>>>>> Rho = (PricesDistrbd['PRup'] - >>>>>>>>>>>>>>>>>> PricesDistrbd['Price'])/(self.dist*100) >>>>>>>>>>>>>>>>>> vega = (PricesDistrbd['PVup'] - >>>>>>>>>>>>>>>>>> PricesDistrbd['Price'])/(self.dist*100) >>>>>>>>>>>>>>>>>> thetaDay = (PricesDistrbd['PTup'] - >>>>>>>>>>>>>>>>>> PricesDistrbd['Price']) >>>>>>>>>>>>>>>>>> option_greeks_.update({'rho': Rho, 'vega': vega, >>>>>>>>>>>>>>>>>> 'theta': thetaDay}) >>>>>>>>>>>>>>>>>> return option_greeks_ >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> settings = { >>>>>>>>>>>>>>>>>> "computeHistoricalVolatiltiy": False, >>>>>>>>>>>>>>>>>> "tenantId": "380", >>>>>>>>>>>>>>>>>> "gridPoints": 149, >>>>>>>>>>>>>>>>>> "computeImpliedVolatiltiy": False, >>>>>>>>>>>>>>>>>> "runId": 3735, >>>>>>>>>>>>>>>>>> "timeSteps": 150, >>>>>>>>>>>>>>>>>> "optionTrades": [ >>>>>>>>>>>>>>>>>> { >>>>>>>>>>>>>>>>>> "underlyingPrice": 98.69, >>>>>>>>>>>>>>>>>> "refNo": "OPT-1135-GVA", >>>>>>>>>>>>>>>>>> "underlyingPriceUnit": "US cents/LB", >>>>>>>>>>>>>>>>>> "valueDate": "17-03-2022", >>>>>>>>>>>>>>>>>> "fixingStartDate":"01-05-2022", >>>>>>>>>>>>>>>>>> "pastFixings":0, >>>>>>>>>>>>>>>>>> "volatility": 0.6015, >>>>>>>>>>>>>>>>>> "openQuantity": 1, >>>>>>>>>>>>>>>>>> "strikePriceUnit": "US cents/LB", >>>>>>>>>>>>>>>>>> "optionType": "Call", >>>>>>>>>>>>>>>>>> "expiryDate": "31-05-2022", >>>>>>>>>>>>>>>>>> "exType": "asian", >>>>>>>>>>>>>>>>>> "riskFreeRate": 0.8080374999999999, >>>>>>>>>>>>>>>>>> "premium": 1, >>>>>>>>>>>>>>>>>> "portfolioId": 18209, >>>>>>>>>>>>>>>>>> "marketPremium": 11.42, >>>>>>>>>>>>>>>>>> "longShort": "Long", >>>>>>>>>>>>>>>>>> "optionInstrument": "EURO USD 1.105 Call", >>>>>>>>>>>>>>>>>> "asset": "EURO USD 1.105 Call", >>>>>>>>>>>>>>>>>> "portfolioName": "Option Trades", >>>>>>>>>>>>>>>>>> "scenarioId": 8356, >>>>>>>>>>>>>>>>>> "scenarioName": "Option Valuation - Greeks", >>>>>>>>>>>>>>>>>> "strikePrice": 95, >>>>>>>>>>>>>>>>>> "maturityInYears": 0.205479452 >>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>> ], >>>>>>>>>>>>>>>>>> "userId": "5263", >>>>>>>>>>>>>>>>>> "americanOptionsEngine": "CrankNicolson" >>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> opt = AsianOptionPrice(**settings["optionTrades"][0]) >>>>>>>>>>>>>>>>>> opt.evaluate_asian_npv() >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Wed, May 18, 2022 at 9:25 PM Ashish Bansal < >>>>>>>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi Jack, >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Please find attached the Asian option python code and >>>>>>>>>>>>>>>>>>> the option trade payload. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Thanks for your help, >>>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Wed, 18 May 2022 at 12:12, Jack G < >>>>>>>>>>>>>>>>>>> jac...@gm...> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Ashish, >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> I've just lifted the examples from your references >>>>>>>>>>>>>>>>>>>> directly for a discrete arithmetic Asian using the FD Asian engine and it >>>>>>>>>>>>>>>>>>>> is working for me - can you share the code you are using that breaks please? >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Best, >>>>>>>>>>>>>>>>>>>> Jack >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On Wed, 18 May 2022, 13:55 Ashish Bansal, < >>>>>>>>>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi all, >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Could somebody help with the asian options? We are >>>>>>>>>>>>>>>>>>>>> using FdBlackScholesAsianengine with DiscreteAveragingAsianOption. Online >>>>>>>>>>>>>>>>>>>>> references are given below. In DiscreteAveragingAsianOption, we need to >>>>>>>>>>>>>>>>>>>>> pass the past fixing which is suggested to be 0 for new trade. Whereas when >>>>>>>>>>>>>>>>>>>>> we are passing it as 0, we are getting the following error: >>>>>>>>>>>>>>>>>>>>> "QuantLib Error - Running average requires at least >>>>>>>>>>>>>>>>>>>>> one past fixing" >>>>>>>>>>>>>>>>>>>>> ref: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> https://quantlib-python-docs.readthedocs.io/en/latest/pricing_engines.html#fdblackscholesasianengine >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> https://quantlib-python-docs.readthedocs.io/en/latest/instruments/options.html?highlight=DiscreteAveragingAsianOption#ql.DiscreteAveragingAsianOption >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Queries: >>>>>>>>>>>>>>>>>>>>> 1. What is to be passed here for new trade if not 0? >>>>>>>>>>>>>>>>>>>>> 2. For trade which is mid of averaging and has few >>>>>>>>>>>>>>>>>>>>> past fixings, do we need to pass the count of past fixing or the actual >>>>>>>>>>>>>>>>>>>>> rates of the pastfixing as an array? >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Any help will be appreciated. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Thanks in advance >>>>>>>>>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>>>>>>>> QuantLib-users mailing list >>>>>>>>>>>>>>>>>>>>> Qua...@li... >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> https://lists.sourceforge.net/lists/listinfo/quantlib-users >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>>>> QuantLib-users mailing list >>>>>>>>>>>>>>>>> Qua...@li... >>>>>>>>>>>>>>>>> https://lists.sourceforge.net/lists/listinfo/quantlib-users >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> |
|
From: Arkadiy N. <ark...@gm...> - 2022-06-02 11:52:13
|
Hi Victoria, The default for this parameter is the very curve you are building. You’d set the parameter’s value explicitly in order to replicate a methodology used (the example may not too relevant for too long) to build USD LIBOR curve, where the discounting is done at SOFR (and, before that, at EFF OIS). Please check out section 2.2. of this paper for some background: Everything You Always Wanted to Know About Multiple Interest Rate Curve Bootstrapping But Were Afraid To Ask (free download from ssrn) Sent from my iPad > On Jun 2, 2022, at 6:02 AM, Victoria Titon <vic...@we...> wrote: > > > Hello, > > I saw we can precise a DiscountingCurve (YieldTermStructureHandle format) argument in the ql.SwapRateHelper function. > As it is not mandatory (the default value is an empty value), I don't understand which information does the function take from this argument? > Actually, if I put a yieldTermstructureHandle discounting curve, in what way the SwapHelper will change? > > Thanks in advance for your answer. > _______________________________________________ > QuantLib-users mailing list > Qua...@li... > https://lists.sourceforge.net/lists/listinfo/quantlib-users |
|
From: Giuseppe T. <tr...@gm...> - 2022-06-02 10:41:25
|
Hello Victoria, Relinkable handles are useful when you are instantiating objects that requires a Handle to something (a yield curve, a volatility structure...). You can relink the handle to another object without reinstantiating the object that requires it. For example say you want to observe the effect of different interpolations of the yield curve on the NPV of a swap. You can create two yield curves with the two interpolations and pass the Relinkable Handle to your pricing engine. This way you can just call NPV on your swap, relink the Handle to the second curve and call NPV again and check the difference. With a regular Handle you would have to reinstantiate your pricing engine with the Handle to the second curve, reset the new pricing engine to the swap and then recompute the NPV. Of course it's doable but think about the hassle if you have different instruments, different curves, volatility surfaces... Il Gio 2 Giu 2022, 12:17 Victoria Titon <vic...@we...> ha scritto: > Hello, > > I read some blog articles about the function > yts1=ql.RelinkableYieldTermStructureHandle and the method > yts1.linkTo(YieldTermStructureHandle2). > > I understand that it allows the yts1 to be updated according to another > yts2 (please correct me if I'm wrong). > > But I don't see the purpose of doing this: using yts1 and link it to yts2, > instead of using directly yts2? > > Thanks in advance for your answer. > _______________________________________________ > QuantLib-users mailing list > Qua...@li... > https://lists.sourceforge.net/lists/listinfo/quantlib-users > > |
|
From: Victoria T. <vic...@we...> - 2022-06-02 10:16:03
|
Hello, I read some blog articles about the function yts1=ql.RelinkableYieldTermStructureHandle and the method yts1.linkTo(YieldTermStructureHandle2). I understand that it allows the yts1 to be updated according to another yts2 (please correct me if I'm wrong). But I don't see the purpose of doing this: using yts1 and link it to yts2, instead of using directly yts2? Thanks in advance for your answer. |
|
From: Victoria T. <vic...@we...> - 2022-06-02 09:58:48
|
Hello, I saw we can precise a DiscountingCurve (YieldTermStructureHandle format) argument in the ql.SwapRateHelper function. As it is not mandatory (the default value is an empty value), I don't understand which information does the function take from this argument? Actually, if I put a yieldTermstructureHandle discounting curve, in what way the SwapHelper will change? Thanks in advance for your answer. |
|
From: Ashish B. <ash...@gm...> - 2022-06-02 05:23:20
|
That is great news. I have been waiting for TW engine for a long time :) . Special thanks to Fredrick (@gbfredrik) for adding it. When is v1.27 planned to be released? Hoping that it will be released on SWIG at the same time. Where can I read about other changes in 1.27 so that we can plan accordingly? Thanks Ashish On Thu, 2 Jun 2022 at 01:35, Luigi Ballabio <lui...@gm...> wrote: > Hello, > it does mention it now -- the Turnbull-Wakeman engine was added to the > repository less than a month ago and will be in release 1.27. It didn't > exist in release 1.17. > > Luigi > > > On Wed, Jun 1, 2022 at 7:55 PM Ashish Bansal <ash...@gm...> > wrote: > >> Luigi, >> >> You had given me the following link sometime back. It does mention about >> the Turnbull Wakeman model based on 2 moment matching: >> >> https://github.com/lballabio/QuantLib/blob/master/test-suite/asianoptions.cpp >> <ql/pricingengines/asian/turnbullwakemanasianengine.hpp> >> >> [image: image.png] >> Even the example is given in the above file. Although the asianoption is >> part of test-suite but the Turnbull...engine is part of main QL. Is it not >> part of SWIG? i tried in it in python but could not find it. >> >> How can I use this in python with QL v1.17? >> >> Regards, >> Ashish >> >> On Mon, 30 May 2022 at 19:39, Ashish Bansal <ash...@gm...> >> wrote: >> >>> Thanks for the responses. I am trying various papers to find the moment >>> matching for the asian options. I did find the calculation based on >>> Turnbull-Wakeman model here: >>> >>> https://osf.io/efq6a/download >>> >>> >>> I tried this but did not get good results for options expiring in a few >>> months. I will try some other source probably. >>> >>> >>> One last question, does QL's FdBlackScholesAsianengine with DiscreteAveragingAsianOption >>> adjust the valuation for trade which are in between the averaging period; >>> as mentioned on slide # 9 and 10 of this deck? >>> >>> >>> Regards, >>> >>> Ashish >>> >>> On Thu, 26 May 2022 at 13:24, Luigi Ballabio <lui...@gm...> >>> wrote: >>> >>>> I mean that the two engines give the same price, i.e. 6.09. I don't >>>> have info on moment matching. >>>> >>>> On Wed, May 25, 2022 at 6:51 PM Ashish Bansal <ash...@gm...> >>>> wrote: >>>> >>>>> By same price, you mean same as exchange i.e. 4.57. or same as aRA >>>>> parameter i.e. 6.09? >>>>> >>>>> Any guidance on moment matching? I could not find anything online >>>>> about it. >>>>> >>>>> Regards >>>>> Ashish >>>>> >>>>> On Wed, May 25, 2022, 7:02 PM Luigi Ballabio <lui...@gm...> >>>>> wrote: >>>>> >>>>>> Hi, >>>>>> no, the engine doesn't do moment matching. I don't think we have >>>>>> something ready to use for that in the library. >>>>>> As for the accumulator: I confirm it's the sum. If you create a >>>>>> virtual Python environment and install the latest QuantLib in it, you can >>>>>> try your shortened code with the other constructor for the Asian option >>>>>> (the one taking the list of fixings). It returns the same price. >>>>>> >>>>>> Luigi >>>>>> >>>>>> >>>>>> On Wed, May 25, 2022 at 2:46 PM Ashish Bansal < >>>>>> ash...@gm...> wrote: >>>>>> >>>>>>> Hi Luigi, >>>>>>> >>>>>>> One question about the QL calculation: Does QL code for the Asian >>>>>>> option include *moment matching *of the volatility or do we need to >>>>>>> do that before passing to the DiscAvAsOption? >>>>>>> >>>>>>> Regarding the code, I had attached the full code from our system in >>>>>>> my previous email, attaching here too. The shortened version of the code, >>>>>>> containing only the QL interaction and excluding excess processing, is also >>>>>>> attached here. It includes the trade parameters we are using to evaluate >>>>>>> the Asian option. Strangely, the value is coming zero with short-code but >>>>>>> with full code in our system, we are getting the values. >>>>>>> >>>>>>> Following is the NPV that we are getting in our system (using full >>>>>>> code) for our trade which has averaging period from 1st March to 31st March >>>>>>> 2022 and the market traded premium of 4.56: >>>>>>> arithmeticRunningAccumulator NPV >>>>>>> 0 4.5711 >>>>>>> 1302.88 6.09 >>>>>>> >>>>>>> Thanks in advance for help. >>>>>>> >>>>>>> PS: We are using QL1.17 and the vols are sourced from Reuters could >>>>>>> be different from implied in the market traded premium. >>>>>>> >>>>>>> Regards, >>>>>>> Ashish >>>>>>> >>>>>>> On Mon, 23 May 2022 at 22:26, Luigi Ballabio < >>>>>>> lui...@gm...> wrote: >>>>>>> >>>>>>>> May you send sample code and the value of the fixings for one of >>>>>>>> those options? Thanks! >>>>>>>> >>>>>>>> Luigi >>>>>>>> >>>>>>>> >>>>>>>> On Mon, May 23, 2022 at 8:32 AM Ashish Bansal < >>>>>>>> ash...@gm...> wrote: >>>>>>>> >>>>>>>>> Luigi, >>>>>>>>> >>>>>>>>> We ran the asian code, which i sent earlier for a couple of asian >>>>>>>>> options traded on exchange. We got prices very close to traded prices when >>>>>>>>> we used the value of running accumulator as 1 for march option being valued >>>>>>>>> on 17th with past fixing count as 12. But when we used the sum of past >>>>>>>>> fixing prices i.e. 1302.88 we got a very different number like 6.09 against >>>>>>>>> 4.57 earlier and 14.11 against 12.39 earlier. >>>>>>>>> >>>>>>>>> Just want to confirm if i am missing something about running >>>>>>>>> accumulator and should it be really the sum of all past fixings? >>>>>>>>> >>>>>>>>> Thanks for help in advance. >>>>>>>>> Ashish >>>>>>>>> >>>>>>>>> On Fri, 20 May 2022 at 14:58, Ashish Bansal < >>>>>>>>> ash...@gm...> wrote: >>>>>>>>> >>>>>>>>>> Ok understood. thanks. >>>>>>>>>> >>>>>>>>>> On Fri, 20 May 2022 at 14:46, Luigi Ballabio < >>>>>>>>>> lui...@gm...> wrote: >>>>>>>>>> >>>>>>>>>>> It would be the sum of past fixings; for three past fixings of >>>>>>>>>>> 100.2, 101.3 and 94.6 it would be 296.1. >>>>>>>>>>> >>>>>>>>>>> Luigi >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Thu, May 19, 2022 at 12:37 PM Ashish Bansal < >>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>> >>>>>>>>>>>> Thanks, Luigi for the suggestion. After taking the running >>>>>>>>>>>> accumulator, we are able to generate the numbers. What exactly should be >>>>>>>>>>>> passed here? The average price of past fixings or just 1 when the trade is >>>>>>>>>>>> priced during averaging period? >>>>>>>>>>>> >>>>>>>>>>>> Thanks for help. >>>>>>>>>>>> >>>>>>>>>>>> Ashish >>>>>>>>>>>> >>>>>>>>>>>> On Wed, 18 May 2022 at 21:17, Luigi Ballabio < >>>>>>>>>>>> lui...@gm...> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> I don't have a 1.7 version to try it, but the check is the one >>>>>>>>>>>>> at < >>>>>>>>>>>>> https://github.com/lballabio/QuantLib/blob/QuantLib-v1.7/ql/pricingengines/asian/fdblackscholesasianengine.cpp#L51-L53>, >>>>>>>>>>>>> suggesting that your running accumulator should be 0 (which makes sense, >>>>>>>>>>>>> because you're using arithmetic average, i.e., a sum, and if you don't have >>>>>>>>>>>>> any fixings yet the sum should be 0.) >>>>>>>>>>>>> Your default seems to be 1 instead. >>>>>>>>>>>>> >>>>>>>>>>>>> Luigi >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Wed, May 18, 2022 at 5:17 PM Ashish Bansal < >>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> Luigi, >>>>>>>>>>>>>> >>>>>>>>>>>>>> Our code is not too much but we are using >>>>>>>>>>>>>> deprecated functions like FDEuropeanEngine and FDAmericanEngine. >>>>>>>>>>>>>> Not sure if using new function called >>>>>>>>>>>>>> FdBlackScholesVanillaEngine has any change in the >>>>>>>>>>>>>> calculation that our code will have an impact. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Can we use the DiscreteAveragingAsianOption without the >>>>>>>>>>>>>> overloaded parameter of pastfixings under 1.7? >>>>>>>>>>>>>> >>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Wed, 18 May 2022 at 20:00, Luigi Ballabio < >>>>>>>>>>>>>> lui...@gm...> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi — it could be. Any particular reason you're still using >>>>>>>>>>>>>>> a version from 4 years ago? If you have a substantial amount of code that >>>>>>>>>>>>>>> depends on QuantLib, it might require some work to update because some >>>>>>>>>>>>>>> methods were deprecated and then removed in the meantime; and of course >>>>>>>>>>>>>>> you'll probably have some validation process in place when updating, so >>>>>>>>>>>>>>> that's work too. But on the other hand, you're missing 4 years worth of >>>>>>>>>>>>>>> bug fixings... >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Luigi >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Wed, May 18, 2022 at 4:19 PM Ashish Bansal < >>>>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> We tried again and got the same error. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Could it be due to the old version (1.7) we are using? I >>>>>>>>>>>>>>>> see in the release notes of Apr-2021 that the overload for past fixing was >>>>>>>>>>>>>>>> added: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> - Added an overloaded constructor for Asian options >>>>>>>>>>>>>>>> that takes all past fixings and thus allows to reprice them correctly when >>>>>>>>>>>>>>>> the evaluation date changes (thanks to Jack Gillett). >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Wed, 18 May 2022 at 19:14, Jack G < >>>>>>>>>>>>>>>> jac...@gm...> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi Ashish, >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I have a better answer for you with a screenshot awaiting >>>>>>>>>>>>>>>>> moderation as it's quite large, but in the meantime, I was able to run your >>>>>>>>>>>>>>>>> code without problems using the python at the bottom of this email >>>>>>>>>>>>>>>>> (although I didn't check the numbers). >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> If there is something you're doing specifically to >>>>>>>>>>>>>>>>> generate the error, could you please attach a minimal reproduction of it? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Best, >>>>>>>>>>>>>>>>> Jack >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> import QuantLib as ql >>>>>>>>>>>>>>>>> from copy import deepcopy >>>>>>>>>>>>>>>>> from datetime import datetime >>>>>>>>>>>>>>>>> from datetime import timedelta >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> # DEFAULT_PERIODS = [ql.Period(f"{i}d") for i in >>>>>>>>>>>>>>>>> range(0,31)] >>>>>>>>>>>>>>>>> DEFAULT_PERIODS = [ql.Period("6M"), ql.Period("12M"), >>>>>>>>>>>>>>>>> ql.Period("18M"), ql.Period("24M")] >>>>>>>>>>>>>>>>> DEFAULT_tGRID = 100 >>>>>>>>>>>>>>>>> DEFAULT_xGRID = 100 >>>>>>>>>>>>>>>>> DEFAULT_aGRID = 50 >>>>>>>>>>>>>>>>> DEFAULT_aRA = 1 # arithmeticRunningAccumulator >>>>>>>>>>>>>>>>> DEFAULT_PASTFIXINGS = 1 >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> class AsianOptionPrice: >>>>>>>>>>>>>>>>> def __init__(self, **x): >>>>>>>>>>>>>>>>> for k, v in x.items(): >>>>>>>>>>>>>>>>> setattr(self, k, v) >>>>>>>>>>>>>>>>> self.tGrid = x.get("tGrid", DEFAULT_tGRID) >>>>>>>>>>>>>>>>> self.xGrid = x.get("xGrid", DEFAULT_xGRID) >>>>>>>>>>>>>>>>> self.aGrid = x.get("aGrid", DEFAULT_aGRID) >>>>>>>>>>>>>>>>> self.periods = x.get("periods", DEFAULT_PERIODS) >>>>>>>>>>>>>>>>> self.pastFixings = x.get("pastFixings", >>>>>>>>>>>>>>>>> DEFAULT_PASTFIXINGS) >>>>>>>>>>>>>>>>> self.aRA = x.get("arithmeticRunningAccumulator", >>>>>>>>>>>>>>>>> DEFAULT_aRA) >>>>>>>>>>>>>>>>> self.keyList = [k for k, v in x.items()] >>>>>>>>>>>>>>>>> self.dist = 10**(-2) >>>>>>>>>>>>>>>>> self.date_format = "%d-%m-%Y" >>>>>>>>>>>>>>>>> self.value_date = ql.DateParser.parseFormatted( >>>>>>>>>>>>>>>>> self.valueDate, '%d-%m-%Y') >>>>>>>>>>>>>>>>> self.expiry_date = ql.DateParser.parseFormatted( >>>>>>>>>>>>>>>>> self.expiryDate, '%d-%m-%Y') >>>>>>>>>>>>>>>>> ql.Settings.instance().evaluationDate = >>>>>>>>>>>>>>>>> self.value_date >>>>>>>>>>>>>>>>> self.exDay = >>>>>>>>>>>>>>>>> ql.DateParser.parseFormatted(self.expiryDate, '%d-%m-%Y') >>>>>>>>>>>>>>>>> # Volatility input is required for running the >>>>>>>>>>>>>>>>> computing implied volatility function. This volatility is NOT used in the >>>>>>>>>>>>>>>>> implied volatility calculation. >>>>>>>>>>>>>>>>> self.vol_for_iv_calc = 0.10 >>>>>>>>>>>>>>>>> self.IV = None >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> def >>>>>>>>>>>>>>>>> generate_fixture_dates(self,start_date,end_date,period): >>>>>>>>>>>>>>>>> schedule = ql.MakeSchedule(start_date, end_date, >>>>>>>>>>>>>>>>> period) >>>>>>>>>>>>>>>>> fixture_dates = [_date for _date in schedule if >>>>>>>>>>>>>>>>> _date.weekday() not in [1,7]] >>>>>>>>>>>>>>>>> return fixture_dates >>>>>>>>>>>>>>>>> def asian(self): >>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>> arithmeticRunningAccumulator(aRA) >>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>> arithmeticRunningAccumulator = self.aRA >>>>>>>>>>>>>>>>> pastFixings = self.pastFixings >>>>>>>>>>>>>>>>> print(pastFixings) >>>>>>>>>>>>>>>>> option_type = self.optionType.lower() >>>>>>>>>>>>>>>>> if option_type not in ["call", "put"]: >>>>>>>>>>>>>>>>> raise Exception( >>>>>>>>>>>>>>>>> f"Option Type is Neither Call nor Put, >>>>>>>>>>>>>>>>> Option type is {option_type}") >>>>>>>>>>>>>>>>> option_type = ql.Option.Call if option_type == >>>>>>>>>>>>>>>>> "call" else ql.Option.Put >>>>>>>>>>>>>>>>> strike = self.strikePrice >>>>>>>>>>>>>>>>> today = self.value_date >>>>>>>>>>>>>>>>> print(today) >>>>>>>>>>>>>>>>> fixingStartDate >>>>>>>>>>>>>>>>> =ql.DateParser.parseFormatted(self.fixingStartDate, '%d-%m-%Y') >>>>>>>>>>>>>>>>> print("#"*40,fixingStartDate) >>>>>>>>>>>>>>>>> periods = self.periods >>>>>>>>>>>>>>>>> asianFutureFixingDates = >>>>>>>>>>>>>>>>> self.generate_fixture_dates(fixingStartDate,self.expiry_date,ql.Period("1d")) >>>>>>>>>>>>>>>>> print("#"*40,asianFutureFixingDates) >>>>>>>>>>>>>>>>> asianExpiryDate = self.expiry_date >>>>>>>>>>>>>>>>> vanillaPayoff = ql.PlainVanillaPayoff(option_type, >>>>>>>>>>>>>>>>> strike) >>>>>>>>>>>>>>>>> europeanExercise = >>>>>>>>>>>>>>>>> ql.EuropeanExercise(asianExpiryDate) >>>>>>>>>>>>>>>>> arithmeticAverage = ql.Average().Arithmetic >>>>>>>>>>>>>>>>> discreteArithmeticAsianOption = >>>>>>>>>>>>>>>>> ql.DiscreteAveragingAsianOption( >>>>>>>>>>>>>>>>> arithmeticAverage, >>>>>>>>>>>>>>>>> arithmeticRunningAccumulator, pastFixings, asianFutureFixingDates, >>>>>>>>>>>>>>>>> vanillaPayoff, europeanExercise) >>>>>>>>>>>>>>>>> return discreteArithmeticAsianOption >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> def create_arg_list(self, Option=None, >>>>>>>>>>>>>>>>> compute_implied_vol=None, implied_vol_am_put=None): >>>>>>>>>>>>>>>>> ''' >>>>>>>>>>>>>>>>> The arguments with disturbances added. Will be >>>>>>>>>>>>>>>>> used for calculation of Greeks >>>>>>>>>>>>>>>>> using numerical differentiation. >>>>>>>>>>>>>>>>> Creating a dictionary of arguments that will >>>>>>>>>>>>>>>>> be used for option price and greeks calculation. >>>>>>>>>>>>>>>>> ''' >>>>>>>>>>>>>>>>> self.riskFreeRate = self.riskFreeRate/100 >>>>>>>>>>>>>>>>> originalDict_ = {k: getattr(self, k) for k in >>>>>>>>>>>>>>>>> self.keyList} >>>>>>>>>>>>>>>>> ListDict = [] >>>>>>>>>>>>>>>>> for i in range(4): >>>>>>>>>>>>>>>>> ListDict.append(deepcopy(originalDict_)) >>>>>>>>>>>>>>>>> ListDict[1]['riskFreeRate'] = self.riskFreeRate + >>>>>>>>>>>>>>>>> self.dist >>>>>>>>>>>>>>>>> ListDict[2]['volatility'] = self.volatility + >>>>>>>>>>>>>>>>> self.dist >>>>>>>>>>>>>>>>> ListDict[3]['expiryDate'] = (datetime.strptime( >>>>>>>>>>>>>>>>> self.expiryDate, self.date_format) - >>>>>>>>>>>>>>>>> timedelta(days=1)).strftime(self.date_format) >>>>>>>>>>>>>>>>> print(ListDict) >>>>>>>>>>>>>>>>> return(ListDict) >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> def bs_process(self, create_process_for_iv=None, >>>>>>>>>>>>>>>>> use_IV=None): >>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>> Creating the Black-Scholes process for option >>>>>>>>>>>>>>>>> valuation. >>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>> riskFreeTS = ql.YieldTermStructureHandle( >>>>>>>>>>>>>>>>> ql.FlatForward(self.value_date, >>>>>>>>>>>>>>>>> self.riskFreeRate, ql.Actual365Fixed())) >>>>>>>>>>>>>>>>> dividendTS = ql.YieldTermStructureHandle( >>>>>>>>>>>>>>>>> ql.FlatForward(self.value_date, 0, >>>>>>>>>>>>>>>>> ql.Actual365Fixed())) >>>>>>>>>>>>>>>>> volatility = >>>>>>>>>>>>>>>>> ql.BlackVolTermStructureHandle(ql.BlackConstantVol( >>>>>>>>>>>>>>>>> self.value_date, ql.NullCalendar(), >>>>>>>>>>>>>>>>> self.volatility, ql.Actual365Fixed())) >>>>>>>>>>>>>>>>> initialValue = >>>>>>>>>>>>>>>>> ql.QuoteHandle(ql.SimpleQuote(self.underlyingPrice)) >>>>>>>>>>>>>>>>> process = ql.BlackScholesMertonProcess( >>>>>>>>>>>>>>>>> initialValue, dividendTS, riskFreeTS, >>>>>>>>>>>>>>>>> volatility) >>>>>>>>>>>>>>>>> return(process) >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> def evaluate(self, Option=None, >>>>>>>>>>>>>>>>> compute_implied_vol=None): >>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>> Call the relevant option based on the input. >>>>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>>>> self.riskFreeRate = self.riskFreeRate/100 >>>>>>>>>>>>>>>>> res = None >>>>>>>>>>>>>>>>> option = AsianOptionPrice.asian(self) >>>>>>>>>>>>>>>>> if compute_implied_vol == True: >>>>>>>>>>>>>>>>> # create Black Scholes process using IV. >>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>>>> use_IV=True) >>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>>>> process, tGrid=self.tGrid, >>>>>>>>>>>>>>>>> xGrid=self.xGrid, aGrid=self.aGrid) >>>>>>>>>>>>>>>>> option.setPricingEngine(engine) >>>>>>>>>>>>>>>>> res = {'value': option.NPV(), >>>>>>>>>>>>>>>>> 'impliedVolatility': self.IV} >>>>>>>>>>>>>>>>> else: >>>>>>>>>>>>>>>>> # Create Black Scholes process using HV. >>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>>>> use_IV=False) >>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>>>> process, tGrid=self.tGrid, >>>>>>>>>>>>>>>>> xGrid=self.xGrid, aGrid=self.aGrid) >>>>>>>>>>>>>>>>> option.setPricingEngine(engine) >>>>>>>>>>>>>>>>> res = {'value': option.NPV()} >>>>>>>>>>>>>>>>> return res >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> def evaluate_asian_npv(self): >>>>>>>>>>>>>>>>> Option = AsianOptionPrice.asian(self) >>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>>>> use_IV=False) >>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>>>> process, tGrid=self.tGrid, xGrid=self.xGrid, >>>>>>>>>>>>>>>>> aGrid=self.aGrid) >>>>>>>>>>>>>>>>> Option.setPricingEngine(engine) >>>>>>>>>>>>>>>>> res = Option.NPV() >>>>>>>>>>>>>>>>> return(res) >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> def calculate_greeks(self, Option=None, >>>>>>>>>>>>>>>>> compute_implied_vol=None): >>>>>>>>>>>>>>>>> today = self.value_date >>>>>>>>>>>>>>>>> Option = AsianOptionPrice.asian(self) >>>>>>>>>>>>>>>>> if compute_implied_vol == True: >>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>>>> use_IV=True) >>>>>>>>>>>>>>>>> else: >>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>>>> use_IV=False) >>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>>>> process, tGrid=self.tGrid, xGrid=self.xGrid, >>>>>>>>>>>>>>>>> aGrid=self.aGrid) >>>>>>>>>>>>>>>>> Option.setPricingEngine(engine) >>>>>>>>>>>>>>>>> option_greeks_ = {"delta": Option.delta(), >>>>>>>>>>>>>>>>> "gamma": Option.gamma( >>>>>>>>>>>>>>>>> )} >>>>>>>>>>>>>>>>> ArgmntList = AsianOptionPrice.create_arg_list( >>>>>>>>>>>>>>>>> self, Option, compute_implied_vol=True, >>>>>>>>>>>>>>>>> implied_vol_am_put=self.volatility) >>>>>>>>>>>>>>>>> DisturbedPrices = [] >>>>>>>>>>>>>>>>> arg_keys = ['Price', 'PRup', 'PVup', 'PTup'] >>>>>>>>>>>>>>>>> for i in range(4): >>>>>>>>>>>>>>>>> DisturbedPrices.append(eval( >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> "AsianOptionPrice(**ArgmntList[i]).evaluate_asian_npv()")) >>>>>>>>>>>>>>>>> print(DisturbedPrices) >>>>>>>>>>>>>>>>> PricesDistrbd = dict(zip(arg_keys, >>>>>>>>>>>>>>>>> DisturbedPrices)) >>>>>>>>>>>>>>>>> Rho = (PricesDistrbd['PRup'] - >>>>>>>>>>>>>>>>> PricesDistrbd['Price'])/(self.dist*100) >>>>>>>>>>>>>>>>> vega = (PricesDistrbd['PVup'] - >>>>>>>>>>>>>>>>> PricesDistrbd['Price'])/(self.dist*100) >>>>>>>>>>>>>>>>> thetaDay = (PricesDistrbd['PTup'] - >>>>>>>>>>>>>>>>> PricesDistrbd['Price']) >>>>>>>>>>>>>>>>> option_greeks_.update({'rho': Rho, 'vega': vega, >>>>>>>>>>>>>>>>> 'theta': thetaDay}) >>>>>>>>>>>>>>>>> return option_greeks_ >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> settings = { >>>>>>>>>>>>>>>>> "computeHistoricalVolatiltiy": False, >>>>>>>>>>>>>>>>> "tenantId": "380", >>>>>>>>>>>>>>>>> "gridPoints": 149, >>>>>>>>>>>>>>>>> "computeImpliedVolatiltiy": False, >>>>>>>>>>>>>>>>> "runId": 3735, >>>>>>>>>>>>>>>>> "timeSteps": 150, >>>>>>>>>>>>>>>>> "optionTrades": [ >>>>>>>>>>>>>>>>> { >>>>>>>>>>>>>>>>> "underlyingPrice": 98.69, >>>>>>>>>>>>>>>>> "refNo": "OPT-1135-GVA", >>>>>>>>>>>>>>>>> "underlyingPriceUnit": "US cents/LB", >>>>>>>>>>>>>>>>> "valueDate": "17-03-2022", >>>>>>>>>>>>>>>>> "fixingStartDate":"01-05-2022", >>>>>>>>>>>>>>>>> "pastFixings":0, >>>>>>>>>>>>>>>>> "volatility": 0.6015, >>>>>>>>>>>>>>>>> "openQuantity": 1, >>>>>>>>>>>>>>>>> "strikePriceUnit": "US cents/LB", >>>>>>>>>>>>>>>>> "optionType": "Call", >>>>>>>>>>>>>>>>> "expiryDate": "31-05-2022", >>>>>>>>>>>>>>>>> "exType": "asian", >>>>>>>>>>>>>>>>> "riskFreeRate": 0.8080374999999999, >>>>>>>>>>>>>>>>> "premium": 1, >>>>>>>>>>>>>>>>> "portfolioId": 18209, >>>>>>>>>>>>>>>>> "marketPremium": 11.42, >>>>>>>>>>>>>>>>> "longShort": "Long", >>>>>>>>>>>>>>>>> "optionInstrument": "EURO USD 1.105 Call", >>>>>>>>>>>>>>>>> "asset": "EURO USD 1.105 Call", >>>>>>>>>>>>>>>>> "portfolioName": "Option Trades", >>>>>>>>>>>>>>>>> "scenarioId": 8356, >>>>>>>>>>>>>>>>> "scenarioName": "Option Valuation - Greeks", >>>>>>>>>>>>>>>>> "strikePrice": 95, >>>>>>>>>>>>>>>>> "maturityInYears": 0.205479452 >>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>> ], >>>>>>>>>>>>>>>>> "userId": "5263", >>>>>>>>>>>>>>>>> "americanOptionsEngine": "CrankNicolson" >>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> opt = AsianOptionPrice(**settings["optionTrades"][0]) >>>>>>>>>>>>>>>>> opt.evaluate_asian_npv() >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Wed, May 18, 2022 at 9:25 PM Ashish Bansal < >>>>>>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi Jack, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Please find attached the Asian option python code and the >>>>>>>>>>>>>>>>>> option trade payload. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Thanks for your help, >>>>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Wed, 18 May 2022 at 12:12, Jack G < >>>>>>>>>>>>>>>>>> jac...@gm...> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi Ashish, >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> I've just lifted the examples from your references >>>>>>>>>>>>>>>>>>> directly for a discrete arithmetic Asian using the FD Asian engine and it >>>>>>>>>>>>>>>>>>> is working for me - can you share the code you are using that breaks please? >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Best, >>>>>>>>>>>>>>>>>>> Jack >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Wed, 18 May 2022, 13:55 Ashish Bansal, < >>>>>>>>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi all, >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Could somebody help with the asian options? We are >>>>>>>>>>>>>>>>>>>> using FdBlackScholesAsianengine with DiscreteAveragingAsianOption. Online >>>>>>>>>>>>>>>>>>>> references are given below. In DiscreteAveragingAsianOption, we need to >>>>>>>>>>>>>>>>>>>> pass the past fixing which is suggested to be 0 for new trade. Whereas when >>>>>>>>>>>>>>>>>>>> we are passing it as 0, we are getting the following error: >>>>>>>>>>>>>>>>>>>> "QuantLib Error - Running average requires at least one >>>>>>>>>>>>>>>>>>>> past fixing" >>>>>>>>>>>>>>>>>>>> ref: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> https://quantlib-python-docs.readthedocs.io/en/latest/pricing_engines.html#fdblackscholesasianengine >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> https://quantlib-python-docs.readthedocs.io/en/latest/instruments/options.html?highlight=DiscreteAveragingAsianOption#ql.DiscreteAveragingAsianOption >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Queries: >>>>>>>>>>>>>>>>>>>> 1. What is to be passed here for new trade if not 0? >>>>>>>>>>>>>>>>>>>> 2. For trade which is mid of averaging and has few past >>>>>>>>>>>>>>>>>>>> fixings, do we need to pass the count of past fixing or the actual rates of >>>>>>>>>>>>>>>>>>>> the pastfixing as an array? >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Any help will be appreciated. >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Thanks in advance >>>>>>>>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>>>>>>> QuantLib-users mailing list >>>>>>>>>>>>>>>>>>>> Qua...@li... >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> https://lists.sourceforge.net/lists/listinfo/quantlib-users >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>>> QuantLib-users mailing list >>>>>>>>>>>>>>>> Qua...@li... >>>>>>>>>>>>>>>> https://lists.sourceforge.net/lists/listinfo/quantlib-users >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> |
|
From: Luigi B. <lui...@gm...> - 2022-06-01 20:05:17
|
Hello,
it does mention it now -- the Turnbull-Wakeman engine was added to the
repository less than a month ago and will be in release 1.27. It didn't
exist in release 1.17.
Luigi
On Wed, Jun 1, 2022 at 7:55 PM Ashish Bansal <ash...@gm...>
wrote:
> Luigi,
>
> You had given me the following link sometime back. It does mention about
> the Turnbull Wakeman model based on 2 moment matching:
>
> https://github.com/lballabio/QuantLib/blob/master/test-suite/asianoptions.cpp
> <ql/pricingengines/asian/turnbullwakemanasianengine.hpp>
>
> [image: image.png]
> Even the example is given in the above file. Although the asianoption is
> part of test-suite but the Turnbull...engine is part of main QL. Is it not
> part of SWIG? i tried in it in python but could not find it.
>
> How can I use this in python with QL v1.17?
>
> Regards,
> Ashish
>
> On Mon, 30 May 2022 at 19:39, Ashish Bansal <ash...@gm...>
> wrote:
>
>> Thanks for the responses. I am trying various papers to find the moment
>> matching for the asian options. I did find the calculation based on
>> Turnbull-Wakeman model here:
>>
>> https://osf.io/efq6a/download
>>
>>
>> I tried this but did not get good results for options expiring in a few
>> months. I will try some other source probably.
>>
>>
>> One last question, does QL's FdBlackScholesAsianengine with DiscreteAveragingAsianOption
>> adjust the valuation for trade which are in between the averaging period;
>> as mentioned on slide # 9 and 10 of this deck?
>>
>>
>> Regards,
>>
>> Ashish
>>
>> On Thu, 26 May 2022 at 13:24, Luigi Ballabio <lui...@gm...>
>> wrote:
>>
>>> I mean that the two engines give the same price, i.e. 6.09. I don't
>>> have info on moment matching.
>>>
>>> On Wed, May 25, 2022 at 6:51 PM Ashish Bansal <ash...@gm...>
>>> wrote:
>>>
>>>> By same price, you mean same as exchange i.e. 4.57. or same as aRA
>>>> parameter i.e. 6.09?
>>>>
>>>> Any guidance on moment matching? I could not find anything online about
>>>> it.
>>>>
>>>> Regards
>>>> Ashish
>>>>
>>>> On Wed, May 25, 2022, 7:02 PM Luigi Ballabio <lui...@gm...>
>>>> wrote:
>>>>
>>>>> Hi,
>>>>> no, the engine doesn't do moment matching. I don't think we have
>>>>> something ready to use for that in the library.
>>>>> As for the accumulator: I confirm it's the sum. If you create a
>>>>> virtual Python environment and install the latest QuantLib in it, you can
>>>>> try your shortened code with the other constructor for the Asian option
>>>>> (the one taking the list of fixings). It returns the same price.
>>>>>
>>>>> Luigi
>>>>>
>>>>>
>>>>> On Wed, May 25, 2022 at 2:46 PM Ashish Bansal <ash...@gm...>
>>>>> wrote:
>>>>>
>>>>>> Hi Luigi,
>>>>>>
>>>>>> One question about the QL calculation: Does QL code for the Asian
>>>>>> option include *moment matching *of the volatility or do we need to
>>>>>> do that before passing to the DiscAvAsOption?
>>>>>>
>>>>>> Regarding the code, I had attached the full code from our system in
>>>>>> my previous email, attaching here too. The shortened version of the code,
>>>>>> containing only the QL interaction and excluding excess processing, is also
>>>>>> attached here. It includes the trade parameters we are using to evaluate
>>>>>> the Asian option. Strangely, the value is coming zero with short-code but
>>>>>> with full code in our system, we are getting the values.
>>>>>>
>>>>>> Following is the NPV that we are getting in our system (using full
>>>>>> code) for our trade which has averaging period from 1st March to 31st March
>>>>>> 2022 and the market traded premium of 4.56:
>>>>>> arithmeticRunningAccumulator NPV
>>>>>> 0 4.5711
>>>>>> 1302.88 6.09
>>>>>>
>>>>>> Thanks in advance for help.
>>>>>>
>>>>>> PS: We are using QL1.17 and the vols are sourced from Reuters could
>>>>>> be different from implied in the market traded premium.
>>>>>>
>>>>>> Regards,
>>>>>> Ashish
>>>>>>
>>>>>> On Mon, 23 May 2022 at 22:26, Luigi Ballabio <
>>>>>> lui...@gm...> wrote:
>>>>>>
>>>>>>> May you send sample code and the value of the fixings for one of
>>>>>>> those options? Thanks!
>>>>>>>
>>>>>>> Luigi
>>>>>>>
>>>>>>>
>>>>>>> On Mon, May 23, 2022 at 8:32 AM Ashish Bansal <
>>>>>>> ash...@gm...> wrote:
>>>>>>>
>>>>>>>> Luigi,
>>>>>>>>
>>>>>>>> We ran the asian code, which i sent earlier for a couple of asian
>>>>>>>> options traded on exchange. We got prices very close to traded prices when
>>>>>>>> we used the value of running accumulator as 1 for march option being valued
>>>>>>>> on 17th with past fixing count as 12. But when we used the sum of past
>>>>>>>> fixing prices i.e. 1302.88 we got a very different number like 6.09 against
>>>>>>>> 4.57 earlier and 14.11 against 12.39 earlier.
>>>>>>>>
>>>>>>>> Just want to confirm if i am missing something about running
>>>>>>>> accumulator and should it be really the sum of all past fixings?
>>>>>>>>
>>>>>>>> Thanks for help in advance.
>>>>>>>> Ashish
>>>>>>>>
>>>>>>>> On Fri, 20 May 2022 at 14:58, Ashish Bansal <
>>>>>>>> ash...@gm...> wrote:
>>>>>>>>
>>>>>>>>> Ok understood. thanks.
>>>>>>>>>
>>>>>>>>> On Fri, 20 May 2022 at 14:46, Luigi Ballabio <
>>>>>>>>> lui...@gm...> wrote:
>>>>>>>>>
>>>>>>>>>> It would be the sum of past fixings; for three past fixings of
>>>>>>>>>> 100.2, 101.3 and 94.6 it would be 296.1.
>>>>>>>>>>
>>>>>>>>>> Luigi
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Thu, May 19, 2022 at 12:37 PM Ashish Bansal <
>>>>>>>>>> ash...@gm...> wrote:
>>>>>>>>>>
>>>>>>>>>>> Thanks, Luigi for the suggestion. After taking the running
>>>>>>>>>>> accumulator, we are able to generate the numbers. What exactly should be
>>>>>>>>>>> passed here? The average price of past fixings or just 1 when the trade is
>>>>>>>>>>> priced during averaging period?
>>>>>>>>>>>
>>>>>>>>>>> Thanks for help.
>>>>>>>>>>>
>>>>>>>>>>> Ashish
>>>>>>>>>>>
>>>>>>>>>>> On Wed, 18 May 2022 at 21:17, Luigi Ballabio <
>>>>>>>>>>> lui...@gm...> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> I don't have a 1.7 version to try it, but the check is the one
>>>>>>>>>>>> at <
>>>>>>>>>>>> https://github.com/lballabio/QuantLib/blob/QuantLib-v1.7/ql/pricingengines/asian/fdblackscholesasianengine.cpp#L51-L53>,
>>>>>>>>>>>> suggesting that your running accumulator should be 0 (which makes sense,
>>>>>>>>>>>> because you're using arithmetic average, i.e., a sum, and if you don't have
>>>>>>>>>>>> any fixings yet the sum should be 0.)
>>>>>>>>>>>> Your default seems to be 1 instead.
>>>>>>>>>>>>
>>>>>>>>>>>> Luigi
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>> On Wed, May 18, 2022 at 5:17 PM Ashish Bansal <
>>>>>>>>>>>> ash...@gm...> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> Luigi,
>>>>>>>>>>>>>
>>>>>>>>>>>>> Our code is not too much but we are using deprecated functions
>>>>>>>>>>>>> like FDEuropeanEngine and FDAmericanEngine. Not sure if
>>>>>>>>>>>>> using new function called FdBlackScholesVanillaEngine has any
>>>>>>>>>>>>> change in the calculation that our code will have an impact.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Can we use the DiscreteAveragingAsianOption without the
>>>>>>>>>>>>> overloaded parameter of pastfixings under 1.7?
>>>>>>>>>>>>>
>>>>>>>>>>>>> Ashish
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Wed, 18 May 2022 at 20:00, Luigi Ballabio <
>>>>>>>>>>>>> lui...@gm...> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Hi — it could be. Any particular reason you're still using
>>>>>>>>>>>>>> a version from 4 years ago? If you have a substantial amount of code that
>>>>>>>>>>>>>> depends on QuantLib, it might require some work to update because some
>>>>>>>>>>>>>> methods were deprecated and then removed in the meantime; and of course
>>>>>>>>>>>>>> you'll probably have some validation process in place when updating, so
>>>>>>>>>>>>>> that's work too. But on the other hand, you're missing 4 years worth of
>>>>>>>>>>>>>> bug fixings...
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Luigi
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> On Wed, May 18, 2022 at 4:19 PM Ashish Bansal <
>>>>>>>>>>>>>> ash...@gm...> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> We tried again and got the same error.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Could it be due to the old version (1.7) we are using? I see
>>>>>>>>>>>>>>> in the release notes of Apr-2021 that the overload for past fixing was
>>>>>>>>>>>>>>> added:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> - Added an overloaded constructor for Asian options that
>>>>>>>>>>>>>>> takes all past fixings and thus allows to reprice them correctly when the
>>>>>>>>>>>>>>> evaluation date changes (thanks to Jack Gillett).
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Ashish
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Wed, 18 May 2022 at 19:14, Jack G <
>>>>>>>>>>>>>>> jac...@gm...> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Hi Ashish,
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I have a better answer for you with a screenshot awaiting
>>>>>>>>>>>>>>>> moderation as it's quite large, but in the meantime, I was able to run your
>>>>>>>>>>>>>>>> code without problems using the python at the bottom of this email
>>>>>>>>>>>>>>>> (although I didn't check the numbers).
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> If there is something you're doing specifically to generate
>>>>>>>>>>>>>>>> the error, could you please attach a minimal reproduction of it?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Best,
>>>>>>>>>>>>>>>> Jack
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> import QuantLib as ql
>>>>>>>>>>>>>>>> from copy import deepcopy
>>>>>>>>>>>>>>>> from datetime import datetime
>>>>>>>>>>>>>>>> from datetime import timedelta
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> # DEFAULT_PERIODS = [ql.Period(f"{i}d") for i in
>>>>>>>>>>>>>>>> range(0,31)]
>>>>>>>>>>>>>>>> DEFAULT_PERIODS = [ql.Period("6M"), ql.Period("12M"),
>>>>>>>>>>>>>>>> ql.Period("18M"), ql.Period("24M")]
>>>>>>>>>>>>>>>> DEFAULT_tGRID = 100
>>>>>>>>>>>>>>>> DEFAULT_xGRID = 100
>>>>>>>>>>>>>>>> DEFAULT_aGRID = 50
>>>>>>>>>>>>>>>> DEFAULT_aRA = 1 # arithmeticRunningAccumulator
>>>>>>>>>>>>>>>> DEFAULT_PASTFIXINGS = 1
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> class AsianOptionPrice:
>>>>>>>>>>>>>>>> def __init__(self, **x):
>>>>>>>>>>>>>>>> for k, v in x.items():
>>>>>>>>>>>>>>>> setattr(self, k, v)
>>>>>>>>>>>>>>>> self.tGrid = x.get("tGrid", DEFAULT_tGRID)
>>>>>>>>>>>>>>>> self.xGrid = x.get("xGrid", DEFAULT_xGRID)
>>>>>>>>>>>>>>>> self.aGrid = x.get("aGrid", DEFAULT_aGRID)
>>>>>>>>>>>>>>>> self.periods = x.get("periods", DEFAULT_PERIODS)
>>>>>>>>>>>>>>>> self.pastFixings = x.get("pastFixings",
>>>>>>>>>>>>>>>> DEFAULT_PASTFIXINGS)
>>>>>>>>>>>>>>>> self.aRA = x.get("arithmeticRunningAccumulator",
>>>>>>>>>>>>>>>> DEFAULT_aRA)
>>>>>>>>>>>>>>>> self.keyList = [k for k, v in x.items()]
>>>>>>>>>>>>>>>> self.dist = 10**(-2)
>>>>>>>>>>>>>>>> self.date_format = "%d-%m-%Y"
>>>>>>>>>>>>>>>> self.value_date = ql.DateParser.parseFormatted(
>>>>>>>>>>>>>>>> self.valueDate, '%d-%m-%Y')
>>>>>>>>>>>>>>>> self.expiry_date = ql.DateParser.parseFormatted(
>>>>>>>>>>>>>>>> self.expiryDate, '%d-%m-%Y')
>>>>>>>>>>>>>>>> ql.Settings.instance().evaluationDate =
>>>>>>>>>>>>>>>> self.value_date
>>>>>>>>>>>>>>>> self.exDay =
>>>>>>>>>>>>>>>> ql.DateParser.parseFormatted(self.expiryDate, '%d-%m-%Y')
>>>>>>>>>>>>>>>> # Volatility input is required for running the
>>>>>>>>>>>>>>>> computing implied volatility function. This volatility is NOT used in the
>>>>>>>>>>>>>>>> implied volatility calculation.
>>>>>>>>>>>>>>>> self.vol_for_iv_calc = 0.10
>>>>>>>>>>>>>>>> self.IV = None
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> def
>>>>>>>>>>>>>>>> generate_fixture_dates(self,start_date,end_date,period):
>>>>>>>>>>>>>>>> schedule = ql.MakeSchedule(start_date, end_date,
>>>>>>>>>>>>>>>> period)
>>>>>>>>>>>>>>>> fixture_dates = [_date for _date in schedule if
>>>>>>>>>>>>>>>> _date.weekday() not in [1,7]]
>>>>>>>>>>>>>>>> return fixture_dates
>>>>>>>>>>>>>>>> def asian(self):
>>>>>>>>>>>>>>>> """
>>>>>>>>>>>>>>>> arithmeticRunningAccumulator(aRA)
>>>>>>>>>>>>>>>> """
>>>>>>>>>>>>>>>> arithmeticRunningAccumulator = self.aRA
>>>>>>>>>>>>>>>> pastFixings = self.pastFixings
>>>>>>>>>>>>>>>> print(pastFixings)
>>>>>>>>>>>>>>>> option_type = self.optionType.lower()
>>>>>>>>>>>>>>>> if option_type not in ["call", "put"]:
>>>>>>>>>>>>>>>> raise Exception(
>>>>>>>>>>>>>>>> f"Option Type is Neither Call nor Put,
>>>>>>>>>>>>>>>> Option type is {option_type}")
>>>>>>>>>>>>>>>> option_type = ql.Option.Call if option_type ==
>>>>>>>>>>>>>>>> "call" else ql.Option.Put
>>>>>>>>>>>>>>>> strike = self.strikePrice
>>>>>>>>>>>>>>>> today = self.value_date
>>>>>>>>>>>>>>>> print(today)
>>>>>>>>>>>>>>>> fixingStartDate
>>>>>>>>>>>>>>>> =ql.DateParser.parseFormatted(self.fixingStartDate, '%d-%m-%Y')
>>>>>>>>>>>>>>>> print("#"*40,fixingStartDate)
>>>>>>>>>>>>>>>> periods = self.periods
>>>>>>>>>>>>>>>> asianFutureFixingDates =
>>>>>>>>>>>>>>>> self.generate_fixture_dates(fixingStartDate,self.expiry_date,ql.Period("1d"))
>>>>>>>>>>>>>>>> print("#"*40,asianFutureFixingDates)
>>>>>>>>>>>>>>>> asianExpiryDate = self.expiry_date
>>>>>>>>>>>>>>>> vanillaPayoff = ql.PlainVanillaPayoff(option_type,
>>>>>>>>>>>>>>>> strike)
>>>>>>>>>>>>>>>> europeanExercise =
>>>>>>>>>>>>>>>> ql.EuropeanExercise(asianExpiryDate)
>>>>>>>>>>>>>>>> arithmeticAverage = ql.Average().Arithmetic
>>>>>>>>>>>>>>>> discreteArithmeticAsianOption =
>>>>>>>>>>>>>>>> ql.DiscreteAveragingAsianOption(
>>>>>>>>>>>>>>>> arithmeticAverage,
>>>>>>>>>>>>>>>> arithmeticRunningAccumulator, pastFixings, asianFutureFixingDates,
>>>>>>>>>>>>>>>> vanillaPayoff, europeanExercise)
>>>>>>>>>>>>>>>> return discreteArithmeticAsianOption
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> def create_arg_list(self, Option=None,
>>>>>>>>>>>>>>>> compute_implied_vol=None, implied_vol_am_put=None):
>>>>>>>>>>>>>>>> '''
>>>>>>>>>>>>>>>> The arguments with disturbances added. Will be
>>>>>>>>>>>>>>>> used for calculation of Greeks
>>>>>>>>>>>>>>>> using numerical differentiation.
>>>>>>>>>>>>>>>> Creating a dictionary of arguments that will be
>>>>>>>>>>>>>>>> used for option price and greeks calculation.
>>>>>>>>>>>>>>>> '''
>>>>>>>>>>>>>>>> self.riskFreeRate = self.riskFreeRate/100
>>>>>>>>>>>>>>>> originalDict_ = {k: getattr(self, k) for k in
>>>>>>>>>>>>>>>> self.keyList}
>>>>>>>>>>>>>>>> ListDict = []
>>>>>>>>>>>>>>>> for i in range(4):
>>>>>>>>>>>>>>>> ListDict.append(deepcopy(originalDict_))
>>>>>>>>>>>>>>>> ListDict[1]['riskFreeRate'] = self.riskFreeRate +
>>>>>>>>>>>>>>>> self.dist
>>>>>>>>>>>>>>>> ListDict[2]['volatility'] = self.volatility +
>>>>>>>>>>>>>>>> self.dist
>>>>>>>>>>>>>>>> ListDict[3]['expiryDate'] = (datetime.strptime(
>>>>>>>>>>>>>>>> self.expiryDate, self.date_format) -
>>>>>>>>>>>>>>>> timedelta(days=1)).strftime(self.date_format)
>>>>>>>>>>>>>>>> print(ListDict)
>>>>>>>>>>>>>>>> return(ListDict)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> def bs_process(self, create_process_for_iv=None,
>>>>>>>>>>>>>>>> use_IV=None):
>>>>>>>>>>>>>>>> """
>>>>>>>>>>>>>>>> Creating the Black-Scholes process for option
>>>>>>>>>>>>>>>> valuation.
>>>>>>>>>>>>>>>> """
>>>>>>>>>>>>>>>> riskFreeTS = ql.YieldTermStructureHandle(
>>>>>>>>>>>>>>>> ql.FlatForward(self.value_date,
>>>>>>>>>>>>>>>> self.riskFreeRate, ql.Actual365Fixed()))
>>>>>>>>>>>>>>>> dividendTS = ql.YieldTermStructureHandle(
>>>>>>>>>>>>>>>> ql.FlatForward(self.value_date, 0,
>>>>>>>>>>>>>>>> ql.Actual365Fixed()))
>>>>>>>>>>>>>>>> volatility =
>>>>>>>>>>>>>>>> ql.BlackVolTermStructureHandle(ql.BlackConstantVol(
>>>>>>>>>>>>>>>> self.value_date, ql.NullCalendar(),
>>>>>>>>>>>>>>>> self.volatility, ql.Actual365Fixed()))
>>>>>>>>>>>>>>>> initialValue =
>>>>>>>>>>>>>>>> ql.QuoteHandle(ql.SimpleQuote(self.underlyingPrice))
>>>>>>>>>>>>>>>> process = ql.BlackScholesMertonProcess(
>>>>>>>>>>>>>>>> initialValue, dividendTS, riskFreeTS,
>>>>>>>>>>>>>>>> volatility)
>>>>>>>>>>>>>>>> return(process)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> def evaluate(self, Option=None,
>>>>>>>>>>>>>>>> compute_implied_vol=None):
>>>>>>>>>>>>>>>> """
>>>>>>>>>>>>>>>> Call the relevant option based on the input.
>>>>>>>>>>>>>>>> """
>>>>>>>>>>>>>>>> self.riskFreeRate = self.riskFreeRate/100
>>>>>>>>>>>>>>>> res = None
>>>>>>>>>>>>>>>> option = AsianOptionPrice.asian(self)
>>>>>>>>>>>>>>>> if compute_implied_vol == True:
>>>>>>>>>>>>>>>> # create Black Scholes process using IV.
>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process(
>>>>>>>>>>>>>>>> self, create_process_for_iv=False,
>>>>>>>>>>>>>>>> use_IV=True)
>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine(
>>>>>>>>>>>>>>>> process, tGrid=self.tGrid,
>>>>>>>>>>>>>>>> xGrid=self.xGrid, aGrid=self.aGrid)
>>>>>>>>>>>>>>>> option.setPricingEngine(engine)
>>>>>>>>>>>>>>>> res = {'value': option.NPV(),
>>>>>>>>>>>>>>>> 'impliedVolatility': self.IV}
>>>>>>>>>>>>>>>> else:
>>>>>>>>>>>>>>>> # Create Black Scholes process using HV.
>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process(
>>>>>>>>>>>>>>>> self, create_process_for_iv=False,
>>>>>>>>>>>>>>>> use_IV=False)
>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine(
>>>>>>>>>>>>>>>> process, tGrid=self.tGrid,
>>>>>>>>>>>>>>>> xGrid=self.xGrid, aGrid=self.aGrid)
>>>>>>>>>>>>>>>> option.setPricingEngine(engine)
>>>>>>>>>>>>>>>> res = {'value': option.NPV()}
>>>>>>>>>>>>>>>> return res
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> def evaluate_asian_npv(self):
>>>>>>>>>>>>>>>> Option = AsianOptionPrice.asian(self)
>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process(
>>>>>>>>>>>>>>>> self, create_process_for_iv=False, use_IV=False)
>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine(
>>>>>>>>>>>>>>>> process, tGrid=self.tGrid, xGrid=self.xGrid,
>>>>>>>>>>>>>>>> aGrid=self.aGrid)
>>>>>>>>>>>>>>>> Option.setPricingEngine(engine)
>>>>>>>>>>>>>>>> res = Option.NPV()
>>>>>>>>>>>>>>>> return(res)
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> def calculate_greeks(self, Option=None,
>>>>>>>>>>>>>>>> compute_implied_vol=None):
>>>>>>>>>>>>>>>> today = self.value_date
>>>>>>>>>>>>>>>> Option = AsianOptionPrice.asian(self)
>>>>>>>>>>>>>>>> if compute_implied_vol == True:
>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process(
>>>>>>>>>>>>>>>> self, create_process_for_iv=False,
>>>>>>>>>>>>>>>> use_IV=True)
>>>>>>>>>>>>>>>> else:
>>>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process(
>>>>>>>>>>>>>>>> self, create_process_for_iv=False,
>>>>>>>>>>>>>>>> use_IV=False)
>>>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine(
>>>>>>>>>>>>>>>> process, tGrid=self.tGrid, xGrid=self.xGrid,
>>>>>>>>>>>>>>>> aGrid=self.aGrid)
>>>>>>>>>>>>>>>> Option.setPricingEngine(engine)
>>>>>>>>>>>>>>>> option_greeks_ = {"delta": Option.delta(), "gamma":
>>>>>>>>>>>>>>>> Option.gamma(
>>>>>>>>>>>>>>>> )}
>>>>>>>>>>>>>>>> ArgmntList = AsianOptionPrice.create_arg_list(
>>>>>>>>>>>>>>>> self, Option, compute_implied_vol=True,
>>>>>>>>>>>>>>>> implied_vol_am_put=self.volatility)
>>>>>>>>>>>>>>>> DisturbedPrices = []
>>>>>>>>>>>>>>>> arg_keys = ['Price', 'PRup', 'PVup', 'PTup']
>>>>>>>>>>>>>>>> for i in range(4):
>>>>>>>>>>>>>>>> DisturbedPrices.append(eval(
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> "AsianOptionPrice(**ArgmntList[i]).evaluate_asian_npv()"))
>>>>>>>>>>>>>>>> print(DisturbedPrices)
>>>>>>>>>>>>>>>> PricesDistrbd = dict(zip(arg_keys, DisturbedPrices))
>>>>>>>>>>>>>>>> Rho = (PricesDistrbd['PRup'] -
>>>>>>>>>>>>>>>> PricesDistrbd['Price'])/(self.dist*100)
>>>>>>>>>>>>>>>> vega = (PricesDistrbd['PVup'] -
>>>>>>>>>>>>>>>> PricesDistrbd['Price'])/(self.dist*100)
>>>>>>>>>>>>>>>> thetaDay = (PricesDistrbd['PTup'] -
>>>>>>>>>>>>>>>> PricesDistrbd['Price'])
>>>>>>>>>>>>>>>> option_greeks_.update({'rho': Rho, 'vega': vega,
>>>>>>>>>>>>>>>> 'theta': thetaDay})
>>>>>>>>>>>>>>>> return option_greeks_
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> settings = {
>>>>>>>>>>>>>>>> "computeHistoricalVolatiltiy": False,
>>>>>>>>>>>>>>>> "tenantId": "380",
>>>>>>>>>>>>>>>> "gridPoints": 149,
>>>>>>>>>>>>>>>> "computeImpliedVolatiltiy": False,
>>>>>>>>>>>>>>>> "runId": 3735,
>>>>>>>>>>>>>>>> "timeSteps": 150,
>>>>>>>>>>>>>>>> "optionTrades": [
>>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>> "underlyingPrice": 98.69,
>>>>>>>>>>>>>>>> "refNo": "OPT-1135-GVA",
>>>>>>>>>>>>>>>> "underlyingPriceUnit": "US cents/LB",
>>>>>>>>>>>>>>>> "valueDate": "17-03-2022",
>>>>>>>>>>>>>>>> "fixingStartDate":"01-05-2022",
>>>>>>>>>>>>>>>> "pastFixings":0,
>>>>>>>>>>>>>>>> "volatility": 0.6015,
>>>>>>>>>>>>>>>> "openQuantity": 1,
>>>>>>>>>>>>>>>> "strikePriceUnit": "US cents/LB",
>>>>>>>>>>>>>>>> "optionType": "Call",
>>>>>>>>>>>>>>>> "expiryDate": "31-05-2022",
>>>>>>>>>>>>>>>> "exType": "asian",
>>>>>>>>>>>>>>>> "riskFreeRate": 0.8080374999999999,
>>>>>>>>>>>>>>>> "premium": 1,
>>>>>>>>>>>>>>>> "portfolioId": 18209,
>>>>>>>>>>>>>>>> "marketPremium": 11.42,
>>>>>>>>>>>>>>>> "longShort": "Long",
>>>>>>>>>>>>>>>> "optionInstrument": "EURO USD 1.105 Call",
>>>>>>>>>>>>>>>> "asset": "EURO USD 1.105 Call",
>>>>>>>>>>>>>>>> "portfolioName": "Option Trades",
>>>>>>>>>>>>>>>> "scenarioId": 8356,
>>>>>>>>>>>>>>>> "scenarioName": "Option Valuation - Greeks",
>>>>>>>>>>>>>>>> "strikePrice": 95,
>>>>>>>>>>>>>>>> "maturityInYears": 0.205479452
>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>> ],
>>>>>>>>>>>>>>>> "userId": "5263",
>>>>>>>>>>>>>>>> "americanOptionsEngine": "CrankNicolson"
>>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> opt = AsianOptionPrice(**settings["optionTrades"][0])
>>>>>>>>>>>>>>>> opt.evaluate_asian_npv()
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> On Wed, May 18, 2022 at 9:25 PM Ashish Bansal <
>>>>>>>>>>>>>>>> ash...@gm...> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Hi Jack,
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Please find attached the Asian option python code and the
>>>>>>>>>>>>>>>>> option trade payload.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Thanks for your help,
>>>>>>>>>>>>>>>>> Regards,
>>>>>>>>>>>>>>>>> Ashish
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> On Wed, 18 May 2022 at 12:12, Jack G <
>>>>>>>>>>>>>>>>> jac...@gm...> wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Hi Ashish,
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> I've just lifted the examples from your references
>>>>>>>>>>>>>>>>>> directly for a discrete arithmetic Asian using the FD Asian engine and it
>>>>>>>>>>>>>>>>>> is working for me - can you share the code you are using that breaks please?
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Best,
>>>>>>>>>>>>>>>>>> Jack
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> On Wed, 18 May 2022, 13:55 Ashish Bansal, <
>>>>>>>>>>>>>>>>>> ash...@gm...> wrote:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Hi all,
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Could somebody help with the asian options? We are using
>>>>>>>>>>>>>>>>>>> FdBlackScholesAsianengine with DiscreteAveragingAsianOption. Online
>>>>>>>>>>>>>>>>>>> references are given below. In DiscreteAveragingAsianOption, we need to
>>>>>>>>>>>>>>>>>>> pass the past fixing which is suggested to be 0 for new trade. Whereas when
>>>>>>>>>>>>>>>>>>> we are passing it as 0, we are getting the following error:
>>>>>>>>>>>>>>>>>>> "QuantLib Error - Running average requires at least one
>>>>>>>>>>>>>>>>>>> past fixing"
>>>>>>>>>>>>>>>>>>> ref:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> https://quantlib-python-docs.readthedocs.io/en/latest/pricing_engines.html#fdblackscholesasianengine
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> https://quantlib-python-docs.readthedocs.io/en/latest/instruments/options.html?highlight=DiscreteAveragingAsianOption#ql.DiscreteAveragingAsianOption
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Queries:
>>>>>>>>>>>>>>>>>>> 1. What is to be passed here for new trade if not 0?
>>>>>>>>>>>>>>>>>>> 2. For trade which is mid of averaging and has few past
>>>>>>>>>>>>>>>>>>> fixings, do we need to pass the count of past fixing or the actual rates of
>>>>>>>>>>>>>>>>>>> the pastfixing as an array?
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Any help will be appreciated.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Thanks in advance
>>>>>>>>>>>>>>>>>>> Ashish
>>>>>>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>>>>>>> QuantLib-users mailing list
>>>>>>>>>>>>>>>>>>> Qua...@li...
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> _______________________________________________
>>>>>>>>>>>>>>> QuantLib-users mailing list
>>>>>>>>>>>>>>> Qua...@li...
>>>>>>>>>>>>>>> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
|
|
From: Luigi B. <lui...@gm...> - 2022-06-01 19:58:10
|
In other words: the Estr class only gives you the daily fixing of the
index, so it doesn't have any of the conventions for the swap. It's like,
for instance, the Euribor class; it models the underlying floating index.
As Jonathan suggested, you can then create the OvernightIndexedSwap based
on Estr and with the conventions you need.
Hope this helps,
Luigi
On Wed, Jun 1, 2022 at 8:29 PM Jonathan Sweemer <sw...@gm...> wrote:
> Hi Victoria,
>
> The definition of overnight indexes in QuantLib just takes the settlement
> days, currency, fixing calendar, and day counter - you can find the values
> for Estr here:
>
>
> https://github.com/lballabio/QuantLib/blob/master/ql/indexes/ibor/estr.cpp#L28
>
> If you want to model Estr swaps using QuantLib, then there are some test
> cases for Eonia that you can modify to reflect the deal terms you need.
>
>
> https://github.com/lballabio/QuantLib/blob/master/test-suite/overnightindexedswap.cpp#L180
>
>
> On Tue, May 31, 2022 at 10:37 PM Victoria Titon
> <vic...@we...> wrote:
>
>> Hello,
>>
>> I would like to know if the QuantLib implementation of ql.Estr is done
>> with these conventions:
>> Floating leg: DAILY compounding, Annual payment, Actual360
>> Fixed leg: Fix rate, Annual payment, Actual360
>>
>> Thanks in advance.
>>
>> _______________________________________________
>> QuantLib-users mailing list
>> Qua...@li...
>> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>>
> _______________________________________________
> QuantLib-users mailing list
> Qua...@li...
> https://lists.sourceforge.net/lists/listinfo/quantlib-users
>
|
|
From: Luigi B. <lui...@gm...> - 2022-06-01 19:55:15
|
In short: with a term structure, the Estr instance will be able to forecast future fixings off the curve. Without it, it can only give past fixings (if they were previously loaded with the addFixing method.). This goes for all other indexes as well — Euribor etc. Luigi On Wed, Jun 1, 2022 at 8:54 PM Jonathan Sweemer <sw...@gm...> wrote: > Hi Victoria, > > ql.Estr and all other overnight index classes take a > Handle<YieldTermStructure>& constructor argument with a default empty > value, so when you pass in nothing then the default empty value is used. > > See the code here: > https://github.com/lballabio/QuantLib-SWIG/blob/master/SWIG/indexes.i#L233 > > To understand more about what the argument is for, read this: > https://stackoverflow.com/a/42907325 > > The StackOverflow answer is to a different question, but it should help > answer your question as well. > > > > On Tue, May 31, 2022 at 10:21 PM Victoria Titon > <vic...@we...> wrote: > >> Hello, >> >> I don't understand why ql.Estr can be called without nothing: ql.Estr(), >> or with a Yield term structureHandle in argument. >> Actually, if I put a yieldTermstructureHandle, in what way the Estrcurve >> will change? which information does the function take from this argument? >> >> Same questions for ql.Euribor, where you can specify a >> ZeroCurveTermStructure as last argument if you want: how does it change the >> result? >> >> I didn't find any answer on the blogs and docs. >> >> Thank you in advance for your answer. >> _______________________________________________ >> QuantLib-users mailing list >> Qua...@li... >> https://lists.sourceforge.net/lists/listinfo/quantlib-users >> > _______________________________________________ > QuantLib-users mailing list > Qua...@li... > https://lists.sourceforge.net/lists/listinfo/quantlib-users > |
|
From: Jonathan S. <sw...@gm...> - 2022-06-01 18:51:20
|
Hi Victoria, ql.Estr and all other overnight index classes take a Handle<YieldTermStructure>& constructor argument with a default empty value, so when you pass in nothing then the default empty value is used. See the code here: https://github.com/lballabio/QuantLib-SWIG/blob/master/SWIG/indexes.i#L233 To understand more about what the argument is for, read this: https://stackoverflow.com/a/42907325 The StackOverflow answer is to a different question, but it should help answer your question as well. On Tue, May 31, 2022 at 10:21 PM Victoria Titon <vic...@we...> wrote: > Hello, > > I don't understand why ql.Estr can be called without nothing: ql.Estr(), > or with a Yield term structureHandle in argument. > Actually, if I put a yieldTermstructureHandle, in what way the Estrcurve > will change? which information does the function take from this argument? > > Same questions for ql.Euribor, where you can specify a > ZeroCurveTermStructure as last argument if you want: how does it change the > result? > > I didn't find any answer on the blogs and docs. > > Thank you in advance for your answer. > _______________________________________________ > QuantLib-users mailing list > Qua...@li... > https://lists.sourceforge.net/lists/listinfo/quantlib-users > |
|
From: Jonathan S. <sw...@gm...> - 2022-06-01 18:26:07
|
Hi Victoria, The definition of overnight indexes in QuantLib just takes the settlement days, currency, fixing calendar, and day counter - you can find the values for Estr here: https://github.com/lballabio/QuantLib/blob/master/ql/indexes/ibor/estr.cpp#L28 If you want to model Estr swaps using QuantLib, then there are some test cases for Eonia that you can modify to reflect the deal terms you need. https://github.com/lballabio/QuantLib/blob/master/test-suite/overnightindexedswap.cpp#L180 On Tue, May 31, 2022 at 10:37 PM Victoria Titon <vic...@we...> wrote: > Hello, > > I would like to know if the QuantLib implementation of ql.Estr is done > with these conventions: > Floating leg: DAILY compounding, Annual payment, Actual360 > Fixed leg: Fix rate, Annual payment, Actual360 > > Thanks in advance. > > _______________________________________________ > QuantLib-users mailing list > Qua...@li... > https://lists.sourceforge.net/lists/listinfo/quantlib-users > |
|
From: Ashish B. <ash...@gm...> - 2022-06-01 17:55:33
|
Luigi, You had given me the following link sometime back. It does mention about the Turnbull Wakeman model based on 2 moment matching: https://github.com/lballabio/QuantLib/blob/master/test-suite/asianoptions.cpp <ql/pricingengines/asian/turnbullwakemanasianengine.hpp> [image: image.png] Even the example is given in the above file. Although the asianoption is part of test-suite but the Turnbull...engine is part of main QL. Is it not part of SWIG? i tried in it in python but could not find it. How can I use this in python with QL v1.17? Regards, Ashish On Mon, 30 May 2022 at 19:39, Ashish Bansal <ash...@gm...> wrote: > Thanks for the responses. I am trying various papers to find the moment > matching for the asian options. I did find the calculation based on > Turnbull-Wakeman model here: > > https://osf.io/efq6a/download > > > I tried this but did not get good results for options expiring in a few > months. I will try some other source probably. > > > One last question, does QL's FdBlackScholesAsianengine with DiscreteAveragingAsianOption > adjust the valuation for trade which are in between the averaging period; > as mentioned on slide # 9 and 10 of this deck? > > > Regards, > > Ashish > > On Thu, 26 May 2022 at 13:24, Luigi Ballabio <lui...@gm...> > wrote: > >> I mean that the two engines give the same price, i.e. 6.09. I don't have >> info on moment matching. >> >> On Wed, May 25, 2022 at 6:51 PM Ashish Bansal <ash...@gm...> >> wrote: >> >>> By same price, you mean same as exchange i.e. 4.57. or same as aRA >>> parameter i.e. 6.09? >>> >>> Any guidance on moment matching? I could not find anything online about >>> it. >>> >>> Regards >>> Ashish >>> >>> On Wed, May 25, 2022, 7:02 PM Luigi Ballabio <lui...@gm...> >>> wrote: >>> >>>> Hi, >>>> no, the engine doesn't do moment matching. I don't think we have >>>> something ready to use for that in the library. >>>> As for the accumulator: I confirm it's the sum. If you create a >>>> virtual Python environment and install the latest QuantLib in it, you can >>>> try your shortened code with the other constructor for the Asian option >>>> (the one taking the list of fixings). It returns the same price. >>>> >>>> Luigi >>>> >>>> >>>> On Wed, May 25, 2022 at 2:46 PM Ashish Bansal <ash...@gm...> >>>> wrote: >>>> >>>>> Hi Luigi, >>>>> >>>>> One question about the QL calculation: Does QL code for the Asian >>>>> option include *moment matching *of the volatility or do we need to >>>>> do that before passing to the DiscAvAsOption? >>>>> >>>>> Regarding the code, I had attached the full code from our system in my >>>>> previous email, attaching here too. The shortened version of the code, >>>>> containing only the QL interaction and excluding excess processing, is also >>>>> attached here. It includes the trade parameters we are using to evaluate >>>>> the Asian option. Strangely, the value is coming zero with short-code but >>>>> with full code in our system, we are getting the values. >>>>> >>>>> Following is the NPV that we are getting in our system (using full >>>>> code) for our trade which has averaging period from 1st March to 31st March >>>>> 2022 and the market traded premium of 4.56: >>>>> arithmeticRunningAccumulator NPV >>>>> 0 4.5711 >>>>> 1302.88 6.09 >>>>> >>>>> Thanks in advance for help. >>>>> >>>>> PS: We are using QL1.17 and the vols are sourced from Reuters could be >>>>> different from implied in the market traded premium. >>>>> >>>>> Regards, >>>>> Ashish >>>>> >>>>> On Mon, 23 May 2022 at 22:26, Luigi Ballabio <lui...@gm...> >>>>> wrote: >>>>> >>>>>> May you send sample code and the value of the fixings for one of >>>>>> those options? Thanks! >>>>>> >>>>>> Luigi >>>>>> >>>>>> >>>>>> On Mon, May 23, 2022 at 8:32 AM Ashish Bansal < >>>>>> ash...@gm...> wrote: >>>>>> >>>>>>> Luigi, >>>>>>> >>>>>>> We ran the asian code, which i sent earlier for a couple of asian >>>>>>> options traded on exchange. We got prices very close to traded prices when >>>>>>> we used the value of running accumulator as 1 for march option being valued >>>>>>> on 17th with past fixing count as 12. But when we used the sum of past >>>>>>> fixing prices i.e. 1302.88 we got a very different number like 6.09 against >>>>>>> 4.57 earlier and 14.11 against 12.39 earlier. >>>>>>> >>>>>>> Just want to confirm if i am missing something about running >>>>>>> accumulator and should it be really the sum of all past fixings? >>>>>>> >>>>>>> Thanks for help in advance. >>>>>>> Ashish >>>>>>> >>>>>>> On Fri, 20 May 2022 at 14:58, Ashish Bansal <ash...@gm...> >>>>>>> wrote: >>>>>>> >>>>>>>> Ok understood. thanks. >>>>>>>> >>>>>>>> On Fri, 20 May 2022 at 14:46, Luigi Ballabio < >>>>>>>> lui...@gm...> wrote: >>>>>>>> >>>>>>>>> It would be the sum of past fixings; for three past fixings of >>>>>>>>> 100.2, 101.3 and 94.6 it would be 296.1. >>>>>>>>> >>>>>>>>> Luigi >>>>>>>>> >>>>>>>>> >>>>>>>>> On Thu, May 19, 2022 at 12:37 PM Ashish Bansal < >>>>>>>>> ash...@gm...> wrote: >>>>>>>>> >>>>>>>>>> Thanks, Luigi for the suggestion. After taking the running >>>>>>>>>> accumulator, we are able to generate the numbers. What exactly should be >>>>>>>>>> passed here? The average price of past fixings or just 1 when the trade is >>>>>>>>>> priced during averaging period? >>>>>>>>>> >>>>>>>>>> Thanks for help. >>>>>>>>>> >>>>>>>>>> Ashish >>>>>>>>>> >>>>>>>>>> On Wed, 18 May 2022 at 21:17, Luigi Ballabio < >>>>>>>>>> lui...@gm...> wrote: >>>>>>>>>> >>>>>>>>>>> I don't have a 1.7 version to try it, but the check is the one >>>>>>>>>>> at < >>>>>>>>>>> https://github.com/lballabio/QuantLib/blob/QuantLib-v1.7/ql/pricingengines/asian/fdblackscholesasianengine.cpp#L51-L53>, >>>>>>>>>>> suggesting that your running accumulator should be 0 (which makes sense, >>>>>>>>>>> because you're using arithmetic average, i.e., a sum, and if you don't have >>>>>>>>>>> any fixings yet the sum should be 0.) >>>>>>>>>>> Your default seems to be 1 instead. >>>>>>>>>>> >>>>>>>>>>> Luigi >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Wed, May 18, 2022 at 5:17 PM Ashish Bansal < >>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>> >>>>>>>>>>>> Luigi, >>>>>>>>>>>> >>>>>>>>>>>> Our code is not too much but we are using deprecated functions >>>>>>>>>>>> like FDEuropeanEngine and FDAmericanEngine. Not sure if using >>>>>>>>>>>> new function called FdBlackScholesVanillaEngine has any change >>>>>>>>>>>> in the calculation that our code will have an impact. >>>>>>>>>>>> >>>>>>>>>>>> Can we use the DiscreteAveragingAsianOption without the >>>>>>>>>>>> overloaded parameter of pastfixings under 1.7? >>>>>>>>>>>> >>>>>>>>>>>> Ashish >>>>>>>>>>>> >>>>>>>>>>>> On Wed, 18 May 2022 at 20:00, Luigi Ballabio < >>>>>>>>>>>> lui...@gm...> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> Hi — it could be. Any particular reason you're still using a >>>>>>>>>>>>> version from 4 years ago? If you have a substantial amount of code that >>>>>>>>>>>>> depends on QuantLib, it might require some work to update because some >>>>>>>>>>>>> methods were deprecated and then removed in the meantime; and of course >>>>>>>>>>>>> you'll probably have some validation process in place when updating, so >>>>>>>>>>>>> that's work too. But on the other hand, you're missing 4 years worth of >>>>>>>>>>>>> bug fixings... >>>>>>>>>>>>> >>>>>>>>>>>>> Luigi >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Wed, May 18, 2022 at 4:19 PM Ashish Bansal < >>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> We tried again and got the same error. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Could it be due to the old version (1.7) we are using? I see >>>>>>>>>>>>>> in the release notes of Apr-2021 that the overload for past fixing was >>>>>>>>>>>>>> added: >>>>>>>>>>>>>> >>>>>>>>>>>>>> - Added an overloaded constructor for Asian options that >>>>>>>>>>>>>> takes all past fixings and thus allows to reprice them correctly when the >>>>>>>>>>>>>> evaluation date changes (thanks to Jack Gillett). >>>>>>>>>>>>>> >>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Wed, 18 May 2022 at 19:14, Jack G < >>>>>>>>>>>>>> jac...@gm...> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Hi Ashish, >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> I have a better answer for you with a screenshot awaiting >>>>>>>>>>>>>>> moderation as it's quite large, but in the meantime, I was able to run your >>>>>>>>>>>>>>> code without problems using the python at the bottom of this email >>>>>>>>>>>>>>> (although I didn't check the numbers). >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> If there is something you're doing specifically to generate >>>>>>>>>>>>>>> the error, could you please attach a minimal reproduction of it? >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Best, >>>>>>>>>>>>>>> Jack >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> import QuantLib as ql >>>>>>>>>>>>>>> from copy import deepcopy >>>>>>>>>>>>>>> from datetime import datetime >>>>>>>>>>>>>>> from datetime import timedelta >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> # DEFAULT_PERIODS = [ql.Period(f"{i}d") for i in range(0,31)] >>>>>>>>>>>>>>> DEFAULT_PERIODS = [ql.Period("6M"), ql.Period("12M"), >>>>>>>>>>>>>>> ql.Period("18M"), ql.Period("24M")] >>>>>>>>>>>>>>> DEFAULT_tGRID = 100 >>>>>>>>>>>>>>> DEFAULT_xGRID = 100 >>>>>>>>>>>>>>> DEFAULT_aGRID = 50 >>>>>>>>>>>>>>> DEFAULT_aRA = 1 # arithmeticRunningAccumulator >>>>>>>>>>>>>>> DEFAULT_PASTFIXINGS = 1 >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> class AsianOptionPrice: >>>>>>>>>>>>>>> def __init__(self, **x): >>>>>>>>>>>>>>> for k, v in x.items(): >>>>>>>>>>>>>>> setattr(self, k, v) >>>>>>>>>>>>>>> self.tGrid = x.get("tGrid", DEFAULT_tGRID) >>>>>>>>>>>>>>> self.xGrid = x.get("xGrid", DEFAULT_xGRID) >>>>>>>>>>>>>>> self.aGrid = x.get("aGrid", DEFAULT_aGRID) >>>>>>>>>>>>>>> self.periods = x.get("periods", DEFAULT_PERIODS) >>>>>>>>>>>>>>> self.pastFixings = x.get("pastFixings", >>>>>>>>>>>>>>> DEFAULT_PASTFIXINGS) >>>>>>>>>>>>>>> self.aRA = x.get("arithmeticRunningAccumulator", >>>>>>>>>>>>>>> DEFAULT_aRA) >>>>>>>>>>>>>>> self.keyList = [k for k, v in x.items()] >>>>>>>>>>>>>>> self.dist = 10**(-2) >>>>>>>>>>>>>>> self.date_format = "%d-%m-%Y" >>>>>>>>>>>>>>> self.value_date = ql.DateParser.parseFormatted( >>>>>>>>>>>>>>> self.valueDate, '%d-%m-%Y') >>>>>>>>>>>>>>> self.expiry_date = ql.DateParser.parseFormatted( >>>>>>>>>>>>>>> self.expiryDate, '%d-%m-%Y') >>>>>>>>>>>>>>> ql.Settings.instance().evaluationDate = >>>>>>>>>>>>>>> self.value_date >>>>>>>>>>>>>>> self.exDay = >>>>>>>>>>>>>>> ql.DateParser.parseFormatted(self.expiryDate, '%d-%m-%Y') >>>>>>>>>>>>>>> # Volatility input is required for running the >>>>>>>>>>>>>>> computing implied volatility function. This volatility is NOT used in the >>>>>>>>>>>>>>> implied volatility calculation. >>>>>>>>>>>>>>> self.vol_for_iv_calc = 0.10 >>>>>>>>>>>>>>> self.IV = None >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> def >>>>>>>>>>>>>>> generate_fixture_dates(self,start_date,end_date,period): >>>>>>>>>>>>>>> schedule = ql.MakeSchedule(start_date, end_date, >>>>>>>>>>>>>>> period) >>>>>>>>>>>>>>> fixture_dates = [_date for _date in schedule if >>>>>>>>>>>>>>> _date.weekday() not in [1,7]] >>>>>>>>>>>>>>> return fixture_dates >>>>>>>>>>>>>>> def asian(self): >>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>> arithmeticRunningAccumulator(aRA) >>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>> arithmeticRunningAccumulator = self.aRA >>>>>>>>>>>>>>> pastFixings = self.pastFixings >>>>>>>>>>>>>>> print(pastFixings) >>>>>>>>>>>>>>> option_type = self.optionType.lower() >>>>>>>>>>>>>>> if option_type not in ["call", "put"]: >>>>>>>>>>>>>>> raise Exception( >>>>>>>>>>>>>>> f"Option Type is Neither Call nor Put, >>>>>>>>>>>>>>> Option type is {option_type}") >>>>>>>>>>>>>>> option_type = ql.Option.Call if option_type == >>>>>>>>>>>>>>> "call" else ql.Option.Put >>>>>>>>>>>>>>> strike = self.strikePrice >>>>>>>>>>>>>>> today = self.value_date >>>>>>>>>>>>>>> print(today) >>>>>>>>>>>>>>> fixingStartDate >>>>>>>>>>>>>>> =ql.DateParser.parseFormatted(self.fixingStartDate, '%d-%m-%Y') >>>>>>>>>>>>>>> print("#"*40,fixingStartDate) >>>>>>>>>>>>>>> periods = self.periods >>>>>>>>>>>>>>> asianFutureFixingDates = >>>>>>>>>>>>>>> self.generate_fixture_dates(fixingStartDate,self.expiry_date,ql.Period("1d")) >>>>>>>>>>>>>>> print("#"*40,asianFutureFixingDates) >>>>>>>>>>>>>>> asianExpiryDate = self.expiry_date >>>>>>>>>>>>>>> vanillaPayoff = ql.PlainVanillaPayoff(option_type, >>>>>>>>>>>>>>> strike) >>>>>>>>>>>>>>> europeanExercise = >>>>>>>>>>>>>>> ql.EuropeanExercise(asianExpiryDate) >>>>>>>>>>>>>>> arithmeticAverage = ql.Average().Arithmetic >>>>>>>>>>>>>>> discreteArithmeticAsianOption = >>>>>>>>>>>>>>> ql.DiscreteAveragingAsianOption( >>>>>>>>>>>>>>> arithmeticAverage, arithmeticRunningAccumulator, >>>>>>>>>>>>>>> pastFixings, asianFutureFixingDates, vanillaPayoff, europeanExercise) >>>>>>>>>>>>>>> return discreteArithmeticAsianOption >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> def create_arg_list(self, Option=None, >>>>>>>>>>>>>>> compute_implied_vol=None, implied_vol_am_put=None): >>>>>>>>>>>>>>> ''' >>>>>>>>>>>>>>> The arguments with disturbances added. Will be >>>>>>>>>>>>>>> used for calculation of Greeks >>>>>>>>>>>>>>> using numerical differentiation. >>>>>>>>>>>>>>> Creating a dictionary of arguments that will be >>>>>>>>>>>>>>> used for option price and greeks calculation. >>>>>>>>>>>>>>> ''' >>>>>>>>>>>>>>> self.riskFreeRate = self.riskFreeRate/100 >>>>>>>>>>>>>>> originalDict_ = {k: getattr(self, k) for k in >>>>>>>>>>>>>>> self.keyList} >>>>>>>>>>>>>>> ListDict = [] >>>>>>>>>>>>>>> for i in range(4): >>>>>>>>>>>>>>> ListDict.append(deepcopy(originalDict_)) >>>>>>>>>>>>>>> ListDict[1]['riskFreeRate'] = self.riskFreeRate + >>>>>>>>>>>>>>> self.dist >>>>>>>>>>>>>>> ListDict[2]['volatility'] = self.volatility + >>>>>>>>>>>>>>> self.dist >>>>>>>>>>>>>>> ListDict[3]['expiryDate'] = (datetime.strptime( >>>>>>>>>>>>>>> self.expiryDate, self.date_format) - >>>>>>>>>>>>>>> timedelta(days=1)).strftime(self.date_format) >>>>>>>>>>>>>>> print(ListDict) >>>>>>>>>>>>>>> return(ListDict) >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> def bs_process(self, create_process_for_iv=None, >>>>>>>>>>>>>>> use_IV=None): >>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>> Creating the Black-Scholes process for option >>>>>>>>>>>>>>> valuation. >>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>> riskFreeTS = ql.YieldTermStructureHandle( >>>>>>>>>>>>>>> ql.FlatForward(self.value_date, >>>>>>>>>>>>>>> self.riskFreeRate, ql.Actual365Fixed())) >>>>>>>>>>>>>>> dividendTS = ql.YieldTermStructureHandle( >>>>>>>>>>>>>>> ql.FlatForward(self.value_date, 0, >>>>>>>>>>>>>>> ql.Actual365Fixed())) >>>>>>>>>>>>>>> volatility = >>>>>>>>>>>>>>> ql.BlackVolTermStructureHandle(ql.BlackConstantVol( >>>>>>>>>>>>>>> self.value_date, ql.NullCalendar(), >>>>>>>>>>>>>>> self.volatility, ql.Actual365Fixed())) >>>>>>>>>>>>>>> initialValue = >>>>>>>>>>>>>>> ql.QuoteHandle(ql.SimpleQuote(self.underlyingPrice)) >>>>>>>>>>>>>>> process = ql.BlackScholesMertonProcess( >>>>>>>>>>>>>>> initialValue, dividendTS, riskFreeTS, volatility) >>>>>>>>>>>>>>> return(process) >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> def evaluate(self, Option=None, >>>>>>>>>>>>>>> compute_implied_vol=None): >>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>> Call the relevant option based on the input. >>>>>>>>>>>>>>> """ >>>>>>>>>>>>>>> self.riskFreeRate = self.riskFreeRate/100 >>>>>>>>>>>>>>> res = None >>>>>>>>>>>>>>> option = AsianOptionPrice.asian(self) >>>>>>>>>>>>>>> if compute_implied_vol == True: >>>>>>>>>>>>>>> # create Black Scholes process using IV. >>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>> use_IV=True) >>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>> process, tGrid=self.tGrid, xGrid=self.xGrid, >>>>>>>>>>>>>>> aGrid=self.aGrid) >>>>>>>>>>>>>>> option.setPricingEngine(engine) >>>>>>>>>>>>>>> res = {'value': option.NPV(), >>>>>>>>>>>>>>> 'impliedVolatility': self.IV} >>>>>>>>>>>>>>> else: >>>>>>>>>>>>>>> # Create Black Scholes process using HV. >>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>> use_IV=False) >>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>> process, tGrid=self.tGrid, xGrid=self.xGrid, >>>>>>>>>>>>>>> aGrid=self.aGrid) >>>>>>>>>>>>>>> option.setPricingEngine(engine) >>>>>>>>>>>>>>> res = {'value': option.NPV()} >>>>>>>>>>>>>>> return res >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> def evaluate_asian_npv(self): >>>>>>>>>>>>>>> Option = AsianOptionPrice.asian(self) >>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>> self, create_process_for_iv=False, use_IV=False) >>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>> process, tGrid=self.tGrid, xGrid=self.xGrid, >>>>>>>>>>>>>>> aGrid=self.aGrid) >>>>>>>>>>>>>>> Option.setPricingEngine(engine) >>>>>>>>>>>>>>> res = Option.NPV() >>>>>>>>>>>>>>> return(res) >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> def calculate_greeks(self, Option=None, >>>>>>>>>>>>>>> compute_implied_vol=None): >>>>>>>>>>>>>>> today = self.value_date >>>>>>>>>>>>>>> Option = AsianOptionPrice.asian(self) >>>>>>>>>>>>>>> if compute_implied_vol == True: >>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>> use_IV=True) >>>>>>>>>>>>>>> else: >>>>>>>>>>>>>>> process = AsianOptionPrice.bs_process( >>>>>>>>>>>>>>> self, create_process_for_iv=False, >>>>>>>>>>>>>>> use_IV=False) >>>>>>>>>>>>>>> engine = ql.FdBlackScholesAsianEngine( >>>>>>>>>>>>>>> process, tGrid=self.tGrid, xGrid=self.xGrid, >>>>>>>>>>>>>>> aGrid=self.aGrid) >>>>>>>>>>>>>>> Option.setPricingEngine(engine) >>>>>>>>>>>>>>> option_greeks_ = {"delta": Option.delta(), "gamma": >>>>>>>>>>>>>>> Option.gamma( >>>>>>>>>>>>>>> )} >>>>>>>>>>>>>>> ArgmntList = AsianOptionPrice.create_arg_list( >>>>>>>>>>>>>>> self, Option, compute_implied_vol=True, >>>>>>>>>>>>>>> implied_vol_am_put=self.volatility) >>>>>>>>>>>>>>> DisturbedPrices = [] >>>>>>>>>>>>>>> arg_keys = ['Price', 'PRup', 'PVup', 'PTup'] >>>>>>>>>>>>>>> for i in range(4): >>>>>>>>>>>>>>> DisturbedPrices.append(eval( >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> "AsianOptionPrice(**ArgmntList[i]).evaluate_asian_npv()")) >>>>>>>>>>>>>>> print(DisturbedPrices) >>>>>>>>>>>>>>> PricesDistrbd = dict(zip(arg_keys, DisturbedPrices)) >>>>>>>>>>>>>>> Rho = (PricesDistrbd['PRup'] - >>>>>>>>>>>>>>> PricesDistrbd['Price'])/(self.dist*100) >>>>>>>>>>>>>>> vega = (PricesDistrbd['PVup'] - >>>>>>>>>>>>>>> PricesDistrbd['Price'])/(self.dist*100) >>>>>>>>>>>>>>> thetaDay = (PricesDistrbd['PTup'] - >>>>>>>>>>>>>>> PricesDistrbd['Price']) >>>>>>>>>>>>>>> option_greeks_.update({'rho': Rho, 'vega': vega, >>>>>>>>>>>>>>> 'theta': thetaDay}) >>>>>>>>>>>>>>> return option_greeks_ >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> settings = { >>>>>>>>>>>>>>> "computeHistoricalVolatiltiy": False, >>>>>>>>>>>>>>> "tenantId": "380", >>>>>>>>>>>>>>> "gridPoints": 149, >>>>>>>>>>>>>>> "computeImpliedVolatiltiy": False, >>>>>>>>>>>>>>> "runId": 3735, >>>>>>>>>>>>>>> "timeSteps": 150, >>>>>>>>>>>>>>> "optionTrades": [ >>>>>>>>>>>>>>> { >>>>>>>>>>>>>>> "underlyingPrice": 98.69, >>>>>>>>>>>>>>> "refNo": "OPT-1135-GVA", >>>>>>>>>>>>>>> "underlyingPriceUnit": "US cents/LB", >>>>>>>>>>>>>>> "valueDate": "17-03-2022", >>>>>>>>>>>>>>> "fixingStartDate":"01-05-2022", >>>>>>>>>>>>>>> "pastFixings":0, >>>>>>>>>>>>>>> "volatility": 0.6015, >>>>>>>>>>>>>>> "openQuantity": 1, >>>>>>>>>>>>>>> "strikePriceUnit": "US cents/LB", >>>>>>>>>>>>>>> "optionType": "Call", >>>>>>>>>>>>>>> "expiryDate": "31-05-2022", >>>>>>>>>>>>>>> "exType": "asian", >>>>>>>>>>>>>>> "riskFreeRate": 0.8080374999999999, >>>>>>>>>>>>>>> "premium": 1, >>>>>>>>>>>>>>> "portfolioId": 18209, >>>>>>>>>>>>>>> "marketPremium": 11.42, >>>>>>>>>>>>>>> "longShort": "Long", >>>>>>>>>>>>>>> "optionInstrument": "EURO USD 1.105 Call", >>>>>>>>>>>>>>> "asset": "EURO USD 1.105 Call", >>>>>>>>>>>>>>> "portfolioName": "Option Trades", >>>>>>>>>>>>>>> "scenarioId": 8356, >>>>>>>>>>>>>>> "scenarioName": "Option Valuation - Greeks", >>>>>>>>>>>>>>> "strikePrice": 95, >>>>>>>>>>>>>>> "maturityInYears": 0.205479452 >>>>>>>>>>>>>>> } >>>>>>>>>>>>>>> ], >>>>>>>>>>>>>>> "userId": "5263", >>>>>>>>>>>>>>> "americanOptionsEngine": "CrankNicolson" >>>>>>>>>>>>>>> } >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> opt = AsianOptionPrice(**settings["optionTrades"][0]) >>>>>>>>>>>>>>> opt.evaluate_asian_npv() >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Wed, May 18, 2022 at 9:25 PM Ashish Bansal < >>>>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hi Jack, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Please find attached the Asian option python code and the >>>>>>>>>>>>>>>> option trade payload. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Thanks for your help, >>>>>>>>>>>>>>>> Regards, >>>>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Wed, 18 May 2022 at 12:12, Jack G < >>>>>>>>>>>>>>>> jac...@gm...> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Hi Ashish, >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I've just lifted the examples from your references >>>>>>>>>>>>>>>>> directly for a discrete arithmetic Asian using the FD Asian engine and it >>>>>>>>>>>>>>>>> is working for me - can you share the code you are using that breaks please? >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Best, >>>>>>>>>>>>>>>>> Jack >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> On Wed, 18 May 2022, 13:55 Ashish Bansal, < >>>>>>>>>>>>>>>>> ash...@gm...> wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi all, >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Could somebody help with the asian options? We are using >>>>>>>>>>>>>>>>>> FdBlackScholesAsianengine with DiscreteAveragingAsianOption. Online >>>>>>>>>>>>>>>>>> references are given below. In DiscreteAveragingAsianOption, we need to >>>>>>>>>>>>>>>>>> pass the past fixing which is suggested to be 0 for new trade. Whereas when >>>>>>>>>>>>>>>>>> we are passing it as 0, we are getting the following error: >>>>>>>>>>>>>>>>>> "QuantLib Error - Running average requires at least one >>>>>>>>>>>>>>>>>> past fixing" >>>>>>>>>>>>>>>>>> ref: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> https://quantlib-python-docs.readthedocs.io/en/latest/pricing_engines.html#fdblackscholesasianengine >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> https://quantlib-python-docs.readthedocs.io/en/latest/instruments/options.html?highlight=DiscreteAveragingAsianOption#ql.DiscreteAveragingAsianOption >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Queries: >>>>>>>>>>>>>>>>>> 1. What is to be passed here for new trade if not 0? >>>>>>>>>>>>>>>>>> 2. For trade which is mid of averaging and has few past >>>>>>>>>>>>>>>>>> fixings, do we need to pass the count of past fixing or the actual rates of >>>>>>>>>>>>>>>>>> the pastfixing as an array? >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Any help will be appreciated. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Thanks in advance >>>>>>>>>>>>>>>>>> Ashish >>>>>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>>>>>> QuantLib-users mailing list >>>>>>>>>>>>>>>>>> Qua...@li... >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> https://lists.sourceforge.net/lists/listinfo/quantlib-users >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> _______________________________________________ >>>>>>>>>>>>>> QuantLib-users mailing list >>>>>>>>>>>>>> Qua...@li... >>>>>>>>>>>>>> https://lists.sourceforge.net/lists/listinfo/quantlib-users >>>>>>>>>>>>>> >>>>>>>>>>>>> |
|
From: Victoria T. <vic...@we...> - 2022-05-31 13:34:25
|
Hello, I would like to know if the QuantLib implementation of ql.Estr is done with these conventions: Floating leg: DAILY compounding, Annual payment, Actual360 Fixed leg: Fix rate, Annual payment, Actual360 Thanks in advance. |
|
From: Victoria T. <vic...@we...> - 2022-05-31 13:18:35
|
Hello, I don't understand why ql.Estr can be called without nothing: ql.Estr(), or with a Yield term structureHandle in argument. Actually, if I put a yieldTermstructureHandle, in what way the Estrcurve will change? which information does the function take from this argument? Same questions for ql.Euribor, where you can specify a ZeroCurveTermStructure as last argument if you want: how does it change the result? I didn't find any answer on the blogs and docs. Thank you in advance for your answer. |