When CQG Algo Server starts, it loads all plugins listed in the /sparkbin/plugins directory and calls an exported function called 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 Algo API Test Client ladder and 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 }
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. CQG Algo Server Algos are composable, so one Algo can activate another. See Child Orders 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 when rendered in Algo API Test Client ladder:
The above parameters when viewed in Algo API Test Client order book:
Each descriptor can be one of the following types:
// Primitive
int32
uint32
double
string
bool
// Complex
Order
Array
Struct
Currently Algo API Test Client only renders parameters with primitive types. The complex types can only be provided by a parent order or the Algo API.
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 be an IceBerg order. The Algo doesn't need special logic to handle different child order types.
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 through an array parameter.
*desc.add_param_desc() = param_array("Price Points", param_double("unused").param_type());
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());