Interpolate price/IV for strike and expiry between market given expiry dates and strikes - c++

I have looked "everywhere" but I cannot find one. Is there an example of how to use c++ Quantlib on how to interpolate for options prices with synthetic strikes/expiry dates?
So for example, if "today" is February 6, 2017, and I get mass quote of the INTC option chain for the expiry's of February 17 2017, March 17 2017, April 14 2017 (etc), and for the sake of argument say the strikes in the mass quote are in $5 wide increments from 15 to 45, and I compute the IV surface for that mass quote for the market given expiry dates/strikes/prices (using some model), how do interpolate for a __synthetic__ expiry date and/or strike, say I want the IV and price for the "April 5, 2017, 39.33 strike call" option?
I see that QL support these interpolation methods, but I am unsure which to use or how to set up the problem to run the solver(s).
LinearInterpolation (1-D)
LogLinearInterpolation and LogCubicInterpolation (1-D)
BackwardFlatInterpolation (1-D)
ConvexMonotone (1-D)
CubicInterpolation (1-D)
ForwardFlatInterpolation (1-D)
SABRInterpolation (1-D)
BilinearInterpolation (2-D)
BicubicSpline (2-D)
[I probably don't want to use weekly's to interpolate in between. Probably only the monthly and quarterly expiration since I believe those prices especially the further out the expiry is.]
This is a similar problem as bootstraping a yield curve, except we are bootstraping on the dimension of strike/tenor between known values on the vol surface, to some given granularity. It is also interesting that we can see new values of NPV changes to an option by simulating changes the underlying value with no extra work [since the market data are stored in Quote instances and thus can notify the option when any of the parameters changes] and holding everything else constant. That the library does not support the same kind of "simulation" by turning the dial on strikes/tenor seems an omission. It is also an inverse problem, using different dimensions.
I need both American and European with/without dividends.

You create a Black volatility surface and let it interpolate.
At this time, the only class you have available to do this is the BlackVarianceSurface class. Its constructor takes a vector of exercise dates, a vector of strikes, and a matrix of corresponding volatilities. The matrix must be full, so you'll need to quote a volatility for each combination of exercise and strike. By default, it uses bilinear interpolation on variances; the method can be changed by calling
volSurface.setInterpolation<Bicubic>();
after construction.
Once you have built the surface, you can use it to get volatilities and prices. To get the volatility, ask the surface:
Volatility v = volSurface.blackVol(exerciseDate, strike);
will interpolate on the exercise date and strike and return the volatility. To get the price, pass the whole surface to an instance of a Black-Scholes process, pass the process to an engine and use the latter to price the option; the engine will pick the correct volatility for the given exercise and strike.

Related

Linear Programming - Re-setting a variable based on it's cumulative count

Detailed business problem:
I'm trying to solve a production scheduling business problem as below:
I have two plants producing FG A and B respectively.
Both the products consume the same Raw Material x
I need to create a 30 day production schedule looking at the Raw Material availability.
FG A and B can be produced if there is sufficient raw material available on the day.
After every 6 days of production the plant has to undergo maintenance and the production on that day will be zero.
Objective is to maximize the margin looking at the day level Raw material available and adhere to the production constraint (i.e. shutdown after every 6th day)
I need to build a linear programming to address the below problem:
Variable y: (binary)
variable z: cumulative of y
When z > 6 then y = 0. I also need to reset the cumulation of z after this point.
Desired output:
How can I build the statement to MILP constraint. Are there any techniques for solving this problem. Thank you.
I think you can model your maintenance differently. Just forbid any sequences of 7 ones for y. I.e.
y[t-6]+y[t-5]+y[t-4]+y[t-3]+y[t-2]+y[t-1]+y[t] <= 6 for t=1,..,T
This is easier than using your accumulator. Note that the beginning needs some attention: you can use historic data for this. I.e., at t=1, the values for t=0,-1,-2,.. are known.
Your accumulator approach is not inherently wrong. We often use it to model inventory. An inventory capacity is a restriction on how large the accumulated inventory can be.

Matched-maturity vanilla swap in Quantlib

Firstly apologies if this has been answered elsewhere.
I am using QuantLib (via Excel) to build a "standard" bond pricing sheet: prices, yields, spline AND matched-maturity ASW.
I can price the bonds, and have successfully built a forecast (Euribor) and discount (EONIA) curve. I can use qlMakeVanillaSwap() to define a spot-start swap by tenor (eg "1y","2Y" etc) and it works fine. However I am struggling to define a "broken date" swap, ie one which starts T+2 and ends on a given date (and so usually has a short stub on the first payment), to match the bond maturity. All the examples I can find have integer year tenors.
I would be grateful if someone could point me to the right method (can be in python, C++ or Excel). Or do I have to go down the route of creating explicit fixed and floating rate schedules for the swaps?
The answer seems to be: Yes, I do have to create explicit fixed and floating rate schedules, using qlSchedule(), but it turns out to be not too onerous. NB. I am pricing a vanilla EUR ABB vs 6m Euribor swap.
As for pricing, it seems the qlMakeVanillaSwap() is doing a few helpful things in one call, but only IF your swap has a whole-period tenor (eg "1y"). I found the answer for what I wanted to do in the example sheet that came with the QuantLibXL download package.
The other thing that qlMakeVanillaSwap() is doing (in addition to creating the schedules) is setting the Pricing Engine (which is used to discount the cashflows). In the longer version you have to (a) set it yourself using qlInstrumentSetPricingEngine() and (b) pass the result of that call to the Trigger parameter of qlVanillaSwapFairRate(), to establish the calculation order.

AWS Forecast cannot train the predictor due to missing data

This question is close, but doesn't quite help me with a similar issue as I am using a single data set and no related time series.
I am using AWS Forecast with a single time series dataset (no related data, just the main DS). It is a daily data set with about 10 years of data ranging from 2010-2020.
I have 3572 data points in the original data set; I manually filled missing data to ensure there were no missing days in the date range for a total of 3739 data points. I lopped off everything in 2020 to create a validation dataset and then configured the predictor for a 180 day Forecast. I keep getting the following error:
Unable to evaluate this dataset because there is missing data in the evaluation window for all items. Ensure that there is complete data for at least one item in the evaluation window starting from 2019-03-07T00:00:00 up to 2020-01-01T00:00.
There is definitely no missing data, I've double and triple checked the date range and data fill and every day between start and end dates has a data point. I also tried adding a data point for 1/1/2020 (it ended at 12/31/2019) and I continue to get this error. I can't figure out what it's asking me for, except that maybe I'm missing something in my math about the forecast Horizon and Backtest window offset?
Dataset example:
Brief model parameters (can share more if I'm missing something pertinent):
Total data points in training data: 3479
forecastHorizon = 180
create_predictor_response=forecast.create_predictor(PredictorName=predictorName,
ForecastHorizon=forecastHorizon,
PerformAutoML= True,
PerformHPO=False,
EvaluationParameters= {"NumberOfBacktestWindows": 1,
"BackTestWindowOffset": 180},
InputDataConfig= {"DatasetGroupArn": datasetGroupArn},
FeaturizationConfig= {"ForecastFrequency": 'D'
I noticed you don't have entry for 6/24/10 (this american date format is the worst btw)
I faced a similar problem when leaving out days (assuming you're modelling in daily frequency) just like that and having the Forecast automatic filling of gaps to nan values (as opposed to zero which is the default). I suggest you:
pre-fill literally every date within the range of training data (and of forecast window, if using related data)
choose zero as the option for automatically filling of missing values. I think mean or any other float value would also work for that matter
let me know if that works! I am also using Forecast and it's good to keep track of possible problems and solutions

C++ Quantlib Vanilla Swap: setting future fixing dates and gearing for floating leg

Is it possible for user to change the future fixing dates and gearing of the floating leg in Quantlib?
First, when Quantlib calculate the NPV for floating leg, it will go into couponpricer.hpp to call inline function BlackIborCouponPricer::swapletPrice(). Inside this function, there is a parameter called gearing_. This parameter is automatically setting to 1 in my case. If I need to change this to other value, say 0.8, where shall I make this change?
Second, all my future fixing dates are the same as the date vector generated in floating leg schedule. i.e. fixing dates are the same as accrual period starting dates. Is it possible to change these fixing dates to be different from the accrual period starting dates, say 2 business days before accrual starting dates subject to normal business day convention adjustment? Alternatively, is it possible for me to pass a date vector to store these fixing dates?
Many thanks.
VanillaSwap doesn't take gearings as a constructor argument (I guess the idea was to keep it simple). Instead, you can create the fixed and floating legs separately using the FixedLeg and IborLeg classes and pass them to a Swap instance. You can see an example of that in SwapTest::testInArrears(), in the test-suite/swap.cpp file.
As for the fixing dates: when you build the IborIndex instance to be passed to IborLeg, you can pass a number of fixing days to its constructor. If you're using the available indexes such as Euribor or USDLibor, though, they already use 2 fixing days (as well as the correct calendar and business-day convention).

Quantlib USDLibor, how does it knows which is the correct fixing date?

When pricing floating rate bonds, one needs to work with instances of the USDLibor class and adding new fixings given a date (which is equivalent to the last reset date minus two business days). However, sometimes it complaints on runtime telling the user that the fixing for a specified date is not available (meaning that one has provided the fixing for a wrong date).
How do instances of USDLibor know which is correct date? I ask this because maybe I can sort this problem by retrieving the correct date directly as USDLibor gets it working around the problem of figuring out the correct date.
The fixing date is two business days before the reset date, as you said (the implementation of the logic is in the FloatingRateCoupon::fixingDate() method, if you want to check it).
However, you might be using the wrong business days. USD LIBOR is fixed in London, so holidays are determined according to the UK calendar, not the US calendar.
In any case, once you have built the bond, you can ask the cashflows themselves for their fixings dates with something like this (which I haven't tested, so it might not even compile, but you should get the idea):
using namespace QuantLib;
Leg cashflows = bond.cashflows();
std::vector<Date> fixingDates;
for (Size i=0; i<cashflows.size(); ++i) {
boost::shared_ptr<FloatingRateCoupon> coupon =
boost::dynamic_pointer_cast<FloatingRateCoupon>(cashflows[i]);
if (coupon)
fixingDates.append(coupon->fixingDate());
}
after which the fixingDates vector will contain (not surprisingly) the fixing dates.