All Downloads are FREE. Search and download functionalities are using the official Maven repository.

.cdm-java.6.0.0-dev.82.source-code.margin-schedule-func.rosetta Maven / Gradle / Ivy

There is a newer version: 6.0.0-dev.89
Show newest version
namespace cdm.margin.schedule
version "${project.version}"

import cdm.event.common.*
import cdm.event.position.*

import cdm.base.datetime.*
import cdm.base.math.*

import cdm.product.qualification.*
import cdm.product.template.*
import cdm.product.common.settlement.*

func BuildStandardizedSchedule: <"Takes a trade and uses qualification to extract the relevant information to populate the grid that will be used to calculate the gross initial margin.">
    inputs:
        trade Trade (1..1)
    output:
        standardizedSchedule StandardizedSchedule (1..1)
    set standardizedSchedule -> assetClass: StandardizedScheduleAssetClass(trade)
    set standardizedSchedule -> productClass: StandardizedScheduleProductClass(trade)
    set standardizedSchedule -> notional: StandardizedScheduleNotional(trade)
    set standardizedSchedule -> notionalCurrency:
        StandardizedScheduleNotionalCurrency(trade)
    set standardizedSchedule -> durationInYears: StandardizedScheduleDuration(trade)

func GetGrossInitialMarginFromStandardizedSchedule: <"Takes the grid information from an specific trade and calculates the gross initial margin.">
    inputs:
        standardizedSchedule StandardizedSchedule (1..1)
    output:
        grossInitialMargin Quantity (0..1)
    alias initialMarginRequirement:
        GetIMRequirement(
                standardizedSchedule -> assetClass,
                standardizedSchedule -> durationInYears
            )
    set grossInitialMargin -> value:
        standardizedSchedule -> notional * initialMarginRequirement * 0.01
    set grossInitialMargin -> unit -> currency: standardizedSchedule -> notionalCurrency

func StandardizedScheduleAssetClass: <"Identifies the asset class of a trade, according to the standardized schedule classification.">
    inputs:
        trade Trade (1..1)
    output:
        assetClass StandardizedScheduleAssetClassEnum (0..1)

    alias economicTerms: trade -> product -> economicTerms

    set assetClass:
        if Qualify_AssetClass_InterestRate(economicTerms)
        then StandardizedScheduleAssetClassEnum -> InterestRates
        else if Qualify_AssetClass_Credit(economicTerms)
        then StandardizedScheduleAssetClassEnum -> Credit
        else if Qualify_AssetClass_ForeignExchange(economicTerms)
        then StandardizedScheduleAssetClassEnum -> ForeignExchange
        else if Qualify_AssetClass_Equity(economicTerms)
        then StandardizedScheduleAssetClassEnum -> Equity
        else if Qualify_AssetClass_Commodity(economicTerms)
        then StandardizedScheduleAssetClassEnum -> Commodity

func StandardizedScheduleProductClass: <"Identifies the product class of a trade, according to the standardized schedule classification.">
    inputs:
        trade Trade (1..1)
    output:
        productClass StandardizedScheduleProductClassEnum (0..1)

    alias economicTerms: trade -> product -> economicTerms

    set productClass:
        if IsIRSwapWithCallableBermudanRightToEnterExitSwaps(economicTerms)
        then StandardizedScheduleProductClassEnum -> SwapWithCallableBermudanRightToEnterExitSwaps
        else if Qualify_BaseProduct_IRSwap(economicTerms)
        then StandardizedScheduleProductClassEnum -> Swap
        else if Qualify_BaseProduct_CrossCurrency(economicTerms)
        then StandardizedScheduleProductClassEnum -> CrossCurrencySwap
        else if IsIRSwaptionStraddle(economicTerms)
        then StandardizedScheduleProductClassEnum -> SwaptionStraddle
        else if Qualify_InterestRate_Option_Swaption(economicTerms)
        then StandardizedScheduleProductClassEnum -> Swaption
        // IR Exotic swap with an exotic coupon against a floating leg not supported
        else if Qualify_InterestRate_CapFloor(economicTerms)
        then StandardizedScheduleProductClassEnum -> Option
        else if Qualify_InterestRate_Fra(economicTerms)
        then StandardizedScheduleProductClassEnum -> ForwardRateAgreement
        else if Qualify_CreditDefaultSwap_SingleName(economicTerms)
        then StandardizedScheduleProductClassEnum -> SingleNameCreditDefaultSwap
        else if Qualify_CreditDefaultSwap_Index(economicTerms)
        then StandardizedScheduleProductClassEnum -> IndexCDS
        else if Qualify_CreditDefaultSwap_IndexTranche(economicTerms)
        then StandardizedScheduleProductClassEnum -> IndexTranche
        else if Qualify_CreditDefaultSwaption(economicTerms)
        then StandardizedScheduleProductClassEnum -> Swaption
        else if IsCreditNthToDefault(economicTerms)
        then StandardizedScheduleProductClassEnum -> CreditNthToDefault
        // Credit Total return swap on a bond not supported
        else if Qualify_ForeignExchange_Swap(economicTerms)
        then StandardizedScheduleProductClassEnum -> DeliverableSwap
        else if Qualify_ForeignExchange_NDS(economicTerms)
        then StandardizedScheduleProductClassEnum -> NonDeliverableCrossCurrencySwap
        else if Qualify_ForeignExchange_Spot_Forward(economicTerms)
        then StandardizedScheduleProductClassEnum -> DeliverableForward
        else if Qualify_ForeignExchange_NDF(economicTerms)
        then StandardizedScheduleProductClassEnum -> NonDeliverableForward
        else if IsFXDeliverableOption(economicTerms)
        then StandardizedScheduleProductClassEnum -> DeliverableOption
        else if IsFXNonDeliverableOption(economicTerms)
        then StandardizedScheduleProductClassEnum -> NonDeliverableOption
        else if Qualify_ForeignExchange_ParameterReturnVariance(economicTerms)
        then StandardizedScheduleProductClassEnum -> VarianceSwap
        else if Qualify_ForeignExchange_ParameterReturnVolatility(economicTerms)
        then StandardizedScheduleProductClassEnum -> VolatilitySwap
        else if Qualify_ForeignExchange_ParameterReturnCorrelation(economicTerms)
        then StandardizedScheduleProductClassEnum -> CorrelationSwap
        else if Qualify_EquityOption_PriceReturnBasicPerformance_Basket(economicTerms)
                or Qualify_EquityOption_PriceReturnBasicPerformance_Index(economicTerms)
                or Qualify_EquityOption_PriceReturnBasicPerformance_SingleName(
                        economicTerms
                    )
                or Qualify_EquityOption_ParameterReturnVolatility_Basket(economicTerms)
                or Qualify_EquityOption_ParameterReturnVolatility_Index(economicTerms)
                or Qualify_EquityOption_ParameterReturnVolatility_SingleName(economicTerms)
                or Qualify_EquityOption_ParameterReturnVariance_Basket(economicTerms)
                or Qualify_EquityOption_ParameterReturnVariance_Index(economicTerms)
                or Qualify_EquityOption_ParameterReturnVariance_SingleName(economicTerms)
                or Qualify_EquityOption_ParameterReturnCorrelation_Basket(economicTerms)
                    // or Qualify_EquityOption_ParameterReturnCorrelation_Index(economicTerms)
                    // or Qualify_EquityOption_ParameterReturnCorrelation_SingleName(economicTerms)
                or Qualify_EquityOption_ParameterReturnDividend_Basket(economicTerms)
                or Qualify_EquityOption_ParameterReturnDividend_Index(economicTerms)
                or Qualify_EquityOption_ParameterReturnDividend_SingleName(economicTerms)
        then StandardizedScheduleProductClassEnum -> Option
        else if Qualify_BaseProduct_EquityForward(economicTerms)
        then StandardizedScheduleProductClassEnum -> Forward
        else if Qualify_EquitySwap_ParameterReturnDividend_Basket(economicTerms)
                or Qualify_EquitySwap_ParameterReturnDividend_Index(economicTerms)
                or Qualify_EquitySwap_ParameterReturnDividend_SingleName(economicTerms)
        then StandardizedScheduleProductClassEnum -> DividendSwap
        else if Qualify_EquitySwap_ParameterReturnVariance_Basket(economicTerms)
                or Qualify_EquitySwap_ParameterReturnVariance_Index(economicTerms)
                or Qualify_EquitySwap_ParameterReturnVariance_SingleName(economicTerms)
        then StandardizedScheduleProductClassEnum -> VarianceSwap
        else if Qualify_EquitySwap_ParameterReturnVolatility_Basket(economicTerms)
                or Qualify_EquitySwap_ParameterReturnVolatility_Index(economicTerms)
                or Qualify_EquitySwap_ParameterReturnVolatility_SingleName(economicTerms)
        then StandardizedScheduleProductClassEnum -> VolatilitySwap
        // EQ Contract fo Difference (CFD) not supported
        else if Qualify_BaseProduct_EquitySwap(economicTerms)
        then StandardizedScheduleProductClassEnum -> SwapsAndPortfolioSwaps
        else if Qualify_Commodity_Forward(economicTerms)
        then StandardizedScheduleProductClassEnum -> Forward
        else if Qualify_Commodity_Option(economicTerms)
        then StandardizedScheduleProductClassEnum -> Option
        else if Qualify_Commodity_Swap_FixedFloat(economicTerms)
        then StandardizedScheduleProductClassEnum -> FixedFloatSwap
        else if Qualify_Commodity_Swap_Basis(economicTerms)
        then StandardizedScheduleProductClassEnum -> BasisSwap
        else if Qualify_Commodity_Swaption(economicTerms)
        then StandardizedScheduleProductClassEnum -> Swaption

// CO Contract for Difference (CFD) not supported

func StandardizedScheduleNotional: <"Extracts the notional amount of a trade, according to the product class-depending extraction method defined in the ISDA industry survey.">
    inputs: trade Trade (1..1)
    output: notional number (0..1)

    alias product:
        trade -> product

    alias economicTerms:
        product -> economicTerms

    set notional:
    if Qualify_BaseProduct_IRSwap(economicTerms) or IsIRSwapWithCallableBermudanRightToEnterExitSwaps(economicTerms)
    then (
        economicTerms -> payout -> InterestRatePayout 
        filter priceQuantity -> quantitySchedule exists
        then first 
        then priceQuantity
        then StandardizedScheduleMonetaryNotionalFromResolvablePQ
    )
    else if Qualify_BaseProduct_CrossCurrency(economicTerms)
    then (
        economicTerms -> payout -> InterestRatePayout 
        filter (True /*how do we identify the receiver party?*/) 
        then first 
        then priceQuantity
        then StandardizedScheduleMonetaryNotionalFromResolvablePQ
    )
    else if Qualify_InterestRate_Option_Swaption(economicTerms) or IsIRSwaptionStraddle(economicTerms)
    then (
        UnderlierForProduct(product) -> Product ->> economicTerms -> payout -> InterestRatePayout 
        filter (priceQuantity -> quantitySchedule exists) 
        then first 
        then priceQuantity
        then StandardizedScheduleMonetaryNotionalFromResolvablePQ
    )
    // IR Exotic swap with an exotic coupon against a floating leg not supported
    else if Qualify_InterestRate_CapFloor(economicTerms)
    then (
        economicTerms -> payout -> InterestRatePayout only-element -> priceQuantity
        then StandardizedScheduleMonetaryNotionalFromResolvablePQ
    )
    else if Qualify_InterestRate_Fra(economicTerms)
    then (
        economicTerms -> payout -> InterestRatePayout 
        filter rateSpecification -> FixedRateSpecification exists 
        then only-element 
        then priceQuantity
        then StandardizedScheduleMonetaryNotionalFromResolvablePQ
    )
    else if Qualify_CreditDefaultSwap_SingleName(economicTerms)
    or Qualify_CreditDefaultSwap_Index(economicTerms)
    or Qualify_CreditDefaultSwap_IndexTranche(economicTerms)
    or IsCreditNthToDefault(economicTerms)
    then (
        economicTerms -> payout -> CreditDefaultPayout only-element -> priceQuantity
        then StandardizedScheduleMonetaryNotionalFromResolvablePQ
    )
    else if Qualify_CreditDefaultSwaption(economicTerms)
    then (
        UnderlierForProduct(product) -> Product ->> economicTerms -> payout -> CreditDefaultPayout only-element -> priceQuantity
        then StandardizedScheduleMonetaryNotionalFromResolvablePQ
    )
    // Credit Total return swap on a bond not supported
    else if Qualify_ForeignExchange_Swap(economicTerms)
    then (
        economicTerms -> payout -> SettlementPayout only-element -> priceQuantity -> quantitySchedule -> value
    )
    else if Qualify_ForeignExchange_NDS(economicTerms)
    then 0.0 //Recieve side notional and currency. What does that mean?
    else if Qualify_ForeignExchange_Spot_Forward(economicTerms)
    then (
        economicTerms -> payout -> SettlementPayout only-element -> priceQuantity -> quantitySchedule -> value
    )
    else if Qualify_ForeignExchange_NDF(economicTerms)
    then (
        economicTerms -> payout -> SettlementPayout only-element -> settlementTerms -> cashSettlementTerms -> cashSettlementAmount only-element -> value
    )
    else if IsFXDeliverableOption(economicTerms)
    then (
        economicTerms -> payout -> OptionPayout only-element -> priceQuantity -> quantitySchedule -> value
    )
    else if IsFXNonDeliverableOption(economicTerms)
    then (
        StandardizedScheduleFXNDONotional(economicTerms -> payout -> OptionPayout only-element) -> value
    )    
    else if Qualify_ForeignExchange_ParameterReturnVariance(economicTerms)
    then (
        StandardizedScheduleFXVarianceNotionalAmount(economicTerms -> payout -> PerformancePayout only-element)
    )
    else if Qualify_ForeignExchange_ParameterReturnVolatility(economicTerms)
    then 0.0 //Vega notional amount not mapped in the product
    else if Qualify_ForeignExchange_ParameterReturnCorrelation(economicTerms)
    then 0.0 //No sample trades
    else if Qualify_EquityOption_PriceReturnBasicPerformance_Basket(economicTerms)
            or Qualify_EquityOption_PriceReturnBasicPerformance_Index(economicTerms)
            or Qualify_EquityOption_PriceReturnBasicPerformance_SingleName(economicTerms)
            //To determine if the method used applies to the following equity options:
            // or Qualify_EquityOption_ParameterReturnVolatility_Basket(economicTerms)
            // or Qualify_EquityOption_ParameterReturnVolatility_Index(economicTerms)
            // or Qualify_EquityOption_ParameterReturnVolatility_SingleName(economicTerms)
            // or Qualify_EquityOption_ParameterReturnVariance_Basket(economicTerms)
            // or Qualify_EquityOption_ParameterReturnVariance_Index(economicTerms)
            // or Qualify_EquityOption_ParameterReturnVariance_SingleName(economicTerms)
            // or Qualify_EquityOption_ParameterReturnCorrelation_Basket(economicTerms)
            // // or Qualify_EquityOption_ParameterReturnCorrelation_Index(economicTerms)
            // // or Qualify_EquityOption_ParameterReturnCorrelation_SingleName(economicTerms)
            // or Qualify_EquityOption_ParameterReturnDividend_Basket(economicTerms)
            // or Qualify_EquityOption_ParameterReturnDividend_Index(economicTerms)
            // or Qualify_EquityOption_ParameterReturnDividend_SingleName(economicTerms)
    then (
        StandardizedScheduleOptionNotionalAmount(economicTerms -> payout -> OptionPayout only-element)
    )
    else if Qualify_BaseProduct_EquityForward(economicTerms)
    then (
        StandardizedScheduleEquityForwardNotionalAmount(economicTerms -> payout -> SettlementPayout only-element)
    )
    else if Qualify_EquitySwap_ParameterReturnDividend_Basket(economicTerms)
            or Qualify_EquitySwap_ParameterReturnDividend_Index(economicTerms)
            or Qualify_EquitySwap_ParameterReturnDividend_SingleName(economicTerms)
    then 0.0 //All dividend swaps are defined with a monetary payment, no strike price or number of shares
    else if Qualify_EquitySwap_ParameterReturnVariance_Basket(economicTerms)
            or Qualify_EquitySwap_ParameterReturnVariance_Index(economicTerms)
            or Qualify_EquitySwap_ParameterReturnVariance_SingleName(economicTerms)
    then (
        StandardizedScheduleVarianceSwapNotionalAmount(economicTerms -> payout -> PerformancePayout only-element)
    )
    else if Qualify_EquitySwap_ParameterReturnVolatility_Basket(economicTerms)
            or Qualify_EquitySwap_ParameterReturnVolatility_Index(economicTerms)
            or Qualify_EquitySwap_ParameterReturnVolatility_SingleName(economicTerms)
    then 0.0 //Is volatility amount = vega notional amount?
    // EQ Contract fo Difference (CFD) not supported
    else if Qualify_BaseProduct_EquitySwap(economicTerms)
    then 0.0 //No initial value or current value available in the test samples
    else if Qualify_Commodity_Forward(economicTerms)
    then (
        StandardizedScheduleCommodityForwardNotionalAmount(economicTerms) //Floating price forwards not supported
    )
    else if Qualify_Commodity_Option(economicTerms)
    then (
        StandardizedScheduleOptionNotionalAmount(economicTerms -> payout -> OptionPayout only-element) 
    )
    else if Qualify_Commodity_Swap_FixedFloat(economicTerms)
    then (
        StandardizedScheduleCommoditySwapFixedFloatNotionalAmount(economicTerms)
    )
    else if Qualify_Commodity_Swap_Basis(economicTerms)
    then 0.0 //No spot price available
    else if Qualify_Commodity_Swaption(economicTerms)
    then (
        StandardizedScheduleCommoditySwapFixedFloatNotionalAmount(UnderlierForProduct(product) -> Product ->> economicTerms)
    )
    // CO Contract for Difference (CFD) not supported
 
func StandardizedScheduleNotionalCurrency: <"Extracts the notional currency of a trade, according to the product class-depending extraction method defined in the ISDA industry survey.">
    inputs: trade Trade (1..1)
    output: notionalCurrency string (0..1)

    alias product: trade -> product
    alias economicTerms: trade -> product -> economicTerms

    set notionalCurrency:
        if Qualify_BaseProduct_IRSwap(economicTerms) or IsIRSwapWithCallableBermudanRightToEnterExitSwaps(economicTerms)
        then (
            economicTerms -> payout -> InterestRatePayout 
            filter priceQuantity -> quantitySchedule exists
            then first 
            then priceQuantity 
            then StandardizedScheduleMonetaryNotionalCurrencyFromResolvablePQ
        )
        else if Qualify_BaseProduct_CrossCurrency(economicTerms)
        then (
            economicTerms -> payout -> InterestRatePayout 
            filter (True /*how do we identify the receiver party?*/) 
            then first 
            then priceQuantity 
            then StandardizedScheduleMonetaryNotionalCurrencyFromResolvablePQ
        )
        else if Qualify_InterestRate_Option_Swaption(economicTerms) or IsIRSwaptionStraddle(economicTerms)
        then (
            UnderlierForProduct(product) -> Product ->> economicTerms -> payout -> InterestRatePayout 
            filter priceQuantity -> quantitySchedule exists
            then first 
            then priceQuantity 
            then StandardizedScheduleMonetaryNotionalCurrencyFromResolvablePQ
        )
        // IR Exotic swap with an exotic coupon against a floating leg not supported
        else if Qualify_InterestRate_CapFloor(economicTerms)
        then (
            economicTerms -> payout -> InterestRatePayout only-element -> priceQuantity 
            then StandardizedScheduleMonetaryNotionalCurrencyFromResolvablePQ
        )
        else if Qualify_InterestRate_Fra(economicTerms)
        then (
            economicTerms -> payout -> InterestRatePayout 
            filter rateSpecification -> FixedRateSpecification exists 
            then only-element 
            then priceQuantity 
            then StandardizedScheduleMonetaryNotionalCurrencyFromResolvablePQ
        )
        else if Qualify_CreditDefaultSwap_SingleName(economicTerms)
            or Qualify_CreditDefaultSwap_Index(economicTerms)
            or Qualify_CreditDefaultSwap_IndexTranche(economicTerms)
            or IsCreditNthToDefault(economicTerms)
        then (
            economicTerms -> payout -> CreditDefaultPayout only-element -> priceQuantity 
            then StandardizedScheduleMonetaryNotionalCurrencyFromResolvablePQ
        )
        else if Qualify_CreditDefaultSwaption(economicTerms)
        then (
            UnderlierForProduct(product) -> Product ->> economicTerms -> payout -> CreditDefaultPayout only-element -> priceQuantity 
            then StandardizedScheduleMonetaryNotionalCurrencyFromResolvablePQ
        )
        // Credit Total return swap on a bond not supported
        else if Qualify_ForeignExchange_Swap(economicTerms)
        then (
            economicTerms -> payout -> SettlementPayout only-element -> priceQuantity -> quantitySchedule -> unit -> currency
        )
        else if Qualify_ForeignExchange_NDS(economicTerms)
        then "AAA" // Receive side notional and currency. What does that mean?
        else if Qualify_ForeignExchange_Spot_Forward(economicTerms)
        then (
            economicTerms -> payout -> SettlementPayout only-element -> priceQuantity -> quantitySchedule -> unit -> currency
        )
        else if Qualify_ForeignExchange_NDF(economicTerms)
        then (
            StandardizedScheduleFXNDFNotional(economicTerms -> payout -> SettlementPayout only-element) -> unit -> currency
        )
        else if IsFXDeliverableOption(economicTerms)
        then (
            economicTerms -> payout -> OptionPayout only-element -> priceQuantity -> quantitySchedule -> unit -> currency
        )
        else if IsFXNonDeliverableOption(economicTerms)
        then (
            StandardizedScheduleFXNDONotional(economicTerms -> payout -> OptionPayout only-element) -> unit -> currency
        )   
        else if Qualify_ForeignExchange_ParameterReturnVariance(economicTerms)
        then (
            economicTerms -> payout -> PerformancePayout only-element -> returnTerms -> varianceReturnTerms -> varianceStrikePrice -> unit -> currency
        )
        else if Qualify_ForeignExchange_ParameterReturnVolatility(economicTerms)
        then "AAA" //Vega notional amount not mapped in the product
        else if Qualify_ForeignExchange_ParameterReturnCorrelation(economicTerms)
        then "AAA" //No sample trades
        else if Qualify_EquityOption_PriceReturnBasicPerformance_Basket(economicTerms)
            or Qualify_EquityOption_PriceReturnBasicPerformance_Index(economicTerms)
            or Qualify_EquityOption_PriceReturnBasicPerformance_SingleName(economicTerms)
            //To determine if the method used applies to the following equity options:
            // or Qualify_EquityOption_ParameterReturnVolatility_Basket(economicTerms)
            // or Qualify_EquityOption_ParameterReturnVolatility_Index(economicTerms)
            // or Qualify_EquityOption_ParameterReturnVolatility_SingleName(economicTerms)
            // or Qualify_EquityOption_ParameterReturnVariance_Basket(economicTerms)
            // or Qualify_EquityOption_ParameterReturnVariance_Index(economicTerms)
            // or Qualify_EquityOption_ParameterReturnVariance_SingleName(economicTerms)
            // or Qualify_EquityOption_ParameterReturnCorrelation_Basket(economicTerms)
            // // or Qualify_EquityOption_ParameterReturnCorrelation_Index(economicTerms)
            // // or Qualify_EquityOption_ParameterReturnCorrelation_SingleName(economicTerms)
            // or Qualify_EquityOption_ParameterReturnDividend_Basket(economicTerms)
            // or Qualify_EquityOption_ParameterReturnDividend_Index(economicTerms)
            // or Qualify_EquityOption_ParameterReturnDividend_SingleName(economicTerms)
        then (
            economicTerms -> payout -> OptionPayout only-element -> strike -> strikePrice -> unit -> currency
        )
        else if Qualify_BaseProduct_EquityForward(economicTerms)
        then (
            economicTerms -> payout -> SettlementPayout only-element -> priceQuantity -> quantitySchedule -> unit -> currency
        )
        else if Qualify_EquitySwap_ParameterReturnDividend_Basket(economicTerms)
            or Qualify_EquitySwap_ParameterReturnDividend_Index(economicTerms)
            or Qualify_EquitySwap_ParameterReturnDividend_SingleName(economicTerms)
        then "AAA" //All dividend swaps are defined with a monetary payment, no strike price or number of shares
        // EQ Deliverable Option F not supported
        else if Qualify_EquitySwap_ParameterReturnVariance_Basket(economicTerms)
            or Qualify_EquitySwap_ParameterReturnVariance_Index(economicTerms)
            or Qualify_EquitySwap_ParameterReturnVariance_SingleName(economicTerms)
        then (
            economicTerms -> payout -> PerformancePayout only-element -> returnTerms -> varianceReturnTerms -> volatilityStrikePrice -> unit -> currency
        )
        else if Qualify_EquitySwap_ParameterReturnVolatility_Basket(economicTerms)
            or Qualify_EquitySwap_ParameterReturnVolatility_Index(economicTerms)
            or Qualify_EquitySwap_ParameterReturnVolatility_SingleName(economicTerms)
        then "AAA" //Is volatility amount = vega notional amount?
        // EQ Contract fo Difference (CFD) not supported
        else if Qualify_BaseProduct_EquitySwap(economicTerms)
        then "AAA" //No initial value or current value available in the test samples
        else if Qualify_Commodity_Forward(economicTerms)
        then (
            economicTerms -> payout -> FixedPricePayout only-element -> fixedPrice -> price -> unit -> currency //Floating price forwards not supported
        )
        else if Qualify_Commodity_Option(economicTerms)
        then (
            economicTerms -> payout -> OptionPayout only-element -> strike -> strikePrice -> unit -> currency 
        )
        else if Qualify_Commodity_Swap_FixedFloat(economicTerms)
        then (
            economicTerms -> payout -> FixedPricePayout only-element -> fixedPrice -> price -> unit -> currency
        )
        else if Qualify_Commodity_Swap_Basis(economicTerms)
        then "AAA" //No spot price available
        else if Qualify_Commodity_Swaption(economicTerms)
        then (
            UnderlierForProduct(product) -> Product ->> economicTerms -> payout -> FixedPricePayout only-element -> fixedPrice -> price -> unit -> currency
        )
        // CO Contract for Difference (CFD) not supported

func AuxiliarEffectiveDate: <"Extracts the effective date of specific products such as interest rate swaps and swaptions.">
    inputs:
        trade Trade (1..1)
    output:
        effectiveDate date (0..1)

    alias economicTerms: trade -> product -> economicTerms

    set effectiveDate:
        // interestRatePayout
        if economicTerms -> payout -> InterestRatePayout -> calculationPeriodDates -> effectiveDate -> adjustableDate exists
        then (economicTerms -> payout -> InterestRatePayout -> calculationPeriodDates -> effectiveDate -> adjustableDate
            extract AdjustableDateResolution
            then min)
        // interestRateSwaptions
        else if economicTerms -> payout -> OptionPayout only-element -> underlier -> Product ->> economicTerms -> payout -> InterestRatePayout -> calculationPeriodDates -> effectiveDate -> adjustableDate exists
        then (economicTerms -> payout -> OptionPayout only-element -> underlier -> Product ->> economicTerms -> payout -> InterestRatePayout -> calculationPeriodDates -> effectiveDate -> adjustableDate
            extract AdjustableDateResolution
            then min)

func AuxiliarTerminationDate: <"Extracts the termination date of specific products such as interest rate swaps and swaptions.">
    inputs: trade Trade (1..1)
    output: terminationDate date (0..1)

    alias economicTerms: trade -> product -> economicTerms

    set terminationDate:
        // interestRatePayout
        if economicTerms -> payout -> InterestRatePayout -> calculationPeriodDates -> terminationDate -> adjustableDate exists
                then (economicTerms -> payout -> InterestRatePayout -> calculationPeriodDates -> terminationDate -> adjustableDate
                    extract AdjustableDateResolution
                    then max)
        // interestRateSwaptions
        else if economicTerms -> payout -> OptionPayout only-element -> underlier -> Product ->> economicTerms -> payout -> InterestRatePayout -> calculationPeriodDates -> terminationDate -> adjustableDate exists
        then (economicTerms -> payout -> OptionPayout only-element -> underlier -> Product ->> economicTerms -> payout -> InterestRatePayout -> calculationPeriodDates -> terminationDate -> adjustableDate
            extract AdjustableDateResolution
            then max)

func StandardizedScheduleDuration: <"Extracts the duration of a trade, according to the product class-depending extraction method defined in the ISDA industry survey.">
    inputs:
        trade Trade (1..1)
    output:
        durationInYears number (0..1)

    alias product: trade -> product
    alias economicTerms: trade -> product -> economicTerms
    alias underlier: UnderlierForProduct(product)

    alias transactionEffectiveDate:
        AdjustableOrAdjustedOrRelativeDateResolution(
                ConvertToAdjustableOrAdjustedOrRelativeDate(economicTerms -> effectiveDate)
            )
    alias transactionTerminationDate:
        AdjustableOrAdjustedOrRelativeDateResolution(
                ConvertToAdjustableOrAdjustedOrRelativeDate(
                        economicTerms -> terminationDate
                    )
            )
    alias transactionTenorInYears:
        if transactionEffectiveDate exists and transactionTerminationDate exists
        then DateDifferenceYears(transactionEffectiveDate, transactionTerminationDate)
    alias underlyingTransactionEffectiveDate:
        AdjustableOrAdjustedOrRelativeDateResolution(
                ConvertToAdjustableOrAdjustedOrRelativeDate(
                        underlier -> Product ->> economicTerms -> effectiveDate
                    )
            )
    alias underlyingTransactionTerminationDate:
        AdjustableOrAdjustedOrRelativeDateResolution(
                ConvertToAdjustableOrAdjustedOrRelativeDate(
                        underlier -> Product ->> economicTerms -> terminationDate
                    )
            )
    alias underlyingTransactionTenorInYears:
        if underlyingTransactionEffectiveDate exists
                and underlyingTransactionTerminationDate exists
        then DateDifferenceYears(
                    underlyingTransactionEffectiveDate,
                    underlyingTransactionTerminationDate
                )
    alias optionExpiry:
        economicTerms -> payout -> OptionPayout only-element -> exerciseTerms
            then extract
                if style = OptionExerciseStyleEnum -> American
                then AdjustableOrAdjustedOrRelativeDateResolution(
                            ConvertToAdjustableOrAdjustedOrRelativeDate(
                                    expirationDate only-element
                                )
                        )
                else if style = OptionExerciseStyleEnum -> European
                then (expirationDate
                    max [
                        AdjustableOrAdjustedOrRelativeDateResolution(
                                ConvertToAdjustableOrAdjustedOrRelativeDate(item)
                            )
                    ]
                    extract
                        AdjustableOrAdjustedOrRelativeDateResolution(
                                ConvertToAdjustableOrAdjustedOrRelativeDate(item)
                            ))
                else if style = OptionExerciseStyleEnum -> Bermuda
                then (if exerciseDates -> adjustableDates exists
                    then AdjustableDatesResolution(exerciseDates -> adjustableDates)
                        max [ item ]
                        extract item)
    alias timeToOptionExpiryInYears:
        if transactionEffectiveDate exists and optionExpiry exists
        then DateDifferenceYears(transactionEffectiveDate, optionExpiry)
    alias genericDurationInYears:
        if Qualify_BaseProduct_IRSwap(economicTerms)
                or IsIRSwapWithCallableBermudanRightToEnterExitSwaps(economicTerms)
                or Qualify_BaseProduct_CrossCurrency(economicTerms)
                or Qualify_InterestRate_Fra(economicTerms)
                or Qualify_CreditDefaultSwap_SingleName(economicTerms)
                or Qualify_CreditDefaultSwap_Index(economicTerms)
                or Qualify_CreditDefaultSwap_IndexTranche(economicTerms)
                or IsCreditNthToDefault(economicTerms)
        then transactionTenorInYears
        else if Qualify_InterestRate_Option_Swaption(economicTerms)
                or Qualify_CreditDefaultSwaption(economicTerms)
                or IsIRSwaptionStraddle(economicTerms)
        then (if timeToOptionExpiryInYears exists
                    and underlyingTransactionTenorInYears exists
            then timeToOptionExpiryInYears + underlyingTransactionTenorInYears
            else if timeToOptionExpiryInYears exists
            then timeToOptionExpiryInYears
            else if underlyingTransactionTenorInYears exists
            then underlyingTransactionTenorInYears)
        else if Qualify_InterestRate_CapFloor(economicTerms)
                or Qualify_InterestRate_Option_DebtOption(economicTerms)
        then timeToOptionExpiryInYears
    // IR Exotic swap with an exotic coupon against a floating leg not supported
    // Credit Total return swap on a bond not supported
    alias auxiliarDurationInYears:
        DateDifferenceYears(AuxiliarEffectiveDate(trade), AuxiliarTerminationDate(trade))
    set durationInYears:
        if genericDurationInYears exists
        then genericDurationInYears
        else auxiliarDurationInYears

func GetIMRequirement: <"Computes the IM requirement, which is required in the calculation of the gross initial margin. It depends exclusively on the asset class of the trade and, in some cases, on the duration as well.">
    inputs:
        assetClass StandardizedScheduleAssetClassEnum (1..1)
        durationInYears number (1..1)
    output:
        percentage number (1..1)
    set percentage:
        if assetClass = StandardizedScheduleAssetClassEnum -> InterestRates
        then (if durationInYears <= 2
            then 1.0
            else if durationInYears > 2 and durationInYears <= 5
            then 2.0
            else if durationInYears > 5
            then 4.0)
        else if assetClass = StandardizedScheduleAssetClassEnum -> Credit
        then (if durationInYears <= 2
            then 2.0
            else if durationInYears > 2 and durationInYears <= 5
            then 5.0
            else if durationInYears > 5
            then 10.0)
        else if assetClass = StandardizedScheduleAssetClassEnum -> ForeignExchange
        then 6.0
        else if assetClass = StandardizedScheduleAssetClassEnum -> Equity
        then 15.0
        else if assetClass = StandardizedScheduleAssetClassEnum -> Commodity
        then 15.0

func UnderlierForProduct: <"Extracts the underlier product.">
    inputs:
        product NonTransferableProduct (1..1)
    output:
        underlier Underlier (1..1)

    set underlier:
        if product -> economicTerms -> payout -> OptionPayout exists
        then product -> economicTerms -> payout -> OptionPayout only-element-> underlier
        else if product -> economicTerms -> payout -> SettlementPayout exists
        then product -> economicTerms -> payout -> SettlementPayout only-element -> underlier

func AdjustableOrAdjustedOrRelativeDateResolution: <"A fall back for unadjustedDate when adjustedDate is only available.">
    inputs:
        adjustableDate AdjustableOrAdjustedOrRelativeDate (1..1)
    output:
        date date (0..1)
    set date:
        if adjustableDate -> unadjustedDate exists
        then adjustableDate -> unadjustedDate
        else adjustableDate -> adjustedDate

func AdjustableDateResolution: <"A fall back for unadjustedDate when adjustedDate is only available.">
    inputs:
        adjustableDate AdjustableDate (1..1)
    output:
        date date (0..1)

    set date:
        if adjustableDate -> unadjustedDate exists
        then adjustableDate -> unadjustedDate
        else adjustableDate -> adjustedDate

func AdjustableDatesResolution: <"A fall back for unadjustedDate when adjustedDate is only available.">
    inputs:
        adjustableDates AdjustableDates (1..1)
    output:
        date date (0..*)

    add date:
        if adjustableDates -> unadjustedDate exists
        then adjustableDates -> unadjustedDate
        else adjustableDates -> adjustedDate

func StandardizedScheduleMonetaryNotionalFromResolvablePQ: <"Extracts the notional amount for all products that have it populated in the resolvable priceQuantity.">
    inputs:
        priceQuantity ResolvablePriceQuantity (0..1)
    output:
        notional number (0..1)

    set notional:
        if priceQuantity -> quantitySchedule exists
                and priceQuantity -> quantitySchedule -> unit -> currency exists
        then (if priceQuantity -> quantitySchedule -> multiplier exists
            then priceQuantity -> quantitySchedule -> value * priceQuantity -> quantitySchedule -> multiplier -> value
            else priceQuantity -> quantitySchedule -> value)

func StandardizedScheduleMonetaryNotionalCurrencyFromResolvablePQ: <"Extracts the notional currency for all products that have it populated in the resolvable priceQuantity.">
    inputs:
        priceQuantity ResolvablePriceQuantity (0..1)
    output:
        notionalCurrency string (0..1)

    set notionalCurrency:
        if priceQuantity -> quantitySchedule exists
                and priceQuantity -> quantitySchedule -> unit -> currency exists
        then (if priceQuantity -> quantitySchedule -> multiplier exists
            then priceQuantity -> quantitySchedule -> multiplier -> unit -> currency
            else priceQuantity -> quantitySchedule -> unit -> currency)

func FXFarLeg: <"Extracts the far leg of an FX swap (deliverable or not) based on two criteria: the forward payout with the latest value date or the forward payout with the latest settlement date.">
    inputs:
        product NonTransferableProduct (1..1)
    output:
        farLegPayout SettlementPayout (0..1)

    alias settlementPayout: product -> economicTerms -> payout -> SettlementPayout

    set farLegPayout:
        // value date
        if (Qualify_ForeignExchange_Swap(product -> economicTerms) or Qualify_ForeignExchange_NDS(product -> economicTerms))
                and settlementPayout -> settlementTerms -> settlementDate -> valueDate exists
        then settlementPayout max [ item -> settlementTerms -> settlementDate -> valueDate ]
        // adjustable or relative date
        else if (Qualify_ForeignExchange_Swap(product -> economicTerms) or Qualify_ForeignExchange_NDS(product -> economicTerms))
                and settlementPayout -> settlementTerms -> settlementDate -> adjustableOrRelativeDate exists
        then settlementPayout
            max [
                AdjustableOrAdjustedOrRelativeDateResolution(
                        item -> settlementTerms -> settlementDate -> adjustableOrRelativeDate
                    )
            ]

// func StandardizedScheduleFXSwapNotional: <"Extracts the notional amount and currency of an FX swap.">
//     inputs: farLeg SettlementPayout (0..1)
//     output: quantity NonNegativeQuantitySchedule (0..1)
//     // alias exchangedCurrencies:
//     // [
//     //     farLeg -> underlier -> foreignExchange -> exchangedCurrency1,
//     //     farLeg -> underlier -> foreignExchange -> exchangedCurrency2
//     // ]
//     // alias extractedExchangedCurrency:
//     // if exchangedCurrencies -> priceQuantity -> quantitySchedule -> unit -> currency any = "USD" then (
//     //     exchangedCurrencies filter priceQuantity -> quantitySchedule -> unit -> currency = "USD"
//     // )
//     // else if exchangedCurrencies -> priceQuantity -> quantitySchedule -> unit -> currency any = "EUR" then (
//     //     exchangedCurrencies filter priceQuantity -> quantitySchedule -> unit -> currency = "EUR"
//     // )
//     // else if exchangedCurrencies -> priceQuantity -> quantitySchedule -> unit -> currency any = "JPY" then (
//     //     exchangedCurrencies filter priceQuantity -> quantitySchedule -> unit -> currency = "JPY"
//     // )
//     // else if exchangedCurrencies -> priceQuantity -> quantitySchedule -> unit -> currency any = "GBP" then (
//     //     exchangedCurrencies filter priceQuantity -> quantitySchedule -> unit -> currency = "GBP"
//     // )
//     // else if exchangedCurrencies -> priceQuantity -> quantitySchedule -> unit -> currency any = "CHF" then (
//     //     exchangedCurrencies filter priceQuantity -> quantitySchedule -> unit -> currency = "CHF"
//     // )
//     // else (
//     //     exchangedCurrencies then
//     //     min [item -> priceQuantity -> quantitySchedule -> unit -> currency]
//     // )
//     set quantity:
//     // extractedExchangedCurrency only-element -> priceQuantity -> quantitySchedule
//         farLeg -> priceQuantity -> quantitySchedule

func StandardizedScheduleFXNDFNotional: <"Extracts the notional amount and currency of an FX non-deliverable forward.">
    inputs:
        settlementPayout SettlementPayout (0..1)
    output:
        quantity NonNegativeQuantitySchedule (0..1)

    // alias settlementCurrency: settlementPayout -> settlementTerms -> settlementCurrency

    // alias exchangedCurrencies:
    // [
    // forwardPayout -> underlier -> foreignExchange -> exchangedCurrency1,
    // forwardPayout -> underlier -> foreignExchange -> exchangedCurrency2
    // ]

    set quantity:
        // exchangedCurrencies filter priceQuantity -> quantitySchedule -> unit -> currency = settlementCurrency then only-element then priceQuantity -> quantitySchedule
        settlementPayout -> priceQuantity -> quantitySchedule

func StandardizedScheduleFXNDONotional: <"Extracts the notional amount and currency of an FX non-deliverable option.">
    inputs:
        optionPayout OptionPayout (0..1)
    output:
        quantity NonNegativeQuantitySchedule (0..1)

    // alias settlementCurrency:
    // optionPayout -> settlementTerms -> settlementCurrency
    // alias exchangedCurrencies:
    // [
    // optionPayout -> underlier -> foreignExchange -> exchangedCurrency1,
    // optionPayout -> underlier -> foreignExchange -> exchangedCurrency2
    // ]
    
    set quantity:
        // exchangedCurrencies filter priceQuantity -> quantitySchedule -> unit -> currency = settlementCurrency then only-element then priceQuantity -> quantitySchedule
        optionPayout -> priceQuantity -> quantitySchedule

func StandardizedScheduleFXVarianceNotionalAmount: <"Extracts the notional amount of an FX variance swap.">
    inputs:
        performancePayout PerformancePayout (0..1)
    output:
        amount number (0..1)
    alias varianceReturnTerms: performancePayout -> returnTerms -> varianceReturnTerms
    alias vegaNotionalAmount: varianceReturnTerms -> vegaNotionalAmount
    alias fixedRate: varianceReturnTerms -> varianceStrikePrice
    set amount: (vegaNotionalAmount -> value) / (0.02 * (fixedRate -> value))

func StandardizedScheduleOptionNotionalAmount: <"Extracts the notional amount of a CO or EQ option.">
    inputs: 
        optionPayout OptionPayout (0..1)
    output: 
        amount number (0..1)
    alias strikePrice:
        optionPayout -> strike -> strikePrice -> value
    alias notionalQuantity:
        optionPayout -> priceQuantity -> quantitySchedule 
        then (
            if multiplier exists then value * multiplier -> value
            else value
        )
    set amount:
        strikePrice * notionalQuantity

func StandardizedScheduleEquityForwardNotionalAmount: <"Extracts the notional amount of an EQ forward.">
    inputs: 
        settlementPayout SettlementPayout (0..1)
    output: 
        amount number (0..1)

    alias forwardPrice:
        settlementPayout -> priceQuantity -> priceSchedule only-element -> value
    alias notionalQuantity:
        settlementPayout -> priceQuantity -> quantitySchedule then 
            (if multiplier exists then value * multiplier -> value else value)

    set amount:
        forwardPrice * notionalQuantity

func StandardizedScheduleVarianceSwapNotionalAmount: <"Extracts the notional amount of an EQ variance swap.">
    inputs:
        performancePayout PerformancePayout (0..1)
    output:
        amount number (0..1)
    alias varianceAmount:
        performancePayout -> priceQuantity -> quantitySchedule
            then (if multiplier exists
                then value * multiplier -> value
                else value)
            then if item >= 1 then 0.01 * item else item
    alias volatilityStrikePrice:
        performancePayout -> returnTerms -> varianceReturnTerms -> volatilityStrikePrice -> value
    set amount: 200 * varianceAmount * volatilityStrikePrice

func StandardizedScheduleCommodityForwardNotionalAmount: <"Extracts the notional amount of a CO forward. Floating price forwards not supported.">
    inputs:
        economicTerms EconomicTerms (0..1)
    output:
        amount number (0..1)

    alias forwardPrice:
        economicTerms -> payout -> FixedPricePayout only-element -> fixedPrice -> price -> value

    alias notionalQuantity:
        economicTerms -> payout -> SettlementPayout only-element -> priceQuantity -> quantitySchedule
            then (if multiplier exists
                then value * multiplier -> value
                else value)

    set amount: forwardPrice * notionalQuantity

func StandardizedScheduleCommoditySwapFixedFloatNotionalAmount: <"Extracts the notional amount of a CO fixed float swap.">
    inputs:
        economicTerms EconomicTerms (0..1)
    output:
        amount number (0..1)
    alias fixedPrice:
        economicTerms -> payout -> FixedPricePayout only-element -> fixedPrice -> price -> value
    alias notionalQuantity:
        economicTerms -> payout -> CommodityPayout only-element -> priceQuantity -> quantitySchedule
            then (if multiplier exists
                then value * multiplier -> value
                else value)
    set amount: fixedPrice * notionalQuantity

func DateDifferenceYears: <"Computes the difference in years between two dates. All years are supposed to have 365 days.">
    inputs:
        firstDate date (1..1) <"The earlier date.">
        secondDate date (1..1) <"The later date.">
    output:
        difference number (1..1)

    set difference: DateDifference(firstDate, secondDate) / 365.0

func IsCreditNthToDefault: <"Identifies a product as a CR basket Nth to default.">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_Product boolean (1..1)
    set is_Product:
        economicTerms -> payout -> CreditDefaultPayout only-element -> generalTerms -> basketReferenceInformation -> nthToDefault exists

func IsFXDeliverableOption: <"Identifies a product as an FX deliverable option.">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_Product boolean (1..1)
    set is_Product:
        Qualify_ForeignExchange_VanillaOption(economicTerms)
            and economicTerms -> payout -> OptionPayout only-element -> settlementTerms -> settlementType = SettlementTypeEnum -> Physical

func IsFXNonDeliverableOption: <"Identifies a product as an FX non-deliverable option.">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_Product boolean (1..1)
    set is_Product:
        Qualify_ForeignExchange_VanillaOption(economicTerms)
            and economicTerms -> payout -> OptionPayout only-element -> settlementTerms -> settlementType = SettlementTypeEnum -> Cash

func IsIRSwaptionStraddle: <"Identifies a product as an IR swaption straddle.">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_Product boolean (1..1)
    set is_Product:
        Qualify_InterestRate_Option_Swaption(economicTerms)
            and economicTerms -> payout -> OptionPayout only-element -> optionType = OptionTypeEnum -> Straddle

func IsIRSwapWithCallableBermudanRightToEnterExitSwaps: <"Identifies a product as an IR swap with bermudan/callable right to enter/exit swaps.">
    inputs:
        economicTerms EconomicTerms (1..1)
    output:
        is_Product boolean (1..1)
    set is_Product:
        Qualify_BaseProduct_IRSwap(economicTerms)
            and economicTerms -> terminationProvision -> earlyTerminationProvision -> optionalEarlyTermination -> exerciseTerms -> style = OptionExerciseStyleEnum -> Bermuda

func GetNetInitialMarginFromExposure: <"Computes the net initial margin, taking the gross initial margin result and the mark to market value for each trade in the portfolio.">
    inputs:
        exposure Exposure (0..1)
    output:
        initialMargin StandardizedScheduleInitialMargin (0..1)
    alias tradePortfolio: exposure -> tradePortfolio
    alias positions: tradePortfolio -> positions
    alias tradeInitialMargin:
        positions
            extract
                StandardizedScheduleTradeInfo {
                    assetClass: BuildStandardizedSchedule(item -> tradeReference -> trade) -> assetClass,
                    productClass: BuildStandardizedSchedule(item -> tradeReference -> trade) -> productClass,
                    grossInitialMargin: GetGrossInitialMarginFromStandardizedSchedule(
                                BuildStandardizedSchedule(item -> tradeReference -> trade)
                            ),
                    markToMarketValue: item -> tradeReference -> valuationHistory
                            filter method = ValuationTypeEnum -> MarkToMarket
                            then only-element
                            then amount
                }
    alias totalGIM: tradeInitialMargin -> grossInitialMargin -> value sum
    alias netCurrentReplacementCost: tradeInitialMargin -> markToMarketValue -> value sum
    alias grossCurrentReplacementCost:
        tradeInitialMargin -> markToMarketValue
            filter item -> value > 0
            then value sum
    alias netToGrossRatio: netCurrentReplacementCost / grossCurrentReplacementCost
    add initialMargin -> tradeInfo: tradeInitialMargin
    set initialMargin -> netInitialMargin -> value:
        0.4 * totalGIM + 0.6 * totalGIM * netToGrossRatio
    set initialMargin -> netInitialMargin -> unit -> currency:
        tradeInitialMargin -> markToMarketValue -> unit -> currency distinct only-element

func Create_ExposureFromTrades: <"Builds an Exposure structure from a collection of trades.">
    inputs:
        trades TradeState (0..*)
    output:
        exposure Exposure (0..1)

    add exposure -> tradePortfolio -> positions:
        trades
            extract
                Position {
                    cashBalance: empty,
                    priceQuantity: item -> trade -> tradeLot -> priceQuantity,
                    tradeReference: empty,
                    product: Product {
                            NonTransferableProduct: item -> trade -> product,
                            ...
                        }
                }

    set exposure -> tradePortfolio -> lineage -> tradeReference: trades -> trade first




© 2015 - 2025 Weber Informatics LLC | Privacy Policy