|
From: <da...@el...> - 2020-12-01 12:56:49
|
Hi Luigi,
I submitted a pull request for the modified ExponentialSplinesFitting class.
While this satisfies my selfish needs, it is not very general. If other FittingMethod’s could benefit from the ability to fix certain parameters, then perhaps a more generalized mechanism could be included in the base class.
I did play with this idea for a member variable for FittingMethod, which would be initialized by the FittingMethod constructor. I am not sure it is the most elegant solution but I was aiming to reduce the speed of access to the variables in the discountFunction() call (as that is called many times). The FitParameterArray class has to be supplied with a variable array that does not go out of scope while the class is being used.
Pseudo-code:
//Fitting will take 6 params, but only the fourth is fixed
Array arrFixed(6, QL_NULL_REAL);
arrFixed[3] = 0.01;
FitParameterArray fpa(arrFixed);
//When needed the variable array is set
Array arrVariable(5, 1,1);
fpa.setVariableArray(&arrVariable);
//The [] operator returns the fixed parameter if it has been set, or the variable parameter if not
for (Size np = 0; np < fpa.size(); np++)
{
cout << "Param " << np << ": " << fpa[np] << endl;
}
Output is:
Param 0: 1
Param 1: 2
Param 2: 3
Param 3: 0.01
Param 4: 4
Param 5: 5
The class that handles the parameters:
class FitParameterArray
{
typedef const Array * ArrayPtr;
typedef std::pair<ArrayPtr *, Size> FitParameterArrayElement;
public:
//No fixed parameters
FitParameterArray(Size count = 0)
:pFixedParams_(&fixedParameters_), pVariableParams_(0)
{
for (Size n = 0; n < count; n++)
parameters_.push_back(FitParameterArrayElement(&pVariableParams_, n));
}
//Some fixed parameters
FitParameterArray(const Array& fixedParameters)
:pFixedParams_(&fixedParameters_), pVariableParams_(0),fixedParameters_(fixedParameters)
{
Size nVariable = 0;
for (Size n = 0; n < fixedParameters.size(); n++)
{
if (fixedParameters[n] == QL_NULL_REAL) //No fixed parameter, use variable
{
parameters_.push_back(FitParameterArrayElement(&pVariableParams_, nVariable++));
}
else
{
parameters_.push_back(FitParameterArrayElement(&pFixedParams_, n));
}
}
}
Size size() const
{
return parameters_.size();
}
Real operator[](Size n) const
{
const FitParameterArrayElement& elt = parameters_[n];
if (*(elt.first) == 0) return QL_NULL_REAL; //Variable parameter array not set
return (*(*elt.first))[elt.second];
}
void setVariableArray(ArrayPtr p)
{
pVariableParams_ = p;
}
private:
ArrayPtr pFixedParams_;
Array fixedParameters_;
ArrayPtr pVariableParams_;
std::vector<FitParameterArrayElement> parameters_;
};
From: Luigi Ballabio <lui...@gm...>
Sent: Friday, 20 November 2020 15:07
To: da...@el...
Cc: QuantLib users <qua...@li...>
Subject: Re: [Quantlib-users] Modifying ExponentialSplinesFitting class for FittedBondDiscountCurve
Hello David,
if you can do so while keeping backward compatibility (e.g., by adding new constructors or giving defaults to new parameters) I'd suggest you modify the existing class.
Thanks,
Luigi
On Fri, Nov 20, 2020 at 2:44 PM <da...@el... <mailto:da...@el...> > wrote:
Hi everyone,
I’ve made some mods for my own use to the ExponentialSplinesFitting class, and before I go ahead and submit a pull request, I’d appreciate some initial feedback.
The form of the discount function for the exponential spline fit is: df(t) = sum( b(i) exp -i.kappa.t ) for i = 1 to N.
Where b(i) and kappa are the variables used to fit the curve.
The current implementation fixes N at 9 (so 9 x b(i) + 1 x kappa = 10 parameters). If the discount factor is constrained to be 1 at time t=0 (which is usually is) then one of the b(i)s is constrained, since at t=0, sum(b(i)) = 1, reducing the total number of independent parameters to 9. In the implementation b(1) is constrained.
>From my experience of using exponential spline fitting over the years, and from what I have read, there is no definitive argument for fixing N=9. Indeed the number chosen can depend on several considerations: the density of bonds across the curve; whether you want to fit the very short end etc. You also find that the value of kappa doesn’t make much difference to the quality of fit as long as it is in the right range. Other implementations fix kappa (it’s akin to the far-forward overnight rate, so something around 1% in the current environment), and then optimize over the b(i)s. If you extrapolate the spline beyond the last bond (which is probably not a great idea) then kappa does have an effect on the shape of that extrapolated part but I feel it is simply an artefact of the fitting.
In my implementation, the number of parameters is a variable and hence a class member, and there is also the option to fix kappa and supply a non-zero value for that fix (kappa = 0 is a special case as it produces df(t) = 1 no matter how much the b(i)s are varied (in the constrained model) ).
Initially I had derived my new class, unimaginatively named ExponentialSplinesFittingN from ExponentialSplinesFitting, but on reflection the inheritance is redundant as I am over-riding every method, so perhaps it should also derive directly from the abstract base FittedBondDiscountCurve::FittingMethod. I am open to suggestions for a decent name!
I wrote it before I had read the QL “style guide” so will need to amend my implantation anyway: hence this is a good moment to hear any thoughts!
Best wishes
David Sansom
_______________________________________________
QuantLib-users mailing list
Qua...@li... <mailto:Qua...@li...>
https://lists.sourceforge.net/lists/listinfo/quantlib-users
|