Registration

When Spark Server starts, it loads all plugins listed in the /sparkbin/plugins directory and calls an exported function named init_spark_plugin which must have the following signature.

extern "C" void init_spark_plugin(bts::SparkServices &serv) { }

The init_spark_plugin function registers the Algo with a DynamicOrderDescriptor. Once registered, the Algo appears in the Spark ladder and the Algo Studio.

To register an Algo call register_dynamic_algo_order on the provided bts::SparkServices instance. This function takes the DynamicOrderDescriptor and a function that is called to construct the IAlgoOrder. A single init_spark_plugin can call register_dynamic_algo_order multiple times to register multiple Algos.

The DynamicOrderDescriptor must have a dynamic_order_type (name), or the registration will fail.

   DynamicOrderDescriptor desc;
   desc.set_dynamic_order_type("My Algo");
   auto result = 
      serv.register_dynamic_algo_order(
       desc, []() { return std::make_unique<MyAlgo>(); });
   if (result != bts::AlgoRegistrationResult::SUCCESS) {
       // Algo failed to register
   }

DynamicOrderDescriptor

The DynamicOrderDescriptor describes the type of parameters that the Algo accepts. These inputs can come either from the user manually entering them or from a parent Algo. Spark Algos are composable, so one Algo can activate another. See Child Orders for more on how to activate custom order types as child orders.

Add parameters to the DynamicOrderDescriptor by calling add_param_desc() and setting the name and parameter type.

   *desc.add_param_desc() = param_bool("Enable Feature");
   *desc.add_param_desc() = param_uint32("Feature Quantity");

The above parameters look like this when rendered in the Spark ladder.

And like this when viewed in the Spark order book.

Each descriptor can be one of the following types:

// Primitive
int32
uint32
double
string
bool
// Complex
Order
Array
Struct

Currently the Spark UI only renders parameters with primitive types. The complex types can only be provided by a parent order.

Order

This parameter type indicates that another order type parameterizes this Algo. When the Algo needs to create a child order, it can use this parameter type to create a custom order type instead of defaulting to a limit order.

For example, an Algo might be designed to wait for a specific market condition before putting in an order. Instead of placing a limit order when the condition is met, the user can specify that it should an IceBerg order. The Algo doesn't need special logic to handle different child order types.

Array

An array parameter is a collection of the same type of parameter. If your Algo needed to behave differently depending on a table of prices, you could send that list in though an array parameter.

    *desc.add_param_desc() = 
        param_array("Price Points", 
            param_double("unused").param_type());

Struct

A struct parameter is a set of named parameter types similar to the entire DynamicOrderDescriptor. The struct parameter type can be combined with the array type to handle tabular data.

    *desc.add_param_desc() = 
        param_array("Step Table", 
            param_struct("", {
                param_uint32("Market Quantity"),
                param_uint32("Order Quantity")
            }).param_type());

  Next