Algo Control API
Launch, Stop, Configure and Monitor your algo remotely with our Algo Control API. Custom Field Names, Custom Field Types, Real-time GUI Updates.
Here are the steps to enable your algo to support GUI Algo Controls.
1. Implement nanoconda::listener class.
2. Fill nanoconda::guischema object with fields definitions.
3. Hanle start and stop signals via onuialgostart and onuialgostop callbacks.
4. Update GUI at any poinbt by calling setalgoreport().
Callbacks
Callback Listener
Communication between the algo and gui is implemented via callbacks from GUI (for example when a remote user presses a GUI button) and API calls (when algo needs to update GUI for the remote user).
In order to receive GUI callbacks, user must implement a listener class and inherit nanoconda::uilistener
struct myListener : nanoconda::listener
{
void onuischemarequest(guischema* schema) { };
void onuialgostart(algorequest* algo) { };
void onuialgostop(algorequest* algo) { };
/*
...
*/
}
...
int main(int argc, char *argv[])
{
/*...*/
myListener* l = new myListener();
/*...*/
nanoconda::dmasession* session = nanoconda::dmasession::init(account, rcode, cpu);
/*...*/
/*...*/
}
GUI Schema
In order for GUI to display algo custom fields user must define field descriptions (Schema). It must be done in onuischemarequest callback which will be raised whenever a User Starts Algo Window in GUI. The guischema* is passed as an argument and must be filled.
User must populate: 1. Number of Input Fields 2. Number of Algo Report Fields 3. Field Names and Types. 4. Optionaly, default, minimum, maximum and step values if user inputs should be limited or controlled.
enum fieldType : unsigned char
{
NC_BLANK=0,
NC_C=1,
NC_UC=2,
NC_S=3,
NC_US=4,
NC_I=5,
NC_UI=6,
NC_P=7,
NC_STR=9,
NC_LL=10,
NC_ULL=11,
NC_F=12
};
template <typename T> void setField(const char* name, fieldType type, T deflt, T min, T max, T step );
void setField(const char* name, fieldType type);
Note
deflt, min, max, step must be of same type.
Here is an example for creating a schema with 4 Input Fields, 3 Algo Report Fields and optional default, minimum, maximum and step arguments configured.
void onuischemarequest(nanoconda::guischema* schema)
{
schema->inputFieldCount = 4;
schema->inputFields[0].setField("Input1", nanoconda::NC_F, 100.123, 10.0, 200.5, 10.0);
schema->inputFields[1].setField("Input2", nanoconda::NC_LL, 200, 0, 200, 7);
schema->inputFields[2].setField("Input3", nanoconda::NC_F, -30.0, -20.0, 200.0, 11.0);
schema->inputFields[3].setField("Input4", nanoconda::NC_I, 400, -998, 222, 23);
schema->algoFieldCount = 3;
schema->algoFields[0].setField("AlgoField1", nanoconda::NC_F);
schema->algoFields[1].setField("AlgoField2", nanoconda::NC_UI);
schema->algoFields[2].setField("AlgoField2", nanoconda::NC_I);
}
Once provided, GUI will display such Schema:

Launching and Stopping Algos
Once Schema is displayed user can set input parameters and Launch Algos with them. Whenever 'Launch Algo' button is clicked user application will receive the onuialgostart() callback. algo object will be provided a unique algoId for each Launched Algo.
Here is a sample implementation where we send a Buy market order for any new algo launch, save the new algo data internally and add a new line to the Algo Report with custom fields to update GUI with information that the algo is running.
void onuialgostart (nanoconda::algorequest* algo)
{
nanoconda::order od;
nanoconda::order* o = &od;
o->setSymbol("MNQH5");
o->quantity = 10;
o->type = nanoconda::orderType::MKT;
o->side= 'B';
nanoconda::reasoncode code = _session->newOrder(o);
if (code == nanoconda::SUCCESS)
{
nanoconda::algorecord* adata = &_areport.algos[_areport.algoCount]; //_areport is an internally saved nanoconda::algoreport object;
adata->algoId = algo->algoId;
adata->fields[0]._f((float) _areport.algoCount);
adata->fields[1]._ui( _areport.algoCount * 10);
adata->fields[2]._ui( _areport.algoCount * 20);
_areport.algoCount++;
_session->setalgoreport(&_areport);
}
}
If nanoconda::algoreport contains algos (nanoconda::algoreport::algoCount > 0) the lines will be displayed in GUI.

Whenever X is pressed onuialgostop() callback will be raised. algo object will contain algoId and algoIndex of the relevant line in GUI algo report which should be used to indicate which algo received a stop signal.
Here is an example implementation of onuialgostop() where we send an opposing Sell market order and remove an algo line from internal and GUI algo reports.
void onuialgostop (nanoconda::algorequest* algo)
{
nanoconda::order od;
nanoconda::order* o = &od;
o->setSymbol("MNQH5");
o->quantity = 10;
o->type = nanoconda::orderType::MKT;
o->side= 'S';
nanoconda::reasoncode code = _session->newOrder(o);
if (code == nanoconda::SUCCESS)
{
int maxAlgos = 30;
if(algo->algoIndex < maxAlgos-1)
{
memmove(&(_areport.algos[algo->algoIndex]),&(_areport.algos[algo->algoIndex+1]), sizeof(nanoconda::algorecord) * (maxAlgos - (algo->algoIndex+1)));
}
memset(&(_areport.algos[maxAlgos-1]),0x0,sizeof(nanoconda::algorecord));
_areport.algoCount--;
_session->setalgoreport(&_areport);
}
}
Note
There are no requirements to how onuialgostart() or onuialgostop() callbacks should be implemented. They serve as communication with a remote GUI user. For example user can ignore the some callbacks completely or create / delete multiple algo report lines in a single callback.
Updating Algo Report
We gave some examples on how to update GUI via calling setalgoreport() with information about new and deleted algos in previous sections.
The beauty of setalgoreport() is that it can be called from anywhere in your algo code.For example on order confirmations, executions or book updates. This can help pass real-time updates for each algo. Some useful information might be the real-time PNL of a specific algo or average price.
Gui data refresh rate is 4x a second, so there is no need to set setalgoreport() more frequently (even though it is allowed).
A recommended approach to updating the GUI state is to have a separate thread that periodically updates the GUI with user internally kept algoreport:
pthread_t gui_pub_trhead;
pthread_create(&gui_pub_trhead, NULL, guiPublisher, myListener);
...
void* guiPublisher(void* data)
{
myListener* l = (myListener*) myListener;
if(!l) return NULL;
if(!l->_session) return NULL;
while (1) {
l->_session->setalgoreport(&l->_areport)
usleep(250000); //sleep for 250 milliseconds
}
return NULL;
}
Sample Algo: Brackets
The NanoConda package includes a sample trading algorithm called Brackets. This algo is designed as a simple example to demonstrate how to build trading strategies using the NanoConda API. It is also a useful template for developers starting custom algo development.
The Brackets algo extends the base prototype defined in:
Behavior
When launched from the GUI, the Brackets algo performs the following cycle:
- Sends a Market order in the direction selected by the user.
-
After the fill is confirmed, it sends a bracket consisting of:
- One Limit order (take profit)
- One Stop Loss order (risk protection)
-
When either of the bracket orders is filled:
- The position is fully closed
- The algo immediately restarts the cycle by opening a new position with another Market order
This shows how an algo can remain continuously active until explicitly stopped by the user.
Note
The Brackets algo is intended as a reference implementation only. Its logic is fully customizable. Users are free to:
- Modify the trading workflow
- Configure custom bracket logic
- Add risk or position sizing rules
- Control when algo lines are added or removed in the GUI
- Maintain any number of simultaneous algo instances
Tip
The above logic is all implemented inside the client code and is fully custom. User is free to chose how many algo lines are present in the report and when any line is added or removed.
Starting the Algo
To compile bracketsalgo please execute the following commands:
Usage: ./bracketsalgo -e exchange -s symbol1,symbol2,... -u username -p password [-a account] [-c cpu]
./bracketsalgo -e XCME -s ESM5,NQM5 -u hftclient -p password -a hftclientAcc100
Note
Please replace command line arguments for your use case.
GUI Controls
The Brackets algo can be controlled directly from the NanoConda GUI:
| Action | Description |
|---|---|
| Launch | Starts the algo and begins trading |
| X (Stop) | Stops the algo and closes open positions safely |
| Remove | Clicking X again when status is CANCEL removes it from the report |
Tip
After stopping, the algo status transitions to CANCEL, but it remains visible so the user can review metrics such as algo P&L and lifecycle events.

Notes:
Algo is Onlineindicates that the application is running and connected.- The first row shows Algo Status = CANCEL, meaning this algo was stopped via the API.
- The second row shows Algo Status = ON, meaning the algo is currently active and trading.
- Custom algo
Names were provided at launch to clearly identify which algo trades in which direction. - The active algo has linked Stop and Profit orders visible, and these can also be confirmed in the
Live Orderswindow.