// obtains the data and calculates the grid of results
  private static void calculate(CalculationRunner runner) {
    // the trades that will have measures calculated
    List<Trade> trades = createCdsTrades();

    // the columns, specifying the measures to be calculated
    List<Column> columns =
        ImmutableList.of(
            Column.of(Measure.PRESENT_VALUE),
            Column.of(Measure.PAR_RATE),
            Column.of(Measure.RECOVERY01),
            Column.of(Measure.JUMP_TO_DEFAULT),
            Column.of(Measure.IR01_PARALLEL_PAR),
            Column.of(Measure.IR01_PARALLEL_ZERO),
            Column.of(Measure.CS01_PARALLEL_PAR),
            Column.of(Measure.CS01_PARALLEL_HAZARD),
            Column.of(Measure.IR01_BUCKETED_PAR),
            Column.of(Measure.IR01_BUCKETED_ZERO),
            Column.of(Measure.CS01_BUCKETED_PAR),
            Column.of(Measure.CS01_BUCKETED_HAZARD));

    // use the built-in example market data
    ExampleMarketDataBuilder marketDataBuilder = ExampleMarketData.builder();

    // the complete set of rules for calculating measures
    CalculationRules rules =
        CalculationRules.builder()
            .pricingRules(StandardComponents.pricingRules())
            .marketDataRules(marketDataBuilder.rules())
            .build();

    // build a market data snapshot for the valuation date
    LocalDate valuationDate = LocalDate.of(2014, 10, 16);
    MarketEnvironment marketSnapshot = marketDataBuilder.buildSnapshot(valuationDate);

    // calculate the results
    Results results = runner.calculateSingleScenario(rules, trades, columns, marketSnapshot);

    // use the report runner to transform the engine results into a trade report
    ReportCalculationResults calculationResults =
        ReportCalculationResults.of(valuationDate, trades, columns, results);

    TradeReportTemplate reportTemplate = ExampleData.loadTradeReportTemplate("cds-report-template");
    TradeReport tradeReport = TradeReport.of(calculationResults, reportTemplate);
    tradeReport.writeAsciiTable(System.out);
  }
  // obtains the data and calculates the grid of results
  private static void calculate(CalculationRunner runner) {
    // the trade that will have measures calculated
    List<Trade> trades = ImmutableList.of(createVanillaFixedVsLibor3mSwap());

    // the columns, specifying the measures to be calculated
    List<Column> columns =
        ImmutableList.of(
            Column.of(Measures.PRESENT_VALUE), Column.of(Measures.PV01_CALIBRATED_SUM));

    // use the built-in example market data
    ExampleMarketDataBuilder marketDataBuilder = ExampleMarketData.builder();

    // the complete set of rules for calculating measures
    LocalDate valuationDate = LocalDate.of(2014, 1, 22);
    CalculationFunctions functions = StandardComponents.calculationFunctions();
    CalculationRules rules =
        CalculationRules.of(functions, Currency.USD, marketDataBuilder.ratesLookup(valuationDate));

    // mappings that select which market data to apply perturbations to
    // this applies the perturbations above to all curves
    PerturbationMapping<Curve> mapping =
        PerturbationMapping.of(
            Curve.class,
            MarketDataFilter.ofIdType(CurveId.class),
            // no shift for the base scenario, 1bp absolute shift to calibrated curves (zeros)
            CurveParallelShifts.absolute(0, ONE_BP));

    // create a scenario definition containing the single mapping above
    // this creates two scenarios - one for each perturbation in the mapping
    ScenarioDefinition scenarioDefinition = ScenarioDefinition.ofMappings(mapping);

    // build a market data snapshot for the valuation date
    MarketData marketData = marketDataBuilder.buildSnapshot(valuationDate);

    // the reference data, such as holidays and securities
    ReferenceData refData = ReferenceData.standard();

    // calculate the results
    MarketDataRequirements reqs = MarketDataRequirements.of(rules, trades, columns, refData);
    ScenarioMarketData scenarioMarketData =
        marketDataFactory()
            .createMultiScenario(
                reqs, MarketDataConfig.empty(), marketData, refData, scenarioDefinition);
    Results results =
        runner.calculateMultiScenario(rules, trades, columns, scenarioMarketData, refData);

    // TODO Replace the results processing below with a report once the reporting framework supports
    // scenarios

    // The results are lists of currency amounts containing one value for each scenario
    ScenarioArray<?> pvList = (ScenarioArray<?>) results.get(0, 0).getValue();
    ScenarioArray<?> pv01List = (ScenarioArray<?>) results.get(0, 1).getValue();

    double pvBase = ((CurrencyAmount) pvList.get(0)).getAmount();
    double pvShifted = ((CurrencyAmount) pvList.get(1)).getAmount();
    double pv01Base = ((CurrencyAmount) pv01List.get(0)).getAmount();
    NumberFormat numberFormat =
        new DecimalFormat("###,##0.00", new DecimalFormatSymbols(Locale.ENGLISH));

    System.out.println("                         PV (base) = " + numberFormat.format(pvBase));
    System.out.println("             PV (1 bp curve shift) = " + numberFormat.format(pvShifted));
    System.out.println("PV01 (algorithmic differentiation) = " + numberFormat.format(pv01Base));
    System.out.println(
        "          PV01 (finite difference) = " + numberFormat.format(pvShifted - pvBase));
  }