LibHFTDocumentationStart evaluating

From a local exchange to your workload

Evaluate LibHFT.

Evaluate LibHFT by choosing a runtime, completing a local FIX order exchange, then measuring the connection your application needs.

1 · Choose your deployment

Request the package for your team.

Evaluation access and terms are arranged directly with Atrekes. Email the flavor, operating system and CPU architecture you want to use, your FIX version or custom dictionary, and the transport and traffic rate you need to assess. We can then agree the package, example peer and evaluation scope.

LibHFT source code is not public. Package contents, native dependencies and licensing are confirmed for the evaluation; the commands below describe the included example layouts rather than a public package-manager installation.

FlavorImplementationLocal example prerequisites
C++Native engineLinux, C++11 compiler, make and pthreads for the plaintext examples.
Java PureIndependent JVM engineLinux and a JDK with --release; examples target Java 8 and are documented with JDK 21.
Java/JNIJava API over C++Java prerequisites plus C++11, JDK headers and OpenSSL development libraries for the default native build.
.NET PureIndependent C# engineLinux and the .NET 8 SDK for the example application.
.NET NativeC# API over C++.NET prerequisites plus C++17, make and OpenSSL development libraries for the native build.
RustIndependent Rust engineLinux and Rust/Cargo; the example is documented with Rust 1.93.

The walkthrough uses Linux. For Windows or another deployment target, confirm the compiler/runtime, CPU architecture and native library bundle with the team. Vendor transports also need the matching NIC, drivers and SDK. Compare the six flavors → · Check transport requirements →

2 · Complete a local exchange

Log on, send an order, receive its report.

Use the matching example files supplied with your package. Run commands from that language package’s root. Development checkouts use oss/cpp, oss/java, oss/dotnet and oss/rust. Keep each trial’s build outputs and session stores in their own directory.

The C++ simulator below is a self-contained first exercise. The Java, .NET and Rust clients use the separate FileStore executor on port 9877; its setup is given next.

C++ · run the local simulator and client

In the first terminal, build and start the simulator:

make -j2 libhft-sim libhft-sim-client
./bin/libhft-sim --profile order --execution book --port 9880 --quiet

In a second terminal, from the same C++ root:

./bin/libhft-sim-client --host 127.0.0.1 --port 9880 --timeout-ms 5000

The client sends eight orders, consumes execution reports and cancels resting orders. Success is exit status 0 with orders_sent=8, rejects=0 and ok=1. This is a framing/socket simulator exercise; the package’s C++ user guide covers the session-owner API.

Java Pure and Java/JNI · run the shared order client

Start the executor below first. Compile the shared Java client once:

example_dir=$(mktemp -d)
mkdir "$example_dir/classes"
find src/main/java -name '*.java' > "$example_dir/sources.txt"
javac --release 8 -d "$example_dir/classes" \
  @"$example_dir/sources.txt" examples/OrderClient.java
java -cp "$example_dir/classes" OrderClient pure-java examples/order-client.cfg

For Java/JNI, restart the executor with a fresh store, then build and load the matching native library:

make HFTJAVA_OPEN=1 TARGET_DIR="$example_dir/native" native
java -Djava.library.path="$example_dir/native" -cp "$example_dir/classes" \
  OrderClient jni examples/order-client.cfg

Set JAVA_HOME to the full JDK. In a development checkout also set LIBHFT_CPP_ROOT to the exact oss/cpp tree; a standalone package uses its pinned native headers. The client prints order accepted and ExecutionReport received and exits 0.

.NET Pure and .NET Native · run the shared order client

With a fresh executor running, select the managed provider:

dotnet run -c Release --project examples/OrderClient -- \
  managed examples/OrderClient/client.cfg

For .NET Native, restart the executor with a fresh store, then select the exact native build:

native_dir=$(mktemp -d)
make -C src/native HFTNET_PRIVATE=0 OUTDIR="$native_dir"
LIBHFTNET_LIBRARY="$native_dir/libhftnet.so" \
  dotnet run -c Release --project examples/OrderClient -- \
  native examples/OrderClient/client.cfg

In a development checkout set LIBHFT_CPP_ROOT to the exact oss/cpp tree before either build. The client prints order accepted and ExecutionReport received and exits 0. A native request fails if its library cannot load.

Rust · run the typed order client

With a fresh executor running and the Rust toolchain installed:

cargo run --offline --example order_client -- examples/client.cfg

The client logs on, sends one order through a typed builder, consumes an ExecutionReport and sends Logout. Success is exit status 0 with Rust: order accepted and ExecutionReport received. The Rust client needs no C++ library; the example peer is a separate C++ process.

Local peer for Java, .NET and Rust · start the executor

From the C++ package root, in a separate terminal:

make quickfix-filestore-executor-example
trial_dir=$(mktemp -d)
mkdir "$trial_dir/store"
sed "s|FileStorePath=./quickfix-filestore-executor|FileStorePath=$trial_dir/store|" \
  examples/quickfix_filestore_executor.cfg > "$trial_dir/executor.cfg"
./bin/quickfix_filestore_executor "$trial_dir/executor.cfg"

The executor listens at 127.0.0.1:9877 as LIBHFT_EXECUTOR, with peer COUNTERPARTY. The client configurations mirror those identities. It acknowledges orders with a NEW ExecutionReport; it does not fill them.

Run one client at a time. Stop the executor with Ctrl-C and use a new trial directory before each provider run. The supplied clients reset their local demo sessions; retain production stores and agree reset policy separately. Stop both processes before removing their trial files.

With LIBHFT_BUILD_ROOT, use the binary paths described in the package README rather than the default ./bin. A development C++ build writes under $LIBHFT_BUILD_ROOT/oss/cpp/bin; a standalone C++ package uses $LIBHFT_BUILD_ROOT/bin.

3 · Check the behaviour you need

Move from the demo to your session.

  1. Inspect the exchange. Confirm the CompIDs, order identity, report status and sequence numbers. Inspect synthetic logs in the FIX parser or use the read-only Workbench.
  2. Load your dictionary. Check required fields, groups and the application messages your counterparty uses. Review protocol coverage.
  3. Exercise recovery. Verify disconnect/reconnect, resend, replay and store ownership before moving a real session. Follow the recovery guide.
  4. Measure a matching workload. Record hardware, runtime, transport, target rate and the timed work. Use the benchmark methodology and compare the published results.

A successful local exchange establishes connectivity and receipt of a report. Inspect rejects and order state, and reconcile outstanding orders before retrying in a trading application. A timeout, connection failure or missing expected report should fail the evaluation step.