|
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 >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> |