inline
    Real ReplicatingVarianceSwapEngine::computeReplicatingPortfolio(
                                    const weights_type& optionWeights) const {

        boost::shared_ptr<Exercise> exercise(
                               new EuropeanExercise(arguments_.maturityDate));
        boost::shared_ptr<PricingEngine> optionEngine(
                                        new AnalyticEuropeanEngine(process_));
        Real optionsValue = 0.0;

        for (weights_type::const_iterator i = optionWeights.begin();
             i < optionWeights.end(); ++i) {
            boost::shared_ptr<StrikedTypePayoff> payoff = i->first;
            EuropeanOption option(payoff, exercise);
            option.setPricingEngine(optionEngine);
            Real weight = i->second;
            optionsValue += option.NPV() * weight;
        }

        Real f = optionWeights.front().first->strike();
        return 2.0 * riskFreeRate() -
            2.0/residualTime() *
            (((underlying()/riskFreeDiscount() - f)/f) +
             std::log(f/underlying())) +
            optionsValue/riskFreeDiscount();
    }
 Real AnalyticBarrierEngine::B(Real phi) const {
     Real x2 =
         std::log(underlying()/barrier())/stdDeviation() + muSigma();
     Real N1 = f_(phi*x2);
     Real N2 = f_(phi*(x2-stdDeviation()));
     return phi*(underlying() * dividendDiscount() * N1
                 - strike() * riskFreeDiscount() * N2);
 }
 Real AnalyticBarrierEngine::D(Real eta, Real phi) const {
     Real HS = barrier()/underlying();
     Real powHS0 = std::pow(HS, 2 * mu());
     Real powHS1 = powHS0 * HS * HS;
     Real y2 = std::log(barrier()/underlying())/stdDeviation() + muSigma();
     Real N1 = f_(eta*y2);
     Real N2 = f_(eta*(y2-stdDeviation()));
     return phi*(underlying() * dividendDiscount() * powHS1 * N1
                 - strike() * riskFreeDiscount() * powHS0 * N2);
 }
 Real AnalyticBarrierEngine::E(Real eta) const {
     if (rebate() > 0) {
         Real powHS0 = std::pow(barrier()/underlying(), 2 * mu());
         Real x2 =
             std::log(underlying()/barrier())/stdDeviation() + muSigma();
         Real y2 =
             std::log(barrier()/underlying())/stdDeviation() + muSigma();
         Real N1 = f_(eta*(x2 - stdDeviation()));
         Real N2 = f_(eta*(y2 - stdDeviation()));
         return rebate() * riskFreeDiscount() * (N1 - powHS0 * N2);
     } else {
         return 0.0;
     }
 }
Example #5
0
    /**
     * Apply the sketching transform on A and write to sketch_of_A.
     * Implementation for columnwise.
     */
    void apply_impl(const matrix_type& A,
        output_matrix_type& sketch_of_A,
        skylark::sketch::columnwise_tag tag) const {

        // TODO verify sizes etc.
        underlying_t underlying(*data_type::_underlying_data);
        underlying.apply(A, sketch_of_A, tag);

#       if SKYLARK_HAVE_OPENMP
#       pragma omp parallel for collapse(2)
#       endif
        for(int j = 0; j < base::Width(A); j++)
            for(int i = 0; i < data_type::_S; i++) {
                value_type x = sketch_of_A.Get(i, j);
                x += data_type::_shifts[i];

#               ifndef SKYLARK_INEXACT_COSINE
                x = std::cos(x);
#               else
                // x = std::cos(x) is slow
                // Instead use low-accuracy approximation
                if (x < -3.14159265) x += 6.28318531;
                else if (x >  3.14159265) x -= 6.28318531;
                x += 1.57079632;
                if (x >  3.14159265)
                    x -= 6.28318531;
                x = (x < 0) ?
                    1.27323954 * x + 0.405284735 * x * x :
                    1.27323954 * x - 0.405284735 * x * x;
#               endif

                x = data_type::_outscale * x;
                sketch_of_A.Set(i, j, x);
            }
    }
 Real AnalyticContinuousFloatingLookbackEngine::A(Real eta) const {
     Volatility vol = volatility();
     Real lambda = 2.0*(riskFreeRate() - dividendYield())/(vol*vol);
     Real s = underlying()/minmax();
     Real d1 = std::log(s)/stdDeviation() + 0.5*(lambda+1.0)*stdDeviation();
     Real n1 = f_(eta*d1);
     Real n2 = f_(eta*(d1-stdDeviation()));
     Real n3 = f_(eta*(-d1+lambda*stdDeviation()));
     Real n4 = f_(eta*-d1);
     Real pow_s = std::pow(s, -lambda);
     return eta*((underlying() * dividendDiscount() * n1 -
                 minmax() * riskFreeDiscount() * n2) +
                 (underlying() * riskFreeDiscount() *
                 (pow_s * n3 - dividendDiscount()* n4/riskFreeDiscount())/
         lambda));
 }
Example #7
0
    void apply (const matrix_type& A,
                output_matrix_type& sketch_of_A,
                Dimension dimension) const {
        try {

            // TODO verify sizes etc.
            underlying_t underlying(*data_type::_underlying_data);
            underlying.apply(A, sketch_of_A, dimension);

#           if SKYLARK_HAVE_OPENMP
#           pragma omp parallel for collapse(2)
#           endif
            for(int j = 0; j < base::Width(sketch_of_A); j++)
                for(int i = 0; i < base::Height(sketch_of_A); i++) {
                    value_type val = sketch_of_A.Get(i, j);
                    sketch_of_A.Set(i, j,
                        data_type::_outscale * std::exp(-val));
                }

        } catch (std::logic_error e) {
            SKYLARK_THROW_EXCEPTION (
                base::elemental_exception()
                    << base::error_msg(e.what()) );
        } catch(boost::mpi::exception e) {
            SKYLARK_THROW_EXCEPTION (
                base::mpi_exception()
                    << base::error_msg(e.what()) );
        }
    }
    Real AnalyticDoubleBarrierEngine::putKO() const {
       Real mu1 = 2 * costOfCarry() / volatilitySquared() + 1;
       Real bsigma = (costOfCarry() + volatilitySquared() / 2.0) * residualTime() / stdDeviation();

       Real acc1 = 0;
       Real acc2 = 0;
       for (int n = -series_ ; n <= series_ ; ++n) {
          Real L2n = std::pow(barrierLo(), 2 * n);
          Real U2n = std::pow(barrierHi(), 2 * n);
          Real y1 = std::log( underlying()* U2n / (std::pow(barrierLo(), 2 * n + 1)) ) / stdDeviation() + bsigma;
          Real y2 = std::log( underlying()* U2n / (strike() * L2n) ) / stdDeviation() + bsigma;
          Real y3 = std::log( std::pow(barrierLo(), 2 * n + 2) / (barrierLo() * underlying() * U2n) ) / stdDeviation() + bsigma;
          Real y4 = std::log( std::pow(barrierLo(), 2 * n + 2) / (strike() * underlying() * U2n) ) / stdDeviation() + bsigma;

          acc1 += std::pow( std::pow(barrierHi(), n) / std::pow(barrierLo(), n), mu1-2) * 
                  (f_(y1 - stdDeviation()) - f_(y2 - stdDeviation())) -
                  std::pow( std::pow(barrierLo(), n+1) / (std::pow(barrierHi(), n) * underlying()), mu1-2 ) * 
                  (f_(y3-stdDeviation()) - f_(y4-stdDeviation()));

          acc2 += std::pow( std::pow(barrierHi(), n) / std::pow(barrierLo(), n), mu1 ) * 
                  (f_(y1) - f_(y2)) -
                  std::pow( std::pow(barrierLo(), n+1) / (std::pow(barrierHi(), n) * underlying()), mu1 ) * 
                  (f_(y3) - f_(y4));

       }

       Real rend = std::exp(-dividendYield() * residualTime());
       Real kov = strike() * riskFreeDiscount() * acc1 - underlying() * rend  * acc2;
       return std::max(0.0, kov);
    }
 Real AnalyticDoubleBarrierEngine::vanillaEquivalent() const {
     // Call KI equates to vanilla - callKO
     boost::shared_ptr<StrikedTypePayoff> payoff =
         boost::dynamic_pointer_cast<StrikedTypePayoff>(arguments_.payoff);
     Real forwardPrice = underlying() * dividendDiscount() / riskFreeDiscount();
     BlackCalculator black(payoff, forwardPrice, stdDeviation(), riskFreeDiscount());
     Real vanilla = black.value();
     if (vanilla < 0.0)
        vanilla = 0.0;
     return vanilla;
 }
    Real AnalyticBarrierEngine::F(Real eta) const {
        if (rebate() > 0) {
            Rate m = mu();
            Volatility vol = volatility();
            Real lambda = std::sqrt(m*m + 2.0*riskFreeRate()/(vol * vol));
            Real HS = barrier()/underlying();
            Real powHSplus = std::pow(HS, m + lambda);
            Real powHSminus = std::pow(HS, m - lambda);

            Real sigmaSqrtT = stdDeviation();
            Real z = std::log(barrier()/underlying())/sigmaSqrtT
                + lambda * sigmaSqrtT;

            Real N1 = f_(eta * z);
            Real N2 = f_(eta * (z - 2.0 * lambda * sigmaSqrtT));
            return rebate() * (powHSplus * N1 + powHSminus * N2);
        } else {
            return 0.0;
        }
    }
Example #11
0
int ConfigObjectLoader::toInt( expr_cref value ) const
{
	expr_cref expr = underlying( value );
	
	// If we want an int it has to be that. Not a double.
	if( expr.type() != EInt )
	{
		std::ostringstream oss;
		oss << "expected int, got " << expr.value() << " interpreted as " << typestr[expr.type()];
		throw TypeError( oss.str() );
	}
	return boost::lexical_cast<int>( expr.value() );
}
Example #12
0
double ConfigObjectLoader::toDouble( expr_cref value ) const
{
	expr_cref expr = underlying( value );
	
	// we want a double. If we get an int, that will suffice. All ints are also doubles.
	if( expr.type() != EReal && expr.type() != EInt )
	{
		std::ostringstream oss;
		oss << "expected a number, got " << expr.value() << " interpreted as " << typestr[expr.type()];
		throw TypeError( oss.str() );
	}
	return boost::lexical_cast<double>( expr.value() );
}
Example #13
0
bool ConfigObjectLoader::toBool( expr_cref value ) const
{
	expr_cref expr = underlying( value );
	if( expr.type() != EBool )
	{
		std::ostringstream oss;
		oss << "expected boolean, got " << expr.value() << " interpreted as " << typestr[expr.type()] << 
			" (note, numbers do not convert to booleans)";
		throw TypeError( oss.str() );
	}
	
	return ( expr.value() == "true" ); // there are stored as "true" and "false". Anything else would not be interpreted as boolean
}
Example #14
0
std::string ConfigObjectLoader::toEnum( IOC::expr_cref value ) const
{
	std::string last;
	expr_cref expr = underlying( value, &last, false );
	if( expr.type() != EVariable )
	{
		std::ostringstream oss;
		oss << last << " has been defined to " << expr.value() << " of type " <<
			typestr[expr.type()] << " expecting an enumeration";
		throw TypeError( oss.str() );
	}

	return last; // which should be the same as expr.value()
}
Example #15
0
void ConfigObjectLoader::toVector( expr_cref value, std::vector< RecursiveExpressionPtr > & res ) const
{
	// this is actually fairly straightforward
	// once again traverse down through any variables
	expr_cref expr = underlying( value );

	// it must be expressed as List.
	if( expr.type() != EList )
	{
		std::ostringstream oss;
		oss << "expected a list, got " << expr.value() << " interpreted as " << typestr[expr.type()];
		throw TypeError( oss.str() );
	}

	// now just populate it
	res = expr.params();
}
Example #16
0
ObjectInfoPtr ConfigObjectLoader::getObjectInfo( expr_cref expr, str_cref name ) const
{
	if( !name.empty() )
	{
		ObjectInfoPtr obj;

		// already found.
		if( Utility::mapLookup( m_objects, name, obj ) )
		{
			return obj;
		}
	}

	if( expr.type() == EObject ) // it's an object expression
	{
		std::string className = expr.value();
		ClassInfoPtr classInfo = getClassInfo( className );
		BuilderPtr builder = classInfo->createBuilder( name, expr );
        ObjectInfoPtr obj( new ObjectInfo( name, expr, *classInfo, builder ) );

        // It needs to be in the map before we bind its parameters so a circular reference can be detected
        m_objects[name] = obj;
        builder->bindParams( *this );
		return obj;
	}
	else if( expr.type() == EVariable )
	{
		// this could recurse indefinitely with circular reference..

		// NOTE: if anything throws here, let ParamBinderBase manage the context of the error.

		std::string objName;
		expr_cref expr2 = underlying( expr, &objName );
		return getObjectInfo( expr2, objName );
	}
	else // this isn't a class. It might be a map or list or whatever but isn't an object
	{
		std::ostringstream oss;
		oss << expr.value() << " is not an object";

		// Do not throw TypeError here. If it isn't an object it can't be a proxy either
		throw std::invalid_argument( oss.str() );
	}

}
Example #17
0
// To return an actual std::map at this stage would be far too complex. We returns a vector of pairs
// which will then be 
void ConfigObjectLoader::toMap( expr_cref value, 
		std::vector< std::pair< RecursiveExpressionPtr, RecursiveExpressionPtr > > & res ) const
{
	expr_cref expr = underlying( value );
	
	if( expr.type() != EMap )
	{
		std::ostringstream oss;
		oss << "expected a map, got " << expr.value() << " interpreted as " << typestr[expr.type()]
		<< " (note: a List of Pair items is not a map)";

		throw TypeError( oss.str() );
	}

	std::vector<RecursiveExpressionPtr> const& params = expr.params();

	res.resize( params.size() );
	std::transform( params.begin(), params.end(), res.begin(), PairConverter( this ) );
}
Example #18
0
size_t ConfigObjectLoader::toUInt( expr_cref value ) const
{
	expr_cref expr = underlying( value );
	
	if( expr.type() != EInt )
	{
		std::ostringstream oss;
		oss << "expected unsigned int, got " << expr.value() << " interpreted as " << typestr[expr.type()];
		throw TypeError( oss.str() );
	}
	try
	{
		return boost::lexical_cast<size_t>( expr.value() );
	}
	catch( std::exception const& ) // in case it's a negative number in which case I assume it won't cast
	{
		// I want to throw my own exception.
		std::ostringstream oss;
		oss << "Expected unsigned int, got " << expr.value() << " Which did not convert (is it negative?)";
		throw std::invalid_argument( oss.str() );
	}
}
Example #19
0
    /**
     * Apply the sketching transform that is described in by the sketch_of_A.
     * Implementation for columnwise.
     */
    void apply_impl(const matrix_type& A,
        output_matrix_type& sketch_of_A,
        skylark::sketch::columnwise_tag tag) const {

        underlying_t underlying(*data_type::_underlying_data);
        underlying.apply(A, sketch_of_A, tag);

        El::Matrix<value_type> &SAl = sketch_of_A.Matrix();
        size_t col_shift = sketch_of_A.ColShift();
        size_t col_stride = sketch_of_A.ColStride();

#       if SKYLARK_HAVE_OPENMP
#       pragma omp parallel for collapse(2)
#       endif
        for(size_t j = 0; j < base::Width(SAl); j++)
            for(size_t i = 0; i < base::Height(SAl); i++) {
                value_type x = SAl.Get(i, j);
                x += data_type::_shifts[col_shift + i * col_stride];

#               ifndef SKYLARK_INEXACT_COSINE
                x = std::cos(x);
#               else
                // x = std::cos(x) is slow
                // Instead use low-accuracy approximation
                if (x < -3.14159265) x += 6.28318531;
                else if (x >  3.14159265) x -= 6.28318531;
                x += 1.57079632;
                if (x >  3.14159265)
                    x -= 6.28318531;
                x = (x < 0) ?
                    1.27323954 * x + 0.405284735 * x * x :
                    1.27323954 * x - 0.405284735 * x * x;
#               endif

                x = data_type::_outscale * x;
                SAl.Set(i, j, x);
            }
    }
Example #20
0
// For string it is more complex as we have to handle Concat expressions too
std::string ConfigObjectLoader::toString( expr_cref value ) const
{
	expr_cref expr = underlying( value );
	if( expr.type() == EString )
	{
		return expr.value();
	}
	else if( expr.type() == EConcat ) 
	{
		std::vector< RecursiveExpressionPtr > const& params = expr.params();
		std::string res;
		for( RecursiveExpressionPtr pexp : params )
		{
			res.append( toString( *pexp ) );
		}
		return res;
	}
	else
	{
		std::ostringstream oss;
		oss << "Could not interpret " << expr.value() << " as a string: interpreted as " << typestr[expr.type()];
		throw TypeError( oss.str() );
	}
}
Example #21
0
 U underlying_cast(T const& v)
 {
   return static_cast<U>(underlying(v));
 }
    void AnalyticDoubleBarrierEngine::calculate() const {

        QL_REQUIRE(arguments_.exercise->type() == Exercise::European,
                   "this engine handles only european options");

        boost::shared_ptr<PlainVanillaPayoff> payoff =
            boost::dynamic_pointer_cast<PlainVanillaPayoff>(arguments_.payoff);
        QL_REQUIRE(payoff, "non-plain payoff given");

        Real strike = payoff->strike();
        QL_REQUIRE(strike>0.0,
                   "strike must be positive");

        Real spot = underlying();
        QL_REQUIRE(spot >= 0.0, "negative or null underlying given");
        QL_REQUIRE(!triggered(spot), "barrier(s) already touched");

        DoubleBarrier::Type barrierType = arguments_.barrierType;

        if (triggered(spot)) {
           if (barrierType == DoubleBarrier::KnockIn)
               results_.value = vanillaEquivalent();  // knocked in
           else
               results_.value = 0.0;  // knocked out
        } else {
           switch (payoff->optionType()) {
             case Option::Call:
               switch (barrierType) {
                 case DoubleBarrier::KnockIn:
                   results_.value = callKI();
                   break;
                 case DoubleBarrier::KnockOut:
                   results_.value = callKO();
                   break;
                 case DoubleBarrier::KIKO:
                 case DoubleBarrier::KOKI:
                   QL_FAIL("unsupported double-barrier type: "
                           << barrierType);
                 default:
                   QL_FAIL("unknown double-barrier type: "
                           << barrierType);
               }
               break;
             case Option::Put:
               switch (barrierType) {
                 case DoubleBarrier::KnockIn:
                   results_.value = putKI();
                   break;
                 case DoubleBarrier::KnockOut:
                   results_.value = putKO();
                   break;
                 case DoubleBarrier::KIKO:
                 case DoubleBarrier::KOKI:
                   QL_FAIL("unsupported double-barrier type: "
                           << barrierType);
                 default:
                   QL_FAIL("unknown double-barrier type: "
                           << barrierType);
               }
               break;
             default:
               QL_FAIL("unknown type");
           }
        }
    }
 std::basic_ostream<Ch, Tr> &
   operator<<(std::basic_ostream<Ch, Tr> & o, std::stack<T, C> const & s)
 { return o << underlying(s); }
 std::basic_ostream<Ch, Tr> &
   operator<<(std::basic_ostream<Ch, Tr> & o, std::priority_queue<T, C, P> const & q)
 { return o << underlying(q); }
Example #25
0
  /// F flags2 = F{Opt::MoveArms};
  /// F flags3 = flags2;
  /// F flags = ( flags1 | flags2 ) & flags3;
  /// // flags == flags2
  ///
  /// // ...
  /// startBehavior(flags);
  /// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~/
  ///
  /// HasUnderlying<BitmaskType> Type
  template <typename Type>
  class Flags
  {
  public:
    using type = Type;
    using underlying_type = traits::Decay<decltype(underlying(std::declval<Type>()))>;

  private:
    explicit Flags(underlying_type value)
      : _value(value)
    {}

  public:
  // Regular:
    Flags()
      : _value{}
    {}

    QI_GENERATE_FRIEND_REGULAR_OPS_1(Flags, _value)

  // HasUnderlying: