Scripting API

Introduction

Every box has access to an API allowing to trigger script executions. This API allows you to choose your parallelization axis and to chain multiple GPU calls, potentially with different parallelization strategies. Keep in mind that even though boxes can be executed in parallel, if a box uses an openCL device then the others will have to queue to run computations.

There are a few objects you need to create before you can call the scripting API and the data manager.

Scenario and Historical Values

The script execution relies on a set of data that represent past and future values. Those data have an Id consisting of a type and qualifiers (e.g. FX_RATE / EUR-USD) that can be created through the ScenarioIdentifier class:

// The id of TYPE / Qualifier1-Qualifier2
def id = ScenarioIdentifier.create("TYPE", ["Qualifier1", "Qualifier2"])

Once you have an id, you can link it to its current and future values though a ScenarioValues object or to its past values through a HistoricalValues object. You need to create one ScenarioValues per point of the structure you create, and each of the ScenarioValues can contain an arbitrary number of scenarios:

// List of the parallel values. You fill 5 points on the X axis with the values 0,1,2,3,4
def parallelValues = []
for (def i = 0 ; i < 5 ; ++i){
    // List of scenario values
    // Here you have twelve scenarios assuming you only have one step date
    // Or you have six scenarios if you consider two step dates
    def values = new double [12]
    parallelValues.add(new ScenarioValues(id, Point.of(i), values)) // Add the array structure
}

DataManager and dates

You can now create your DataManager that will be used during computation:

// Create the number of scenarios and the list of step dates used for the simulation
def scenarios = 6
def dates = [new LocalDate("2017-01-01"), new LocalDate("2017-02-01")]
def dataManager = new DataManager(scenarios, dates).addScenarios(parallelValues)

You are strongly recommended to have the ScenarioValues/HistoricalValues boilerplate code separated in a box that you write only once. Those objects are serializable so they can be transferred across boxes. This will also simplify the codes in your boxes.

Scripts and documents

You are now ready to call the scripting API. The process() method is very similar to a chain of calls, setting particular parameters. The chain should be finished by the collect() call.

def scriptName = "myScriptName"
def document = "{"dealStamp":"myDocument"}"
def documentId = "myDocumentId"

def results = engine().buildSession(dataManager).process(scriptName, document, documentId).collect()

output("results", results["myDocumentId"])

If you store multiple documents in a array, these can also be priced with the collect() method and a list of all results is returned at the end. You have used the following methods:

  • engine(): sets the instance of the pricing engine.
  • buildSession(dataManager): sets the data manager builder populated with the market data inputs.
  • process(scriptName, document, documentId): processes a document according to the script name to call, the JSON document data and the document id.
  • collect(): sets the results and errors consumer.