packages feed

hasquant-0.8.0.0: cbits/qlPricingEngine.cpp

#include "qlCheckedFdEngine.h"
#include "qlExactMeanH1HwEngine.h"
#include <ql/experimental/callablebonds/blackcallablebondengine.hpp>
#include <ql/experimental/callablebonds/treecallablebondengine.hpp>
#include <ql/experimental/swaptions/haganirregularswaptionengine.hpp>
#include <ql/experimental/math/zigguratrng.hpp>
#include <ql/experimental/variancegamma/all.hpp>
#include <ql/experimental/barrieroption/vannavolgabarrierengine.hpp>
#include <ql/experimental/varianceoption/integralhestonvarianceoptionengine.hpp>
#include <ql/legacy/libormarketmodels/lfmswaptionengine.hpp>
#include <ql/methods/montecarlo/lsmbasissystem.hpp>
#include <ql/math/generallinearleastsquares.hpp>
#include <ql/version.hpp>
#include <ql/pricingengines/asian/analytic_cont_geom_av_price.hpp>
#include <ql/pricingengines/asian/analytic_discr_geom_av_strike.hpp>
#include <ql/pricingengines/asian/mc_discr_arith_av_price.hpp>
#include <ql/experimental/asian/analytic_cont_geom_av_price_heston.hpp>
#include <ql/pricingengines/asian/mc_discr_arith_av_price_heston.hpp>
#include <ql/pricingengines/asian/turnbullwakemanasianengine.hpp>
#include <ql/pricingengines/asian/fdblackscholesasianengine.hpp>
#include <ql/pricingengines/forward/forwardengine.hpp>
#include <ql/pricingengines/vanilla/fdblackscholesvanillaengine.hpp>
#include <ql/pricingengines/vanilla/analyticeuropeanengine.hpp>
#include <ql/experimental/forward/analytichestonforwardeuropeanengine.hpp>
#include <ql/experimental/barrieroption/vannavolgadoublebarrierengine.hpp>
#include <ql/pricingengines/barrier/analyticbarrierengine.hpp>
#include <ql/pricingengines/barrier/analytictwoassetbarrierengine.hpp>
#include <ql/pricingengines/barrier/analyticsoftbarrierengine.hpp>
#include <ql/pricingengines/quanto/quantoengine.hpp>
#include <ql/instruments/quantovanillaoption.hpp>
#include <ql/instruments/forwardvanillaoption.hpp>
#include <ql/pricingengines/forward/forwardperformanceengine.hpp>
#include <ql/pricingengines/exotic/analyticsimplechooserengine.hpp>
#include <ql/pricingengines/exotic/analytictwoassetcorrelationengine.hpp>
#include <ql/pricingengines/exotic/analyticeuropeanmargrabeengine.hpp>
#include <ql/pricingengines/exotic/analyticamericanmargrabeengine.hpp>
#include <ql/pricingengines/exotic/analyticwriterextensibleoptionengine.hpp>
#include <ql/pricingengines/barrier/analyticpartialtimebarrieroptionengine.hpp>
#include <ql/pricingengines/barrier/analyticbinarybarrierengine.hpp>
#include <ql/pricingengines/barrier/analyticdoublebarrierengine.hpp>
#include <ql/pricingengines/barrier/fdblackscholesbarrierengine.hpp>
#include <ql/pricingengines/barrier/fdhestonbarrierengine.hpp>
#include <ql/pricingengines/barrier/fdhestondoublebarrierengine.hpp>
#include <ql/pricingengines/basket/kirkengine.hpp>
#include <ql/pricingengines/basket/stulzengine.hpp>
#include <ql/pricingengines/basket/bjerksundstenslandspreadengine.hpp>
#include <ql/pricingengines/basket/operatorsplittingspreadengine.hpp>
#include <ql/pricingengines/basket/pearsonspreadengine.hpp>
#include <ql/pricingengines/basket/gaussiancopulaspreadengine.hpp>
#include <ql/pricingengines/basket/fd2dblackscholesvanillaengine.hpp>
#include <ql/pricingengines/basket/choibasketengine.hpp>
#include <ql/pricingengines/basket/denglizhoubasketengine.hpp>
#include <ql/pricingengines/basket/fdndimblackscholesvanillaengine.hpp>
#include <ql/pricingengines/basket/singlefactorbsmbasketengine.hpp>
#include <ql/pricingengines/bacheliercalculator.hpp>
#include <ql/pricingengines/blackdeltacalculator.hpp>
#include <ql/pricingengines/blackformula.hpp>
#include <ql/pricingengines/blackscholescalculator.hpp>
#include <ql/pricingengines/bond/discountingbondengine.hpp>
#include <ql/pricingengines/futures/discountingperpetualfuturesengine.hpp>
#include <ql/pricingengines/bond/riskybondengine.hpp>
#include <ql/pricingengines/capfloor/analyticcapfloorengine.hpp>
#include <ql/pricingengines/capfloor/bacheliercapfloorengine.hpp>
#include <ql/pricingengines/capfloor/blackcapfloorengine.hpp>
#include <ql/pricingengines/capfloor/treecapfloorengine.hpp>
#include <ql/pricingengines/cliquet/analyticcliquetengine.hpp>
#include <ql/pricingengines/cliquet/analyticperformanceengine.hpp>
#include <ql/experimental/credit/blackcdsoptionengine.hpp>
#include <ql/experimental/credit/integralcdoengine.hpp>
#include <ql/experimental/credit/midpointcdoengine.hpp>
#include <ql/experimental/credit/integralntdengine.hpp>
#include <ql/pricingengines/credit/integralcdsengine.hpp>
#include <ql/pricingengines/credit/isdacdsengine.hpp>
#include <ql/pricingengines/exotic/analyticcompoundoptionengine.hpp>
#include <ql/pricingengines/credit/midpointcdsengine.hpp>
#include <ql/pricingengines/forward/discountingfxforwardengine.hpp>
#include <ql/pricingengines/forward/replicatingvarianceswapengine.hpp>
#include <ql/pricingengines/greeks.hpp>
#include <ql/pricingengines/lookback/analyticcontinuousfixedlookback.hpp>
#include <ql/pricingengines/lookback/analyticcontinuousfloatinglookback.hpp>
#include <ql/pricingengines/lookback/analyticcontinuouspartialfixedlookback.hpp>
#include <ql/pricingengines/lookback/analyticcontinuouspartialfloatinglookback.hpp>
#include <ql/pricingengines/swap/cvaswapengine.hpp>
#include <ql/pricingengines/swap/treeswapengine.hpp>
#include <ql/pricingengines/swap/discountingconstnotionalcrosscurrencyswapengine.hpp>
#include <ql/pricingengines/swaption/blackswaptionengine.hpp>
#include <ql/termstructures/volatility/sabr.hpp>
#include <ql/pricingengines/swaption/fdg2swaptionengine.hpp>
#include <ql/pricingengines/swaption/fdg2swaptionengine.hpp>
#include <ql/pricingengines/swaption/fdhullwhiteswaptionengine.hpp>
#include <ql/pricingengines/swaption/g2swaptionengine.hpp>
#include <ql/pricingengines/capfloor/gaussian1dcapfloorengine.hpp>
#include <ql/pricingengines/swaption/gaussian1dswaptionengine.hpp>
#include <ql/pricingengines/swaption/gaussian1dnonstandardswaptionengine.hpp>
#include <ql/pricingengines/swaption/gaussian1dfloatfloatswaptionengine.hpp>
#include <ql/pricingengines/swaption/gaussian1djamshidianswaptionengine.hpp>
#include <ql/models/shortrate/onefactormodels/gaussian1dmodel.hpp>
#include <ql/models/shortrate/calibrationhelpers/swaptionhelper.hpp>
#include <ql/models/equity/hestonslvmcmodel.hpp>
#include <ql/models/equity/hestonslvfdmmodel.hpp>
#include <ql/processes/hestonslvprocess.hpp>
#include <ql/models/marketmodels/browniangenerators/mtbrowniangenerator.hpp>
#include <ql/models/marketmodels/browniangenerators/sobolbrowniangenerator.hpp>
#include <ql/pricingengines/swaption/jamshidianswaptionengine.hpp>
#include <ql/pricingengines/swaption/treeswaptionengine.hpp>
#include <ql/pricingengines/vanilla/analyticbsmhullwhiteengine.hpp>
#include <ql/pricingengines/vanilla/analyticdigitalamericanengine.hpp>
#include <ql/pricingengines/vanilla/analyticdividendeuropeanengine.hpp>
#include <ql/pricingengines/vanilla/analyticgjrgarchengine.hpp>
#include <ql/pricingengines/vanilla/analytich1hwengine.hpp>
#include <ql/pricingengines/vanilla/analytichestonhullwhiteengine.hpp>
#include <ql/pricingengines/vanilla/baroneadesiwhaleyengine.hpp>
#include <ql/pricingengines/vanilla/batesengine.hpp>
#include <ql/pricingengines/vanilla/bjerksundstenslandengine.hpp>
#include <ql/pricingengines/vanilla/integralengine.hpp>
#include <ql/pricingengines/vanilla/jumpdiffusionengine.hpp>
#include <ql/pricingengines/vanilla/juquadraticengine.hpp>
#include <ql/pricingengines/vanilla/qdplusamericanengine.hpp>
#include <ql/pricingengines/vanilla/qdfpamericanengine.hpp>
#include <ql/experimental/exoticoptions/continuousarithmeticasianvecerengine.hpp>
#include <ql/instruments/dividendschedule.hpp>
#include <ql/methods/finitedifferences/solvers/fdmbackwardsolver.hpp>
#include <ql/methods/finitedifferences/operators/fdmlinearopcomposite.hpp>
#include <ql/methods/finitedifferences/stepconditions/fdmstepconditioncomposite.hpp>
#include <ql/methods/finitedifferences/utilities/fdmquantohelper.hpp>
#include <ql/methods/finitedifferences/utilities/fdminnervaluecalculator.hpp>
#include <ql/methods/finitedifferences/utilities/fdmaffinemodelswapinnervalue.hpp>
#include <ql/methods/finitedifferences/meshers/fdmmesher.hpp>
#include <ql/methods/finitedifferences/operators/fdmlinearoplayout.hpp>
#include <ql/methods/finitedifferences/meshers/fdmmeshercomposite.hpp>
#include <ql/methods/finitedifferences/meshers/predefined1dmesher.hpp>
#include <ql/methods/finitedifferences/meshers/uniform1dmesher.hpp>
#include <ql/methods/finitedifferences/meshers/concentrating1dmesher.hpp>
#include <ql/methods/finitedifferences/meshers/fdmblackscholesmesher.hpp>
#include <ql/methods/finitedifferences/meshers/fdmcev1dmesher.hpp>
#include <ql/methods/finitedifferences/meshers/exponentialjump1dmesher.hpp>
#include <ql/methods/finitedifferences/meshers/fdmsimpleprocess1dmesher.hpp>
#include <ql/methods/finitedifferences/meshers/fdmhestonvariancemesher.hpp>
#include <ql/experimental/finitedifferences/glued1dmesher.hpp>
#include <ql/pricingengines/vanilla/fdhestonvanillaengine.hpp>
#include <ql/pricingengines/vanilla/fdhestonhullwhitevanillaengine.hpp>
#include <ql/pricingengines/exotic/analyticcomplexchooserengine.hpp>
#include <ql/pricingengines/exotic/analyticholderextensibleoptionengine.hpp>
#include <ql/pricingengines/vanilla/coshestonengine.hpp>
#include <ql/pricingengines/vanilla/analyticpdfhestonengine.hpp>
#include <ql/pricingengines/vanilla/fdbatesvanillaengine.hpp>
#include <ql/pricingengines/vanilla/fdblackscholesshoutengine.hpp>
#include <ql/models/all.hpp>
#include <ql/legacy/libormarketmodels/all.hpp>
#include <ql/experimental/shortrate/generalizedhullwhite.hpp>
#include <ql/experimental/variancegamma/variancegammamodel.hpp>
#include <ql/processes/all.hpp>
#include <ql/experimental/processes/all.hpp>
#include <ql/experimental/variancegamma/all.hpp>
#include <ql/legacy/libormarketmodels/lfmprocess.hpp>
#include <type_traits>

#include "qlaux.h"
#if QL_HEX_VERSION >= 0x01440000
#include <ql/models/equity/roughhestonmodel.hpp>
#include <ql/pricingengines/vanilla/analyticroughhestonengine.hpp>
#include <ql/experimental/fx/discountingmtmcrosscurrencybasisswapengine.hpp>
#endif
#include "qlPricingEngineAux.h"
#include "qlPricingEngine.h"

namespace hasquant {
#include "qlEnumObjects.h"
}

using namespace QuantLib;

#ifdef QLTRACK_ALLOCATIONS
QL_TRACE_NAME(SamplePath)
QL_TRACE_NAME(hasquant::ExactMeanH1HWEngine)
#endif

namespace {
  template <class Engine, class = void>
  struct HasExactVarianceRootMean : std::false_type {};

  template <class Engine>
  struct HasExactVarianceRootMean<Engine, std::void_t<decltype(Engine::VarianceRootMean::Exact)>>
      : std::true_type {};

  template <class Engine = AnalyticH1HWEngine, class... Integration>
  QlPricingEngine* h1HwEngine(const shared_ptr<HestonModel>& model,
                            const shared_ptr<HullWhite>& hullWhiteModel, Real rhoSr,
                            bool exactMean, Size meanOrder, Integration... integration) {
    if (!exactMean)
      return ret(new QlPricingEngine(alloc(new Engine(model, hullWhiteModel, rhoSr, integration...))));
    if constexpr (HasExactVarianceRootMean<Engine>::value)
      return ret(new QlPricingEngine(alloc(new Engine(model, hullWhiteModel, rhoSr, integration...,
                                                    Engine::VarianceRootMean::Exact, meanOrder))));
    else
      return ret(new QlPricingEngine(alloc(new hasquant::ExactMeanH1HWEngine(
          model, hullWhiteModel, rhoSr, integration..., meanOrder))));
  }

  shared_ptr<StochasticProcess1D::discretization> createDiscretization1D(int n) {
    switch (n) {
    case hasquant::EulerDiscretization:
      return shared_ptr<StochasticProcess1D::discretization>(new EulerDiscretization());
    case hasquant::EndEulerDiscretization:
      return shared_ptr<StochasticProcess1D::discretization>(new EndEulerDiscretization());
    default:
      QL_FAIL("Invalid discretization: " << n);
    }
  }

  // Wraps 3 Haskell-defined callbacks (produced by QuantLib.Internal.Type's withFdmApply/
  // withFdmApplyDirection/withFdmSolveSplitting, mirroring qlOptimize's HsCostFunction above) as a
  // QuantLib FdmLinearOpComposite driving FdmBackwardSolver::rollback -- see the "coarsen the
  // language-boundary crossing" bullet in CLAUDE.md and qlFdmRollback below. Only the 3 virtuals
  // DouglasScheme::step actually calls (size/setTime are plain state, not callbacks -- see below)
  // are implemented; apply_mixed/preconditioner QL_FAIL, so only schemes that never need them
  // (Douglas, Crank-Nicolson in 1D) work through this hook.
  using FdmCallbackFun = QlCallback;

  class HsFdmLinearOpComposite : public FdmLinearOpComposite {
  public:
    HsFdmLinearOpComposite(Size size, FdmCallbackFun applyFn, FdmCallbackFun applyDirFn, FdmCallbackFun solveSplitFn)
    : size_(size), applyFn_(applyFn), applyDirFn_(applyDirFn), solveSplitFn_(solveSplitFn), t1_(0.0), t2_(0.0) {}

    Size size() const override {return size_;}
    // Not a callback: DouglasScheme (and every scheme) calls setTime once per outer step, then
    // makes several apply*/solve_splitting calls against the *same* (t1,t2) -- so the C++
    // wrapper just stores them as mutable state and passes them as extra scalar args to every
    // apply*/solve_splitting callback below, keeping the Haskell callbacks themselves pure.
    void setTime(Time t1, Time t2) override {t1_ = t1; t2_ = t2;}

    Array apply(const Array& r) const override {
      Array out(r.size());
      FdmCallbackArgs args{0.0, t1_, t2_, r.begin(), out.begin(), (unsigned)r.size(), 0};
      applyFn_->invoke(args);
      return out;
    }
    Array apply_direction(Size direction, const Array& r) const override {
      Array out(r.size());
      FdmCallbackArgs args{0.0, t1_, t2_, r.begin(), out.begin(), (unsigned)r.size(), (unsigned)direction};
      applyDirFn_->invoke(args);
      return out;
    }
    Array solve_splitting(Size direction, const Array& r, Real s) const override {
      Array out(r.size());
      FdmCallbackArgs args{s, t1_, t2_, r.begin(), out.begin(), (unsigned)r.size(), (unsigned)direction};
      solveSplitFn_->invoke(args);
      return out;
    }
    Array apply_mixed(const Array&) const override {
      QL_FAIL("HsFdmLinearOpComposite::apply_mixed not implemented -- fdmRollback only supports schemes that never need mixed derivatives (Douglas, Crank-Nicolson in 1D)");
    }
    Array preconditioner(const Array&, Real) const override {
      QL_FAIL("HsFdmLinearOpComposite::preconditioner not implemented -- fdmRollback only supports schemes that never need it (Douglas, Crank-Nicolson in 1D)");
    }
  private:
    Size size_;
    FdmCallbackFun applyFn_;
    FdmCallbackFun applyDirFn_;
    FdmCallbackFun solveSplitFn_;
    mutable Time t1_, t2_;
  };

  // Step conditions share their input/output buffer. Haskell uses an overlap-safe copy
  // because a callback can return the borrowed vector itself or a slice of it.
  class HsFdmStepCondition : public StepCondition<Array> {
  public:
    explicit HsFdmStepCondition(FdmCallbackFun fn) : fn_(fn) {}
    void applyTo(Array& a, Time t) const override {
      FdmCallbackArgs args{0.0, t, 0.0, a.begin(), a.begin(), (unsigned)a.size(), 0};
      fn_->invoke(args);
    }
  private:
    FdmCallbackFun fn_;
  };
  // Genuine per-grid-node Haskell callback -- see QuantLib.Method's haddock ("coarsen the
  // language-boundary crossing" exception case) and CLAUDE.md's own note on this hook. Unlike
  // HsFdmLinearOpComposite/HsFdmStepCondition above, this cannot be coarsened to cross once per
  // outer iteration: FdmInnerValueCalculator::innerValue/avgInnerValue is called once per mesher
  // node (see qlFdmSolve below, mirroring Fdm1DimSolver's/FdmNdimSolver's own constructor loop),
  // and QuantLib's own step conditions (e.g. FdmAmericanStepCondition, not bound here) call it
  // again per node at every exercise date -- matching QuantLib-SWIG's own
  // FdmInnerValueCalculatorDelegate (SWIG/fdm.i), which accepts the same real per-call cost.
  using FdmInnerValueFun = QlCallback;

  class HsFdmInnerValueCalculator : public FdmInnerValueCalculator {
  public:
    HsFdmInnerValueCalculator(shared_ptr<FdmMesher> mesher, FdmInnerValueFun innerValueFn, FdmInnerValueFun avgInnerValueFn)
    : mesher_(std::move(mesher)), innerValueFn_(innerValueFn), avgInnerValueFn_(avgInnerValueFn) {}

    Real innerValue(const FdmLinearOpIterator& iter, Time t) override {return call(innerValueFn_, iter, t);}
    Real avgInnerValue(const FdmLinearOpIterator& iter, Time t) override {return call(avgInnerValueFn_, iter, t);}
  private:
    // Converts the node's grid-index iterator into its real-valued location per dimension --
    // the reason this whole feature needs a mesher, unlike qlFdmRollback's raw-index callbacks.
    Real call(FdmInnerValueFun fn, const FdmLinearOpIterator& iter, Time t) const {
      const Size n = mesher_->layout()->dim().size();
      std::vector<Real> loc(n);
      for (Size d = 0; d < n; ++d) loc[d] = mesher_->location(iter, d);
      return fn->array(loc.data(), (unsigned)n, t);
    }
    shared_ptr<FdmMesher> mesher_;
    FdmInnerValueFun innerValueFn_, avgInnerValueFn_;
  };

  // Builds the FdmLinearOpIterator for the node at `coords` (one index per dimension) from
  // mesher's own layout dim(), the reverse of what HsFdmInnerValueCalculator::call does above --
  // lets any bound FdmInnerValueCalculator (native or Haskell-callback-driven) be inspected
  // node-by-node without assembling a whole PDE solve.
  // extern "C++": this whole file sits inside qlPricingEngine.h's extern "C" block, but a free
  // function returning a non-POD C++ class by value (rather than only pointers, as every C-linkage
  // shim function here does) needs real C++ linkage or GHC's C++ frontend warns
  // (-Wreturn-type-c-linkage).
  FdmLinearOpIterator fdmIteratorAt(QlFdmMesher* mesher, unsigned ndims, unsigned* coords) {
    const shared_ptr<FdmLinearOpLayout>& layout = (*arg(mesher))->layout();
    std::vector<Size> dim = layout->dim();
    std::vector<Size> coordinates(coords, coords + ndims);
    Size index = 0, stride = 1;
    for (Size d = 0; d < dim.size(); ++d) {
      index += coordinates[d] * stride;
      stride *= dim[d];
    }
    return FdmLinearOpIterator(dim, coordinates, index);
  }
  // FdmAffineModelSwapInnerValue<ModelType> -- template isn't crossable into a C signature, so one
  // concrete shim per ModelType (G2/HullWhite), matching how those two models are already separate
  // plain pointer types (QlG2/QlHullWhite), not a shared family. exerciseDates (upstream's
  // std::map<Time, Date>) is marshalled as two parallel arrays, zipped back into the map here --
  // same array-pair convention as every other multi-field marshaller in this codebase.
  // extern "C++": templates can't have C linkage (this file sits inside qlPricingEngine.h's
  // extern "C" block) -- same reasoning as fdmIteratorAt above.
  template <class ModelType>
  QlFdmInnerValueCalculator* fdmAffineModelSwapInnerValue(
                                                          shared_ptr<ModelType>* disModel, shared_ptr<ModelType>* fwdModel, QlFixedVsFloatingSwap* swap,
                                                          unsigned exDatesLen, double* exerciseTimes, int* exerciseDates,
                                                          QlFdmMesher* mesher, unsigned direction, QlError **e) { QlCallScope callbackScope(e);
    try {
      std::map<Time, Date> t2d;
      for (unsigned i = 0; i < exDatesLen; ++i) t2d[exerciseTimes[i]] = Date(exerciseDates[i]);
      return ret(new QlFdmInnerValueCalculator(alloc(new FdmAffineModelSwapInnerValue<ModelType>(
                                                                                                 *arg(disModel), *arg(fwdModel), *arg(swap), t2d, *arg(mesher), direction))));
    } catch (std::exception& er) {return handleException<QlFdmInnerValueCalculator*>(e, er);}
  }
}

#ifdef QLTRACK_ALLOCATIONS
// These live in the anonymous namespace above, so -- unlike PolymorphicPathGenerator, which is
// forward-declared in qlaux.h precisely so its label can sit beside the rest -- they cannot be
// named there. Specialize here instead; without it ObjClassName's primary template falls back to
// typeid().name() and the trace carries a mangled name. All three are shared_ptr payloads: alloc()
// only, never freed, so alloc-summary.py --census lists them rather than flagging a leak.
QL_TRACE_NAME(HsFdmLinearOpComposite)
QL_TRACE_NAME(HsFdmStepCondition)
QL_TRACE_NAME(HsFdmInnerValueCalculator)
#endif

struct HestonSLVFDMLogEntries {
  struct Entry {
    double time;
    std::vector<double> spotGrid, varianceGrid, density;
  };
  std::vector<Entry> entries;
};

#if QL_HEX_VERSION >= 0x01440000
namespace {
FourierIntegration roughFourierIntegration(int algorithm, unsigned count, double relative, double absolute, bool convergence) {
  switch (algorithm) {
    case 0: return FourierIntegration::gaussLaguerre(count);
    case 1: return FourierIntegration::gaussLegendre(count);
    case 2: return FourierIntegration::gaussChebyshev(count);
    case 3: return FourierIntegration::gaussChebyshev2nd(count);
    case 4: return FourierIntegration::gaussLobatto(relative, absolute, count, convergence);
    case 5: return FourierIntegration::gaussKronrod(absolute, count);
    case 6: return FourierIntegration::simpson(absolute, count);
    case 7: return FourierIntegration::trapezoid(absolute, count);
    case 8: return FourierIntegration::discreteSimpson(count);
    case 9: return FourierIntegration::discreteTrapezoid(count);
    case 10: return FourierIntegration::expSinh(relative);
    case 11: return FourierIntegration::tanhSinh(relative);
    default: QL_FAIL("unknown Fourier integration algorithm");
  }
}
}
#endif

extern "C" {
QlPricingEngine *qlDiscountingBondEngine(QlYieldTermStructure *ts, int f, QlError **e) { QlCallScope callbackScope(e);
  try {
    return ret(new QlPricingEngine(alloc(new DiscountingBondEngine(*arg(ts), qlOptBool(f)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine *>(e, er);}}
QlPricingEngine* qlDiscountingPerpetualFuturesEngine(
    QlYieldTermStructure* domesticDiscountCurve, QlYieldTermStructure* foreignDiscountCurve,
    QlQuote* assetSpot, unsigned fundingTimesLen, double* fundingTimes,
    unsigned fundingRatesLen, double* fundingRates, unsigned interestRateDiffsLen,
    double* interestRateDiffs, int fundingInterpType, double maxT, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new DiscountingPerpetualFuturesEngine(
      *arg(domesticDiscountCurve), *arg(foreignDiscountCurve), *arg(assetSpot),
      std::vector<Time>(fundingTimes, fundingTimes + fundingTimesLen),
      std::vector<Rate>(fundingRates, fundingRates + fundingRatesLen),
      std::vector<Spread>(interestRateDiffs, interestRateDiffs + interestRateDiffsLen),
      (DiscountingPerpetualFuturesEngine::InterpolationType)fundingInterpType, maxT))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlRiskyBondEngine(QlDefaultProbabilityTermStructure* defaultTS, double recoveryRate, QlYieldTermStructure* yieldTS, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new RiskyBondEngine(Handle<DefaultProbabilityTermStructure>(*arg(defaultTS)), recoveryRate, *arg(yieldTS)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlDiscountingSwapEngine(QlYieldTermStructure* discountCurve, int includeSettlementDateFlows, int settlementDate, int npvDate, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new DiscountingSwapEngine(*arg(discountCurve), qlOptBool(includeSettlementDateFlows), qlNullableDate(settlementDate), qlNullableDate(npvDate)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlDiscountingFxForwardEngine(QlYieldTermStructure* sourceCurrencyDiscountCurve, QlYieldTermStructure* targetCurrencyDiscountCurve, QlQuote* spotFx, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new DiscountingFxForwardEngine(*arg(sourceCurrencyDiscountCurve), *arg(targetCurrencyDiscountCurve), *arg(spotFx)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlDiscountingConstNotionalCrossCurrencySwapEngine(Currency* domesticCcy, QlYieldTermStructure* domesticCcyDiscountCurve, Currency* foreignCcy, QlYieldTermStructure* foreignCcyDiscountCurve, QlQuote* spotFX, int includeSettlementDateFlows, int settlementDate, int npvDate, int spotFXSettleDate, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new DiscountingConstNotionalCrossCurrencySwapEngine(*arg(domesticCcy), *arg(domesticCcyDiscountCurve), *arg(foreignCcy), *arg(foreignCcyDiscountCurve), *arg(spotFX), qlOptBool(includeSettlementDateFlows), qlNullableDate(settlementDate), qlNullableDate(npvDate), qlNullableDate(spotFXSettleDate)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlCounterpartyAdjSwapEngine(QlYieldTermStructure* discountCurve, QlQuote* blackVol, QlDefaultProbabilityTermStructure* ctptyDTS, double ctptyRecoveryRate, QlDefaultProbabilityTermStructure* invstDTS, double invstRecoveryRate, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new CounterpartyAdjSwapEngine(*arg(discountCurve), *arg(blackVol), Handle<DefaultProbabilityTermStructure>(*arg(ctptyDTS)), ctptyRecoveryRate, qlNullableHandle(arg(invstDTS)), invstRecoveryRate))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticBarrierEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticBarrierEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticTwoAssetBarrierEngine(QlGeneralizedBlackScholesProcess* process1, QlGeneralizedBlackScholesProcess* process2, QlQuote* rho, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticTwoAssetBarrierEngine(*arg(process1), *arg(process2), *arg(rho)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticSoftBarrierEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticSoftBarrierEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticSimpleChooserEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticSimpleChooserEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticComplexChooserEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticComplexChooserEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticTwoAssetCorrelationEngine(QlGeneralizedBlackScholesProcess* process1, QlGeneralizedBlackScholesProcess* process2, QlQuote* correlation, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticTwoAssetCorrelationEngine(*arg(process1), *arg(process2), *arg(correlation)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticEuropeanMargrabeEngine(QlGeneralizedBlackScholesProcess* process1, QlGeneralizedBlackScholesProcess* process2, double correlation, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticEuropeanMargrabeEngine(*arg(process1), *arg(process2), correlation))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticAmericanMargrabeEngine(QlGeneralizedBlackScholesProcess* process1, QlGeneralizedBlackScholesProcess* process2, double correlation, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticAmericanMargrabeEngine(*arg(process1), *arg(process2), correlation))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticWriterExtensibleOptionEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticWriterExtensibleOptionEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticHolderExtensibleOptionEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticHolderExtensibleOptionEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticPartialTimeBarrierOptionEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticPartialTimeBarrierOptionEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticBinaryBarrierEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticBinaryBarrierEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdBlackScholesBarrierEngine(QlGeneralizedBlackScholesProcess* process, unsigned tGrid, unsigned xGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, int localVol, double illegalLocalVolOverwrite, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FdBlackScholesBarrierEngine(*arg(process), tGrid, xGrid, dampingSteps, *arg(fdScheme), localVol, illegalLocalVolOverwrite))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdHestonBarrierEngine(QlHestonModel* model, unsigned tGrid, unsigned xGrid, unsigned vGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, QlLocalVolTermStructure* leverageFct, double mixingFactor, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FdHestonBarrierEngine(*arg(model), tGrid, xGrid, vGrid, dampingSteps, *arg(fdScheme), leverageFct ? *arg(leverageFct) : shared_ptr<LocalVolTermStructure>(), mixingFactor))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdHestonBarrierEngine1(QlHestonModel* model, unsigned dividendsLen, QlDividend** dividends, unsigned tGrid, unsigned xGrid, unsigned vGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, QlLocalVolTermStructure* leverageFct, double mixingFactor, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FdHestonBarrierEngine(*arg(model), qlVector(dividends, dividendsLen), tGrid, xGrid, vGrid, dampingSteps, *arg(fdScheme), leverageFct ? *arg(leverageFct) : shared_ptr<LocalVolTermStructure>(), mixingFactor))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdHestonDoubleBarrierEngine(QlHestonModel* model, unsigned tGrid, unsigned xGrid, unsigned vGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, QlLocalVolTermStructure* leverageFct, double mixingFactor, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FdHestonDoubleBarrierEngine(*arg(model), tGrid, xGrid, vGrid, dampingSteps, *arg(fdScheme), leverageFct ? *arg(leverageFct) : shared_ptr<LocalVolTermStructure>(), mixingFactor))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBinomialBarrierEngine(int tree, QlGeneralizedBlackScholesProcess* process, unsigned timeSteps, unsigned maxTimeSteps, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlBinomialBarrierEngineAux(tree, *arg(process), timeSteps, maxTimeSteps))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlVannaVolgaBarrierEngine(QlDeltaVolQuote* atmVol, QlDeltaVolQuote* vol25Put, QlDeltaVolQuote* vol25Call, QlQuote* spotFX, QlYieldTermStructure* domesticTS, QlYieldTermStructure* foreignTS, int adaptVanDelta, double bsPriceWithSmile, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new VannaVolgaBarrierEngine(Handle<DeltaVolQuote>(*arg(atmVol)), Handle<DeltaVolQuote>(*arg(vol25Put)), Handle<DeltaVolQuote>(*arg(vol25Call)), *arg(spotFX), *arg(domesticTS), *arg(foreignTS), adaptVanDelta, bsPriceWithSmile))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticDoubleBarrierEngine(QlGeneralizedBlackScholesProcess* process, int series, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticDoubleBarrierEngine(*arg(process), series))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlVannaVolgaDoubleBarrierEngine(QlDeltaVolQuote* atmVol, QlDeltaVolQuote* vol25Put, QlDeltaVolQuote* vol25Call, QlQuote* spotFX, QlYieldTermStructure* domesticTS, QlYieldTermStructure* foreignTS, int adaptVanDelta, double bsPriceWithSmile, int series, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new VannaVolgaDoubleBarrierEngine<AnalyticDoubleBarrierEngine>(Handle<DeltaVolQuote>(*arg(atmVol)), Handle<DeltaVolQuote>(*arg(vol25Put)), Handle<DeltaVolQuote>(*arg(vol25Call)), *arg(spotFX), *arg(domesticTS), *arg(foreignTS), adaptVanDelta, bsPriceWithSmile, series))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBinomialDoubleBarrierEngine(int tree, QlGeneralizedBlackScholesProcess* process, unsigned timeSteps, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlBinomialDoubleBarrierEngineAux(tree, *arg(process), timeSteps))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCDoubleBarrierEngine(int rngtrait, int stattrait, QlGeneralizedBlackScholesProcess* process, unsigned timeSteps, unsigned timeStepsPerYear, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCDoubleBarrierEngineAux(rngtrait, stattrait, *arg(process), timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticCliquetEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticCliquetEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticCompoundOptionEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticCompoundOptionEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticContinuousFixedLookbackEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticContinuousFixedLookbackEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticContinuousFloatingLookbackEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticContinuousFloatingLookbackEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticContinuousPartialFloatingLookbackEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticContinuousPartialFloatingLookbackEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticContinuousPartialFixedLookbackEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticContinuousPartialFixedLookbackEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticContinuousGeometricAveragePriceAsianEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticContinuousGeometricAveragePriceAsianEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticContinuousGeometricAveragePriceAsianHestonEngine(QlHestonProcess* process, unsigned summationCutoff, double xiRightLimit, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticContinuousGeometricAveragePriceAsianHestonEngine(*arg(process), summationCutoff, xiRightLimit))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticDiscreteGeometricAveragePriceAsianHestonEngine(QlHestonProcess* process, double xiRightLimit, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticDiscreteGeometricAveragePriceAsianHestonEngine(*arg(process), xiRightLimit))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCLookbackFixedEngine(int rngtrait, int stattrait, QlGeneralizedBlackScholesProcess* process, unsigned timeSteps, unsigned timeStepsPerYear, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCLookbackFixedEngineAux(rngtrait, stattrait, *arg(process), timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCLookbackFloatingEngine(int rngtrait, int stattrait, QlGeneralizedBlackScholesProcess* process, unsigned timeSteps, unsigned timeStepsPerYear, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCLookbackFloatingEngineAux(rngtrait, stattrait, *arg(process), timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCLookbackPartialFixedEngine(int rngtrait, int stattrait, QlGeneralizedBlackScholesProcess* process, unsigned timeSteps, unsigned timeStepsPerYear, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCLookbackPartialFixedEngineAux(rngtrait, stattrait, *arg(process), timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCLookbackPartialFloatingEngine(int rngtrait, int stattrait, QlGeneralizedBlackScholesProcess* process, unsigned timeSteps, unsigned timeStepsPerYear, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCLookbackPartialFloatingEngineAux(rngtrait, stattrait, *arg(process), timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticDigitalAmericanEngine(QlGeneralizedBlackScholesProcess* x0, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticDigitalAmericanEngine(*arg(x0)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticDigitalAmericanKOEngine(QlGeneralizedBlackScholesProcess* x0, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticDigitalAmericanKOEngine(*arg(x0)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticDiscreteGeometricAveragePriceAsianEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticDiscreteGeometricAveragePriceAsianEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticDiscreteGeometricAverageStrikeAsianEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticDiscreteGeometricAverageStrikeAsianEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlTurnbullWakemanAsianEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new TurnbullWakemanAsianEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdBlackScholesAsianEngine(QlGeneralizedBlackScholesProcess* process, unsigned tGrid, unsigned xGrid, unsigned aGrid, FdmSchemeDesc *fdScheme, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FdBlackScholesAsianEngine(*arg(process), tGrid, xGrid, aGrid, *arg(fdScheme)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlForwardEuropeanEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new ForwardVanillaEngine<AnalyticEuropeanEngine>(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlForwardBaroneAdesiWhaleyEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new ForwardVanillaEngine<BaroneAdesiWhaleyApproximationEngine>(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlForwardBjerksundStenslandEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new ForwardVanillaEngine<BjerksundStenslandApproximationEngine>(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlForwardFdBlackScholesVanillaEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(allocAs<PricingEngine>(new ForwardVanillaEngine<hasquant::CheckedFdEngine<FdBlackScholesVanillaEngine>>(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlQuantoEuropeanEngine(QlGeneralizedBlackScholesProcess* process, QlYieldTermStructure* foreignRiskFreeRate, QlBlackVolTermStructure* exchangeRateVolatility, QlQuote* correlation, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new QuantoEngine<VanillaOption, AnalyticEuropeanEngine>(*arg(process), *arg(foreignRiskFreeRate), *arg(exchangeRateVolatility), *arg(correlation)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlQuantoForwardEuropeanEngine(QlGeneralizedBlackScholesProcess* process, QlYieldTermStructure* foreignRiskFreeRate, QlBlackVolTermStructure* exchangeRateVolatility, QlQuote* correlation, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new QuantoEngine<ForwardVanillaOption, ForwardVanillaEngine<AnalyticEuropeanEngine> >(*arg(process), *arg(foreignRiskFreeRate), *arg(exchangeRateVolatility), *arg(correlation)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlQuantoForwardPerformanceEuropeanEngine(QlGeneralizedBlackScholesProcess* process, QlYieldTermStructure* foreignRiskFreeRate, QlBlackVolTermStructure* exchangeRateVolatility, QlQuote* correlation, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new QuantoEngine<ForwardVanillaOption, ForwardPerformanceVanillaEngine<AnalyticEuropeanEngine> >(*arg(process), *arg(foreignRiskFreeRate), *arg(exchangeRateVolatility), *arg(correlation)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlQuantoBarrierEngine(QlGeneralizedBlackScholesProcess* process, QlYieldTermStructure* foreignRiskFreeRate, QlBlackVolTermStructure* exchangeRateVolatility, QlQuote* correlation, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new QuantoEngine<BarrierOption, AnalyticBarrierEngine>(*arg(process), *arg(foreignRiskFreeRate), *arg(exchangeRateVolatility), *arg(correlation)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlQuantoDoubleBarrierEngine(QlGeneralizedBlackScholesProcess* process, QlYieldTermStructure* foreignRiskFreeRate, QlBlackVolTermStructure* exchangeRateVolatility, QlQuote* correlation, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new QuantoEngine<DoubleBarrierOption, AnalyticDoubleBarrierEngine>(*arg(process), *arg(foreignRiskFreeRate), *arg(exchangeRateVolatility), *arg(correlation)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticHestonForwardEuropeanEngine(QlHestonProcess* process, unsigned integrationOrder, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticHestonForwardEuropeanEngine(*arg(process), integrationOrder))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticDividendEuropeanEngine(QlGeneralizedBlackScholesProcess* x0, unsigned dividendsLen, QlDividend** dividends, QlError **e) { QlCallScope callbackScope(e);
  try {DividendSchedule d = qlVector(dividends, dividendsLen);
    return ret(new QlPricingEngine(alloc(new AnalyticDividendEuropeanEngine(*arg(x0), d))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticEuropeanEngine(QlGeneralizedBlackScholesProcess* x0, QlYieldTermStructure* discountCurve, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticEuropeanEngine(*arg(x0), qlNullableHandle(arg(discountCurve))))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticPerformanceEngine(QlGeneralizedBlackScholesProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticPerformanceEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBlackCapFloorEngine1(QlYieldTermStructure* discountCurve, QlOptionletVolatilityStructure* vol, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BlackCapFloorEngine(*arg(discountCurve), *arg(vol)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBlackCapFloorEngine(QlYieldTermStructure* discountCurve, QlQuote* vol, DayCounter* dc, double displacement, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BlackCapFloorEngine(*arg(discountCurve), *arg(vol), (*arg(dc)), displacement))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBlackSwaptionEngine(QlYieldTermStructure* discountCurve, QlQuote* vol, DayCounter* dc, double displacement, int model, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BlackSwaptionEngine(*arg(discountCurve), *arg(vol), (*arg(dc)), displacement, (BlackSwaptionEngine::CashAnnuityModel)model))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlHaganIrregularSwaptionEngine(QlSwaptionVolatilityStructure* vol, QlYieldTermStructure* curve, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new HaganIrregularSwaptionEngine(*arg(vol), qlNullableHandle(curve)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBlackSwaptionEngine1(QlYieldTermStructure* discountCurve, QlSwaptionVolatilityStructure* vol, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BlackSwaptionEngine(*arg(discountCurve), *arg(vol)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBachelierCapFloorEngine1(QlYieldTermStructure* discountCurve, QlOptionletVolatilityStructure* vol, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BachelierCapFloorEngine(*arg(discountCurve), *arg(vol)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBachelierCapFloorEngine(QlYieldTermStructure* discountCurve, QlQuote* vol, DayCounter* dc, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BachelierCapFloorEngine(*arg(discountCurve), *arg(vol), (*arg(dc))))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBachelierSwaptionEngine(QlYieldTermStructure* discountCurve, QlQuote* vol, DayCounter* dc, int model, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BachelierSwaptionEngine(*arg(discountCurve), *arg(vol), (*arg(dc)), (BachelierSwaptionEngine::CashAnnuityModel)model))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBachelierSwaptionEngine1(QlYieldTermStructure* discountCurve, QlSwaptionVolatilityStructure* vol, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BachelierSwaptionEngine(*arg(discountCurve), *arg(vol)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}

void qlFreePricingEngine(QlPricingEngine *engine) {del(engine);}
void qlFreeBlackCalculator(QlBlackCalculator *o) {del(o);}
void qlFreeBlackScholesCalculator(QlBlackScholesCalculator *o) {del(o);}
QlBlackCalculator* qlBlackScholesCalculatorAsBlackCalculator(QlBlackScholesCalculator *o) {return ret(new QlBlackCalculator(*arg(o)));}

double qlBlackCalculatorAlpha(QlBlackCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->alpha();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorBeta(QlBlackCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->beta();} catch (std::exception& er) {return handleException<double>(e, er);}}
QlBlackCalculator* qlBlackCalculator1(int optionType, double strike, double forward, double stdDev, double discount, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlBlackCalculator(alloc(new BlackCalculator((Option::Type)optionType, strike, forward, stdDev, discount))));
  } catch (std::exception& er) {return handleException<QlBlackCalculator*>(e, er);}}
QlBlackCalculator* qlBlackCalculator(QlStrikedTypePayoff* payoff, double forward, double stdDev, double discount, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlBlackCalculator(alloc(new BlackCalculator(*arg(payoff), forward, stdDev, discount))));
  } catch (std::exception& er) {return handleException<QlBlackCalculator*>(e, er);}}
double qlBlackCalculatorDelta(QlBlackCalculator* o, double spot, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->delta(spot);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorDeltaForward(QlBlackCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->deltaForward();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorDividendRho(QlBlackCalculator* o, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->dividendRho(maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorElasticity(QlBlackCalculator* o, double spot, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->elasticity(spot);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorElasticityForward(QlBlackCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->elasticityForward();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorGamma(QlBlackCalculator* o, double spot, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->gamma(spot);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorGammaForward(QlBlackCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->gammaForward();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorItmAssetProbability(QlBlackCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->itmAssetProbability();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorItmCashProbability(QlBlackCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->itmCashProbability();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorRho(QlBlackCalculator* o, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->rho(maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorStrikeSensitivity(QlBlackCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->strikeSensitivity();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorStrikeGamma(QlBlackCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->strikeGamma();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorTheta(QlBlackCalculator* o, double spot, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->theta(spot, maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorThetaPerDay(QlBlackCalculator* o, double spot, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->thetaPerDay(spot, maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorValue(QlBlackCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->value();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorVanna(QlBlackCalculator* o, double spot, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->vanna(spot, maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorVega(QlBlackCalculator* o, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->vega(maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalculatorVolga(QlBlackCalculator* o, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->volga(maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}

void qlFreeBachelierCalculator(QlBachelierCalculator *o) {del(o);}
double qlBachelierCalculatorAlpha(QlBachelierCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->alpha();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorBeta(QlBachelierCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->beta();} catch (std::exception& er) {return handleException<double>(e, er);}}
QlBachelierCalculator* qlBachelierCalculator1(int optionType, double strike, double forward, double stdDev, double discount, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlBachelierCalculator(alloc(new BachelierCalculator((Option::Type)optionType, strike, forward, stdDev, discount))));
  } catch (std::exception& er) {return handleException<QlBachelierCalculator*>(e, er);}}
QlBachelierCalculator* qlBachelierCalculator(QlStrikedTypePayoff* payoff, double forward, double stdDev, double discount, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlBachelierCalculator(alloc(new BachelierCalculator(*arg(payoff), forward, stdDev, discount))));
  } catch (std::exception& er) {return handleException<QlBachelierCalculator*>(e, er);}}
double qlBachelierCalculatorDelta(QlBachelierCalculator* o, double spot, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->delta(spot);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorDeltaForward(QlBachelierCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->deltaForward();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorDividendRho(QlBachelierCalculator* o, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->dividendRho(maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorElasticity(QlBachelierCalculator* o, double spot, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->elasticity(spot);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorElasticityForward(QlBachelierCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->elasticityForward();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorGamma(QlBachelierCalculator* o, double spot, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->gamma(spot);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorGammaForward(QlBachelierCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->gammaForward();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorItmAssetProbability(QlBachelierCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->itmAssetProbability();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorItmCashProbability(QlBachelierCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->itmCashProbability();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorRho(QlBachelierCalculator* o, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->rho(maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorStrikeSensitivity(QlBachelierCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->strikeSensitivity();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorStrikeGamma(QlBachelierCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->strikeGamma();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorTheta(QlBachelierCalculator* o, double spot, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->theta(spot, maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorThetaPerDay(QlBachelierCalculator* o, double spot, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->thetaPerDay(spot, maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorValue(QlBachelierCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->value();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorVanna(QlBachelierCalculator* o, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->vanna(maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorVega(QlBachelierCalculator* o, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->vega(maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBachelierCalculatorVolga(QlBachelierCalculator* o, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->volga(maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}

QlBlackScholesCalculator* qlBlackScholesCalculator1(int optionType, double strike, double spot, double growth, double stdDev, double discount, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlBlackScholesCalculator(alloc(new BlackScholesCalculator((Option::Type)optionType, strike, spot, growth, stdDev, discount))));
  } catch (std::exception& er) {return handleException<QlBlackScholesCalculator*>(e, er);}}
QlBlackScholesCalculator* qlBlackScholesCalculator(QlStrikedTypePayoff* payoff, double spot, double growth, double stdDev, double discount, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlBlackScholesCalculator(alloc(new BlackScholesCalculator(*arg(payoff), spot, growth, stdDev, discount))));
  } catch (std::exception& er) {return handleException<QlBlackScholesCalculator*>(e, er);}}
double qlBlackScholesCalculatorDelta(QlBlackScholesCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->delta();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackScholesCalculatorElasticity(QlBlackScholesCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->elasticity();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackScholesCalculatorGamma(QlBlackScholesCalculator* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->gamma();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackScholesCalculatorTheta(QlBlackScholesCalculator* o, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->theta(maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackScholesCalculatorThetaPerDay(QlBlackScholesCalculator* o, double maturity, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->thetaPerDay(maturity);} catch (std::exception& er) {return handleException<double>(e, er);}}
void qlFreeBlackDeltaCalculator(BlackDeltaCalculator *o) {del(o);}
BlackDeltaCalculator* qlBlackDeltaCalculator(int optionType, int deltaType, double spot, double dDiscount, double fDiscount, double stdDev, QlError **e) { QlCallScope callbackScope(e);
  try {return alloc(new BlackDeltaCalculator((Option::Type)optionType, (DeltaVolQuote::DeltaType)deltaType, spot, dDiscount, fDiscount, stdDev));
  } catch (std::exception& er) {return handleException<BlackDeltaCalculator*>(e, er);}}
double qlBlackDeltaCalculatorDeltaFromStrike(BlackDeltaCalculator* o, double strike, QlError **e) { QlCallScope callbackScope(e);try {return arg(o)->deltaFromStrike(strike);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackDeltaCalculatorStrikeFromDelta(BlackDeltaCalculator* o, double delta, QlError **e) { QlCallScope callbackScope(e);try {return arg(o)->strikeFromDelta(delta);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackDeltaCalculatorAtmStrike(BlackDeltaCalculator* o, int atmType, QlError **e) { QlCallScope callbackScope(e);try {return arg(o)->atmStrike((DeltaVolQuote::AtmType)atmType);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBlackFormula(int optionType, double strike, double forward, double stdDev, double discount, double displacement, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::blackFormula((Option::Type)optionType, strike, forward, stdDev, discount, displacement);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBlackFormulaCashItmProbability(int optionType, double strike, double forward, double stdDev, double displacement, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::blackFormulaCashItmProbability((Option::Type)optionType, strike, forward, stdDev, displacement);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBlackFormulaImpliedStdDev(int optionType, double strike, double forward, double blackPrice, double discount, double displacement, double guess, double accuracy, unsigned maxIterations, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::blackFormulaImpliedStdDev((Option::Type)optionType, strike, forward, blackPrice, discount, displacement, guess, accuracy, maxIterations);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBlackFormulaImpliedStdDevApproximation(int optionType, double strike, double forward, double blackPrice, double discount, double displacement, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::blackFormulaImpliedStdDevApproximation((Option::Type)optionType, strike, forward, blackPrice, discount, displacement);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBlackFormulaStdDevDerivative(double strike, double forward, double stdDev, double discount, double displacement, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::blackFormulaStdDevDerivative(strike, forward, stdDev, discount, displacement);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBlackFormulaVolDerivative(double strike, double forward, double stdDev, double expiry, double discount, double displacement, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::blackFormulaVolDerivative(strike, forward, stdDev, expiry, discount, displacement);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBlackScholesTheta(QlGeneralizedBlackScholesProcess* x0, double value, double delta, double gamma, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::blackScholesTheta(*arg(x0), value, delta, gamma);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBachelierBlackFormula(int optionType, double strike, double forward, double stdDev, double discount, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::bachelierBlackFormula((Option::Type)optionType, strike, forward, stdDev, discount);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBlackFormulaForwardDerivative(int optionType, double strike, double forward, double stdDev, double discount, double displacement, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::blackFormulaForwardDerivative((Option::Type)optionType, strike, forward, stdDev, discount, displacement);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBlackFormulaImpliedStdDevChambers(int optionType, double strike, double forward, double blackPrice, double blackAtmPrice, double discount, double displacement, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::blackFormulaImpliedStdDevChambers((Option::Type)optionType, strike, forward, blackPrice, blackAtmPrice, discount, displacement);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBlackFormulaImpliedStdDevApproximationRS(int optionType, double strike, double forward, double blackPrice, double discount, double displacement, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::blackFormulaImpliedStdDevApproximationRS((Option::Type)optionType, strike, forward, blackPrice, discount, displacement);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBlackFormulaImpliedStdDevLiRS(int optionType, double strike, double forward, double blackPrice, double discount, double displacement, double guess, double omega, double accuracy, unsigned maxIterations, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::blackFormulaImpliedStdDevLiRS((Option::Type)optionType, strike, forward, blackPrice, discount, displacement, guess, omega, accuracy, maxIterations);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBlackFormulaAssetItmProbability(int optionType, double strike, double forward, double stdDev, double displacement, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::blackFormulaAssetItmProbability((Option::Type)optionType, strike, forward, stdDev, displacement);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBlackFormulaStdDevSecondDerivative(double strike, double forward, double stdDev, double discount, double displacement, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::blackFormulaStdDevSecondDerivative(strike, forward, stdDev, discount, displacement);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBachelierBlackFormulaForwardDerivative(int optionType, double strike, double forward, double stdDev, double discount, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::bachelierBlackFormulaForwardDerivative((Option::Type)optionType, strike, forward, stdDev, discount);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBachelierBlackFormulaImpliedVol(int optionType, double strike, double forward, double tte, double bachelierPrice, double discount, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::bachelierBlackFormulaImpliedVol((Option::Type)optionType, strike, forward, tte, bachelierPrice, discount);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBachelierBlackFormulaImpliedVolChoi(int optionType, double strike, double forward, double tte, double bachelierPrice, double discount, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::bachelierBlackFormulaImpliedVolChoi((Option::Type)optionType, strike, forward, tte, bachelierPrice, discount);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBachelierBlackFormulaStdDevDerivative(double strike, double forward, double stdDev, double discount, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::bachelierBlackFormulaStdDevDerivative(strike, forward, stdDev, discount);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibBachelierBlackFormulaAssetItmProbability(int optionType, double strike, double forward, double stdDev, QlError **e) { QlCallScope callbackScope(e);
  try {return QuantLib::bachelierBlackFormulaAssetItmProbability((Option::Type)optionType, strike, forward, stdDev);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlQuantLibDefaultThetaPerDay(double theta, QlError **e) { QlCallScope callbackScope(e);try {return QuantLib::defaultThetaPerDay(theta);} catch (std::exception& er) {return handleException<double>(e, er);}}

QlPricingEngine* qlAnalyticBSMHullWhiteEngine(double equityShortRateCorrelation, QlGeneralizedBlackScholesProcess* x1, QlHullWhite* x2, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticBSMHullWhiteEngine(equityShortRateCorrelation, *arg(x1), *arg(x2)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticCapFloorEngine(QlAffineModel* model, QlYieldTermStructure* termStructure, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticCapFloorEngine(*arg(model), qlNullableHandle(arg(termStructure))))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticGJRGARCHEngine(QlGJRGARCHModel* model, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticGJRGARCHEngine(*arg(model)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticHestonEngine(QlHestonModel* model, double relTolerance, unsigned maxEvaluations, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticHestonEngine(*arg(model), relTolerance, maxEvaluations))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticH1HWEngine(QlHestonModel* model, QlHullWhite* hullWhiteModel, double rhoSr, unsigned integrationOrder, int exactMean, unsigned meanOrder, QlError **e) { QlCallScope callbackScope(e);
  try {return h1HwEngine(*arg(model), *arg(hullWhiteModel), rhoSr, exactMean, meanOrder, integrationOrder);
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticHestonHullWhiteEngine(QlHestonModel* hestonModel, QlHullWhite* hullWhiteModel, unsigned integrationOrder, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticHestonHullWhiteEngine(*arg(hestonModel), *arg(hullWhiteModel), integrationOrder))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBatesEngine(QlBatesModel* model, unsigned integrationOrder, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BatesEngine(*arg(model), integrationOrder))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFFTVanillaEngine(QlGeneralizedBlackScholesProcess* process, double logStrikeSpacing, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FFTVanillaEngine(*arg(process), logStrikeSpacing))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlG2SwaptionEngine(QlG2* model, double range, unsigned intervals, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new G2SwaptionEngine(*arg(model), range, intervals))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlJumpDiffusionEngine(QlMerton76Process* x0, double relativeAccuracy_, unsigned maxIterations, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new JumpDiffusionEngine(*arg(x0), relativeAccuracy_, maxIterations))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlTreeCapFloorEngine(QlShortRateModel* model, unsigned timeSteps, QlYieldTermStructure* termStructure, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new TreeCapFloorEngine(*arg(model), timeSteps, qlNullableHandle(arg(termStructure))))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlTreeSwaptionEngine(QlShortRateModel* x0, unsigned timeSteps, QlYieldTermStructure* termStructure, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new TreeSwaptionEngine(*arg(x0), timeSteps, qlNullableHandle(arg(termStructure))))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlTreeVanillaSwapEngine(QlShortRateModel* x0, unsigned timeSteps, QlYieldTermStructure* termStructure, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new TreeVanillaSwapEngine(*arg(x0), timeSteps, qlNullableHandle(arg(termStructure))))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlVarianceGammaEngine(QlVarianceGammaProcess* x0, double absoluteError, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new VarianceGammaEngine(*arg(x0), absoluteError))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticHestonEngine1(QlHestonModel* model, unsigned integrationOrder, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticHestonEngine(*arg(model), integrationOrder))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
int qlAnalyticHestonEngineOptimalControlVariate(double t, double v0, double kappa, double theta, double sigma, double rho) {
  return AnalyticHestonEngine::optimalControlVariate(t, v0, kappa, theta, sigma, rho);
}
QlPricingEngine* qlAnalyticHestonHullWhiteEngine1(QlHestonModel* model, QlHullWhite* hullWhiteModel, double relTolerance, unsigned maxEvaluations, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticHestonHullWhiteEngine(*arg(model), *arg(hullWhiteModel), relTolerance, maxEvaluations))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticH1HWEngine1(QlHestonModel* model, QlHullWhite* hullWhiteModel, double rhoSr, double relTolerance, unsigned maxEvaluations, int exactMean, unsigned meanOrder, QlError **e) { QlCallScope callbackScope(e);
  try {
    // Enforce the correlation restriction on older QuantLib tolerance constructors too.
    QL_REQUIRE(rhoSr >= 0.0, "Fourier integration is not stable if the equity interest rate correlation is negative");
    return h1HwEngine(*arg(model), *arg(hullWhiteModel), rhoSr, exactMean, meanOrder, relTolerance, maxEvaluations);
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBatesEngine1(QlBatesModel* model, double relTolerance, unsigned maxEvaluations, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BatesEngine(*arg(model), relTolerance, maxEvaluations))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBaroneAdesiWhaleyApproximationEngine(QlGeneralizedBlackScholesProcess* x0, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BaroneAdesiWhaleyApproximationEngine(*arg(x0)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBatesDetJumpEngine1(QlBatesDetJumpModel* model, double relTolerance, unsigned maxEvaluations, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BatesDetJumpEngine(*arg(model), relTolerance, maxEvaluations))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBatesDetJumpEngine(QlBatesDetJumpModel* model, unsigned integrationOrder, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BatesDetJumpEngine(*arg(model), integrationOrder))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBatesDoubleExpDetJumpEngine1(QlBatesDoubleExpDetJumpModel* model, double relTolerance, unsigned maxEvaluations, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BatesDoubleExpDetJumpEngine(*arg(model), relTolerance, maxEvaluations))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBatesDoubleExpDetJumpEngine(QlBatesDoubleExpDetJumpModel* model, unsigned integrationOrder, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BatesDoubleExpDetJumpEngine(*arg(model), integrationOrder))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBatesDoubleExpEngine1(QlBatesDoubleExpModel* model, double relTolerance, unsigned maxEvaluations, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BatesDoubleExpEngine(*arg(model), relTolerance, maxEvaluations))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBatesDoubleExpEngine(QlBatesDoubleExpModel* model, unsigned integrationOrder, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BatesDoubleExpEngine(*arg(model), integrationOrder))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBjerksundStenslandApproximationEngine(QlGeneralizedBlackScholesProcess* x0, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BjerksundStenslandApproximationEngine(*arg(x0)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlQdPlusAmericanEngine(QlGeneralizedBlackScholesProcess* process, unsigned interpolationPoints, int solverType, double eps, unsigned maxIter, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new QdPlusAmericanEngine(*arg(process), interpolationPoints, (QdPlusAmericanEngine::SolverType)solverType, eps, Size(maxIter)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlQdFpAmericanEngine(QlGeneralizedBlackScholesProcess* process, int scheme, int fpEquation, QlError **e) { QlCallScope callbackScope(e);
  try {
    ext::shared_ptr<QdFpIterationScheme> iterationScheme;
    switch (scheme) {
      case hasquant::FastScheme: iterationScheme = QdFpAmericanEngine::fastScheme(); break;
      case hasquant::HighPrecisionScheme: iterationScheme = QdFpAmericanEngine::highPrecisionScheme(); break;
      default: iterationScheme = QdFpAmericanEngine::accurateScheme(); break;
    }
    return ret(new QlPricingEngine(alloc(new QdFpAmericanEngine(*arg(process), iterationScheme, (QdFpAmericanEngine::FixedPointEquation)fpEquation))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlContinuousArithmeticAsianVecerEngine(QlGeneralizedBlackScholesProcess* process, QlQuote* currentAverage, int startDate, unsigned timeSteps, unsigned assetSteps, double zMin, double zMax, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new ContinuousArithmeticAsianVecerEngine(*arg(process), qlNullableHandle(arg(currentAverage)), Date(startDate), timeSteps, assetSteps, zMin, zMax))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBlackCdsOptionEngine(QlDefaultProbabilityTermStructure* probability, double recoveryRate, QlYieldTermStructure* termStructure, QlQuote* vol, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BlackCdsOptionEngine(Handle<DefaultProbabilityTermStructure>(*arg(probability)), recoveryRate, *arg(termStructure), *arg(vol)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlIntegralCdsEngine(int l, int u, QlDefaultProbabilityTermStructure* x1, double recoveryRate, QlYieldTermStructure* discountCurve, int includeSettlementDateFlows, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new IntegralCdsEngine(Period(l, (TimeUnit)u), Handle<DefaultProbabilityTermStructure>(*arg(x1)), recoveryRate, *arg(discountCurve), qlOptBool(includeSettlementDateFlows)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlIntegralEngine(QlGeneralizedBlackScholesProcess* x0, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new IntegralEngine(*arg(x0)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlJamshidianSwaptionEngine(QlOneFactorAffineModel* model, QlYieldTermStructure* termStructure, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new JamshidianSwaptionEngine(*arg(model), qlNullableHandle(arg(termStructure))))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlJuQuadraticApproximationEngine(QlGeneralizedBlackScholesProcess* x0, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new JuQuadraticApproximationEngine(*arg(x0)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlKirkEngine(QlBlackProcess* process1, QlBlackProcess* process2, double correlation, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new KirkEngine(*arg(process1), *arg(process2), correlation))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlIsdaCdsEngine(QlDefaultProbabilityTermStructure* x0, double recoveryRate, QlYieldTermStructure* discountCurve, int includeSettlementDateFlows, int numericalFix, int accrualBias, int forwardsInCouponPeriod, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new IsdaCdsEngine(Handle<DefaultProbabilityTermStructure>(*arg(x0)), recoveryRate, *arg(discountCurve), qlOptBool(includeSettlementDateFlows),
      (IsdaCdsEngine::NumericalFix)numericalFix, (IsdaCdsEngine::AccrualBias)accrualBias, (IsdaCdsEngine::ForwardsInCouponPeriod)forwardsInCouponPeriod))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMidPointCdsEngine(QlDefaultProbabilityTermStructure* x0, double recoveryRate, QlYieldTermStructure* discountCurve, int includeSettlementDateFlows, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new MidPointCdsEngine(Handle<DefaultProbabilityTermStructure>(*arg(x0)), recoveryRate, *arg(discountCurve), qlOptBool(includeSettlementDateFlows)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMidPointCDOEngine(QlYieldTermStructure* discountCurve, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new MidPointCDOEngine(*arg(discountCurve)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlIntegralCDOEngine(QlYieldTermStructure* discountCurve, int l, int u, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new IntegralCDOEngine(*arg(discountCurve), Period(l, (TimeUnit)u)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlIntegralNtdEngine(int l, int u, QlYieldTermStructure* discountCurve, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new IntegralNtdEngine(Period(l, (TimeUnit)u), *arg(discountCurve)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlReplicatingVarianceSwapEngine(QlGeneralizedBlackScholesProcess* process, double dk, unsigned callStrikesLen, double* callStrikes, unsigned putStrikesLen, double* putStrikes, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new ReplicatingVarianceSwapEngine(*arg(process), dk, std::vector<double>(callStrikes, callStrikes+callStrikesLen), std::vector<double>(putStrikes, putStrikes+putStrikesLen)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlStulzEngine(QlGeneralizedBlackScholesProcess* process1, QlGeneralizedBlackScholesProcess* process2, double correlation, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new StulzEngine(*arg(process1), *arg(process2), correlation))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBjerksundStenslandSpreadEngine(QlGeneralizedBlackScholesProcess* process1, QlGeneralizedBlackScholesProcess* process2, double correlation, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BjerksundStenslandSpreadEngine(*arg(process1), *arg(process2), correlation))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlOperatorSplittingSpreadEngine(QlGeneralizedBlackScholesProcess* process1, QlGeneralizedBlackScholesProcess* process2, double correlation, int order, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new OperatorSplittingSpreadEngine(*arg(process1), *arg(process2), correlation, (OperatorSplittingSpreadEngine::Order)order))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlPearsonSpreadEngine(QlGeneralizedBlackScholesProcess* process1, QlGeneralizedBlackScholesProcess* process2, double correlation, double integrationTolerance, unsigned maxIntegrationIterations, double nStd, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new PearsonSpreadEngine(*arg(process1), *arg(process2), correlation, integrationTolerance, maxIntegrationIterations, nStd))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlGaussianCopulaSpreadEngine(QlGeneralizedBlackScholesProcess* process1, QlGeneralizedBlackScholesProcess* process2, double correlation, unsigned nPoints, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new GaussianCopulaSpreadEngine(*arg(process1), *arg(process2), correlation, nPoints))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFd2dBlackScholesVanillaEngine(QlGeneralizedBlackScholesProcess* p1, QlGeneralizedBlackScholesProcess* p2, double correlation, unsigned xGrid, unsigned yGrid, unsigned tGrid, unsigned dampingSteps, FdmSchemeDesc *schemeDesc, int localVol, double illegalLocalVolOverwrite, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new Fd2dBlackScholesVanillaEngine(*arg(p1), *arg(p2), correlation, xGrid, yGrid, tGrid, dampingSteps, *arg(schemeDesc), localVol, illegalLocalVolOverwrite))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlChoiBasketEngine(unsigned processesLen, QlGeneralizedBlackScholesProcess** processes, unsigned rhoRows, unsigned rhoCols, double* rho, double lambda, unsigned maxNrIntegrationSteps, int calcfwdDelta, int controlVariate, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new ChoiBasketEngine(qlVector(processes, processesLen), qlMatrix(rho, rhoRows, rhoCols), lambda, maxNrIntegrationSteps, calcfwdDelta, controlVariate))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlDengLiZhouBasketEngine(unsigned processesLen, QlGeneralizedBlackScholesProcess** processes, unsigned rhoRows, unsigned rhoCols, double* rho, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new DengLiZhouBasketEngine(qlVector(processes, processesLen), qlMatrix(rho, rhoRows, rhoCols)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdndimBlackScholesVanillaEngine(unsigned processesLen, QlGeneralizedBlackScholesProcess** processes, unsigned rhoRows, unsigned rhoCols, double* rho, unsigned xGridsLen, unsigned* xGrids, unsigned tGrid, unsigned dampingSteps, FdmSchemeDesc *schemeDesc, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FdndimBlackScholesVanillaEngine(qlVector(processes, processesLen), qlMatrix(rho, rhoRows, rhoCols), std::vector<Size>(xGrids, xGrids+xGridsLen), tGrid, dampingSteps, *arg(schemeDesc)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdndimBlackScholesVanillaEngine1(unsigned processesLen, QlGeneralizedBlackScholesProcess** processes, unsigned rhoRows, unsigned rhoCols, double* rho, unsigned xGrid, unsigned tGrid, unsigned dampingSteps, FdmSchemeDesc *schemeDesc, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FdndimBlackScholesVanillaEngine(qlVector(processes, processesLen), qlMatrix(rho, rhoRows, rhoCols), xGrid, tGrid, dampingSteps, *arg(schemeDesc)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlSingleFactorBsmBasketEngine(unsigned processesLen, QlGeneralizedBlackScholesProcess** processes, double xTol, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new SingleFactorBsmBasketEngine(qlVector(processes, processesLen), xTol))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlLfmSwaptionEngine(QlLiborForwardModel* model, QlYieldTermStructure* discountCurve, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new LfmSwaptionEngine(*arg(model), *arg(discountCurve)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlTreeCapFloorEngine1(QlShortRateModel* model, TimeGrid* timeGrid, QlYieldTermStructure* termStructure, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new TreeCapFloorEngine(*arg(model), *arg(timeGrid), qlNullableHandle(arg(termStructure))))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlTreeSwaptionEngine1(QlShortRateModel* x0, TimeGrid* timeGrid, QlYieldTermStructure* termStructure, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new TreeSwaptionEngine(*arg(x0), *arg(timeGrid), qlNullableHandle(arg(termStructure))))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlTreeVanillaSwapEngine1(QlShortRateModel* x0, TimeGrid* timeGrid, QlYieldTermStructure* termStructure, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new TreeVanillaSwapEngine(*arg(x0), *arg(timeGrid), qlNullableHandle(arg(termStructure))))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdG2SwaptionEngine(QlG2* model, unsigned tGrid, unsigned xGrid, unsigned yGrid, unsigned dampingSteps, double invEps, FdmSchemeDesc *schemeDesc, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FdG2SwaptionEngine(*arg(model), tGrid, xGrid, yGrid, dampingSteps, invEps, *arg(schemeDesc)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdHullWhiteSwaptionEngine(QlHullWhite* model, unsigned tGrid, unsigned xGrid, unsigned dampingSteps, double invEps, FdmSchemeDesc *schemeDesc, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FdHullWhiteSwaptionEngine(*arg(model), tGrid, xGrid, dampingSteps, invEps, *arg(schemeDesc)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCVarianceSwapEngine1(int rngtrait, int stattrait, QlGeneralizedBlackScholesProcess* process, unsigned timeSteps, unsigned timeStepsPerYear, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCVarianceSwapEngine1Aux(rngtrait, stattrait, *arg(process), timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCHestonHullWhiteEngine1(int rngtrait, int stattrait, QlHybridHestonHullWhiteProcess* process, unsigned timeSteps, unsigned timeStepsPerYear, int antitheticVariate, int controlVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCHestonHullWhiteEngine1Aux(rngtrait, stattrait, *arg(process), timeSteps, timeStepsPerYear, antitheticVariate, controlVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCAmericanEngine1(int rngtrait, int stattrait, QlGeneralizedBlackScholesProcess* process, unsigned timeSteps, unsigned timeStepsPerYear, int antitheticVariate, int controlVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, unsigned polynomOrder, int polynomType, unsigned nCalibrationSamples, int antitheticVariateCalibration, unsigned seedCalibration, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCAmericanEngine1Aux(rngtrait, stattrait, *arg(process), timeSteps, timeStepsPerYear, antitheticVariate, controlVariate, requiredSamples, requiredTolerance, maxSamples, seed, polynomOrder, (LsmBasisSystem::PolynomialType)polynomType, nCalibrationSamples, qlOptBool(antitheticVariateCalibration), seedCalibration))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCBarrierEngine1(int rngtrait, int stattrait, QlGeneralizedBlackScholesProcess* process, unsigned timeSteps, unsigned timeStepsPerYear, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, int isBiased, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCBarrierEngine1Aux(rngtrait, stattrait, *arg(process), timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, isBiased, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCDigitalEngine1(int rngtrait, int stattrait, QlGeneralizedBlackScholesProcess* x0, unsigned timeSteps, unsigned timeStepsPerYear, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCDigitalEngine1Aux(rngtrait, stattrait, *arg(x0), timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCForwardEuropeanBSEngine1(int rngtrait, int stattrait, QlGeneralizedBlackScholesProcess* process, unsigned timeSteps, unsigned timeStepsPerYear, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCForwardEuropeanBSEngine1Aux(rngtrait, stattrait, *arg(process), timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCForwardEuropeanHestonEngine1(int rngtrait, int stattrait, QlHestonProcess* process, unsigned timeSteps, unsigned timeStepsPerYear, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, int controlVariate, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCForwardEuropeanHestonEngine1Aux(rngtrait, stattrait, *arg(process), timeSteps, timeStepsPerYear, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed, controlVariate))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCDiscreteArithmeticAPEngine1(int rngtrait, int stattrait, QlGeneralizedBlackScholesProcess* process, int brownianBridge, int antitheticVariate, int controlVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCDiscreteArithmeticAPEngine1Aux(rngtrait, stattrait, *arg(process), brownianBridge, antitheticVariate, controlVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCDiscreteArithmeticASEngine1(int rngtrait, int stattrait, QlGeneralizedBlackScholesProcess* process, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCDiscreteArithmeticASEngine1Aux(rngtrait, stattrait, *arg(process), brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCDiscreteArithmeticAPHestonEngine1(int rngtrait, int stattrait, QlHestonProcess* process, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, unsigned timeSteps, unsigned timeStepsPerYear, int controlVariate, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCDiscreteArithmeticAPHestonEngine1Aux(rngtrait, stattrait, *arg(process), antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed, timeSteps, timeStepsPerYear, controlVariate))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCDiscreteGeometricAPHestonEngine1(int rngtrait, int stattrait, QlHestonProcess* process, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, unsigned timeSteps, unsigned timeStepsPerYear, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCDiscreteGeometricAPHestonEngine1Aux(rngtrait, stattrait, *arg(process), antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed, timeSteps, timeStepsPerYear))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCDiscreteGeometricAPEngine1(int rngtrait, int stattrait, QlGeneralizedBlackScholesProcess* process, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCDiscreteGeometricAPEngine1Aux(rngtrait, stattrait, *arg(process), brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCEuropeanEngine1(int rngtrait, int stattrait, QlGeneralizedBlackScholesProcess* process, unsigned timeSteps, unsigned timeStepsPerYear, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCEuropeanEngine1Aux(rngtrait, stattrait, *arg(process), timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCEuropeanGJRGARCHEngine1(int rngtrait, int stattrait, QlGJRGARCHProcess* x0, unsigned timeSteps, unsigned timeStepsPerYear, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCEuropeanGJRGARCHEngine1Aux(rngtrait, stattrait, *arg(x0), timeSteps, timeStepsPerYear, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCEuropeanHestonEngine1(int rngtrait, int stattrait, QlHestonProcess* x0, unsigned timeSteps, unsigned timeStepsPerYear, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCEuropeanHestonEngine1Aux(rngtrait, stattrait, *arg(x0), timeSteps, timeStepsPerYear, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlIntegralHestonVarianceOptionEngine(QlHestonProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new IntegralHestonVarianceOptionEngine(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCHullWhiteCapFloorEngine1(int rngtrait, int stattrait, QlHullWhite* model, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCHullWhiteCapFloorEngine1Aux(rngtrait, stattrait, *arg(model), brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCHimalayaEngine1(int rngtrait, int stattrait, QlStochasticProcessArray* processes, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCHimalayaEngine1Aux(rngtrait, stattrait, *arg(processes), brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCPagodaEngine1(int rngtrait, int stattrait, QlStochasticProcessArray* processes, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCPagodaEngine1Aux(rngtrait, stattrait, *arg(processes), brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCEverestEngine1(int rngtrait, int stattrait, QlStochasticProcessArray* processes, unsigned timeSteps, unsigned timeStepsPerYear, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCEverestEngine1Aux(rngtrait, stattrait, *arg(processes), timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCEuropeanBasketEngine1(int rngtrait, int stattrait, QlStochasticProcessArray* processes, unsigned timeSteps, unsigned timeStepsPerYear, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCEuropeanBasketEngine1Aux(rngtrait, stattrait, *arg(processes), timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCAmericanBasketEngine1(int rngtrait, QlStochasticProcessArray* processes, unsigned timeSteps, unsigned timeStepsPerYear, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, unsigned nCalibrationSamples, unsigned polynomialOrder, int polynomialType, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCAmericanBasketEngine1Aux(rngtrait, *arg(processes), timeSteps, timeStepsPerYear, brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed, nCalibrationSamples, polynomialOrder, (LsmBasisSystem::PolynomialType)polynomialType))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlMCPerformanceEngine1(int rngtrait, int stattrait, QlGeneralizedBlackScholesProcess* process, int brownianBridge, int antitheticVariate, unsigned requiredSamples, double requiredTolerance, unsigned maxSamples, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlMCPerformanceEngine1Aux(rngtrait, stattrait, *arg(process), brownianBridge, antitheticVariate, requiredSamples, requiredTolerance, maxSamples, seed))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBinomialVanillaEngine(int tree, QlGeneralizedBlackScholesProcess* process, unsigned timeSteps, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlBinomialVanillaEngineAux(tree, *arg(process), timeSteps))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdBlackScholesVanillaEngine(QlGeneralizedBlackScholesProcess* process, unsigned tGrid, unsigned xGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, int localVol, double illegalLocalVolOverwrite, int cashDividendModel, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(qlFdBlackScholesVanillaEngineAux(*arg(process), tGrid, xGrid, dampingSteps, *arg(fdScheme), localVol, illegalLocalVolOverwrite, cashDividendModel))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdBlackScholesVanillaEngine1(QlGeneralizedBlackScholesProcess* process, unsigned dividendsLen, QlDividend** dividends, unsigned tGrid, unsigned xGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, int localVol, double illegalLocalVolOverwrite, int cashDividendModel, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(allocAs<PricingEngine>(new hasquant::CheckedFdEngine<FdBlackScholesVanillaEngine>(*arg(process), qlVector(dividends, dividendsLen), tGrid, xGrid, dampingSteps, *arg(fdScheme), localVol, illegalLocalVolOverwrite, (FdBlackScholesVanillaEngine::CashDividendModel)cashDividendModel))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdBlackScholesVanillaEngine2(QlGeneralizedBlackScholesProcess* process, QlFdmQuantoHelper* quantoHelper, unsigned tGrid, unsigned xGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, int localVol, double illegalLocalVolOverwrite, int cashDividendModel, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(allocAs<PricingEngine>(new hasquant::CheckedFdEngine<FdBlackScholesVanillaEngine>(*arg(process), quantoHelper ? *arg(quantoHelper) : shared_ptr<FdmQuantoHelper>(), tGrid, xGrid, dampingSteps, *arg(fdScheme), localVol, illegalLocalVolOverwrite, (FdBlackScholesVanillaEngine::CashDividendModel)cashDividendModel))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdBlackScholesVanillaEngine3(QlGeneralizedBlackScholesProcess* process, unsigned dividendsLen, QlDividend** dividends, QlFdmQuantoHelper* quantoHelper, unsigned tGrid, unsigned xGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, int localVol, double illegalLocalVolOverwrite, int cashDividendModel, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(allocAs<PricingEngine>(new hasquant::CheckedFdEngine<FdBlackScholesVanillaEngine>(*arg(process), qlVector(dividends, dividendsLen), quantoHelper ? *arg(quantoHelper) : shared_ptr<FdmQuantoHelper>(), tGrid, xGrid, dampingSteps, *arg(fdScheme), localVol, illegalLocalVolOverwrite, (FdBlackScholesVanillaEngine::CashDividendModel)cashDividendModel))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdHestonVanillaEngine(QlHestonModel* model, unsigned tGrid, unsigned xGrid, unsigned vGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, QlLocalVolTermStructure* leverageFct, double mixingFactor, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(allocAs<PricingEngine>(new hasquant::CheckedFdEngine<FdHestonVanillaEngine>(*arg(model), tGrid, xGrid, vGrid, dampingSteps, *arg(fdScheme), leverageFct ? *arg(leverageFct) : shared_ptr<LocalVolTermStructure>(), mixingFactor))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdHestonVanillaEngine1(QlHestonModel* model, unsigned dividendsLen, QlDividend** dividends, unsigned tGrid, unsigned xGrid, unsigned vGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, QlLocalVolTermStructure* leverageFct, double mixingFactor, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(allocAs<PricingEngine>(new hasquant::CheckedFdEngine<FdHestonVanillaEngine>(*arg(model), qlVector(dividends, dividendsLen), tGrid, xGrid, vGrid, dampingSteps, *arg(fdScheme), leverageFct ? *arg(leverageFct) : shared_ptr<LocalVolTermStructure>(), mixingFactor))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlCOSHestonEngine(QlHestonModel* model, double L, unsigned N, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new COSHestonEngine(*arg(model), L, N))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlAnalyticPDFHestonEngine(QlHestonModel* model, double eps, unsigned integrationOrder, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new AnalyticPDFHestonEngine(*arg(model), eps, integrationOrder))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdBatesVanillaEngine(QlBatesModel* model, unsigned tGrid, unsigned xGrid, unsigned vGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FdBatesVanillaEngine(*arg(model), tGrid, xGrid, vGrid, dampingSteps, *arg(fdScheme)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdBatesVanillaEngine1(QlBatesModel* model, unsigned dividendsLen, QlDividend** dividends, unsigned tGrid, unsigned xGrid, unsigned vGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FdBatesVanillaEngine(*arg(model), qlVector(dividends, dividendsLen), tGrid, xGrid, vGrid, dampingSteps, *arg(fdScheme)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdBlackScholesShoutEngine(QlGeneralizedBlackScholesProcess* process, unsigned tGrid, unsigned xGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FdBlackScholesShoutEngine(*arg(process), tGrid, xGrid, dampingSteps, *arg(fdScheme)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdBlackScholesShoutEngine1(QlGeneralizedBlackScholesProcess* process, unsigned dividendsLen, QlDividend** dividends, unsigned tGrid, unsigned xGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FdBlackScholesShoutEngine(*arg(process), qlVector(dividends, dividendsLen), tGrid, xGrid, dampingSteps, *arg(fdScheme)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdHestonVanillaEngine2(QlHestonModel* model, QlFdmQuantoHelper* quantoHelper, unsigned tGrid, unsigned xGrid, unsigned vGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, QlLocalVolTermStructure* leverageFct, double mixingFactor, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(allocAs<PricingEngine>(new hasquant::CheckedFdEngine<FdHestonVanillaEngine>(*arg(model), quantoHelper ? *arg(quantoHelper) : shared_ptr<FdmQuantoHelper>(), tGrid, xGrid, vGrid, dampingSteps, *arg(fdScheme), leverageFct ? *arg(leverageFct) : shared_ptr<LocalVolTermStructure>(), mixingFactor))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdHestonVanillaEngine3(QlHestonModel* model, unsigned dividendsLen, QlDividend** dividends, QlFdmQuantoHelper* quantoHelper, unsigned tGrid, unsigned xGrid, unsigned vGrid, unsigned dampingSteps, FdmSchemeDesc *fdScheme, QlLocalVolTermStructure* leverageFct, double mixingFactor, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(allocAs<PricingEngine>(new hasquant::CheckedFdEngine<FdHestonVanillaEngine>(*arg(model), qlVector(dividends, dividendsLen), quantoHelper ? *arg(quantoHelper) : shared_ptr<FdmQuantoHelper>(), tGrid, xGrid, vGrid, dampingSteps, *arg(fdScheme), leverageFct ? *arg(leverageFct) : shared_ptr<LocalVolTermStructure>(), mixingFactor))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdHestonHullWhiteVanillaEngine(QlHestonModel* model, QlHullWhiteProcess* hwProcess, double corrEquityShortRate, unsigned tGrid, unsigned xGrid, unsigned vGrid, unsigned rGrid, unsigned dampingSteps, int controlVariate, FdmSchemeDesc *fdScheme, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FdHestonHullWhiteVanillaEngine(*arg(model), *arg(hwProcess), corrEquityShortRate, tGrid, xGrid, vGrid, rGrid, dampingSteps, controlVariate, *arg(fdScheme)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlFdHestonHullWhiteVanillaEngine1(QlHestonModel* model, QlHullWhiteProcess* hwProcess, unsigned dividendsLen, QlDividend** dividends, double corrEquityShortRate, unsigned tGrid, unsigned xGrid, unsigned vGrid, unsigned rGrid, unsigned dampingSteps, int controlVariate, FdmSchemeDesc *fdScheme, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new FdHestonHullWhiteVanillaEngine(*arg(model), *arg(hwProcess), qlVector(dividends, dividendsLen), corrEquityShortRate, tGrid, xGrid, vGrid, rGrid, dampingSteps, controlVariate, *arg(fdScheme)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBinomialConvertibleEngine(int tree, QlGeneralizedBlackScholesProcess* process, unsigned timeSteps, QlQuote* creditSpread, unsigned dividendsLen, QlDividend** dividends, QlError **e) { QlCallScope callbackScope(e);
  try {const Handle<Quote>& cs = *arg(creditSpread); DividendSchedule d = qlVector(dividends, dividendsLen);
    return ret(new QlPricingEngine(alloc(qlBinomialConvertibleEngineAux(tree, *arg(process), timeSteps, cs, d))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBlackCallableFixedRateBondEngine1(QlCallableBondVolatilityStructure* yieldVolStructure, QlYieldTermStructure* discountCurve, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BlackCallableFixedRateBondEngine(Handle<CallableBondVolatilityStructure>(*arg(yieldVolStructure)), *arg(discountCurve)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBlackCallableFixedRateBondEngine(QlQuote* fwdYieldVol, QlYieldTermStructure* discountCurve, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BlackCallableFixedRateBondEngine(*arg(fwdYieldVol), *arg(discountCurve)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBlackCallableZeroCouponBondEngine1(QlCallableBondVolatilityStructure* yieldVolStructure, QlYieldTermStructure* discountCurve, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BlackCallableZeroCouponBondEngine(Handle<CallableBondVolatilityStructure>(*arg(yieldVolStructure)), *arg(discountCurve)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlBlackCallableZeroCouponBondEngine(QlQuote* fwdYieldVol, QlYieldTermStructure* discountCurve, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new BlackCallableZeroCouponBondEngine(*arg(fwdYieldVol), *arg(discountCurve)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlTreeCallableFixedRateBondEngine1(QlShortRateModel* x0, TimeGrid* timeGrid, QlYieldTermStructure* termStructure, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new TreeCallableFixedRateBondEngine(*arg(x0), *arg(timeGrid), qlNullableHandle(arg(termStructure))))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlTreeCallableFixedRateBondEngine(QlShortRateModel* x0, unsigned timeSteps, QlYieldTermStructure* termStructure, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new TreeCallableFixedRateBondEngine(*arg(x0), timeSteps, qlNullableHandle(arg(termStructure))))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlTreeCallableZeroCouponBondEngine1(QlShortRateModel* model, TimeGrid* timeGrid, QlYieldTermStructure* termStructure, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new TreeCallableZeroCouponBondEngine(*arg(model), *arg(timeGrid), qlNullableHandle(arg(termStructure))))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlTreeCallableZeroCouponBondEngine(QlShortRateModel* model, unsigned timeSteps, QlYieldTermStructure* termStructure, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new TreeCallableZeroCouponBondEngine(*arg(model), timeSteps, qlNullableHandle(arg(termStructure))))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}

FdmSchemeDesc* qlFdmSchemeDesc(int type, double theta, double mu, QlError **e) { QlCallScope callbackScope(e);try {return alloc(new FdmSchemeDesc((FdmSchemeDesc::FdmSchemeType)type, theta, mu));} catch (std::exception& er) {return handleException<FdmSchemeDesc*>(e, er);}}
FdmSchemeDesc* qlFdmSchemeDescCraigSneyd(QlError **e) { QlCallScope callbackScope(e);try {return alloc(new FdmSchemeDesc(FdmSchemeDesc::CraigSneyd()));} catch (std::exception& er) {return handleException<FdmSchemeDesc*>(e, er);}}
FdmSchemeDesc* qlFdmSchemeDescDouglas(QlError **e) { QlCallScope callbackScope(e);try {return alloc(new FdmSchemeDesc(FdmSchemeDesc::Douglas()));} catch (std::exception& er) {return handleException<FdmSchemeDesc*>(e, er);}}
FdmSchemeDesc* qlFdmSchemeDescExplicitEuler(QlError **e) { QlCallScope callbackScope(e);try {return alloc(new FdmSchemeDesc(FdmSchemeDesc::ExplicitEuler()));} catch (std::exception& er) {return handleException<FdmSchemeDesc*>(e, er);}}
FdmSchemeDesc* qlFdmSchemeDescHundsdorfer(QlError **e) { QlCallScope callbackScope(e);try {return alloc(new FdmSchemeDesc(FdmSchemeDesc::Hundsdorfer()));} catch (std::exception& er) {return handleException<FdmSchemeDesc*>(e, er);}}
FdmSchemeDesc* qlFdmSchemeDescImplicitEuler(QlError **e) { QlCallScope callbackScope(e);try {return alloc(new FdmSchemeDesc(FdmSchemeDesc::ImplicitEuler()));} catch (std::exception& er) {return handleException<FdmSchemeDesc*>(e, er);}}
FdmSchemeDesc* qlFdmSchemeDescModifiedCraigSneyd(QlError **e) { QlCallScope callbackScope(e);try {return alloc(new FdmSchemeDesc(FdmSchemeDesc::ModifiedCraigSneyd()));} catch (std::exception& er) {return handleException<FdmSchemeDesc*>(e, er);}}
FdmSchemeDesc* qlFdmSchemeDescModifiedHundsdorfer(QlError **e) { QlCallScope callbackScope(e);try {return alloc(new FdmSchemeDesc(FdmSchemeDesc::ModifiedHundsdorfer()));} catch (std::exception& er) {return handleException<FdmSchemeDesc*>(e, er);}}
FdmSchemeDesc* qlFdmSchemeDescMethodOfLines(double eps, double relInitStepSize, QlError **e) { QlCallScope callbackScope(e);try {return alloc(new FdmSchemeDesc(FdmSchemeDesc::MethodOfLines(eps, relInitStepSize)));} catch (std::exception& er) {return handleException<FdmSchemeDesc*>(e, er);}}
void qlFreeFdmSchemeDesc(FdmSchemeDesc *o) {del(o);}

// Drives FdmBackwardSolver::rollback with a Haskell-defined operator/step condition instead of a
// bound mesher+FdmInnerValueCalculator -- see QuantLib.Method.fdmRollback's haddock and the
// HsFdmLinearOpComposite/HsFdmStepCondition comments above. bcSet is always the empty
// FdmBoundaryConditionSet(); boundary conditions are not bound. A null stepCondFn means no step
// condition at all (matches FdmBackwardSolver's own null-condition default, an empty
// FdmStepConditionComposite({}, {})).
void qlFdmRollback(unsigned opSize, QlCallback* applyFn, QlCallback* applyDirFn, QlCallback* solveSplitFn,
                    QlCallback* stepCondFn, unsigned stoppingTimesLen, double* stoppingTimes,
                    FdmSchemeDesc* schemeDesc,
                    unsigned gridLen, double* grid,
                    double from, double to, unsigned steps, unsigned dampingSteps,
                    unsigned* outLen, double** outValues, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {
    ext::shared_ptr<FdmLinearOpComposite> map(alloc(new HsFdmLinearOpComposite(opSize, *arg(applyFn), *arg(applyDirFn), *arg(solveSplitFn))));
    FdmStepConditionComposite::Conditions conditions;
    std::list<std::vector<Time> > stoppingTimesList;
    if (stepCondFn) {
      conditions.push_back(ext::shared_ptr<StepCondition<Array> >(alloc(new HsFdmStepCondition(*arg(stepCondFn)))));
      stoppingTimesList.push_back(std::vector<Time>(stoppingTimes, stoppingTimes + stoppingTimesLen));
    }
    ext::shared_ptr<FdmStepConditionComposite> condition(alloc(new FdmStepConditionComposite(stoppingTimesList, conditions)));
    FdmBackwardSolver solver(map, FdmBoundaryConditionSet(), condition, *arg(schemeDesc));
    Array a(grid, grid + gridLen);
    solver.rollback(a, from, to, steps, dampingSteps);
    return a;
  }, outLen, outValues);
  } catch (std::exception& er) {qlSetError(e, er.what());}}

void qlFreeFdm1dMesher(QlFdm1dMesher *o) {del(o);}
void qlFreeFdmMesher(QlFdmMesher *o) {del(o);}

QlFdm1dMesher* qlPredefined1dMesher(unsigned len, double* points, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdm1dMesher(alloc(new Predefined1dMesher(std::vector<Real>(points, points + len)))));
  } catch (std::exception& er) {return handleException<QlFdm1dMesher*>(e, er);}}
QlFdm1dMesher* qlUniform1dMesher(double start, double end, unsigned size, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdm1dMesher(alloc(new Uniform1dMesher(start, end, size))));
  } catch (std::exception& er) {return handleException<QlFdm1dMesher*>(e, er);}}
QlFdm1dMesher* qlConcentrating1dMesher(double start, double end, unsigned size, double cPointLoc, double cPointDensity, int requireCPoint, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdm1dMesher(alloc(new Concentrating1dMesher(start, end, size, std::pair<Real, Real>(cPointLoc, cPointDensity), requireCPoint))));
  } catch (std::exception& er) {return handleException<QlFdm1dMesher*>(e, er);}}
QlFdm1dMesher* qlConcentrating1dMesherMulti(double start, double end, unsigned size, unsigned cPointsLen, double* cPointLoc, double* cPointDensity, int* cPointRequire, double tol, QlError **e) { QlCallScope callbackScope(e);
  try {std::vector<std::tuple<Real, Real, bool> > cPoints;
    cPoints.reserve(cPointsLen);
    for (unsigned i = 0; i < cPointsLen; ++i)
      cPoints.push_back(std::make_tuple(cPointLoc[i], cPointDensity[i], cPointRequire[i] != 0));
    return ret(new QlFdm1dMesher(alloc(new Concentrating1dMesher(start, end, size, cPoints, tol))));
  } catch (std::exception& er) {return handleException<QlFdm1dMesher*>(e, er);}}
QlFdm1dMesher* qlGluedMesher(QlFdm1dMesher* left, QlFdm1dMesher* right, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdm1dMesher(alloc(new Glued1dMesher(**arg(left), **arg(right)))));
  } catch (std::exception& er) {return handleException<QlFdm1dMesher*>(e, er);}}
QlFdm1dMesher* qlFdmBlackScholesMesher(unsigned size, QlGeneralizedBlackScholesProcess* process, double maturity, double strike,
    double xMinConstraint, double xMaxConstraint, double eps, double scaleFactor, double cPointLoc, double cPointDensity,
    unsigned dividendsLen, QlDividend** dividends, QlFdmQuantoHelper* fdmQuantoHelper, double spotAdjustment, QlError **e) { QlCallScope callbackScope(e);
  try {DividendSchedule d = qlVector(dividends, dividendsLen);
    return ret(new QlFdm1dMesher(alloc(new FdmBlackScholesMesher(size, *arg(process), maturity, strike,
      xMinConstraint, xMaxConstraint, eps, scaleFactor, std::pair<Real, Real>(cPointLoc, cPointDensity), d,
      fdmQuantoHelper ? *arg(fdmQuantoHelper) : shared_ptr<FdmQuantoHelper>(), spotAdjustment))));
  } catch (std::exception& er) {return handleException<QlFdm1dMesher*>(e, er);}}
QlFdm1dMesher* qlFdmCev1dMesher(unsigned size, double f0, double alpha, double beta, double maturity, double eps, double scaleFactor, double cPointLoc, double cPointDensity, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdm1dMesher(alloc(new FdmCEV1dMesher(size, f0, alpha, beta, maturity, eps, scaleFactor, std::pair<Real, Real>(cPointLoc, cPointDensity)))));
  } catch (std::exception& er) {return handleException<QlFdm1dMesher*>(e, er);}}
QlFdm1dMesher* qlExponentialJump1dMesher(unsigned steps, double beta, double jumpIntensity, double eta, double eps, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdm1dMesher(alloc(new ExponentialJump1dMesher(steps, beta, jumpIntensity, eta, eps))));
  } catch (std::exception& er) {return handleException<QlFdm1dMesher*>(e, er);}}
QlFdm1dMesher* qlFdmSimpleProcess1dMesher(unsigned size, QlStochasticProcess1D* process, double maturity, unsigned tAvgSteps, double epsilon, double mandatoryPoint, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdm1dMesher(alloc(new FdmSimpleProcess1dMesher(size, *arg(process), maturity, tAvgSteps, epsilon, mandatoryPoint))));
  } catch (std::exception& er) {return handleException<QlFdm1dMesher*>(e, er);}}
QlFdm1dMesher* qlFdmHestonVarianceMesher(unsigned size, QlHestonProcess* process, double maturity, unsigned tAvgSteps, double epsilon, double mixingFactor, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdm1dMesher(alloc(new FdmHestonVarianceMesher(size, *arg(process), maturity, tAvgSteps, epsilon, mixingFactor))));
  } catch (std::exception& er) {return handleException<QlFdm1dMesher*>(e, er);}}
QlFdm1dMesher* qlFdmHestonLocalVolatilityVarianceMesher(unsigned size, QlHestonProcess* process, QlLocalVolTermStructure* leverageFct, double maturity, unsigned tAvgSteps, double epsilon, double mixingFactor, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdm1dMesher(alloc(new FdmHestonLocalVolatilityVarianceMesher(size, *arg(process), *arg(leverageFct), maturity, tAvgSteps, epsilon, mixingFactor))));
  } catch (std::exception& er) {return handleException<QlFdm1dMesher*>(e, er);}}
QlFdmMesher* qlFdmMesherComposite(unsigned meshersLen, QlFdm1dMesher** meshers, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdmMesher(alloc(new FdmMesherComposite(qlVector(meshers, meshersLen)))));
  } catch (std::exception& er) {return handleException<QlFdmMesher*>(e, er);}}
void qlFdmMesherLocations(QlFdmMesher* mesher, unsigned direction, unsigned* outLen, double** outValues, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return (*arg(mesher))->locations(direction);}, outLen, outValues);
  } catch (std::exception& er) {qlSetError(e, er.what());}}

void qlFreeFdmInnerValueCalculator(QlFdmInnerValueCalculator *o) {del(o);}

// Give Haskell-defined inner-value callbacks a reusable QlFdmInnerValueCalculator lifetime.
QlFdmInnerValueCalculator* qlFdmInnerValueCalculatorFromFunctions(QlFdmMesher* mesher, QlCallback* innerValueFn, QlCallback* avgInnerValueFn, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdmInnerValueCalculator(alloc(new HsFdmInnerValueCalculator(*arg(mesher), *arg(innerValueFn), *arg(avgInnerValueFn)))));
  } catch (std::exception& er) {return handleException<QlFdmInnerValueCalculator*>(e, er);}}

double qlFdmInnerValueCalculatorEval(QlFdmInnerValueCalculator* calc, QlFdmMesher* mesher, unsigned ndims, unsigned* coords, double t, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(calc))->innerValue(fdmIteratorAt(mesher, ndims, coords), t);
  } catch (std::exception& er) {qlSetError(e, er.what()); return 0.0;}}
double qlFdmInnerValueCalculatorAvgEval(QlFdmInnerValueCalculator* calc, QlFdmMesher* mesher, unsigned ndims, unsigned* coords, double t, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(calc))->avgInnerValue(fdmIteratorAt(mesher, ndims, coords), t);
  } catch (std::exception& er) {qlSetError(e, er.what()); return 0.0;}}

// Sibling of qlFdmRollback that derives its own initial grid from a mesher + a (native or
// Haskell-callback-driven) FdmInnerValueCalculator (calc->avgInnerValue(iter, maturity) per node)
// instead of taking a precomputed array -- everything else (operator/step-condition/scheme/
// rollback) is identical, reusing HsFdmLinearOpComposite/HsFdmStepCondition verbatim.
// Fdm1DimSolver/FdmNdimSolver themselves (their own LazyObject caching and spline interpolation)
// are not bound; a caller wanting interpolation combines this function's result with
// qlFdmMesherLocations itself.
void qlFdmSolve(QlFdmMesher* mesher, QlFdmInnerValueCalculator* calculator,
                unsigned opSize, QlCallback* applyFn, QlCallback* applyDirFn, QlCallback* solveSplitFn,
                QlCallback* stepCondFn, unsigned stoppingTimesLen, double* stoppingTimes,
                FdmSchemeDesc* schemeDesc,
                double maturity, double to, unsigned steps, unsigned dampingSteps,
                unsigned* outLen, double** outValues, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {
    shared_ptr<FdmMesher> m = *arg(mesher);
    shared_ptr<FdmInnerValueCalculator> calc = *arg(calculator);
    Array a(m->layout()->size());
    for (const auto& iter : *m->layout())
      a[iter.index()] = calc->avgInnerValue(iter, maturity);

    ext::shared_ptr<FdmLinearOpComposite> map(alloc(new HsFdmLinearOpComposite(opSize, *arg(applyFn), *arg(applyDirFn), *arg(solveSplitFn))));
    FdmStepConditionComposite::Conditions conditions;
    std::list<std::vector<Time> > stoppingTimesList;
    if (stepCondFn) {
      conditions.push_back(ext::shared_ptr<StepCondition<Array> >(alloc(new HsFdmStepCondition(*arg(stepCondFn)))));
      stoppingTimesList.push_back(std::vector<Time>(stoppingTimes, stoppingTimes + stoppingTimesLen));
    }
    ext::shared_ptr<FdmStepConditionComposite> condition(alloc(new FdmStepConditionComposite(stoppingTimesList, conditions)));
    FdmBackwardSolver solver(map, FdmBoundaryConditionSet(), condition, *arg(schemeDesc));
    solver.rollback(a, maturity, to, steps, dampingSteps);
    return a;
  }, outLen, outValues);
  } catch (std::exception& er) {qlSetError(e, er.what());}}

// Native inner-value calculators avoid per-node Haskell callbacks and return the shared base type.
QlFdmInnerValueCalculator* qlFdmZeroInnerValue(QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdmInnerValueCalculator(alloc(new FdmZeroInnerValue())));
  } catch (std::exception& er) {return handleException<QlFdmInnerValueCalculator*>(e, er);}}

QlFdmInnerValueCalculator* qlFdmCellAveragingInnerValue(QlPayoff* payoff, QlFdmMesher* mesher, unsigned direction, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdmInnerValueCalculator(alloc(new FdmCellAveragingInnerValue(*arg(payoff), *arg(mesher), direction))));
  } catch (std::exception& er) {return handleException<QlFdmInnerValueCalculator*>(e, er);}}

// gridMapping is a genuine per-node Haskell callback (invoked from inside avgInnerValueCalc's
// Simpson integration and from every innerValue call), unlike the identity-mapping ctor above --
// see QuantLib.Method.withCustomCellAveragingInnerValue's haddock for why its Haskell wrapper must
// be continuation-style, same reasoning as qlFdmInnerValueCalculatorFromFunctions/
// withCustomFdmInnerValueCalculator.
QlFdmInnerValueCalculator* qlFdmCellAveragingInnerValueMapped(QlPayoff* payoff, QlFdmMesher* mesher, unsigned direction, QlCallback* mappingFn, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdmInnerValueCalculator(alloc(new FdmCellAveragingInnerValue(*arg(payoff), *arg(mesher), direction,
    hasquant::UnaryCallback{*arg(mappingFn)}))));
  } catch (std::exception& er) {return handleException<QlFdmInnerValueCalculator*>(e, er);}}

QlFdmInnerValueCalculator* qlFdmLogInnerValue(QlPayoff* payoff, QlFdmMesher* mesher, unsigned direction, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdmInnerValueCalculator(alloc(new FdmLogInnerValue(*arg(payoff), *arg(mesher), direction))));
  } catch (std::exception& er) {return handleException<QlFdmInnerValueCalculator*>(e, er);}}

QlFdmInnerValueCalculator* qlFdmLogBasketInnerValue(QlBasketPayoff* payoff, QlFdmMesher* mesher, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFdmInnerValueCalculator(alloc(new FdmLogBasketInnerValue(*arg(payoff), *arg(mesher)))));
  } catch (std::exception& er) {return handleException<QlFdmInnerValueCalculator*>(e, er);}}

QlFdmInnerValueCalculator* qlFdmAffineG2ModelSwapInnerValue(QlG2* disModel, QlG2* fwdModel, QlFixedVsFloatingSwap* swap,
    unsigned exDatesLen, double* exerciseTimes, int* exerciseDates, QlFdmMesher* mesher, unsigned direction, QlError **e) { QlCallScope callbackScope(e);
  return fdmAffineModelSwapInnerValue<G2>(disModel, fwdModel, swap, exDatesLen, exerciseTimes, exerciseDates, mesher, direction, e);
}
QlFdmInnerValueCalculator* qlFdmAffineHullWhiteModelSwapInnerValue(QlHullWhite* disModel, QlHullWhite* fwdModel, QlFixedVsFloatingSwap* swap,
    unsigned exDatesLen, double* exerciseTimes, int* exerciseDates, QlFdmMesher* mesher, unsigned direction, QlError **e) { QlCallScope callbackScope(e);
  return fdmAffineModelSwapInnerValue<HullWhite>(disModel, fwdModel, swap, exDatesLen, exerciseTimes, exerciseDates, mesher, direction, e);
}

void qlFreeFdmQuantoHelper(QlFdmQuantoHelper *o) {del(o);}
QlFdmQuantoHelper* qlFdmQuantoHelper(QlYieldTermStructure* rTS, QlYieldTermStructure* fTS, QlBlackVolTermStructure* fxVolTS, double equityFxCorrelation, double exchRateATMlevel, QlError **e) { QlCallScope callbackScope(e);
  try {shared_ptr<YieldTermStructure> r = (*arg(rTS)).currentLink(), f = (*arg(fTS)).currentLink();
    shared_ptr<BlackVolTermStructure> fxVol = (*arg(fxVolTS)).currentLink();
    return ret(new QlFdmQuantoHelper(alloc(new FdmQuantoHelper(r, f, fxVol, equityFxCorrelation, exchRateATMlevel))));
  } catch (std::exception& er) {return handleException<QlFdmQuantoHelper*>(e, er);}}
double qlFdmQuantoHelperQuantoAdjustment(QlFdmQuantoHelper* helper, double equityVol, double t1, double t2, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(helper))->quantoAdjustment(equityVol, t1, t2);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
void qlFreeGJRGARCHModel(QlGJRGARCHModel *o) {del(o);}
void qlFreeHestonModel(QlHestonModel *o) {del(o);}
void qlFreeBrownianGeneratorFactory(QlBrownianGeneratorFactory *o) {del(o);}
QlBrownianGeneratorFactory* qlMTBrownianGeneratorFactory(unsigned long seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlBrownianGeneratorFactory(alloc(new MTBrownianGeneratorFactory(seed))));
  } catch (std::exception& er) {return handleException<QlBrownianGeneratorFactory*>(e, er);}}
QlBrownianGeneratorFactory* qlSobolBrownianGeneratorFactory(int ordering, unsigned long seed, int directionIntegers, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlBrownianGeneratorFactory(alloc(new SobolBrownianGeneratorFactory(
    (SobolBrownianGenerator::Ordering)ordering, seed, (SobolRsg::DirectionIntegers)directionIntegers))));
  } catch (std::exception& er) {return handleException<QlBrownianGeneratorFactory*>(e, er);}}
void qlFreeHestonSLVMCModel(QlHestonSLVMCModel *o) {del(o);}
QlHestonSLVMCModel* qlHestonSLVMCModel(QlLocalVolTermStructure* localVol, QlHestonModel* hestonModel, QlBrownianGeneratorFactory* factory, int endDate, unsigned timeStepsPerYear, unsigned nBins, unsigned calibrationPaths, unsigned mandatoryDatesLen, int* mandatoryDates, double mixingFactor, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlHestonSLVMCModel(alloc(new HestonSLVMCModel(
    Handle<LocalVolTermStructure>(*arg(localVol)), Handle<HestonModel>(*arg(hestonModel)), *arg(factory),
    Date(endDate), timeStepsPerYear, nBins, calibrationPaths, qlDateVector(mandatoryDates, mandatoryDatesLen), mixingFactor))));
  } catch (std::exception& er) {return handleException<QlHestonSLVMCModel*>(e, er);}}
QlLocalVolTermStructure* qlHestonSLVMCModelLeverageFunction(QlHestonSLVMCModel* o, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlLocalVolTermStructure((*arg(o))->leverageFunction()));
  } catch (std::exception& er) {return handleException<QlLocalVolTermStructure*>(e, er);}}
void qlFreeHestonSLVFDMModel(QlHestonSLVFDMModel *o) {del(o);}
QlHestonSLVFDMModel* qlHestonSLVFDMModel(QlLocalVolTermStructure* localVol, QlHestonModel* hestonModel, int endDate,
    unsigned xGrid, unsigned vGrid, unsigned tMaxStepsPerYear, unsigned tMinStepsPerYear, double tStepNumberDecay,
    unsigned nRannacherTimeSteps, unsigned predictionCorretionSteps, double x0Density, double localVolEpsProb,
    unsigned maxIntegrationIterations, double vLowerEps, double vUpperEps, double vMin, double v0Density,
    double vLowerBoundDensity, double vUpperBoundDensity, double leverageFctPropEps, int greensAlgorithm,
    int trafoType, FdmSchemeDesc* schemeDesc, int logging, unsigned mandatoryDatesLen, int* mandatoryDates,
    double mixingFactor, QlError **e) { QlCallScope callbackScope(e);
  try {
    HestonSLVFokkerPlanckFdmParams p = {xGrid, vGrid, tMaxStepsPerYear, tMinStepsPerYear, tStepNumberDecay,
      nRannacherTimeSteps, predictionCorretionSteps, x0Density, localVolEpsProb, maxIntegrationIterations,
      vLowerEps, vUpperEps, vMin, v0Density, vLowerBoundDensity, vUpperBoundDensity, leverageFctPropEps,
      (FdmHestonGreensFct::Algorithm)greensAlgorithm, (FdmSquareRootFwdOp::TransformationType)trafoType,
      *arg(schemeDesc)};
    return ret(new QlHestonSLVFDMModel(alloc(new HestonSLVFDMModel(
      Handle<LocalVolTermStructure>(*arg(localVol)), Handle<HestonModel>(*arg(hestonModel)), Date(endDate), p,
      logging, qlDateVector(mandatoryDates, mandatoryDatesLen), mixingFactor))));
  } catch (std::exception& er) {return handleException<QlHestonSLVFDMModel*>(e, er);}}
QlLocalVolTermStructure* qlHestonSLVFDMModelLeverageFunction(QlHestonSLVFDMModel* o, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlLocalVolTermStructure((*arg(o))->leverageFunction()));
  } catch (std::exception& er) {return handleException<QlLocalVolTermStructure*>(e, er);}}
HestonSLVFDMLogEntries* qlHestonSLVFDMModelLogEntries(QlHestonSLVFDMModel* o, QlError **e) { QlCallScope callbackScope(e);
  try {
    std::unique_ptr<HestonSLVFDMLogEntries> out(new HestonSLVFDMLogEntries);
    const std::list<HestonSLVFDMModel::LogEntry>& entries = (*arg(o))->logEntries();
    out->entries.reserve(entries.size());
    for (const auto& entry : entries) {
      HestonSLVFDMLogEntries::Entry copy;
      copy.time = entry.t;
      const auto& meshers = entry.mesher->getFdm1dMeshers();
      copy.spotGrid.assign(meshers.at(0)->locations().begin(), meshers.at(0)->locations().end());
      copy.varianceGrid.assign(meshers.at(1)->locations().begin(), meshers.at(1)->locations().end());
      copy.density.assign(entry.prob->begin(), entry.prob->end());
      out->entries.push_back(std::move(copy));
    }
    return ret(out.release());
  } catch (std::exception& er) {return handleException<HestonSLVFDMLogEntries*>(e, er);}}
void qlFreeHestonSLVFDMLogEntries(HestonSLVFDMLogEntries* o) {del(o);}
unsigned qlHestonSLVFDMLogEntriesSize(HestonSLVFDMLogEntries* o) {return (unsigned)o->entries.size();}
double qlHestonSLVFDMLogEntriesTime(HestonSLVFDMLogEntries* o, unsigned i, QlError **e) { QlCallScope callbackScope(e);
  try {return o->entries.at(i).time;
  } catch (std::exception& er) {return handleException<double>(e, er);}}
void qlHestonSLVFDMLogEntriesSpotGrid(HestonSLVFDMLogEntries* o, unsigned i, unsigned* len, double** values, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return o->entries.at(i).spotGrid;}, len, values);
  } catch (std::exception& er) {qlSetError(e, er.what());}}
void qlHestonSLVFDMLogEntriesVarianceGrid(HestonSLVFDMLogEntries* o, unsigned i, unsigned* len, double** values, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return o->entries.at(i).varianceGrid;}, len, values);
  } catch (std::exception& er) {qlSetError(e, er.what());}}
void qlHestonSLVFDMLogEntriesDensity(HestonSLVFDMLogEntries* o, unsigned i, unsigned* rows, unsigned* cols, unsigned* len, double** values, QlError **e) { QlCallScope callbackScope(e);
  OutValue<unsigned> rowResult(rows), colResult(cols);
  OutArrayResult<double> result(len, values);
  try {
    const auto& entry = o->entries.at(i);
    double *out = result.allocate((unsigned)entry.density.size());
    std::copy(entry.density.begin(), entry.density.end(), out);
    rowResult.set((unsigned)entry.varianceGrid.size());
    colResult.set((unsigned)entry.spotGrid.size());
    result.commit(); rowResult.commit(); colResult.commit();
  } catch (std::exception& er) {qlSetError(e, er.what());}}
void qlFreeBatesModel(QlBatesModel *o) {del(o);}
void qlFreePiecewiseTimeDependentHestonModel(QlPiecewiseTimeDependentHestonModel *o) {del(o);}
void qlFreeShortRateModel(QlShortRateModel *o) {del(o);}
void qlFreeAffineModel(QlAffineModel *o) {del(o);}
double qlAffineModelDiscount(QlAffineModel* o, double t, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->discount(t);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlAffineModelDiscountBond(QlAffineModel* o, double now, double maturity, unsigned factorsLen, double* factors, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->discountBond(now, maturity, Array(factors, factors+factorsLen));
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlAffineModelDiscountBondOption(QlAffineModel* o, int type, double strike, double maturity, int haveBondStart, double bondStart, double bondMaturity, QlError **e) { QlCallScope callbackScope(e);
  try {return haveBondStart
    ? (*arg(o))->discountBondOption((Option::Type)type, strike, maturity, bondStart, bondMaturity)
    : (*arg(o))->discountBondOption((Option::Type)type, strike, maturity, bondMaturity);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
void qlFreeOneFactorAffineModel(QlOneFactorAffineModel *o) {del(o);}
double qlHullWhiteConvexityBias(double futurePrice, double t, double T, double sigma, double a, QlError **e) { QlCallScope callbackScope(e);
  try {return HullWhite::convexityBias(futurePrice, t, T, sigma, a);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
QlAffineModel* qlOneFactorAffineModelAsAffineModel(QlOneFactorAffineModel *o) {return ret(new QlAffineModel(*arg(o)));}
void qlFreeLiborForwardModel(QlLiborForwardModel *o) {del(o);}
QlAffineModel* qlLiborForwardModelAsAffineModel(QlLiborForwardModel *o) {return ret(new QlAffineModel(*arg(o)));}
void qlFreeHullWhite(QlHullWhite *o) {del(o);}
QlOneFactorAffineModel* qlHullWhiteAsOneFactorAffineModel(QlHullWhite *o) {return ret(new QlOneFactorAffineModel(*arg(o)));}
void qlFreeCalibratedModel(QlCalibratedModel *o) {del(o);}

QlBatesModel* qlBatesModel(QlBatesProcess* process, QlError **e) { QlCallScope callbackScope(e);try {return ret(new QlBatesModel(alloc(new BatesModel(*arg(process)))));} catch (std::exception& er) {return handleException<QlBatesModel*>(e, er);}}
QlShortRateModel* qlBlackKarasinski(QlYieldTermStructure* termStructure, double a, double sigma, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlShortRateModel(alloc(new BlackKarasinski(*arg(termStructure), a, sigma))));
  } catch (std::exception& er) {return handleException<QlShortRateModel*>(e, er);}}
QlOneFactorAffineModel* qlCoxIngersollRoss(double r0, double theta, double k, double sigma, int withFellerConstraint, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlOneFactorAffineModel(alloc(new CoxIngersollRoss(r0, theta, k, sigma, withFellerConstraint))));
  } catch (std::exception& er) {return handleException<QlOneFactorAffineModel*>(e, er);}}
QlOneFactorAffineModel* qlExtendedCoxIngersollRoss(QlYieldTermStructure* termStructure, double theta, double k, double sigma, double x0, int withFellerConstraint, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlOneFactorAffineModel(alloc(new ExtendedCoxIngersollRoss(*arg(termStructure), theta, k, sigma, x0, withFellerConstraint))));
  } catch (std::exception& er) {return handleException<QlOneFactorAffineModel*>(e, er);}}
QlG2* qlG2(QlYieldTermStructure* termStructure, double a, double sigma, double b, double eta, double rho, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlG2(alloc(new G2(*arg(termStructure), a, sigma, b, eta, rho))));
  } catch (std::exception& er) {return handleException<QlG2*>(e, er);}}
QlShortRateModel* qlGeneralizedHullWhite(QlYieldTermStructure* yieldtermStructure, unsigned speedstructureLen, int* speedstructure, unsigned volstructureLen, int* volstructure, unsigned speedLen, double* speed, unsigned volLen, double* vol, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlShortRateModel(alloc(new GeneralizedHullWhite(*arg(yieldtermStructure), qlDateVector(speedstructure, speedstructureLen), qlDateVector(volstructure, volstructureLen), std::vector<double>(speed, speed+speedLen), std::vector<double>(vol, vol+volLen)))));
  } catch (std::exception& er) {return handleException<QlShortRateModel*>(e, er);}}
QlGJRGARCHModel* qlGJRGARCHModel(QlGJRGARCHProcess* process, QlError **e) { QlCallScope callbackScope(e);try {return ret(new QlGJRGARCHModel(alloc(new GJRGARCHModel(*arg(process)))));} catch (std::exception& er) {return handleException<QlGJRGARCHModel*>(e, er);}}
QlHestonModel* qlHestonModel(QlHestonProcess* process, QlError **e) { QlCallScope callbackScope(e);try {return ret(new QlHestonModel(alloc(new HestonModel(*arg(process)))));} catch (std::exception& er) {return handleException<QlHestonModel*>(e, er);}}
QlHullWhite* qlHullWhite(QlYieldTermStructure* termStructure, double a, double sigma, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlHullWhite(alloc(new HullWhite(*arg(termStructure), a, sigma))));
  } catch (std::exception& er) {return handleException<QlHullWhite*>(e, er);}}
QlCalibratedModel* qlVarianceGammaModel(QlVarianceGammaProcess* process, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlCalibratedModel(alloc(new VarianceGammaModel(*arg(process)))));
  } catch (std::exception& er) {return handleException<QlCalibratedModel*>(e, er);}}
QlOneFactorAffineModel* qlVasicek(double r0, double a, double b, double sigma, double lambda, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlOneFactorAffineModel(alloc(new Vasicek(r0, a, b, sigma, lambda))));
  } catch (std::exception& er) {return handleException<QlOneFactorAffineModel*>(e, er);}}

void qlFreeG2(QlG2 *o) {del(o);}
QlAffineModel* qlG2AsAffineModel(QlG2 *o) {return ret(new QlAffineModel(*arg(o)));}
QlShortRateModel* qlG2AsShortRateModel(QlG2 *o) {return ret(new QlShortRateModel(*arg(o)));}
void qlFreeShortRateDynamics(QlShortRateDynamics *o) {del(o);}
QlShortRateDynamics* qlG2Dynamics(QlG2 *o, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlShortRateDynamics((*arg(o))->dynamics()));
  } catch (std::exception& er) {return handleException<QlShortRateDynamics*>(e, er);}}
double qlShortRateDynamicsShortRate(QlShortRateDynamics *o, double t, double x, double y, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->shortRate(t, x, y);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
void qlFreeBatesDetJumpModel(QlBatesDetJumpModel *o) {del(o);}
QlBatesModel* qlBatesDetJumpModelAsBatesModel(QlBatesDetJumpModel *o) {return ret(new QlBatesModel(*arg(o)));}
void qlFreeBatesDoubleExpDetJumpModel(QlBatesDoubleExpDetJumpModel *o) {del(o);}
QlBatesDoubleExpModel* qlBatesDoubleExpDetJumpModelAsBatesDoubleExpModel(QlBatesDoubleExpDetJumpModel *o) {return ret(new QlBatesDoubleExpModel(*arg(o)));}
void qlFreeBatesDoubleExpModel(QlBatesDoubleExpModel *o) {del(o);}
QlHestonModel* qlBatesDoubleExpModelAsHestonModel(QlBatesDoubleExpModel *o) {return ret(new QlHestonModel(*arg(o)));}
void qlFreeLmCorrelationModel(QlLmCorrelationModel *o) {del(o);}
void qlFreeLmVolatilityModel(QlLmVolatilityModel *o) {del(o);}

QlLmCorrelationModel* qlLmConstWrapperCorrelationModel(QlLmCorrelationModel* corrModel, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlLmCorrelationModel(alloc(new LmConstWrapperCorrelationModel(*arg(corrModel)))));
  } catch (std::exception& er) {return handleException<QlLmCorrelationModel*>(e, er);}}
QlLmVolatilityModel* qlLmConstWrapperVolatilityModel(QlLmVolatilityModel* volaModel, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlLmVolatilityModel(alloc(new LmConstWrapperVolatilityModel(*arg(volaModel)))));
  } catch (std::exception& er) {return handleException<QlLmVolatilityModel*>(e, er);}}
QlLmCorrelationModel* qlLmExponentialCorrelationModel(unsigned size, double rho, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlLmCorrelationModel(alloc(new LmExponentialCorrelationModel(size, rho))));
  } catch (std::exception& er) {return handleException<QlLmCorrelationModel*>(e, er);}}
QlLmVolatilityModel* qlLmFixedVolatilityModel(unsigned volatilitiesLen, double* volatilities, unsigned startTimesLen, double * startTimes, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlLmVolatilityModel(alloc(new LmFixedVolatilityModel(Array(volatilities, volatilities+volatilitiesLen), std::vector<double>(startTimes, startTimes+startTimesLen)))));
  } catch (std::exception& er) {return handleException<QlLmVolatilityModel*>(e, er);}}
QlLmCorrelationModel* qlLmLinearExponentialCorrelationModel(unsigned size, double rho, double beta, unsigned factors, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlLmCorrelationModel(alloc(new LmLinearExponentialCorrelationModel(size, rho, beta, factors))));
  } catch (std::exception& er) {return handleException<QlLmCorrelationModel*>(e, er);}}
QlLmVolatilityModel* qlLmLinearExponentialVolatilityModel(unsigned fixingTimesLen, double * fixingTimes, double a, double b, double c, double d, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlLmVolatilityModel(alloc(new LmLinearExponentialVolatilityModel(std::vector<double>(fixingTimes, fixingTimes+fixingTimesLen), a, b, c, d))));
  } catch (std::exception& er) {return handleException<QlLmVolatilityModel*>(e, er);}}
QlLiborForwardModel* qlLiborForwardModel(QlLiborForwardModelProcess* process, QlLmVolatilityModel* volaModel, QlLmCorrelationModel* corrModel, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlLiborForwardModel(alloc(new LiborForwardModel(*arg(process), *arg(volaModel), *arg(corrModel)))));
  } catch (std::exception& er) {return handleException<QlLiborForwardModel*>(e, er);}}
double qlLiborForwardModelS0(QlLiborForwardModel* o, unsigned alpha, unsigned beta, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->S_0(alpha, beta);} catch (std::exception& er) {return handleException<double>(e, er);}}
void qlFreeLfmHullWhiteParameterization(QlLfmHullWhiteParameterization *o) {del(o);}
QlLfmHullWhiteParameterization* qlLfmHullWhiteParameterization(QlLiborForwardModelProcess* process, QlOptionletVolatilityStructure* capletVol, unsigned correlationRows, unsigned correlationCols, double* correlation, unsigned factors, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlLfmHullWhiteParameterization(alloc(new LfmHullWhiteParameterization(*arg(process), handlePtr(arg(capletVol)), qlMatrix(correlation, correlationRows, correlationCols), factors))));
  } catch (std::exception& er) {return handleException<QlLfmHullWhiteParameterization*>(e, er);}}
void qlLfmHullWhiteCovariance(QlLfmHullWhiteParameterization* o, double t, unsigned xLen, double* x, unsigned *rows, unsigned *cols, unsigned *len, double **vs, QlError **e) { QlCallScope callbackScope(e);
  try {fillMatrixOut([&] {return (*arg(o))->covariance(t, Array(x, x+xLen));}, rows, cols, len, vs);
  } catch (std::exception& er) {handleException<double*>(e, er);}}

void qlFreeGsr(QlGsr *o) {del(o);}
void qlFreeMarkovFunctional(QlMarkovFunctional *o) {del(o);}
void qlFreeGaussian1dModel(QlGaussian1dModel *o) {del(o);}
QlCalibratedModel* qlGsrAsCalibratedModel(QlGsr *o) {return ret(new QlCalibratedModel(*arg(o)));}
QlCalibratedModel* qlMarkovFunctionalAsCalibratedModel(QlMarkovFunctional *o) {return ret(new QlCalibratedModel(*arg(o)));}
QlGaussian1dModel* qlGsrAsGaussian1dModel(QlGsr *o) {return ret(new QlGaussian1dModel(*arg(o)));}
QlGaussian1dModel* qlMarkovFunctionalAsGaussian1dModel(QlMarkovFunctional *o) {return ret(new QlGaussian1dModel(*arg(o)));}
QlGsr* qlGsr(QlYieldTermStructure* termStructure, unsigned volstepdatesLen, int* volstepdates, unsigned volatilitiesLen, QlQuote** volatilities, unsigned reversionsLen, QlQuote** reversions, double T, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlGsr(alloc(new Gsr(*arg(termStructure), qlDateVector(volstepdates, volstepdatesLen), qlHandleVector(volatilities, volatilitiesLen), qlHandleVector(reversions, reversionsLen), T))));
  } catch (std::exception& er) {return handleException<QlGsr*>(e, er);}}
void qlGsrVolatility(QlGsr* o, unsigned *len, double **vs, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return (*arg(o))->volatility();}, len, vs);
  } catch (std::exception& er) {handleException<double*>(e, er);}}
void qlGsrReversion(QlGsr* o, unsigned *len, double **vs, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return (*arg(o))->reversion();}, len, vs);
  } catch (std::exception& er) {handleException<double*>(e, er);}}
void qlGsrMoveVolatility(QlGsr* o, unsigned i, unsigned *len, int **fp, QlError **e) { QlCallScope callbackScope(e);
  OutArrayResult<int> result(len, fp);
  try {std::vector<bool> res = (*arg(o))->MoveVolatility(i);
    int *out = result.allocate((unsigned)res.size());
    for (unsigned j = 0; j < res.size(); ++j) out[j] = res[j];
    result.commit();
  } catch (std::exception& er) {handleException<int*>(e, er);}}
void qlGsrMoveReversion(QlGsr* o, unsigned i, unsigned *len, int **fp, QlError **e) { QlCallScope callbackScope(e);
  OutArrayResult<int> result(len, fp);
  try {std::vector<bool> res = (*arg(o))->MoveReversion(i);
    int *out = result.allocate((unsigned)res.size());
    for (unsigned j = 0; j < res.size(); ++j) out[j] = res[j];
    result.commit();
  } catch (std::exception& er) {handleException<int*>(e, er);}}
void qlGsrCalibrateVolatilitiesIterative(QlGsr* o, unsigned helpersLen, QlBlackCalibrationHelper** helpers, QlOptimizationMethod* method, QlEndCriteria* endCriteria, Constraint* constraint, unsigned weightsLen, double* weights, QlError **e) { QlCallScope callbackScope(e);
  try {(*arg(o))->calibrateVolatilitiesIterative(qlVector(helpers, helpersLen), **arg(method), **arg(endCriteria), Constraint(constraint ? *arg(constraint) : Constraint()), std::vector<double>(weights, weights+weightsLen));
  } catch (std::exception& er) {(void)handleException<int>(e, er);}}
void qlGsrCalibrateReversionsIterative(QlGsr* o, unsigned helpersLen, QlBlackCalibrationHelper** helpers, QlOptimizationMethod* method, QlEndCriteria* endCriteria, Constraint* constraint, unsigned weightsLen, double* weights, QlError **e) { QlCallScope callbackScope(e);
  try {(*arg(o))->calibrateReversionsIterative(qlVector(helpers, helpersLen), **arg(method), **arg(endCriteria), Constraint(constraint ? *arg(constraint) : Constraint()), std::vector<double>(weights, weights+weightsLen));
  } catch (std::exception& er) {(void)handleException<int>(e, er);}}
QlMarkovFunctional* qlMarkovFunctional(QlYieldTermStructure* termStructure, double reversion, unsigned volstepdatesLen, int* volstepdates, unsigned volatilitiesLen, double* volatilities, QlSwaptionVolatilityStructure* swaptionVol, unsigned expiriesLen, int* swaptionExpiries, unsigned tenorsLen, int* tenorQuantity, unsigned, int* tenorUnit, QlSwapIndex* swapIndexBase, unsigned yGridPoints, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlMarkovFunctional(alloc(new MarkovFunctional(*arg(termStructure), reversion, qlDateVector(volstepdates, volstepdatesLen), std::vector<double>(volatilities, volatilities+volatilitiesLen), *arg(swaptionVol), qlDateVector(swaptionExpiries, expiriesLen), qlPeriodVector(tenorQuantity, tenorUnit, tenorsLen), *arg(swapIndexBase), MarkovFunctional::ModelSettings().withYGridPoints(yGridPoints)))));
  } catch (std::exception& er) {return handleException<QlMarkovFunctional*>(e, er);}}
QlMarkovFunctional* qlMarkovFunctionalCaplet(QlYieldTermStructure* termStructure, double reversion, unsigned volstepdatesLen, int* volstepdates, unsigned volatilitiesLen, double* volatilities, QlOptionletVolatilityStructure* capletVol, unsigned expiriesLen, int* capletExpiries, QlIborIndex* iborIndex, unsigned yGridPoints, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlMarkovFunctional(alloc(new MarkovFunctional(*arg(termStructure), reversion, qlDateVector(volstepdates, volstepdatesLen), std::vector<double>(volatilities, volatilities+volatilitiesLen), *arg(capletVol), qlDateVector(capletExpiries, expiriesLen), *arg(iborIndex), MarkovFunctional::ModelSettings().withYGridPoints(yGridPoints)))));
  } catch (std::exception& er) {return handleException<QlMarkovFunctional*>(e, er);}}
void qlMarkovFunctionalVolatility(QlMarkovFunctional* o, unsigned *len, double **vs, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return (*arg(o))->volatility();}, len, vs);
  } catch (std::exception& er) {handleException<double*>(e, er);}}
double qlGaussian1dModelNumeraire(QlGaussian1dModel* o, int referenceDate, double y, QlYieldTermStructure* yts, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->numeraire(Date(referenceDate), y, qlNullableHandle(yts));
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlGaussian1dModelZerobond(QlGaussian1dModel* o, int maturity, int referenceDate, double y, QlYieldTermStructure* yts, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->zerobond(Date(maturity), qlNullableDate(referenceDate), y, qlNullableHandle(yts));
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlGaussian1dModelZerobondOption(QlGaussian1dModel* o, int type, int expiry, int valueDate, int maturity, double strike, int referenceDate, double y, QlYieldTermStructure* yts, double yStdDevs, unsigned yGridPoints, int extrapolatePayoff, int flatPayoffExtrapolation, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->zerobondOption((Option::Type)type, Date(expiry), Date(valueDate), Date(maturity), strike, qlNullableDate(referenceDate), y, qlNullableHandle(yts), yStdDevs, yGridPoints, extrapolatePayoff, flatPayoffExtrapolation);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlGaussian1dModelForwardRate(QlGaussian1dModel* o, int fixing, int referenceDate, double y, QlIborIndex* iborIdx, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->forwardRate(Date(fixing), qlNullableDate(referenceDate), y, iborIdx ? *arg(iborIdx) : shared_ptr<IborIndex>());
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlGaussian1dModelSwapRate(QlGaussian1dModel* o, int fixing, int tenorLen, int tenorUnit, int referenceDate, double y, QlSwapIndex* swapIdx, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->swapRate(Date(fixing), Period(tenorLen, (TimeUnit)tenorUnit), qlNullableDate(referenceDate), y, swapIdx ? *arg(swapIdx) : shared_ptr<SwapIndex>());
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlGaussian1dModelSwapAnnuity(QlGaussian1dModel* o, int fixing, int tenorLen, int tenorUnit, int referenceDate, double y, QlSwapIndex* swapIdx, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->swapAnnuity(Date(fixing), Period(tenorLen, (TimeUnit)tenorUnit), qlNullableDate(referenceDate), y, swapIdx ? *arg(swapIdx) : shared_ptr<SwapIndex>());
  } catch (std::exception& er) {return handleException<double>(e, er);}}
void qlGaussian1dModelYGrid(QlGaussian1dModel* o, double yStdDevs, int gridPoints, double bigT, double t, double y, unsigned *len, double **out, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return (*arg(o))->yGrid(yStdDevs, gridPoints, bigT, t, y);}, len, out);
  } catch (std::exception& er) {handleException<double*>(e, er);}}
QlStochasticProcess1D* qlGaussian1dModelStateProcess(QlGaussian1dModel* o, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlStochasticProcess1D((*arg(o))->stateProcess()));
  } catch (std::exception& er) {return handleException<QlStochasticProcess1D*>(e, er);}}
QlPricingEngine* qlGaussian1dSwaptionEngine(QlGaussian1dModel* model, int integrationPoints, double stddevs, int extrapolatePayoff, int flatPayoffExtrapolation, QlYieldTermStructure* discountCurve, int probabilities, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new Gaussian1dSwaptionEngine(*arg(model), integrationPoints, stddevs, extrapolatePayoff, flatPayoffExtrapolation, qlNullableHandle(discountCurve), (Gaussian1dSwaptionEngine::Probabilities)probabilities))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlGaussian1dNonstandardSwaptionEngine(QlGaussian1dModel* model, int integrationPoints, double stddevs, int extrapolatePayoff, int flatPayoffExtrapolation, QlQuote* oas, QlYieldTermStructure* discountCurve, int probabilities, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new Gaussian1dNonstandardSwaptionEngine(*arg(model), integrationPoints, stddevs, extrapolatePayoff, flatPayoffExtrapolation, qlNullableHandle(oas), qlNullableHandle(discountCurve), (Gaussian1dNonstandardSwaptionEngine::Probabilities)probabilities))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
// As qlGaussian1dNonstandardSwaptionEngine, plus a trailing includeTodaysExercise bool before
// probabilities (gaussian1dfloatfloatswaptionengine.hpp).
QlPricingEngine* qlGaussian1dFloatFloatSwaptionEngine(QlGaussian1dModel* model, int integrationPoints, double stddevs, int extrapolatePayoff, int flatPayoffExtrapolation, QlQuote* oas, QlYieldTermStructure* discountCurve, int includeTodaysExercise, int probabilities, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new Gaussian1dFloatFloatSwaptionEngine(*arg(model), integrationPoints, stddevs, extrapolatePayoff, flatPayoffExtrapolation, qlNullableHandle(oas), qlNullableHandle(discountCurve), includeTodaysExercise, (Gaussian1dFloatFloatSwaptionEngine::Probabilities)probabilities))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlGaussian1dJamshidianSwaptionEngine(QlGaussian1dModel* model, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new Gaussian1dJamshidianSwaptionEngine(*arg(model)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}
QlPricingEngine* qlGaussian1dCapFloorEngine(QlGaussian1dModel* model, int integrationPoints, double stddevs, int extrapolatePayoff, int flatPayoffExtrapolation, QlYieldTermStructure* discountCurve, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlPricingEngine(alloc(new Gaussian1dCapFloorEngine(*arg(model), integrationPoints, stddevs, extrapolatePayoff, flatPayoffExtrapolation, qlNullableHandle(discountCurve)))));
  } catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}}

QlCalibratedModel* qlGJRGARCHModelAsCalibratedModel(QlGJRGARCHModel *o) {return ret(new QlCalibratedModel(*arg(o)));}
QlCalibratedModel* qlHestonModelAsCalibratedModel(QlHestonModel *o) {return ret(new QlCalibratedModel(*arg(o)));}
QlHestonModel* qlBatesModelAsHestonModel(QlBatesModel *o) {return ret(new QlHestonModel(*arg(o)));}
QlCalibratedModel* qlLiborForwardModelAsCalibratedModel(QlLiborForwardModel *o) {return ret(new QlCalibratedModel(*arg(o)));}
QlCalibratedModel* qlPiecewiseTimeDependentHestonModelAsCalibratedModel(QlPiecewiseTimeDependentHestonModel *o) {return ret(new QlCalibratedModel(*arg(o)));}
QlCalibratedModel* qlShortRateModelAsCalibratedModel(QlShortRateModel *o) {return ret(new QlCalibratedModel(*arg(o)));}
QlShortRateModel* qlOneFactorAffineModelAsShortRateModel(QlOneFactorAffineModel *o) {return ret(new QlShortRateModel(*arg(o)));}
void qlFreeCalibrationHelper(QlCalibrationHelper *o) {del(o);}
void qlFreeBlackCalibrationHelper(QlBlackCalibrationHelper *o) {del(o);}
QlCalibrationHelper* qlBlackCalibrationHelperAsCalibrationHelper(QlBlackCalibrationHelper *o) {return ret(new QlCalibrationHelper(*arg(o)));}

void qlCalibratedModelCalibrate(QlCalibratedModel* o, unsigned x1Len, QlCalibrationHelper** x1, unsigned wLen, double *weights, QlOptimizationMethod* method, QlEndCriteria* endCriteria, Constraint* constraint, unsigned fpLen, int* fixParameters, QlError **e) { QlCallScope callbackScope(e);
  try {(*arg(o))->calibrate(qlVector(x1, x1Len), **arg(method), **arg(endCriteria), Constraint(constraint ? *arg(constraint) : Constraint()), std::vector<double>(weights, weights+wLen), std::vector<bool>(fixParameters, fixParameters+fpLen));
  } catch (std::exception& er) {(void)handleException<int>(e, er);}}
double qlCalibratedModelValue(QlCalibratedModel* o, unsigned pLen, double* p, unsigned hLen, QlCalibrationHelper** h, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->value(Array(p, p+pLen), qlVector(h, hLen));
  } catch (std::exception& er) {return handleException<double>(e, er);}}
void qlBlackCalibrationHelperSetPricingEngine(QlBlackCalibrationHelper* o, QlPricingEngine* engine, QlError **e) { QlCallScope callbackScope(e);
  try {(*arg(o))->setPricingEngine(*arg(engine));
  } catch (std::exception& er) {(void)handleException<int>(e, er);}}
QlBlackCalibrationHelper* qlCapHelper(int l, int u, QlQuote* volatility, QlIborIndex* index, int fixedLegFrequency, DayCounter* fixedLegDayCounter, int includeFirstSwaplet, QlYieldTermStructure* termStructure, int errorType, int type, double shift, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlBlackCalibrationHelper(alloc(new CapHelper(Period(l, (TimeUnit)u), *arg(volatility), *arg(index), (Frequency)fixedLegFrequency, *arg(fixedLegDayCounter), includeFirstSwaplet, *arg(termStructure), (BlackCalibrationHelper::CalibrationErrorType)errorType, (VolatilityType)type, shift))));
  } catch (std::exception& er) {return handleException<QlBlackCalibrationHelper*>(e, er);}}
QlBlackCalibrationHelper* qlHestonModelHelper(int l, int u, Calendar* calendar, QlQuote* s0, double strikePrice, QlQuote* volatility, QlYieldTermStructure* riskFreeRate, QlYieldTermStructure* dividendYield, int errorType, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlBlackCalibrationHelper(alloc(new HestonModelHelper(Period(l, (TimeUnit)u), *arg(calendar), *arg(s0), strikePrice, *arg(volatility), *arg(riskFreeRate), *arg(dividendYield), (BlackCalibrationHelper::CalibrationErrorType)errorType))));
  } catch (std::exception& er) {return handleException<QlBlackCalibrationHelper*>(e, er);}}
void qlFreeSwaptionHelper(QlSwaptionHelper *o) {del(o);}
QlBlackCalibrationHelper* qlSwaptionHelperAsBlackCalibrationHelper(QlSwaptionHelper *o) {return ret(new QlBlackCalibrationHelper(*arg(o)));}
QlSwaptionHelper* qlSwaptionHelper(int l, int u, int ll, int lu, QlQuote* volatility, QlIborIndex* index, int fl, int fu, DayCounter* fixedLegDayCounter, DayCounter* floatingLegDayCounter, QlYieldTermStructure* termStructure, int errorType, double strike, double nominal, int volatilityType, double shift, unsigned settlementDays, int averagingMethod, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlSwaptionHelper(alloc(new SwaptionHelper(Period(l, (TimeUnit)u), Period(ll, (TimeUnit)lu), *arg(volatility), *arg(index), Period(fl, (TimeUnit)fu), *arg(fixedLegDayCounter), *arg(floatingLegDayCounter), *arg(termStructure), (BlackCalibrationHelper::CalibrationErrorType)errorType, strike, nominal, (VolatilityType)volatilityType, shift, settlementDays, (RateAveraging::Type)averagingMethod))));
  } catch (std::exception& er) {return handleException<QlSwaptionHelper*>(e, er);}}
QlSwaptionHelper* qlSwaptionHelperFromDate(int exerciseDate, int ll, int lu, QlQuote* volatility, QlIborIndex* index, int fl, int fu, DayCounter* fixedLegDayCounter, DayCounter* floatingLegDayCounter, QlYieldTermStructure* termStructure, int errorType, double strike, double nominal, int volatilityType, double shift, unsigned settlementDays, int averagingMethod, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlSwaptionHelper(alloc(new SwaptionHelper(Date(exerciseDate), Period(ll, (TimeUnit)lu), *arg(volatility), *arg(index), Period(fl, (TimeUnit)fu), *arg(fixedLegDayCounter), *arg(floatingLegDayCounter), *arg(termStructure), (BlackCalibrationHelper::CalibrationErrorType)errorType, strike, nominal, (VolatilityType)volatilityType, shift, settlementDays, (RateAveraging::Type)averagingMethod))));
  } catch (std::exception& er) {return handleException<QlSwaptionHelper*>(e, er);}}
QlSwaptionHelper* qlSwaptionHelperFromDates(int exerciseDate, int endDate, QlQuote* volatility, QlIborIndex* index, int fl, int fu, DayCounter* fixedLegDayCounter, DayCounter* floatingLegDayCounter, QlYieldTermStructure* termStructure, int errorType, double strike, double nominal, int volatilityType, double shift, unsigned settlementDays, int averagingMethod, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlSwaptionHelper(alloc(new SwaptionHelper(Date(exerciseDate), Date(endDate), *arg(volatility), *arg(index), Period(fl, (TimeUnit)fu), *arg(fixedLegDayCounter), *arg(floatingLegDayCounter), *arg(termStructure), (BlackCalibrationHelper::CalibrationErrorType)errorType, strike, nominal, (VolatilityType)volatilityType, shift, settlementDays, (RateAveraging::Type)averagingMethod))));
  } catch (std::exception& er) {return handleException<QlSwaptionHelper*>(e, er);}}
// Both accessors are cast-free: o is already a genuine SwaptionHelper (constructed as one above),
// so underlying()/swaption() are plain method calls, not a downcast from a type-erased base.
QlFixedVsFloatingSwap* qlSwaptionHelperUnderlying(QlSwaptionHelper* o, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlFixedVsFloatingSwap((*arg(o))->underlying()));
  } catch (std::exception& er) {return handleException<QlFixedVsFloatingSwap*>(e, er);}}
QlSwaption* qlSwaptionHelperSwaption(QlSwaptionHelper* o, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlSwaption((*arg(o))->swaption()));
  } catch (std::exception& er) {return handleException<QlSwaption*>(e, er);}}
void qlBlackCalibrationHelperTimes(QlBlackCalibrationHelper* o, unsigned *len, double **ts, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {std::list<double> times; (*arg(o))->addTimesTo(times); return times;}, len, ts);
  } catch (std::exception& er) {handleException<double*>(e, er);}}
void qlCalibratedModelParams(QlCalibratedModel* o, unsigned *len, double** ps, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return (*arg(o))->params();}, len, ps);
  } catch (std::exception& er) {handleException<double*>(e, er);}}
void qlCalibratedModelSetParams(QlCalibratedModel* o, unsigned pLen, double* p, QlError **e) { QlCallScope callbackScope(e);
  try {
    // Upstream writes parameters before its size checks, so validate first to keep the model whole.
    const Size expected = (*arg(o))->params().size();
    QL_REQUIRE(pLen == expected, "setParams: expected " << expected << " parameters, got " << pLen);
    (*arg(o))->setParams(Array(p, p+pLen));
  } catch (std::exception& er) {(void)handleException<int>(e, er);}}
double qlBlackCalibrationHelperBlackPrice(QlBlackCalibrationHelper* o, double volatility, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->blackPrice(volatility);} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalibrationHelperCalibrationError(QlBlackCalibrationHelper* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->calibrationError();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalibrationHelperImpliedVolatility(QlBlackCalibrationHelper* o, double targetValue, double accuracy, unsigned maxEvaluations, double minVol, double maxVol, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->impliedVolatility(targetValue, accuracy, maxEvaluations, minVol, maxVol);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalibrationHelperMarketValue(QlBlackCalibrationHelper* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->marketValue();} catch (std::exception& er) {return handleException<double>(e, er);}}
double qlBlackCalibrationHelperModelValue(QlBlackCalibrationHelper* o, QlError **e) { QlCallScope callbackScope(e);try {return (*arg(o))->modelValue();} catch (std::exception& er) {return handleException<double>(e, er);}}
QlQuote* qlBlackCalibrationHelperVolatility(QlBlackCalibrationHelper* o, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlQuote((*arg(o))->volatility().currentLink()));
  } catch (std::exception& er) {return handleException<QlQuote*>(e, er);}}

void qlFreeStochasticProcess1D(QlStochasticProcess1D *o) {del(o);}
QlStochasticProcess* qlStochasticProcess1DAsStochasticProcess(QlStochasticProcess1D *o) {return ret(new QlStochasticProcess(*arg(o)));}
void qlFreeBlackProcess(QlBlackProcess *o) {del(o);}
QlGeneralizedBlackScholesProcess* qlBlackProcessAsGeneralizedBlackScholesProcess(QlBlackProcess *o) {return ret(new QlGeneralizedBlackScholesProcess(*arg(o)));}
void qlFreeGeneralizedBlackScholesProcess(QlGeneralizedBlackScholesProcess *o) {del(o);}
QlStochasticProcess1D* qlGeneralizedBlackScholesProcessAsStochasticProcess1D(QlGeneralizedBlackScholesProcess *o) {return ret(new QlStochasticProcess1D(*arg(o)));}
void qlFreeStochasticProcess(QlStochasticProcess *o) {del(o);}
unsigned qlStochasticProcessFactors(QlStochasticProcess* o, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->factors();
  } catch (std::exception& er) {return handleException<unsigned>(e, er);}}
void qlStochasticProcessInitialValues(QlStochasticProcess* o, unsigned *len, double **vs, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return (*arg(o))->initialValues();}, len, vs);
  } catch (std::exception& er) {handleException<double*>(e, er);}}
void qlStochasticProcessDrift(QlStochasticProcess* o, double t, unsigned xLen, double *x, unsigned *len, double **vs, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return (*arg(o))->drift(t, Array(x, x+xLen));}, len, vs);
  } catch (std::exception& er) {handleException<double*>(e, er);}}
void qlStochasticProcessDiffusion(QlStochasticProcess* o, double t, unsigned xLen, double *x, unsigned *rows, unsigned *cols, unsigned *len, double **vs, QlError **e) { QlCallScope callbackScope(e);
  try {fillMatrixOut([&] {return (*arg(o))->diffusion(t, Array(x, x+xLen));}, rows, cols, len, vs);
  } catch (std::exception& er) {handleException<double*>(e, er);}}
void qlStochasticProcessExpectation(QlStochasticProcess* o, double t0, unsigned x0Len, double *x0, double dt, unsigned *len, double **vs, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return (*arg(o))->expectation(t0, Array(x0, x0+x0Len), dt);}, len, vs);
  } catch (std::exception& er) {handleException<double*>(e, er);}}
void qlStochasticProcessStdDeviation(QlStochasticProcess* o, double t0, unsigned x0Len, double *x0, double dt, unsigned *rows, unsigned *cols, unsigned *len, double **vs, QlError **e) { QlCallScope callbackScope(e);
  try {fillMatrixOut([&] {return (*arg(o))->stdDeviation(t0, Array(x0, x0+x0Len), dt);}, rows, cols, len, vs);
  } catch (std::exception& er) {handleException<double*>(e, er);}}
void qlStochasticProcessCovariance(QlStochasticProcess* o, double t0, unsigned x0Len, double *x0, double dt, unsigned *rows, unsigned *cols, unsigned *len, double **vs, QlError **e) { QlCallScope callbackScope(e);
  try {fillMatrixOut([&] {return (*arg(o))->covariance(t0, Array(x0, x0+x0Len), dt);}, rows, cols, len, vs);
  } catch (std::exception& er) {handleException<double*>(e, er);}}
void qlStochasticProcessApply(QlStochasticProcess* o, unsigned x0Len, double *x0, unsigned dxLen, double *dx, unsigned *len, double **vs, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return (*arg(o))->apply(Array(x0, x0+x0Len), Array(dx, dx+dxLen));}, len, vs);
  } catch (std::exception& er) {handleException<double*>(e, er);}}
void qlStochasticProcessEvolve(QlStochasticProcess* o, double t0, unsigned x0Len, double *x0, double dt, unsigned dwLen, double *dw, unsigned *len, double **vs, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return (*arg(o))->evolve(t0, Array(x0, x0+x0Len), dt, Array(dw, dw+dwLen));}, len, vs);
  } catch (std::exception& er) {handleException<double*>(e, er);}}

QlBlackProcess* qlBlackProcess(QlQuote* x0, QlYieldTermStructure* riskFreeTS, QlBlackVolTermStructure* blackVolTS, int d, int forceDiscretization, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlBlackProcess(alloc(new BlackProcess(*arg(x0), *arg(riskFreeTS), *arg(blackVolTS), createDiscretization1D(d), forceDiscretization))));
  } catch (std::exception& er) {return handleException<QlBlackProcess*>(e, er);}}
QlGeneralizedBlackScholesProcess* qlBlackScholesMertonProcess(QlQuote* x0, QlYieldTermStructure* dividendTS, QlYieldTermStructure* riskFreeTS, QlBlackVolTermStructure* blackVolTS, int d, int forceDiscretization, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlGeneralizedBlackScholesProcess(alloc(new BlackScholesMertonProcess(*arg(x0), *arg(dividendTS), *arg(riskFreeTS), *arg(blackVolTS), createDiscretization1D(d), forceDiscretization))));
  } catch (std::exception& er) {return handleException<QlGeneralizedBlackScholesProcess*>(e, er);}}
QlGeneralizedBlackScholesProcess* qlBlackScholesProcess(QlQuote* x0, QlYieldTermStructure* riskFreeTS, QlBlackVolTermStructure* blackVolTS, int d, int forceDiscretization, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlGeneralizedBlackScholesProcess(alloc(new BlackScholesProcess(*arg(x0), *arg(riskFreeTS), *arg(blackVolTS), createDiscretization1D(d), forceDiscretization))));
  } catch (std::exception& er) {return handleException<QlGeneralizedBlackScholesProcess*>(e, er);}}
QlGeneralizedBlackScholesProcess* qlExtendedBlackScholesMertonProcess(QlQuote* x0, QlYieldTermStructure* dividendTS, QlYieldTermStructure* riskFreeTS, QlBlackVolTermStructure* blackVolTS, int d, int evolDisc, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlGeneralizedBlackScholesProcess(alloc(new ExtendedBlackScholesMertonProcess(*arg(x0), *arg(dividendTS), *arg(riskFreeTS), *arg(blackVolTS), createDiscretization1D(d), (ExtendedBlackScholesMertonProcess::Discretization)evolDisc))));
  } catch (std::exception& er) {return handleException<QlGeneralizedBlackScholesProcess*>(e, er);}}
QlGeneralizedBlackScholesProcess* qlGarmanKohlhagenProcess(QlQuote* x0, QlYieldTermStructure* foreignRiskFreeTS, QlYieldTermStructure* domesticRiskFreeTS, QlBlackVolTermStructure* blackVolTS, int d, int forceDiscretization, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlGeneralizedBlackScholesProcess(alloc(new GarmanKohlagenProcess(*arg(x0), *arg(foreignRiskFreeTS), *arg(domesticRiskFreeTS), *arg(blackVolTS), createDiscretization1D(d), forceDiscretization))));
  } catch (std::exception& er) {return handleException<QlGeneralizedBlackScholesProcess*>(e, er);}}
QlGeneralizedBlackScholesProcess* qlGeneralizedBlackScholesProcess(QlQuote* x0, QlYieldTermStructure* dividendTS, QlYieldTermStructure* riskFreeTS, QlBlackVolTermStructure* blackVolTS, int d, int forceDiscretization, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlGeneralizedBlackScholesProcess(alloc(new GeneralizedBlackScholesProcess(*arg(x0), *arg(dividendTS), *arg(riskFreeTS), *arg(blackVolTS), createDiscretization1D(d), forceDiscretization))));
  } catch (std::exception& er) {return handleException<QlGeneralizedBlackScholesProcess*>(e, er);}}
QlStochasticProcess1D* qlSquareRootProcess(double b, double a, double sigma, double x0, int d, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlStochasticProcess1D(alloc(new SquareRootProcess(b, a, sigma, x0, createDiscretization1D(d)))));
  } catch (std::exception& er) {return handleException<QlStochasticProcess1D*>(e, er);}}
QlGeneralizedBlackScholesProcess* qlVegaStressedBlackScholesProcess(QlQuote* x0, QlYieldTermStructure* dividendTS, QlYieldTermStructure* riskFreeTS, QlBlackVolTermStructure* blackVolTS, double lowerTimeBorderForStressTest, double upperTimeBorderForStressTest, double lowerAssetBorderForStressTest, double upperAssetBorderForStressTest, double stressLevel, int d, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlGeneralizedBlackScholesProcess(alloc(new VegaStressedBlackScholesProcess(*arg(x0), *arg(dividendTS), *arg(riskFreeTS), *arg(blackVolTS), lowerTimeBorderForStressTest, upperTimeBorderForStressTest, lowerAssetBorderForStressTest, upperAssetBorderForStressTest, stressLevel, createDiscretization1D(d)))));
  } catch (std::exception& er) {return handleException<QlGeneralizedBlackScholesProcess*>(e, er);}}

void qlFreeExtOUWithJumpsProcess(QlExtOUWithJumpsProcess *o) {del(o);}
QlStochasticProcess* qlExtOUWithJumpsProcessAsStochasticProcess(QlExtOUWithJumpsProcess *o) {return ret(new QlStochasticProcess(*arg(o)));}
void qlFreeExtendedOrnsteinUhlenbeckProcess(QlExtendedOrnsteinUhlenbeckProcess *o) {del(o);}
QlStochasticProcess1D* qlExtendedOrnsteinUhlenbeckProcessAsStochasticProcess1D(QlExtendedOrnsteinUhlenbeckProcess *o) {return ret(new QlStochasticProcess1D(*arg(o)));}
void qlFreeGJRGARCHProcess(QlGJRGARCHProcess *o) {del(o);}
QlStochasticProcess* qlGJRGARCHProcessAsStochasticProcess(QlGJRGARCHProcess *o) {return ret(new QlStochasticProcess(*arg(o)));}
void qlFreeHestonProcess(QlHestonProcess *o) {del(o);}
QlStochasticProcess* qlHestonProcessAsStochasticProcess(QlHestonProcess *o) {return ret(new QlStochasticProcess(*arg(o)));}
void qlFreeHestonSLVProcess(QlHestonSLVProcess *o) {del(o);}
QlStochasticProcess* qlHestonSLVProcessAsStochasticProcess(QlHestonSLVProcess *o) {return ret(new QlStochasticProcess(*arg(o)));}
QlHestonSLVProcess* qlHestonSLVProcess(QlHestonProcess* hestonProcess, QlLocalVolTermStructure* leverageFct, double mixingFactor, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlHestonSLVProcess(alloc(new HestonSLVProcess(*arg(hestonProcess), *arg(leverageFct), mixingFactor))));
  } catch (std::exception& er) {return handleException<QlHestonSLVProcess*>(e, er);}}
void qlFreeBatesProcess(QlBatesProcess *o) {del(o);}
QlHestonProcess* qlBatesProcessAsHestonProcess(QlBatesProcess *o) {return ret(new QlHestonProcess(*arg(o)));}
void qlFreeHybridHestonHullWhiteProcess(QlHybridHestonHullWhiteProcess *o) {del(o);}
QlStochasticProcess* qlHybridHestonHullWhiteProcessAsStochasticProcess(QlHybridHestonHullWhiteProcess *o) {return ret(new QlStochasticProcess(*arg(o)));}
void qlFreeKlugeExtOUProcess(QlKlugeExtOUProcess *o) {del(o);}
QlStochasticProcess* qlKlugeExtOUProcessAsStochasticProcess(QlKlugeExtOUProcess *o) {return ret(new QlStochasticProcess(*arg(o)));}
void qlFreeLiborForwardModelProcess(QlLiborForwardModelProcess *o) {del(o);}
QlStochasticProcess* qlLiborForwardModelProcessAsStochasticProcess(QlLiborForwardModelProcess *o) {return ret(new QlStochasticProcess(*arg(o)));}
void qlFreeStochasticProcessArray(QlStochasticProcessArray *o) {del(o);}
QlStochasticProcess* qlStochasticProcessArrayAsStochasticProcess(QlStochasticProcessArray *o) {return ret(new QlStochasticProcess(*arg(o)));}
void qlFreeVarianceGammaProcess(QlVarianceGammaProcess *o) {del(o);}
QlStochasticProcess1D* qlVarianceGammaProcessAsStochasticProcess1D(QlVarianceGammaProcess *o) {return ret(new QlStochasticProcess1D(*arg(o)));}
void qlFreeMerton76Process(QlMerton76Process *o) {del(o);}
QlStochasticProcess1D* qlMerton76ProcessAsStochasticProcess1D(QlMerton76Process *o) {return ret(new QlStochasticProcess1D(*arg(o)));}
void qlFreeHullWhiteProcess(QlHullWhiteProcess *o) {del(o);}
QlStochasticProcess1D* qlHullWhiteProcessAsStochasticProcess1D(QlHullWhiteProcess *o) {return ret(new QlStochasticProcess1D(*arg(o)));}
void qlFreeHullWhiteForwardProcess(QlHullWhiteForwardProcess *o) {del(o);}
QlStochasticProcess1D* qlHullWhiteForwardProcessAsStochasticProcess1D(QlHullWhiteForwardProcess *o) {return ret(new QlStochasticProcess1D(*arg(o)));}
void qlHullWhiteForwardProcessSetForwardMeasureTime(QlHullWhiteForwardProcess* o, double t, QlError **e) { QlCallScope callbackScope(e);
  try {(*arg(o))->setForwardMeasureTime(t);
  } catch (std::exception& er) {(void)handleException<double>(e, er);}}
double qlHullWhiteProcessAlpha(QlHullWhiteProcess* o, double t, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->alpha(t);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlHullWhiteForwardProcessAlpha(QlHullWhiteForwardProcess* o, double t, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->alpha(t);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlHullWhiteForwardProcessB(QlHullWhiteForwardProcess* o, double t, double T, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->B(t, T);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlHullWhiteForwardProcessMT(QlHullWhiteForwardProcess* o, double s, double t, double T, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->M_T(s, t, T);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlHybridHestonHullWhiteProcessNumeraire(QlHybridHestonHullWhiteProcess* o, double t, unsigned xLen, double *x, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->numeraire(t, Array(x, x+xLen));
  } catch (std::exception& er) {return handleException<double>(e, er);}}

void qlFreeG2Process(QlG2Process *o) {del(o);}
QlStochasticProcess* qlG2ProcessAsStochasticProcess(QlG2Process *o) {return ret(new QlStochasticProcess(*arg(o)));}
double qlG2ProcessPhi(QlG2Process* o, double t, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->phi(t);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlG2ProcessShortRate(QlG2Process* o, double t, double x, double y) {return (*arg(o))->shortRate(t, x, y);}

void qlFreeG2ForwardProcess(QlG2ForwardProcess *o) {del(o);}
QlStochasticProcess* qlG2ForwardProcessAsStochasticProcess(QlG2ForwardProcess *o) {return ret(new QlStochasticProcess(*arg(o)));}
double qlG2ForwardProcessPhi(QlG2ForwardProcess* o, double t, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->phi(t);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlG2ForwardProcessShortRate(QlG2ForwardProcess* o, double t, double x, double y) {return (*arg(o))->shortRate(t, x, y);}
void qlG2ForwardProcessSetForwardMeasureTime(QlG2ForwardProcess* o, double t, QlError **e) { QlCallScope callbackScope(e);
  try {(*arg(o))->setForwardMeasureTime(t);
  } catch (std::exception& er) {(void)handleException<double>(e, er);}}

QlBatesProcess* qlBatesProcess(QlYieldTermStructure* riskFreeRate, QlYieldTermStructure* dividendYield, QlQuote* s0, double v0, double kappa, double theta, double sigma, double rho, double lambda, double nu, double delta, int d, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlBatesProcess(alloc(new BatesProcess(*arg(riskFreeRate), *arg(dividendYield), *arg(s0), v0, kappa, theta, sigma, rho, lambda, nu, delta, (HestonProcess::Discretization)d))));
  } catch (std::exception& er) {return handleException<QlBatesProcess*>(e, er);}}
QlExtendedOrnsteinUhlenbeckProcess* qlExtendedOrnsteinUhlenbeckProcess(double speed, double sigma, double x0, QlCallback* b, int discretization, double intEps, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlExtendedOrnsteinUhlenbeckProcess(alloc(new ExtendedOrnsteinUhlenbeckProcess(speed, sigma, x0, hasquant::UnaryCallback{*arg(b)}, (ExtendedOrnsteinUhlenbeckProcess::Discretization)discretization, intEps))));
  } catch (std::exception& er) {return handleException<QlExtendedOrnsteinUhlenbeckProcess*>(e, er);}}
QlExtendedOrnsteinUhlenbeckProcess* qlLinearSeasonalOrnsteinUhlenbeckProcess(double speed, double sigma, double x0, double a, double k, double c, double phase, int discretization, double intEps, QlError **e) { QlCallScope callbackScope(e);
  try {
    std::function<Real(Real)> b = [a, k, c, phase](Real t) { return a + k*t + c*std::sin(2*M_PI*t + phase); };
    return ret(new QlExtendedOrnsteinUhlenbeckProcess(alloc(new ExtendedOrnsteinUhlenbeckProcess(speed, sigma, x0, b, (ExtendedOrnsteinUhlenbeckProcess::Discretization)discretization, intEps))));
  } catch (std::exception& er) {return handleException<QlExtendedOrnsteinUhlenbeckProcess*>(e, er);}}
QlExtOUWithJumpsProcess* qlExtOUWithJumpsProcess(QlExtendedOrnsteinUhlenbeckProcess* process, double Y0, double beta, double jumpIntensity, double eta, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlExtOUWithJumpsProcess(alloc(new ExtOUWithJumpsProcess(*arg(process), Y0, beta, jumpIntensity, eta))));
  } catch (std::exception& er) {return handleException<QlExtOUWithJumpsProcess*>(e, er);}}
QlG2ForwardProcess* qlG2ForwardProcess(double a, double sigma, double b, double eta, double rho, QlYieldTermStructure* termStructure, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlG2ForwardProcess(alloc(new G2ForwardProcess(a, sigma, b, eta, rho, qlNullableHandle(arg(termStructure))))));
  } catch (std::exception& er) {return handleException<QlG2ForwardProcess*>(e, er);}}
QlG2Process* qlG2Process(double a, double sigma, double b, double eta, double rho, QlYieldTermStructure* termStructure, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlG2Process(alloc(new G2Process(a, sigma, b, eta, rho, qlNullableHandle(arg(termStructure))))));
  } catch (std::exception& er) {return handleException<QlG2Process*>(e, er);}}
QlStochasticProcess1D* qlGemanRoncoroniProcess(double x0, double alpha, double beta, double gamma, double delta, double eps, double zeta, double d, double k, double tau, double sig2, double a, double b, double theta1, double theta2, double theta3, double psi, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlStochasticProcess1D(alloc(new GemanRoncoroniProcess(x0, alpha, beta, gamma, delta, eps, zeta, d, k, tau, sig2, a, b, theta1, theta2, theta3, psi))));
  } catch (std::exception& er) {return handleException<QlStochasticProcess1D*>(e, er);}}
QlStochasticProcess1D* qlGeometricBrownianMotionProcess(double initialValue, double mue, double sigma, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlStochasticProcess1D(alloc(new GeometricBrownianMotionProcess(initialValue, mue, sigma))));
  } catch (std::exception& er) {return handleException<QlStochasticProcess1D*>(e, er);}}
QlGJRGARCHProcess* qlGJRGARCHProcess(QlYieldTermStructure* riskFreeRate, QlYieldTermStructure* dividendYield, QlQuote* s0, double v0, double omega, double alpha, double beta, double gamma, double lambda, double daysPerYear, int d, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlGJRGARCHProcess(alloc(new GJRGARCHProcess(*arg(riskFreeRate), *arg(dividendYield), *arg(s0), v0, omega, alpha, beta, gamma, lambda, daysPerYear, (GJRGARCHProcess::Discretization)d))));
  } catch (std::exception& er) {return handleException<QlGJRGARCHProcess*>(e, er);}}
QlHestonProcess* qlHestonProcess(QlYieldTermStructure* riskFreeRate, QlYieldTermStructure* dividendYield, QlQuote* s0, double v0, double kappa, double theta, double sigma, double rho, int d, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlHestonProcess(alloc(new HestonProcess(*arg(riskFreeRate), qlNullableHandle(arg(dividendYield)), *arg(s0), v0, kappa, theta, sigma, rho, (HestonProcess::Discretization)d))));
  } catch (std::exception& er) {return handleException<QlHestonProcess*>(e, er);}}
double qlHestonProcessPdf(QlHestonProcess* o, double x, double v, double t, double eps, QlError **e) { QlCallScope callbackScope(e);
  try {return (*arg(o))->pdf(x, v, t, eps);} catch (std::exception& er) {return handleException<double>(e, er);}}
QlHullWhiteForwardProcess* qlHullWhiteForwardProcess(QlYieldTermStructure* h, double a, double sigma, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlHullWhiteForwardProcess(alloc(new HullWhiteForwardProcess(*arg(h), a, sigma))));
  } catch (std::exception& er) {return handleException<QlHullWhiteForwardProcess*>(e, er);}}
QlHullWhiteProcess* qlHullWhiteProcess(QlYieldTermStructure* h, double a, double sigma, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlHullWhiteProcess(alloc(new HullWhiteProcess(*arg(h), a, sigma))));
  } catch (std::exception& er) {return handleException<QlHullWhiteProcess*>(e, er);}}
QlHybridHestonHullWhiteProcess* qlHybridHestonHullWhiteProcess(QlHestonProcess* hestonProcess, QlHullWhiteForwardProcess* hullWhiteProcess, double corrEquityShortRate, int discretization, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlHybridHestonHullWhiteProcess(alloc(new HybridHestonHullWhiteProcess(*arg(hestonProcess), *arg(hullWhiteProcess), corrEquityShortRate, (HybridHestonHullWhiteProcess::Discretization)discretization))));
  } catch (std::exception& er) {return handleException<QlHybridHestonHullWhiteProcess*>(e, er);}}
QlKlugeExtOUProcess* qlKlugeExtOUProcess(double rho, QlExtOUWithJumpsProcess* kluge, QlExtendedOrnsteinUhlenbeckProcess* extOU, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlKlugeExtOUProcess(alloc(new KlugeExtOUProcess(rho, *arg(kluge), (*arg(extOU))))));
  } catch (std::exception& er) {return handleException<QlKlugeExtOUProcess*>(e, er);}}
QlLiborForwardModelProcess* qlLiborForwardModelProcess(unsigned size, QlIborIndex* index, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlLiborForwardModelProcess(alloc(new LiborForwardModelProcess(size, *arg(index)))));
  } catch (std::exception& er) {return handleException<QlLiborForwardModelProcess*>(e, er);}}
void qlLiborForwardModelProcessFixingDates(QlLiborForwardModelProcess* o, unsigned *len, int **dates, QlError **e) { QlCallScope callbackScope(e);
  OutArrayResult<int> result(len, dates);
  try {const std::vector<Date>& fixingDates = (*arg(o))->fixingDates();
    int *out = result.allocate((unsigned)fixingDates.size());
    for (unsigned i = 0; i < fixingDates.size(); ++i) out[i] = fixingDates[i].serialNumber();
    result.commit();
  } catch (std::exception& er) {(void)handleException<int*>(e, er);}}
void qlLiborForwardModelProcessFixingTimes(QlLiborForwardModelProcess* o, unsigned *len, double **times, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return (*arg(o))->fixingTimes();}, len, times);
  } catch (std::exception& er) {(void)handleException<double*>(e, er);}}
Leg* qlLiborForwardModelProcessCashFlows(QlLiborForwardModelProcess* o, double amount, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new Leg((*arg(o))->cashFlows(amount)));
  } catch (std::exception& er) {return handleException<Leg*>(e, er);}}
QlIborIndex* qlLiborForwardModelProcessIndex(QlLiborForwardModelProcess* o, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlIborIndex((*arg(o))->index()));
  } catch (std::exception& er) {return handleException<QlIborIndex*>(e, er);}}
void qlLiborForwardModelProcessSetCovarParam(QlLiborForwardModelProcess* o, QlLfmHullWhiteParameterization* param, QlError **e) { QlCallScope callbackScope(e);
  try {(*arg(o))->setCovarParam(*arg(param));
  } catch (std::exception& er) {(void)handleException<double>(e, er);}}
void qlLiborForwardModelProcessDiscountBond(QlLiborForwardModelProcess* o, unsigned ratesLen, double *rates, unsigned *len, double **dfs, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return (*arg(o))->discountBond(std::vector<Rate>(rates, rates+ratesLen));}, len, dfs);
  } catch (std::exception& er) {(void)handleException<double*>(e, er);}}
void qlLiborForwardModelProcessAccrualTimes(QlLiborForwardModelProcess* o, unsigned *startLen, double **start, unsigned *endLen, double **end, QlError **e) { QlCallScope callbackScope(e);
  OutArrayResult<double> startResult(startLen, start);
  OutArrayResult<double> endResult(endLen, end);
  try {const std::vector<Time>& s = (*arg(o))->accrualStartTimes();
    const std::vector<Time>& t = (*arg(o))->accrualEndTimes();
    double *starts = startResult.allocate((unsigned)s.size());
    std::copy(s.begin(), s.end(), starts);
    double *ends = endResult.allocate((unsigned)t.size());
    std::copy(t.begin(), t.end(), ends);
    startResult.commit(); endResult.commit();
  } catch (std::exception& er) {(void)handleException<double*>(e, er);}}
QlMerton76Process* qlMerton76Process(QlQuote* stateVariable, QlYieldTermStructure* dividendTS, QlYieldTermStructure* riskFreeTS, QlBlackVolTermStructure* blackVolTS, QlQuote* jumpInt, QlQuote* logJMean, QlQuote* logJVol, int d, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlMerton76Process(alloc(new Merton76Process(*arg(stateVariable), *arg(dividendTS), *arg(riskFreeTS), *arg(blackVolTS), *arg(jumpInt), *arg(logJMean), *arg(logJVol), createDiscretization1D(d)))));
  } catch (std::exception& er) {return handleException<QlMerton76Process*>(e, er);}}
QlStochasticProcess1D* qlOrnsteinUhlenbeckProcess(double speed, double vol, double x0, double level, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlStochasticProcess1D(alloc(new OrnsteinUhlenbeckProcess(speed, vol, x0, level))));
  } catch (std::exception& er) {return handleException<QlStochasticProcess1D*>(e, er);}}
QlVarianceGammaProcess* qlVarianceGammaProcess(QlQuote* s0, QlYieldTermStructure* dividendYield, QlYieldTermStructure* riskFreeRate, double sigma, double nu, double theta, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlVarianceGammaProcess(alloc(new VarianceGammaProcess(*arg(s0), *arg(dividendYield), *arg(riskFreeRate), sigma, nu, theta))));
  } catch (std::exception& er) {return handleException<QlVarianceGammaProcess*>(e, er);}}
QlStochasticProcessArray* qlStochasticProcessArray(unsigned x0Len, QlStochasticProcess1D** x0, unsigned correlationRows, unsigned correlationCols, double* correlation, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(new QlStochasticProcessArray(alloc(new StochasticProcessArray(qlVector(x0, x0Len), qlMatrix(correlation, correlationRows, correlationCols)))));
  } catch (std::exception& er) {return handleException<QlStochasticProcessArray*>(e, er);}}

// delWith rather than del(): qlFreePolymorphicPathGeneratorAux does the actual `delete`, since
// PolymorphicPathGenerator is only forward-declared in this translation unit.
void qlFreePathGenerator(PolymorphicPathGenerator *gen) {delWith(gen, qlFreePolymorphicPathGeneratorAux);}
PolymorphicPathGenerator *qlPathGenerator(int rngtrait, QlStochasticProcess *p, TimeGrid *t, unsigned seed, unsigned dim, int brownianBridge, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(qlPathGeneratorAux(rngtrait, *arg(p), *arg(t), seed, dim, brownianBridge));
  } catch (std::exception& er) {return handleException<PolymorphicPathGenerator*>(e, er);}}
PolymorphicPathGenerator *qlSobolPathGenerator(int dir, QlStochasticProcess *p, TimeGrid *t, unsigned seed, unsigned dim, int brownianBridge, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(qlSobolPathGeneratorAux((SobolRsg::DirectionIntegers)dir, *arg(p), *arg(t), seed, dim, brownianBridge));
  } catch (std::exception& er) {return handleException<PolymorphicPathGenerator*>(e, er);}}
SamplePath *qlPathGeneratorNext(PolymorphicPathGenerator *pgen, QlError **e) { QlCallScope callbackScope(e);
  try {return alloc(new SamplePath(qlPathGeneratorNextAux(pgen)));
  } catch (std::exception& er) {return handleException<SamplePath*>(e, er);}}
SamplePath *qlPathGeneratorAntithetic(PolymorphicPathGenerator *pgen, QlError **e) { QlCallScope callbackScope(e);
  try {return alloc(new SamplePath(qlPathGeneratorAntitheticAux(pgen)));
  } catch (std::exception& er) {return handleException<SamplePath*>(e, er);}}

double qlSamplePathWeight(SamplePath *p) {return arg(p)->weight;}
unsigned qlSamplePathAssetNumber(SamplePath *p) {return arg(p)->value.assetNumber();}
unsigned qlSamplePathSize(SamplePath *p) {return arg(p)->value.pathSize();}
void qlFreeSamplePath(SamplePath *p) {del(p);}
double qlSamplePathAt(SamplePath *p, unsigned asset, unsigned point, QlError **e) { QlCallScope callbackScope(e);try {return arg(p)->value.at(asset).at(point);} catch (std::exception& er) {return handleException<double>(e, er);}}

// delWith, for the same reason as qlFreePathGenerator above.
void qlFreeGaussianRsg(PolymorphicGaussianRsg *g) {delWith(g, qlFreePolymorphicGaussianRsgAux);}
// ret() only, no alloc(): the generator is a standalone heap object handed straight to Haskell and
// freed by qlFreeGaussianRsg -- not a shared_ptr payload. Wrapping it in both verbs would trace one
// pointer as two acquisitions against a single release, which alloc-summary.py reports as a leak.
// Same shape as qlPathGenerator below.
PolymorphicGaussianRsg *qlGaussianRsg(int rngtrait, unsigned dimension, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(qlGaussianRsgAux(rngtrait, dimension, seed));
  } catch (std::exception& er) {return handleException<PolymorphicGaussianRsg*>(e, er);}}
PolymorphicGaussianRsg *qlSobolGaussianRsg(int dir, unsigned dimension, unsigned seed, QlError **e) { QlCallScope callbackScope(e);
  try {return ret(qlSobolGaussianRsgAux((SobolRsg::DirectionIntegers)dir, dimension, seed));
  } catch (std::exception& er) {return handleException<PolymorphicGaussianRsg*>(e, er);}}
unsigned qlGaussianRsgDimension(PolymorphicGaussianRsg *g) {return qlGaussianRsgDimensionAux(arg(g));}

void qlGaussianRsgNextSequence(PolymorphicGaussianRsg *g, unsigned *len, double **values, double *weight, QlError **e) { QlCallScope callbackScope(e);
  OutArrayResult<double> valuesResult(len, values);
  OutValue<double> weightResult(weight);
  try {const auto& s = qlGaussianRsgNextSequenceAux(arg(g));
    double *out = valuesResult.allocate((unsigned)s.value.size());
    std::copy(s.value.begin(), s.value.end(), out);
    weightResult.set(s.weight);
    valuesResult.commit(); weightResult.commit();
  } catch (std::exception& er) {qlSetError(e, er.what());}}
void qlGaussianRsgLastSequence(PolymorphicGaussianRsg *g, unsigned *len, double **values, double *weight, QlError **e) { QlCallScope callbackScope(e);
  OutArrayResult<double> valuesResult(len, values);
  OutValue<double> weightResult(weight);
  try {const auto& s = qlGaussianRsgLastSequenceAux(arg(g));
    double *out = valuesResult.allocate((unsigned)s.value.size());
    std::copy(s.value.begin(), s.value.end(), out);
    weightResult.set(s.weight);
    valuesResult.commit(); weightResult.commit();
  } catch (std::exception& er) {qlSetError(e, er.what());}}

void qlSamplePathAssetPath(SamplePath *s, unsigned asset, unsigned *len, double **p, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return std::vector<double>(arg(s)->value.at(asset).begin(), s->value.at(asset).end());}, len, p);
  } catch (std::exception& er) {(void)handleException<double*>(e, er);}}

// One Longstaff-Schwartz basis: scalar at one column when `scalarAtOne`, else multi-dimensional. Every
// entry point below fits and evaluates through it, so stored coefficients repeat a combined call's bits.
namespace {
class LsmBasis {
 public:
  LsmBasis(int polynomType, unsigned order, unsigned cols, bool scalarAtOne) : cols_(cols), scalar_(scalarAtOne && cols == 1) {
    QL_REQUIRE(cols > 0, "a regression needs at least one state column");
    if (scalar_) scalarBasis_ = LsmBasisSystem::pathBasisSystem(order, (LsmBasisSystem::PolynomialType)polynomType);
    else multiBasis_ = LsmBasisSystem::multiPathBasisSystem(cols, order, (LsmBasisSystem::PolynomialType)polynomType);
  }
  Size size() const {return scalar_ ? scalarBasis_.size() : multiBasis_.size();}
  // Row-major states, one row per path.
  Array fit(unsigned rows, const double *states, const double *targets) const {
    std::vector<Real> y(targets, targets + rows);
    if (scalar_) return GeneralLinearLeastSquares(std::vector<Real>(states, states + rows), y, scalarBasis_).coefficients();
    std::vector<Array> x; x.reserve(rows);
    for (unsigned i = 0; i < rows; ++i) x.emplace_back(states + i*cols_, states + (i+1)*cols_);
    return GeneralLinearLeastSquares(x, y, multiBasis_).coefficients();
  }
  void evaluate(const Array& coeff, unsigned rows, const double *states, double *values) const {
    QL_REQUIRE(coeff.size() == size(), "expected " << size() << " regression coefficients, got " << coeff.size());
    for (unsigned i = 0; i < rows; ++i) {
      Real cont = 0.0;
      if (scalar_) {
        for (Size l = 0; l < scalarBasis_.size(); ++l) cont += coeff[l] * scalarBasis_[l](states[i]);
      } else {
        Array row(states + i*cols_, states + (i+1)*cols_);
        for (Size l = 0; l < multiBasis_.size(); ++l) cont += coeff[l] * multiBasis_[l](row);
      }
      values[i] = cont;
    }
  }
 private:
  unsigned cols_;
  bool scalar_;
  std::vector<std::function<Real(Real)> > scalarBasis_;
  std::vector<std::function<Real(Array)> > multiBasis_;
};
}

// Runs one Longstaff-Schwartz basis-function regression (fitStates -> fitTargets) and evaluates the
// fitted continuation value at each evalState -- the cross-path regression step LongstaffSchwartzPathPricer
// performs once per exercise date, with the payoff/exercise values supplied from Haskell instead of a
// bound Payoff.
void qlLsmRegress(int polynomType, unsigned order, unsigned fitStatesLen, double *fitStates, unsigned fitTargetsLen, double *fitTargets, unsigned evalLen, double *evalStates, unsigned *outLen, double **outValues, QlError **e) { QlCallScope callbackScope(e);
  OutArrayResult<double> result(outLen, outValues);
  try {
    QL_REQUIRE(fitStatesLen == fitTargetsLen, "fit states and fit targets must have the same length");
    LsmBasis basis(polynomType, order, 1, true);
    Array coeff = basis.fit(fitStatesLen, fitStates, fitTargets);
    basis.evaluate(coeff, evalLen, evalStates, result.allocate(evalLen));
    result.commit();
  } catch (std::exception& er) {qlSetError(e, er.what());}}

// Multi-asset counterpart of qlLsmRegress, via LsmBasisSystem::multiPathBasisSystem: fitStates/evalStates
// are row-major (one row per path, fitCols/evalCols columns = underlyings, which must agree).
void qlLsmRegressMulti(int polynomType, unsigned order, unsigned fitRows, unsigned fitCols, double *fitStates, unsigned fitTargetsLen, double *fitTargets, unsigned evalRows, unsigned evalCols, double *evalStates, unsigned *outLen, double **outValues, QlError **e) { QlCallScope callbackScope(e);
  OutArrayResult<double> result(outLen, outValues);
  try {
    QL_REQUIRE(fitCols == evalCols, "fit states and eval states must have the same number of columns (underlyings)");
    QL_REQUIRE(fitRows == fitTargetsLen, "fit states and fit targets must have the same number of rows");
    LsmBasis basis(polynomType, order, fitCols, false);
    Array coeff = basis.fit(fitRows, fitStates, fitTargets);
    basis.evaluate(coeff, evalRows, evalStates, result.allocate(evalRows));
    result.commit();
  } catch (std::exception& er) {qlSetError(e, er.what());}}

// The fitting half of the combined calls: the basis coefficients, scalar basis at one column.
void qlLsmFit(int polynomType, unsigned order, unsigned rows, unsigned cols, double *states, unsigned targetsLen, double *targets, unsigned *outLen, double **outCoefficients, QlError **e) { QlCallScope callbackScope(e);
  OutArrayResult<double> result(outLen, outCoefficients);
  try {
    QL_REQUIRE(rows == targetsLen, "fit states and fit targets must have the same number of rows");
    Array coeff = LsmBasis(polynomType, order, cols, true).fit(rows, states, targets);
    std::copy(coeff.begin(), coeff.end(), result.allocate((unsigned)coeff.size()));
    result.commit();
  } catch (std::exception& er) {qlSetError(e, er.what());}}

// The evaluating half: the continuation value of stored coefficients at each row.
void qlLsmEvaluate(int polynomType, unsigned order, unsigned coeffLen, double *coefficients, unsigned rows, unsigned cols, double *states, unsigned *outLen, double **outValues, QlError **e) { QlCallScope callbackScope(e);
  OutArrayResult<double> result(outLen, outValues);
  try {
    LsmBasis basis(polynomType, order, cols, true);
    basis.evaluate(Array(coefficients, coefficients + coeffLen), rows, states, result.allocate(rows));
    result.commit();
  } catch (std::exception& er) {qlSetError(e, er.what());}}

// Bump the revision whenever LsmBasis's basis choice or evaluation order changes.
#if defined(__aarch64__) || defined(_M_ARM64)
#define HQ_LSM_ARCH "arm64"
#elif defined(__x86_64__) || defined(_M_X64)
#define HQ_LSM_ARCH "x86_64"
#else
#define HQ_LSM_ARCH "unknown architecture"
#endif
#ifdef __VERSION__
#define HQ_LSM_COMPILER __VERSION__
#else
#define HQ_LSM_COMPILER "unknown compiler"
#endif
const char *qlLsmEvaluatorIdentity() {return "hasquant LSM basis 1; QuantLib " QL_VERSION "; " HQ_LSM_COMPILER "; " HQ_LSM_ARCH;}

void qlPathGeneratorSequence(PolymorphicPathGenerator *g, unsigned *len, double **values, double *weight, QlError **e) { QlCallScope callbackScope(e);
  OutArrayResult<double> valuesResult(len, values);
  OutValue<double> weightResult(weight);
  try {const auto& s = qlPathGeneratorSequenceAux(arg(g));
    double *out = valuesResult.allocate((unsigned)s.value.size());
    std::copy(s.value.begin(), s.value.end(), out);
    weightResult.set(s.weight);
    valuesResult.commit(); weightResult.commit();
  } catch (std::exception& er) {qlSetError(e, er.what());}}

double qlUnsafeSabrLogNormalVolatility(double strike, double forward, double expiryTime, double alpha, double beta, double nu, double rho, QlError **e) { QlCallScope callbackScope(e);
  try {return unsafeSabrLogNormalVolatility(strike, forward, expiryTime, alpha, beta, nu, rho);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlUnsafeShiftedSabrVolatility(double strike, double forward, double expiryTime, double alpha, double beta, double nu, double rho, double shift, int volatilityType, QlError **e) { QlCallScope callbackScope(e);
  try {return unsafeShiftedSabrVolatility(strike, forward, expiryTime, alpha, beta, nu, rho, shift, (VolatilityType)volatilityType);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlUnsafeSabrNormalVolatility(double strike, double forward, double expiryTime, double alpha, double beta, double nu, double rho, QlError **e) { QlCallScope callbackScope(e);
  try {return unsafeSabrNormalVolatility(strike, forward, expiryTime, alpha, beta, nu, rho);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlUnsafeSabrVolatility(double strike, double forward, double expiryTime, double alpha, double beta, double nu, double rho, int volatilityType, QlError **e) { QlCallScope callbackScope(e);
  try {return unsafeSabrVolatility(strike, forward, expiryTime, alpha, beta, nu, rho, (VolatilityType)volatilityType);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlSabrVolatility(double strike, double forward, double expiryTime, double alpha, double beta, double nu, double rho, int volatilityType, QlError **e) { QlCallScope callbackScope(e);
  try {return sabrVolatility(strike, forward, expiryTime, alpha, beta, nu, rho, (VolatilityType)volatilityType);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlShiftedSabrVolatility(double strike, double forward, double expiryTime, double alpha, double beta, double nu, double rho, double shift, int volatilityType, QlError **e) { QlCallScope callbackScope(e);
  try {return shiftedSabrVolatility(strike, forward, expiryTime, alpha, beta, nu, rho, shift, (VolatilityType)volatilityType);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
double qlSabrFlochKennedyVolatility(double strike, double forward, double expiryTime, double alpha, double beta, double nu, double rho, QlError **e) { QlCallScope callbackScope(e);
  try {return sabrFlochKennedyVolatility(strike, forward, expiryTime, alpha, beta, nu, rho);
  } catch (std::exception& er) {return handleException<double>(e, er);}}
void qlValidateSabrParameters(double alpha, double beta, double nu, double rho, QlError **e) { QlCallScope callbackScope(e);
  try {validateSabrParameters(alpha, beta, nu, rho);
  } catch (std::exception& er) {(void)handleException<int>(e, er);}}
void qlSabrGuess(double k_m, double vol_m, double k_0, double vol_0, double k_p, double vol_p, double forward, double expiryTime, double beta, double shift, int volatilityType, unsigned *len, double **out, QlError **e) { QlCallScope callbackScope(e);
  try {fillVectorOut([&] {return sabrGuess(k_m, vol_m, k_0, vol_0, k_p, vol_p, forward, expiryTime, beta, shift, (VolatilityType)volatilityType);}, len, out);
  } catch (std::exception& er) {(void)handleException<double*>(e, er);}}
double qlGaussian1dModelCompoundedRate(QlGaussian1dModel* model, QlOvernightIndexedCoupon* coupon, int date, double y, QlYieldTermStructure* curve, QlError **e) { QlCallScope scope(e);
#if QL_HEX_VERSION >= 0x01440000
  try {return (*model)->compoundedRate(**coupon, qlNullableDate(date), y, qlNullableHandle(curve));}
  catch (std::exception& er) {return handleException<double>(e, er);}
#else
  (void)model; (void)coupon; (void)date; (void)y; (void)curve;
  qlUnsupportedVersion(e, "gaussian1dCompoundedRate", "1.44"); return 0;
#endif
}
void qlFreeRoughHestonModel(QlRoughHestonModel* o) {del(o);}
QlCalibratedModel* qlRoughHestonModelAsCalibratedModel(QlRoughHestonModel* o) {
#if QL_HEX_VERSION >= 0x01440000
  return ret(new QlCalibratedModel(*arg(o)));
#else
  (void)o; return nullptr;
#endif
}
QlRoughHestonModel* qlRoughHestonModel(QlHestonProcess* process, double hurst, QlError **e) { QlCallScope callbackScope(e);

#if QL_HEX_VERSION >= 0x01440000
  try {return ret(new QlRoughHestonModel(alloc(new RoughHestonModel(*arg(process), hurst))));} catch (std::exception& er) {return handleException<QlRoughHestonModel*>(e, er);}
#else
  (void)process; (void)hurst;
  qlUnsupportedVersion(e, "roughHestonModel", "1.44"); return nullptr;
#endif
}
double qlRoughHestonModelTheta(QlRoughHestonModel* o, QlError **e) { QlCallScope callbackScope(e);

#if QL_HEX_VERSION >= 0x01440000
  try {return (*arg(o))->theta();} catch (std::exception& er) {return handleException<double>(e, er);}
#else
  (void)o;
  qlUnsupportedVersion(e, "roughHestonTheta", "1.44"); return 0;
#endif
}
double qlRoughHestonModelKappa(QlRoughHestonModel* o, QlError **e) { QlCallScope callbackScope(e);

#if QL_HEX_VERSION >= 0x01440000
  try {return (*arg(o))->kappa();} catch (std::exception& er) {return handleException<double>(e, er);}
#else
  (void)o;
  qlUnsupportedVersion(e, "roughHestonKappa", "1.44"); return 0;
#endif
}
double qlRoughHestonModelSigma(QlRoughHestonModel* o, QlError **e) { QlCallScope callbackScope(e);

#if QL_HEX_VERSION >= 0x01440000
  try {return (*arg(o))->sigma();} catch (std::exception& er) {return handleException<double>(e, er);}
#else
  (void)o;
  qlUnsupportedVersion(e, "roughHestonSigma", "1.44"); return 0;
#endif
}
double qlRoughHestonModelRho(QlRoughHestonModel* o, QlError **e) { QlCallScope callbackScope(e);

#if QL_HEX_VERSION >= 0x01440000
  try {return (*arg(o))->rho();} catch (std::exception& er) {return handleException<double>(e, er);}
#else
  (void)o;
  qlUnsupportedVersion(e, "roughHestonRho", "1.44"); return 0;
#endif
}
double qlRoughHestonModelV0(QlRoughHestonModel* o, QlError **e) { QlCallScope callbackScope(e);

#if QL_HEX_VERSION >= 0x01440000
  try {return (*arg(o))->v0();} catch (std::exception& er) {return handleException<double>(e, er);}
#else
  (void)o;
  qlUnsupportedVersion(e, "roughHestonV0", "1.44"); return 0;
#endif
}
double qlRoughHestonModelHurst(QlRoughHestonModel* o, QlError **e) { QlCallScope callbackScope(e);

#if QL_HEX_VERSION >= 0x01440000
  try {return (*arg(o))->hurst();} catch (std::exception& er) {return handleException<double>(e, er);}
#else
  (void)o;
  qlUnsupportedVersion(e, "roughHestonHurst", "1.44"); return 0;
#endif
}
QlHestonProcess* qlRoughHestonModelProcess(QlRoughHestonModel* o, QlError **e) { QlCallScope callbackScope(e);

#if QL_HEX_VERSION >= 0x01440000
  try {return ret(new QlHestonProcess((*arg(o))->process()));} catch (std::exception& er) {return handleException<QlHestonProcess*>(e, er);}
#else
  (void)o;
  qlUnsupportedVersion(e, "roughHestonProcess", "1.44"); return nullptr;
#endif
}
void qlFreeAnalyticRoughHestonEngine(QlAnalyticRoughHestonEngine* o) {del(o);}
QlPricingEngine* qlAnalyticRoughHestonEngineAsPricingEngine(QlAnalyticRoughHestonEngine* o) {
#if QL_HEX_VERSION >= 0x01440000
  return ret(new QlPricingEngine(*arg(o)));
#else
  (void)o; return nullptr;
#endif
}
QlAnalyticRoughHestonEngine* qlAnalyticRoughHestonEngine(QlRoughHestonModel* model, unsigned integrationOrder, unsigned timeSteps, int approximation, unsigned nFactors, QlError **e) { QlCallScope callbackScope(e);

#if QL_HEX_VERSION >= 0x01440000
  try {return ret(new QlAnalyticRoughHestonEngine(alloc(new AnalyticRoughHestonEngine(*arg(model), integrationOrder, timeSteps, (AnalyticRoughHestonEngine::Approximation)approximation, nFactors))));} catch (std::exception& er) {return handleException<QlAnalyticRoughHestonEngine*>(e, er);}
#else
  (void)model; (void)integrationOrder; (void)timeSteps; (void)approximation; (void)nFactors;
  qlUnsupportedVersion(e, "analyticRoughHestonEngine", "1.44"); return nullptr;
#endif
}
QlAnalyticRoughHestonEngine* qlAnalyticRoughHestonEngineWithIntegration(QlRoughHestonModel* model, int algorithm, unsigned count, double relative, double absolute, int convergence, unsigned timeSteps, double epsilon, double alpha, int approximation, unsigned nFactors, QlError **e) { QlCallScope callbackScope(e);

#if QL_HEX_VERSION >= 0x01440000
  try {return ret(new QlAnalyticRoughHestonEngine(alloc(new AnalyticRoughHestonEngine(*arg(model), roughFourierIntegration(algorithm, count, relative, absolute, convergence), timeSteps, epsilon, alpha, (AnalyticRoughHestonEngine::Approximation)approximation, nFactors))));} catch (std::exception& er) {return handleException<QlAnalyticRoughHestonEngine*>(e, er);}
#else
  (void)model; (void)algorithm; (void)count; (void)relative; (void)absolute; (void)convergence; (void)timeSteps; (void)epsilon; (void)alpha; (void)approximation; (void)nFactors;
  qlUnsupportedVersion(e, "analyticRoughHestonEngineWithIntegration", "1.44"); return nullptr;
#endif
}
void qlRoughHestonchF(QlAnalyticRoughHestonEngine* o, double real, double imag, double time, double* outReal, double* outImag, QlError **e) { QlCallScope callbackScope(e);
  *outReal = 0; *outImag = 0;
#if QL_HEX_VERSION >= 0x01440000
  try {auto value = (*arg(o))->chF(std::complex<double>(real, imag), time); *outReal = value.real(); *outImag = value.imag();} catch (std::exception& er) {qlSetError(e, er.what());}
#else
  (void)o; (void)real; (void)imag; (void)time; (void)outReal; (void)outImag;
  qlUnsupportedVersion(e, "roughHestonCharacteristicFunction", "1.44");
#endif
}
void qlRoughHestonlnChF(QlAnalyticRoughHestonEngine* o, double real, double imag, double time, double* outReal, double* outImag, QlError **e) { QlCallScope callbackScope(e);
  *outReal = 0; *outImag = 0;
#if QL_HEX_VERSION >= 0x01440000
  try {auto value = (*arg(o))->lnChF(std::complex<double>(real, imag), time); *outReal = value.real(); *outImag = value.imag();} catch (std::exception& er) {qlSetError(e, er.what());}
#else
  (void)o; (void)real; (void)imag; (void)time; (void)outReal; (void)outImag;
  qlUnsupportedVersion(e, "roughHestonLogCharacteristicFunction", "1.44");
#endif
}
void qlRoughHestonriccatiSolution(QlAnalyticRoughHestonEngine* o, double real, double imag, double time, double* outReal, double* outImag, QlError **e) { QlCallScope callbackScope(e);
  *outReal = 0; *outImag = 0;
#if QL_HEX_VERSION >= 0x01440000
  try {auto value = (*arg(o))->riccatiSolution(std::complex<double>(real, imag), time); *outReal = value.real(); *outImag = value.imag();} catch (std::exception& er) {qlSetError(e, er.what());}
#else
  (void)o; (void)real; (void)imag; (void)time; (void)outReal; (void)outImag;
  qlUnsupportedVersion(e, "roughHestonRiccatiSolution", "1.44");
#endif
}
unsigned qlRoughHestonNumberOfEvaluations(QlAnalyticRoughHestonEngine* o, QlError **e) { QlCallScope callbackScope(e);

#if QL_HEX_VERSION >= 0x01440000
  try {return (*arg(o))->numberOfEvaluations();} catch (std::exception& er) {return handleException<unsigned>(e, er);}
#else
  (void)o;
  qlUnsupportedVersion(e, "roughHestonNumberOfEvaluations", "1.44"); return 0;
#endif
}
double qlRoughHestonPriceDate(QlAnalyticRoughHestonEngine* o, QlPlainVanillaPayoff* payoff, int maturity, QlError **e) { QlCallScope callbackScope(e);

#if QL_HEX_VERSION >= 0x01440000
  try {return (*arg(o))->priceVanillaPayoff(*arg(payoff), Date(maturity));} catch (std::exception& er) {return handleException<double>(e, er);}
#else
  (void)o; (void)payoff; (void)maturity;
  qlUnsupportedVersion(e, "roughHestonPriceVanillaPayoff", "1.44"); return 0;
#endif
}
double qlRoughHestonPriceTime(QlAnalyticRoughHestonEngine* o, QlPlainVanillaPayoff* payoff, double maturity, QlError **e) { QlCallScope callbackScope(e);

#if QL_HEX_VERSION >= 0x01440000
  try {return (*arg(o))->priceVanillaPayoff(*arg(payoff), maturity);} catch (std::exception& er) {return handleException<double>(e, er);}
#else
  (void)o; (void)payoff; (void)maturity;
  qlUnsupportedVersion(e, "roughHestonPriceVanillaPayoff", "1.44"); return 0;
#endif
}
QlPricingEngine* qlDiscountingMtMCrossCurrencyBasisSwapEngine(Currency* domesticCcy, QlYieldTermStructure* domesticCurve, Currency* foreignCcy, QlYieldTermStructure* foreignCurve, QlQuote* spotFx, int includeSettlement, int settlementDate, int npvDate, int spotFxSettleDate, QlError **e) { QlCallScope callbackScope(e);

#if QL_HEX_VERSION >= 0x01440000
  try {return ret(new QlPricingEngine(alloc(new DiscountingMtMCrossCurrencyBasisSwapEngine(*arg(domesticCcy), *arg(domesticCurve), *arg(foreignCcy), *arg(foreignCurve), *arg(spotFx), qlOptBool(includeSettlement), qlNullableDate(settlementDate), qlNullableDate(npvDate), qlNullableDate(spotFxSettleDate)))));} catch (std::exception& er) {return handleException<QlPricingEngine*>(e, er);}
#else
  (void)domesticCcy; (void)domesticCurve; (void)foreignCcy; (void)foreignCurve; (void)spotFx; (void)includeSettlement; (void)settlementDate; (void)npvDate; (void)spotFxSettleDate;
  qlUnsupportedVersion(e, "discountingMtmCrossCurrencyBasisSwapEngine", "1.44"); return nullptr;
#endif
}
}
/* vim: set ft=cpp ff=unix ts=8 sts=2 sw=2 et: */