Each Algo derives from IAlgoOrder and overrides virtual methods to receive callbacks from CQG Algo system.
When an order is activated by a user or 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 setup data structures that the Algo may need.
This call returns an OrderOpResult, which allows the algo 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 its 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{ ORDER_ERROR_INVALID_ORDER_DEFINITON, "Min Quantity parameter must be defined and non zero"}; }
IBeforeLaunchAlgoServices is passed to do_before_launch
and allows the Algo to query its environment.
class IBeforeLaunchAlgoServices { public: // 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; };
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).
Next, you will 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.
☑ 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), CQG Algo Server 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 that by canceling, changing, or adding new child orders.