Each Algo derives from IAlgoOrder and overrides virtual methods to receive callbacks from the Spark system.

Before Launch

When an order is activated by a user or by another Algo, the first call it receives is do_before_launch. This call happens outside of the latency-sensitive path, so it's the place to validate parameters and set up data structures that the Algo might need.

This call returns an OrderOpResult, which allows it to fail and return an error message to its creator. If a user created this order, this message is displayed in the Activity Log and across the bottom of the ladder.

Every SDK Algo is a "Dynamic" Algo since it's parameters are defined during registration. Use the get_if<T> helper to retrieve a named parameter from the order_params collection as a std::option<T>. If a parameter has a valid default value you can use std::option::value_or(...) to set default values for missing parameters. If a parameter must exist or must be within a certain valid range, return an error to the caller.

OrderOpResult MyAlgo::do_before_launch(IBeforeLaunchAlgoServices& serv) {
   auto& def = serv.definition();
   auto& params = def.custom_def().dynamic().order_params();
   auto mqi = get_if<uint32_t>(params, "Min Quantity");
   if (!mqi || mqi.value() == 0)
      return OrderOpResult{
          "Min Quantity parameter must be defined and non zero"};
The parameters are defined during registration by the DynamicOrderDescriptor.


IBeforeLaunchAlgoServices is passed to do_before_launch and allows the Algo to query its environment.

class IBeforeLaunchAlgoServices {
   // The OrderDefinition for this algo
   virtual api::orderman::OrderDefinition const &definition() const = 0;

   // The security this algo is paramterized with (also available from
   // definition())
   virtual api::Security const &security() const = 0;

   // The unique order key for this algo
   virtual OrderKey order_key() const = 0;

   // The parent key for this algo's parent or null_order_key() if the
   // algo does not have a parent
   virtual OrderKey parent_order_key() const = 0;

   // The security identified by k or nullptr if no such security exists
   virtual api::Security const *lookup_security(SecurityKey k) const = 0;

   // Wheter this algo is being attached to an existing order.
   // If an algo does not support attaching it can return an error 
   // if is_attaching() == true from do_before_launch.
   virtual bool is_attaching() const = 0;

   // Build a child template that can later can be used to quickly
   // launch child orders. The reserve parameter indicates how many
   // orders should be created ahead of time, before they are
   // launched. This is usefull to remove the relatively expensive
   // order creation operation to a background thread.
   virtual ChildTemplate &
   make_child_template(api::orderman::OrderDefinition const &child_def,
                       size_t reserve = 1) = 0;

   // Get the current time
   virtual TimeStamp get_time() const;

Launch / Launch Attached

Depending on the state of is_attaching() the next call will either be do_launch or do_launch_attached. The only difference is that in do_launch_attached the existing OrderKey and ChildState are provided.

do_launch and do_launch_attached are in the latency-sensitive path and should not do more work than needed. These functions get a reference to IAlgoServices, which is a superset of the functionality available on IBeforeLaunchAlgoServices. Most Algos should store a pointer or reference to this object for managing child orders (it has a stable address).

Now is the time to use IAlgoServices to subscribe to market events that are relevant to your Algo and create any child orders that need to exist at the start of your Algo. You can safely call IAlgoServices from any IAlgoOrder callback.

To learn more about subscribing to events see subscriptions.

Things to do in the launch callback

☑ Store a reference to IAlgoServices
☑ Subscribe to relevant market events
☑ Launch a child order?


If the user or parent Algo changes the order parameters (price, size, or the custom parameters defined during registration), Spark calls the do_update callback with the new parameters. It is up to the Algo to decide how to apply the new parameters to update the running state. It can do this by canceling, changing, or adding new child orders.

Previous   Next