Skip to content
Get Started

Getting Started with the Nanoconda Simulator

This tutorial walks you through downloading the Nanoconda Simulator CLI and sample data, compiling a plugin, and running the simulator with the GUI.


Prerequisites

System Requirements:

  1. OS: RHEL-compatible system (Rocky Linux, CentOs, Red Hat Enterprice Linux).
  2. C/C++ Development libraries
  3. HugePages enabled
  4. Nanoconda License File is present. (Sent as attachment to the confirmation email)
  5. Nanoconda CLI archive is present. (Link Sent in the confirmation email)
  6. Market Data Files are present (PCAP or DBN). (Link sent in the confirmation email)

Note

If you experience any issues or missing any of the above items, please contact support@nanoconda.com

Docker environment

If your host operating system is different from Rocky or Red Hat, it is possible to run the software inside your Docker environment.

Tip

Refer to Docker Docs to install Docker Engine on your OS.

On Windows, enable WSL before installing Docker. Refer to Windows WSL Docs.

Below is the list of commands required to run a Docker container:

sudo docker pull rockylinux:9
sudo docker run -it --name rocky_env -p 2345:2345 --mount type=bind,source=/dev/hugepages,target=/dev/hugepages rockylinux:9 /bin/bash

Notes

  1. Port 2345 was mapped for future use by the GUI server. You may change it to any desired port.
  2. HugePages must be configured on the host machine and /dev/hugepages must be mounted to the container.

Installation

Follow instructions from your email to download simulator, sample data and the license file:

For the purposes of this totorial we placed all files that were supplied in the email inside our home directory.

Note

This tutorial describes use of sample Databento DBN files that were provided with a simulator license. Please refer to Quick Start guide for information on how to set up a PCAP replay version.

$ cd ~
$ ls -l
 dbn-sample-data.tgz
 nanoconda_CLI_SIM.tgz
 nanoconda_simulator_license.txt

Extract sample files and cli archives:

tar xzf dbn-sample-data.tgz
tar xzf nanoconda_CLI_SIM.tgz

After extraction, your home directory should contain two new directories:

$ cd ~
$ ls -l
...
dbn-sample-data/
nanoconda/

Sample data contents

$ ls dbn-sample-data/ -l
dbn-backtesting.xml
dbn-publisher.xml
env.sh
glbx-mdp3-20260326.definition.dbn.zst
glbx-mdp3-20260326.mbo.dbn.zst

Nanoconda CLI contents

$ ls nanoconda/ -l
bin/
configs/
data/
env.sh
extlib/
include/
lib/
nanoconda-cli
src/

Source Environment Variables

Source both environment files to configure your shell session:

. dbn-sample-data/env.sh
. nanoconda/env.sh

Supply Nanoconda License File

Set NANOCONDA_LICENSE variable with location of your license file.

export NANOCONDA_LICENSE=~/nanoconda_simulator_license.txt

Launching the application

Compile the Sample Plugin

The sample plugin source is located at src/naco-app.cpp. Compile it with:

cd ~/nanoconda/src/
make naco-plugin

Launch the dbnbacktester application:

cd ~/nanoconda
nanoconda-cli -a dbnbacktester -c ../dbn-sample-data/dbn-backtesting.xml -i src/naco-plugin.so

You should now see printouts of market data callbacks on your screen. You can modify src/naco-app.cpp with your logic and start sending orders.

Please check our Market Data and Order Entry API documentation.

This section covers running both the DBN Publisher and the Simulator together, then connecting via the web GUI.

Start the DBN Publisher

Run the DBN Publisher as a background process:

cd ~/nanoconda
nanoconda-cli -a dbnpublisher -c ../dbn-sample-data/dbn-publisher.xml > dbnpub.out &

Configure the Simulator

Edit the simulator configuration file to set your network interface, port, and risk limits:

vi configs/simulator-session-xcme.xml

The relevant sections of the configuration file are shown below:

<Access logger="simulator-session.log" logger-level="debug"
account-id="useraccount1" username="username1"
passwordhash="5411718394350379800">

<Risk>
<Instrument symbol="ES"  maxpositions="10"  clipsize="10"  />
<Instrument symbol="MES" maxpositions="100" clipsize="100" />
<Instrument symbol="NQ"  maxpositions="20"  clipsize="20"  />
<Instrument symbol="MNQ" maxpositions="200" clipsize="200" />
<Instrument symbol="6E"  maxpositions="400" clipsize="100" />
</Risk>

<Markets>
<Market code="XCME" />
</Markets>

<Gui intf="eth0" port="2345" cpu="-1"/>

<Credentials>
<User login="user-trader"  passwordhash="5411718394350379800" role="trader"  />
<User login="clearer"      passwordhash="5411718394350379800" role="clearer" />
<User login="user-viewer1" passwordhash="5411718394350379800" role="viewer"  />
<User login="user-viewer2" passwordhash="5421711394150379800" role="viewer"  />
</Credentials>

</Access>

In this example the GUI is configured to listen on interface eth0 at port 2345. Adjust intf and port to match your environment.

Credentials

  • useraccount1 is the account ID required to connect via the shared memory order entry session.
  • username1 is the username required for the shared memory entry session.
  • The password hash 5411718394350379800 corresponds to the plain-text password password and is applied to all sample credentials.
  • See Configuring Users and Roles to add users or change roles.

Start the Simulator

nanoconda-cli -a simulator -c configs/simulator-session-xcme.xml > simulator.out &

Both the DBN Publisher and the Simulator are now running.


Connect to the GUI

Open the Nanoconda GUI in your browser at gui.nanoconda.com and enter the following connection details under Advanced:

Field Value
Host IP address of eth0
Port 2345
Username user-trader
Password password

Click Connect.

The user-trader login corresponds to the entry configured in the <Credentials> node:

<User login="user-trader" passwordhash="5411718394350379800" role="trader"/>

At this point the GUI will show that your algo is offline, but you can already submit manual trades.

Connecting to localhost

Some browsers block GUI connecting to localhost IP, if this is the case, please download the GUI as a local application for your OS. Windows Linux macOs


Step 6: Compile and Launch the Algo

The sample algo source is located at src/bracketsalgo.cpp. Compile and run it:

cd ~/nanoconda/src/
make bracketsalgo

./bracketsalgo -e XCME -s ESM6 -u username1 -p password -a useraccount1 

The GUI will now show your application as online.

Launch your first bracket order and explore!

Simulated Exchange Latency

The simulator delays every new, modify and cancel request before it reaches the simulated matching engine, to model the time an order takes to reach the exchange.

  • The delay is estimated from the market data: for each exchange event, the difference between the exchange sending time and the matching time of the event's first message.
  • Only events without trades are used (order adds, modifications and cancels). Matching a large order takes the exchange extra time that does not apply to order entry.
  • The estimate is limited smoothly to a maximum, 1 ms by default: small values are almost unchanged, and large values approach the maximum without exceeding it.
  • A request is processed on the first market data update for its instrument after the delay. It is never executed inside the exchange event the algo was reacting to.
  • Requests sent together are processed together, in the order sent.

To change the maximum, add -L (microseconds):

nanoconda-cli -a simulator -c configs/simulator-session-xcme.xml -L 500 > simulator.out &

The value in use is written to the log at startup:

NACO| SIML | max matching latency 500.000 us

-L is also accepted by dbnbacktester and cmebacktester.

Simulator Thread Pinning

The simulator application runs matching and market data on separate threads. Each can be pinned to a CPU core and given real-time FIFO scheduling with these <Access> attributes:

Attribute Description Default
simulator-cpu CPU core for the matching thread -1, not pinned
simulator-fifo-priority FIFO priority for the matching thread FIFO off
simulator-md-cpu CPU core for the market data thread -1, not pinned
simulator-md-fifo-priority FIFO priority for the market data thread 0, FIFO off
<Access logger="simulator-session.log" logger-level="debug"
   simulator-cpu="3" simulator-fifo-priority="50"
   simulator-md-cpu="4" simulator-md-fifo-priority="50"
   account-id="useraccount1" username="username1" passwordhash="5411718394350379800">

Note

simulator-md-fifo-priority only takes effect when simulator-md-cpu is also set, and the value must be above 0. If the operating system refuses FIFO scheduling for the market data thread, the application exits with an error. Use a separate core for each thread.

Next Steps