Capture Fields and Parent Schemas Sample

Introduction

This sample demonstrates how to use capture fields in conjunction with parent schemas to create a reusable module that can match orders for FX trading in one instance and can match orders for Equities trading in another copy of the identical, unchanged module. The module uses abstract schemas for its input stream and for its Query Table that become concrete schemas in actual use.

This sample consists of the following files:

File Purpose
SharedSchemas.sbint A StreamBase interface file that defines named schemas and a table schema used by the two EventFlow modules.
TopLevelFX.sbapp A simple EventFlow module used in this sample as the top-level outer module. It accepts a stream of foreign exchange (FX) trade orders and sends them to the OrderMatcher.sbapp inner module for processing. This module has an output stream that reports filled orders, and a second input stream that triggers a read-all-rows operation of the inner module's Query Table.
OrderMatcher.sbapp An EventFlow module that implements an asset-agnostic order matching engine, used in this sample as the inner module. This module matches parties who would like to sell assets with parties who would like to buy those assets.

Notice that there are no FX-specific schemas in this module. The input stream and Query Table are both defined with abstract schemas that include capture fields, which means the module can handle any generic traded asset. This allows the same module to be re-used to handle different asset classes.

TestFxOrderMatching.java A StreamBase test file in the src/test/java/package-name directory. Run this file as a StreamBase unit test to verify that the sample accepts input and returns the expected results. Select the file, right-click, and invoke Run As>EventFlow Fragment Unit Test.

The important lessons of this sample are in the six named schemas and one table schema defined in SharedSchemas.sbint. The alphabetic order of the schemas in the interface file is also the best order to study them and understand how they work.

Named Schema Description
AbstractInstrument Consists of a single capture field named placeholder with data type placeholderFields.
AbstractOrder Consists of a number of fields for data that is in orders for all instrument types, plus a tuple field named Instrument consisting of a single sub-field, the capture field with data type placeholderFields. This schema is used in the OrderMatcher.sbapp module's input stream, which allows copies of that module to handle orders for varying asset types.
EquitiesInstrument A schema for an equities trade instrument, consisting of parent schema AbstractInstrument plus a single Symbol field.
EquitiesOrder Consists of one parent schema, AbstractOrder, plus one concrete override field that replaces the abstract field of the same name. The Instrument field with data type EquitiesInstrument overrides the abstract Instrument field with type AbstractInstrument because and only because it has the exact same field name, case sensitive.

Notice that the Fields grid that defines this schema uses seven rows to define six fields. This is because the Instrument field is defined once in the parent schema and again in this schema so that the concrete field can override the abstract one.

FXInstrument A schema for a foreign exchange trade instrument, consisting of parent schema AbstractInstrument plus two string fields to hold the two currencies being traded.
FXOrder Like EquitiesOrder above, consists of one parent schema, AbstractOrder, plus one concrete override field that replaces the abstract field of the same name. The Instrument field with data type FXInstrument overrides the abstract Instrument field with type AbstractInstrument because it has the exact same field name, case sensitive.
Table Schema Description
AbstractOrderBookSchema A schema for Query Tables that uses the AbstractOrder named schema and defines keys for it.

It is important to understand that a Query Table can only use a concrete schema at runtime. Using the AbstractOrder schema here allows the Query Tables in different copies of the containing module to take on different concrete schemas based on the same abstract schema defined here.

Importing This Sample into StreamBase Studio

In StreamBase Studio, import this sample with the following steps:

  • From the top-level menu, select File>Import Samples and Community Content.

  • Enter capture field to narrow the list of options.

  • Select Capture fields and parent schemas from the Data Constructs and Operators category.

  • Click Import Now.

StreamBase Studio creates a single project containing the sample files.

Running the Provided Unit Test

Follow these steps to run the provided unit test in StreamBase Studio:

  1. In the Project Explorer view, navigate to src/test/java/package-name. Select the TestFxOrderMatching.java file. (You can also open the file for inspection, but this is not required.)

  2. Right-click the TestFxOrderMatching.java file, and from the context menu, invoke Run As>EventFlow Fragment Unit Test.

  3. In the JUnit view, observe the test running to completion, with a solid green bar indicating success.

  4. Edit and re-run the test file as desired to test different scenarios.

Running This Sample in StreamBase Studio

  1. In the Project Explorer view, open this sample's folder.

    Keep an eye on the bottom right status bar of the Studio window. Make sure any Updating, Downloading, Building, or Rebuild project messages finish before you proceed.

  2. Open the src/main/eventflow/packageName folder.

  3. Double-click to open the TopLevelFX.sbapp module. Make sure the module is the currently active tab in the EventFlow Editor.

  4. Click the Run button. This opens the SB Test/Debug perspective and starts the module.

  5. Wait for the Waiting for fragment to initialize message to clear.

  6. Open the Manual Input view and select the Orders stream. Notice that the Instrument tuple field shows only the concrete Currency1 and Currency2 fields. The capture field that comprised the original abstract Instrument field was overridden by the concrete Instrument field. This replaced the capture field that has data type placeholderFields with the concrete fields Currency1 and Currency2.

  7. Enqueue two tuples to the Orders stream in the Manual Input view:

    Field Tuple 1 Tuple 2
    Id 1 2
    Instrument.Currency1 USD USD
    Instrument.Currency2 CAD CAD
    Price 1.0525 1.0564
    IsBid no yes
    Quantity 1000 1000
    Party A B
  8. Observe a matching order emitted from the Fills stream in the Output Streams view.

  9. Enter other tuples as desired. Remember that no order emits from the Fills stream until there is a match between IsBid=no and IsBid=yes tuples.

  10. When done, press F9 or click the Terminate EventFlow Fragment button.

To understand how the inner module can be re-used to handle a different asset type, perform the following additional steps:

  1. Open the TopLevelFX.sbapp module.

  2. Select all six components and invoke Ctrl+C, Ctrl+V to make a second copy of the module on the same canvas. The copied components take the same names as their counterparts with "Copy" appended.

  3. Double-click the OrdersCopy input stream to open its Properties view.

  4. In the Edit Schema tab, select the EquitiesOrder schema in the drop-down control. This is the only step necessary to convert the OrderMatcherRefCopy module to process order matching for equities orders instead of FX orders.

  5. Save the module and click the Run button.

  6. In the Manual Input view, select the OrdersCopy stream. Notice that the Instrument tuple field now shows only a single field, Symbol.

  7. Enqueue two tuples to the OrdersCopy stream in the Manual Input view:

    Field Tuple 1 Tuple 2
    Id 10 20
    Instrument.Symbol GOOG GOOG
    Price 580.50 580.75
    IsBid no yes
    Quantity 50 50
    Party AA BB
  8. Observe a matching order emitted from the FillsCopy stream in the Output Streams view.

  9. Enter other tuples as desired, matching IsBid=no and IsBid=yes tuples to see output from the FillsCopy stream.

  10. When done, press F9 or click the Terminate EventFlow Fragment button.

Sample Location

When you load the sample into StreamBase Studio, Studio copies the sample project's files to your Studio workspace, which is normally part of your home directory, with full access rights.

Important

Load this sample in StreamBase Studio, and thereafter use the Studio workspace copy of the sample to run and test it, even when running from the command prompt.

Using the workspace copy of the sample avoids permission problems. The default workspace location for this sample is:

studio-workspace/sample_CaptureParentSchemas

See Default Installation Directories for the default location of studio-workspace on your system.