Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/scaddins/source/pricing/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 15 kB image not shown  

Quelle  pricing.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


// pricing functions add in

// all of the UNO add-in technical details have been copied from
// ../datefunc/datefunc.cxx

#include "pricing.hxx"
#include "black_scholes.hxx"
#include <pricing.hrc>
#include <strings.hrc>

#include <cppuhelper/factory.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <cppuhelper/weak.hxx>
#include <algorithm>
#include <cmath>
#include <string_view>
#include <unotools/resmgr.hxx>
#include <i18nlangtag/languagetag.hxx>
#include <o3tl/string_view.hxx>

using namespace ::com::sun::star;
using namespace sca::pricing;


constexpr OUString ADDIN_SERVICE = u"com.sun.star.sheet.AddIn"_ustr;
constexpr OUString MY_SERVICE = u"com.sun.star.sheet.addin.PricingFunctions"_ustr;
constexpr OUStringLiteral MY_IMPLNAME = u"com.sun.star.sheet.addin.PricingFunctionsImpl";

const ScaFuncDataBase pFuncDataArr[] =
{
    { "getOptBarrier", PRICING_FUNCNAME_OptBarrier, PRICING_FUNCDESC_OptBarrier, "OPT_BARRIER", 13, ScaCategory::Finance, falsefalse },
    { "getOptTouch", PRICING_FUNCNAME_OptTouch, PRICING_FUNCDESC_OptTouch, "OPT_TOUCH", 11, ScaCategory::Finance, falsefalse },
    { "getOptProbHit", PRICING_FUNCNAME_OptProbHit, PRICING_FUNCDESC_OptProbHit, "OPT_PROB_HIT", 6, ScaCategory::Finance, falsefalse },
    { "getOptProbInMoney", PRICING_FUNCNAME_OptProbInMoney, PRICING_FUNCDESC_OptProbInMoney, "OPT_PROB_INMONEY", 8, ScaCategory::Finance, falsefalse },
};

ScaFuncData::ScaFuncData( const ScaFuncDataBase& rBaseData ) :
    aIntName( OUString::createFromAscii( rBaseData.pIntName ) ),
    pUINameID( rBaseData.pUINameID ),
    pDescrID( rBaseData.pDescrID ),
    nParamCount( rBaseData.nParamCount ),
    eCat( rBaseData.eCat ),
    bDouble( rBaseData.bDouble ),
    bWithOpt( rBaseData.bWithOpt )
{
    aCompList.push_back(OUString::createFromAscii(rBaseData.pCompName));
}

sal_uInt16 ScaFuncData::GetStrIndex( sal_uInt16 nParam ) const
{
    if( !bWithOpt )
        nParam++;
    return (nParam > nParamCount) ? (nParamCount * 2) : (nParam * 2);
}

void sca::pricing::InitScaFuncDataList(ScaFuncDataList& rList)
{
    for (const auto & nIndex : pFuncDataArr)
        rList.emplace_back(nIndex);
}

// entry points for service registration / instantiation

extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
scaddins_ScaPricingAddIn_get_implementation(
    css::uno::XComponentContext* , css::uno::Sequence<css::uno::Any> const&)
{
    return cppu::acquire(new ScaPricingAddIn());
}

//  "normal" service implementation
ScaPricingAddIn::ScaPricingAddIn()
{
}

ScaPricingAddIn::~ScaPricingAddIn()
{
}

static const char*  pLang[] = { "en" };
static const char*  pCoun[] = { "US" };
constexpr sal_uInt32 nNumOfLoc = std::size( pLang );

void ScaPricingAddIn::InitDefLocales()
{
    pDefLocales.reset( new lang::Locale[ nNumOfLoc ] );

    for( sal_uInt32 nIndex = 0; nIndex < nNumOfLoc; nIndex++ )
    {
        pDefLocales[ nIndex ].Language = OUString::createFromAscii( pLang[ nIndex ] );
        pDefLocales[ nIndex ].Country = OUString::createFromAscii( pCoun[ nIndex ] );
    }
}

const lang::Locale& ScaPricingAddIn::GetLocale( sal_uInt32 nIndex )
{
    if( !pDefLocales )
        InitDefLocales();

    return (nIndex < nNumOfLoc) ? pDefLocales[ nIndex ] : aFuncLoc;
}

void ScaPricingAddIn::InitData()
{
    aResLocale = Translate::Create("sca", LanguageTag(aFuncLoc));
    pFuncDataList.reset(new ScaFuncDataList);
    InitScaFuncDataList(*pFuncDataList);
    pDefLocales.reset();
}

OUString ScaPricingAddIn::GetFuncDescrStr(const TranslateId* pResId, sal_uInt16 nStrIndex)
{
    return ScaResId(pResId[nStrIndex - 1]);
}

// XServiceName
OUString SAL_CALL ScaPricingAddIn::getServiceName()
{
    // name of specific AddIn service
    return MY_SERVICE;
}

// XServiceInfo
OUString SAL_CALL ScaPricingAddIn::getImplementationName()
{
    return MY_IMPLNAME;
}

sal_Bool SAL_CALL ScaPricingAddIn::supportsService( const OUString& aServiceName )
{
    return cppu::supportsService(this, aServiceName);
}

uno::Sequence< OUString > SAL_CALL ScaPricingAddIn::getSupportedServiceNames()
{
    return { ADDIN_SERVICE, MY_SERVICE };
}

// XLocalizable
void SAL_CALL ScaPricingAddIn::setLocale( const lang::Locale& eLocale )
{
    aFuncLoc = eLocale;
    InitData();     // change of locale invalidates resources!
}

lang::Locale SAL_CALL ScaPricingAddIn::getLocale()
{
    return aFuncLoc;
}

// function descriptions start here
// XAddIn
OUString SAL_CALL ScaPricingAddIn::getProgrammaticFuntionName( const OUString& )
{
    //  not used by calc
    //  (but should be implemented for other uses of the AddIn service)
    return OUString();
}

OUString SAL_CALL ScaPricingAddIn::getDisplayFunctionName( const OUString& aProgrammaticName )
{
    OUString aRet;

    auto fDataIt = std::find_if(pFuncDataList->begin(), pFuncDataList->end(),
                                FindScaFuncData( aProgrammaticName ) );
    if (fDataIt != pFuncDataList->end() )
    {
        aRet = ScaResId(fDataIt->GetUINameID());
        if( fDataIt->IsDouble() )
            aRet += "_ADD";
    }
    else
    {
        aRet = "UNKNOWNFUNC_" + aProgrammaticName;
    }

    return aRet;
}

OUString SAL_CALL ScaPricingAddIn::getFunctionDescription( const OUString& aProgrammaticName )
{
    OUString aRet;

    auto fDataIt = std::find_if( pFuncDataList->begin(), pFuncDataList->end(),
                                 FindScaFuncData( aProgrammaticName ) );
    if( fDataIt != pFuncDataList->end() )
        aRet = GetFuncDescrStr( fDataIt->GetDescrID(), 1 );

    return aRet;
}

OUString SAL_CALL ScaPricingAddIn::getDisplayArgumentName(
        const OUString& aProgrammaticName, sal_Int32 nArgument )
{
    OUString aRet;

    auto fDataIt = std::find_if( pFuncDataList->begin(), pFuncDataList->end(),
                                 FindScaFuncData( aProgrammaticName ) );
    if( fDataIt != pFuncDataList->end() && (nArgument <= 0xFFFF) )
    {
        sal_uInt16 nStr = fDataIt->GetStrIndex( static_cast< sal_uInt16 >( nArgument ) );
        if( nStr )
            aRet = GetFuncDescrStr( fDataIt->GetDescrID(), nStr );
        else
            aRet = "internal";
    }

    return aRet;
}

OUString SAL_CALL ScaPricingAddIn::getArgumentDescription(
        const OUString& aProgrammaticName, sal_Int32 nArgument )
{
    OUString aRet;

    auto fDataIt = std::find_if( pFuncDataList->begin(), pFuncDataList->end(),
                                 FindScaFuncData( aProgrammaticName ) );
    if( fDataIt != pFuncDataList->end() && (nArgument <= 0xFFFF) )
    {
        sal_uInt16 nStr = fDataIt->GetStrIndex( static_cast< sal_uInt16 >( nArgument ) );
        if( nStr )
            aRet = GetFuncDescrStr( fDataIt->GetDescrID(), nStr + 1 );
        else
            aRet = "for internal use only";
    }

    return aRet;
}

OUString SAL_CALL ScaPricingAddIn::getProgrammaticCategoryName(
        const OUString& aProgrammaticName )
{
    OUString aRet;

    auto fDataIt = std::find_if( pFuncDataList->begin(), pFuncDataList->end(),
                                 FindScaFuncData( aProgrammaticName ) );
    if( fDataIt != pFuncDataList->end() )
    {
        switch( fDataIt->GetCategory() )
        {
            case ScaCategory::DateTime:   aRet = "Date&Time";    break;
            case ScaCategory::Text:       aRet = "Text";         break;
            case ScaCategory::Finance:    aRet = "Financial";    break;
            case ScaCategory::Inf:        aRet = "Information";  break;
            case ScaCategory::Math:       aRet = "Mathematical"break;
            case ScaCategory::Tech:       aRet = "Technical";    break;
        }
    }

    if( aRet.isEmpty() )
        aRet = "Add-In";
    return aRet;
}

OUString SAL_CALL ScaPricingAddIn::getDisplayCategoryName(
        const OUString& aProgrammaticName )
{
    return getProgrammaticCategoryName( aProgrammaticName );
}

// XCompatibilityNames
uno::Sequence< sheet::LocalizedName > SAL_CALL ScaPricingAddIn::getCompatibilityNames(
        const OUString& aProgrammaticName )
{
    auto fDataIt = std::find_if( pFuncDataList->begin(), pFuncDataList->end(),
                                 FindScaFuncData( aProgrammaticName ) );
    if( fDataIt == pFuncDataList->end() )
        return uno::Sequence< sheet::LocalizedName >( 0 );

    const std::vector<OUString>& rStrList = fDataIt->GetCompNameList();
    sal_uInt32 nCount = rStrList.size();

    uno::Sequence< sheet::LocalizedName > aRet( nCount );
    sheet::LocalizedName* pArray = aRet.getArray();

    for( sal_uInt32 nIndex = 0; nIndex < nCount; nIndex++ )
        pArray[ nIndex ] = sheet::LocalizedName( GetLocale( nIndex ), rStrList[nIndex] );

    return aRet;
}

// actual function implementation starts here
// auxiliary input handling functions
namespace {

bool getinput_putcall(bs::types::PutCall& pc, std::u16string_view str) {
    if(o3tl::starts_with(str, u"c")) {
        pc=bs::types::Call;
    } else if(o3tl::starts_with(str, u"p")) {
        pc=bs::types::Put;
    } else {
        return false;
    }
    return true;
}

bool getinput_putcall(bs::types::PutCall& pc, const uno::Any& anyval) {
    OUString str;
    if(anyval.getValueTypeClass() == uno::TypeClass_STRING) {
        anyval >>= str;
    } else if(anyval.getValueTypeClass() == uno::TypeClass_VOID) {
        str="c";        // call as default
    } else {
        return false;
    }
    return getinput_putcall(pc, str);
}

bool getinput_strike(double& strike, const uno::Any& anyval) {
    if(anyval.getValueTypeClass() == uno::TypeClass_DOUBLE) {
        anyval >>= strike;
    } else if(anyval.getValueTypeClass() == uno::TypeClass_VOID) {
        strike=-1.0;        // -1 as default (means not set)
    } else {
        return false;
    }
    return true;
}

bool getinput_inout(bs::types::BarrierKIO& kio, std::u16string_view str) {
    if(o3tl::starts_with(str, u"i")) {
        kio=bs::types::KnockIn;
    } else if(o3tl::starts_with(str, u"o")) {
        kio=bs::types::KnockOut;
    } else {
        return false;
    }
    return true;
}

bool getinput_barrier(bs::types::BarrierActive& cont, std::u16string_view str) {
    if(o3tl::starts_with(str, u"c")) {
        cont=bs::types::Continuous;
    } else if(o3tl::starts_with(str, u"e")) {
        cont=bs::types::Maturity;
    } else {
        return false;
    }
    return true;
}

bool getinput_fordom(bs::types::ForDom& fd, std::u16string_view str) {
    if(o3tl::starts_with(str, u"f")) {
        fd=bs::types::Foreign;
    } else if(o3tl::starts_with(str, u"d")) {
        fd=bs::types::Domestic;
    } else {
        return false;
    }
    return true;
}

bool getinput_greek(bs::types::Greeks& greek, const uno::Any& anyval) {
    OUString str;
    if(anyval.getValueTypeClass() == uno::TypeClass_STRING) {
        anyval >>= str;
    } else if(anyval.getValueTypeClass() == uno::TypeClass_VOID) {
        str="value";
    } else {
        return false;
    }

    if(str == "value" || str == "price" || str == "v" || str == "p") {
        greek=bs::types::Value;
    } else if(str == "delta" || str == "d") {
        greek=bs::types::Delta;
    } else if(str == "gamma" || str == "g") {
        greek=bs::types::Gamma;
    } else if(str == "theta" || str == "t") {
        greek=bs::types::Theta;
    } else if(str == "vega" || str == "e") {
        greek=bs::types::Vega;
    } else if(str == "volga" || str == "o") {
        greek=bs::types::Volga;
    } else if(str == "vanna" || str == "a") {
        greek=bs::types::Vanna;
    } else if(str == "rho" || str == "r") {
        greek=bs::types::Rho_d;
    } else if(str == "rhof" || str == "f") {
        greek=bs::types::Rho_f;
    } else {
        return false;
    }
    return true;
}

// namespace for auxiliary functions

// OPT_BARRIER(...)
double SAL_CALL ScaPricingAddIn::getOptBarrier( double spot, double vol,
            double r, double rf, double T, double strike,
            double barrier_low, double barrier_up, double rebate,
            const OUString& put_call, const OUString& in_out,
            const OUString& barriercont, const uno::Any& greekstr )
{
    bs::types::PutCall pc;
    bs::types::BarrierKIO kio;
    bs::types::BarrierActive bcont;
    bs::types::Greeks greek;
    // read and check input values
    if( spot<=0.0 || vol<=0.0 || T<0.0 || strike<0.0 ||
                !getinput_putcall(pc,put_call) ||
                !getinput_inout(kio,in_out) ||
                !getinput_barrier(bcont,barriercont) ||
                !getinput_greek(greek,greekstr) ){
        throw lang::IllegalArgumentException();
    }

    double fRet=bs::barrier(spot,vol,r,rf,T,strike, barrier_low,barrier_up,
                            rebate,pc,kio,bcont,greek);

    if (!std::isfinite(fRet))
        throw css::lang::IllegalArgumentException();
    return fRet;
}

// OPT_TOUCH(...)
double SAL_CALL ScaPricingAddIn::getOptTouch( double spot, double vol,
            double r, double rf, double T,
            double barrier_low, double barrier_up,
            const OUString& for_dom, const OUString& in_out,
            const OUString& barriercont, const uno::Any& greekstr )
{
    bs::types::ForDom fd;
    bs::types::BarrierKIO kio;
    bs::types::BarrierActive bcont;
    bs::types::Greeks greek;
    // read and check input values
    if( spot<=0.0 || vol<=0.0 || T<0.0 ||
                !getinput_fordom(fd,for_dom) ||
                !getinput_inout(kio,in_out) ||
                !getinput_barrier(bcont,barriercont) ||
                !getinput_greek(greek,greekstr) ){
        throw lang::IllegalArgumentException();
    }

    double fRet=bs::touch(spot,vol,r,rf,T,barrier_low,barrier_up,
                            fd,kio,bcont,greek);

    if (!std::isfinite(fRet))
        throw css::lang::IllegalArgumentException();
    return fRet;
}

// OPT_PRB_HIT(...)
double SAL_CALL ScaPricingAddIn::getOptProbHit( double spot, double vol,
            double mu, double T,
            double barrier_low, double barrier_up )
{
    // read and check input values
    if( spot<=0.0 || vol<=0.0 || T<0.0 ) {
        throw lang::IllegalArgumentException();
    }

    double fRet=bs::prob_hit(spot,vol,mu,T,barrier_low,barrier_up);

    if (!std::isfinite(fRet))
        throw css::lang::IllegalArgumentException();
    return fRet;
}

// OPT_PROB_INMONEY(...)
double SAL_CALL ScaPricingAddIn::getOptProbInMoney( double spot, double vol,
            double mu, double T,
            double barrier_low, double barrier_up,
            const uno::Any& strikeval, const uno::Any& put_call )
{
    bs::types::PutCall pc=bs::types::Call;
    double  K = 0;

    // read and check input values
    if( spot<=0.0 || vol<=0.0 || T<0.0 ||
            !getinput_putcall(pc,put_call) ||
            !getinput_strike(K,strikeval) ) {
        throw lang::IllegalArgumentException();
    }

    double fRet=bs::prob_in_money(spot,vol,mu,T,K,barrier_low,barrier_up,pc);

    if (!std::isfinite(fRet))
        throw css::lang::IllegalArgumentException();
    return fRet;
}

OUString ScaPricingAddIn::ScaResId(TranslateId aResId)
{
    return Translate::get(aResId, aResLocale);
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=92 H=97 G=94

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.