Trading Lab Project Skeleton
Read at your own pace. Code execution, quizzes, progress tracking, and the AI tutor are available in the interactive view with JavaScript enabled.
Build The Lab
From toolchain to reusable project
In Course Overview & Environment Setup, you verified that your compiler, terminal, and timing smoke tests work.
Now we turn that loose setup into a small trading lab skeleton: a repeatable C++ project shape that later lessons can extend without becoming messy.
For this lesson, the goal is not to connect to an exchange or implement a strategy. The goal is to create a clean home for future pieces:
market ideas -> C++ modules -> tests -> runnable binaries
A good skeleton gives you:
- predictable folders
- repeatable build commands
- simple executable targets
- a place for shared types
- a place for tests
- a clean boundary between source code and generated files
This is how we keep beginner-friendly code from turning into a pile of one-off experiments.

Target Lab Shape
The folder structure we want
Create a project folder named trading-lab/. Inside it, use this shape:
trading-lab/
CMakeLists.txt
README.md
include/
trading_lab/
types.hpp
src/
main.cpp
tests/
types_test.cpp
config/
lab.conf
data/
sample_feed.txt
build/
Each folder has a job:
-
include/trading_lab/: reusable headers shared by multiple programs -
src/: main application code and executable entry points -
tests/: small checks that protect behavior as the course grows -
config/: runtime settings such as mode, symbols, or file paths -
data/: tiny local sample files used by lab programs -
build/: generated build files and compiled binaries
The key idea: source stays stable; build output is disposable.
Later, when we parse feed messages and reconstruct state, this structure gives every piece a natural place to live.

First Lab Binary
Start with a boring executable
Your first src/main.cpp should do something simple and reliable:
- Accept a mode from the command line.
- Accept a symbol name.
- Print startup information.
- Reject unknown modes.
That may sound too basic, but trading systems depend on clean startup behavior. If a binary cannot clearly say what it is running, it becomes hard to debug later.
Example build/run flow:
cmake -S . -B build
cmake --build build
./build/trading_lab sim DEMO
./build/trading_lab replay DEMO
For now, sim and replay are just labels. We will give them deeper meaning as the course progresses.
```cpp
#include <chrono>
#include <iostream>
#include <string>
int main(int argc, char* argv[]) {
const std::string mode = argc > 1 ? argv[1] : "sim";
const std::string symbol = argc > 2 ? argv[2] : "DEMO";
if (mode != "sim" && mode != "replay") {
std::cerr << "[lab] invalid mode: " << mode << '\n';
std::cerr << "[lab] expected: sim or replay\n";
return 1;
}
const auto now = std::chrono::system_clock::now();
const auto epochMs = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()
).count();
std::cout << "[lab] binary=trading_lab\n";
std::cout << "[lab] mode=" << mode << '\n';
std::cout << "[lab] symbol=" << symbol << '\n';
std::cout << "[lab] startup_epoch_ms=" << epochMs << '\n';
std::cout << "[lab] status=ready\n";
return 0;
}
```
Build Folder Check
You are organizing trading-lab/ and need a place for generated compiler output, CMake files, and binaries.
Why should these usually live in build/ instead of being mixed into src/?
One File Myth
True or false: A beginner trading lab should stay as one giant C++ file for as long as possible because folders and headers only matter in production.
Tiny Regression Test
Add a small test executable
You do not need a full testing framework yet. A tiny tests/types_test.cpp program is enough to prove the idea:
- run a few checks
- print pass/fail output
- return nonzero on failure
This matters because trading code changes constantly. Every refactor should answer one question:
Did we preserve the behavior we already trusted?
The test below checks our price tick conversion. In a real project, your build system would compile this as a separate test target.
```cpp
#include <cmath>
#include <cstdint>
#include <iostream>
#include <string>
using PriceTicks = std::int64_t;
PriceTicks toTicks(double price, int scale) {
return static_cast<PriceTicks>(std::llround(price * scale));
}
int recordCheck(bool condition, const std::string& name) {
if (condition) {
std::cout << "PASS " << name << '\n';
return 0;
}
std::cout << "FAIL " << name << '\n';
return 1;
}
int main() {
int failures = 0;
failures += recordCheck(toTicks(100.125, 1000) == 100125, "mills conversion");
failures += recordCheck(toTicks(42.19, 100) == 4219, "cents conversion");
failures += recordCheck(toTicks(0.01, 100) == 1, "one cent conversion");
if (failures == 0) {
std::cout << "All type checks passed.\n";
return 0;
}
std::cout << failures << " check(s) failed.\n";
return 1;
}
```
Folder Name Blank
Fill in the blank:
Generated CMake files, object files, and compiled binaries should usually go in the ____/ directory so they can be deleted and recreated safely.
Commit The Boundary
Know what belongs in Git
A trading lab should be reproducible. That means the important human-written files should be committed, while generated files should stay out.
Usually commit:
CMakeLists.txtREADME.mdinclude/src/tests/- small
config/examples - tiny sample files in
data/when they are part of the lesson
Usually ignore:
build/- compiled binaries
- object files
- editor caches
- large downloaded datasets
- machine-specific temporary files
A useful mental model:
Can I recreate it from source commands? -> ignore it
Did I write it or need it for the lesson? -> commit it
Before moving into Market Microstructure & Data Feeds, make sure your lab can build, run, and survive a clean rebuild.

Skeleton Readiness Check
Before continuing to the next Market Foundations lesson, which checklist best describes a ready trading lab skeleton?
One Pager Cheat Sheet
One Pager Cheat Sheet
- A trading lab skeleton turns one-off C++ experiments into a repeatable project that future lessons can extend.
- Keep reusable headers, executable source, tests, config, data, and generated build output in separate folders.
- A first lab executable should start predictably, print its runtime settings, and fail clearly on invalid input.
- Generated build output belongs in a disposable
build/directory, not mixed with source files. - Shared trading types should be small, explicit, and easy to test; integer ticks are often safer than raw floating-point prices.
- Even beginner trading code benefits from a simple structure before the project grows.
- A tiny test executable can protect important behavior before you introduce heavier tooling.
- Use
build/as the disposable directory for generated files and compiled binaries. - Commit source and lesson inputs; ignore generated artifacts that can be recreated from build commands.
- A ready early lab has structure, repeatable builds, a runnable binary, shared types, and a small test.