AlgoDaily

Algorithmic Trading with C++

Read at your own pace. Code execution, quizzes, progress tracking, and the AI tutor are available in the interactive view with JavaScript enabled.

From Prices To Trades

Why this lesson matters

Now that you've finished Introduction to C++ and C++ for Finance Basics, you can already express calculations, cash flows, and precision-aware money logic in C++.

Algorithmic trading is where those pieces become a running decision system:

  • ingest market data
  • compute features
  • generate a trading signal
  • test the idea on historical data
  • prepare an order for execution

Think of it like basketball film study plus game-time execution: first you study patterns, then you decide when to take the shot. C++ matters because trading systems often care about latency, memory control, predictable performance, and reliability.

From Prices To Trades

Trading System Loop

The core loop

Most algorithmic trading systems can be simplified into this loop:

new market data
      ↓
update internal state
      ↓
compute indicator or feature
      ↓
generate signal
      ↓
place, cancel, or ignore order
      ↓
record what happened

In JavaScript web apps, you're used to event-driven thinking: user clicks, network responses, state updates. Trading is also event-driven, but the events are market events: quotes, trades, bars, fills, cancels.

The job of C++ is not just to calculate correctly. It is to calculate correctly while markets are moving.

Trading System Loop

Market Data Shape

Start with bars

Real trading systems may process every tick, quote, and order-book update. For your first algorithm, use OHLCV bars:

  • open: first price in the interval
  • high: highest price
  • low: lowest price
  • close: final price
  • volume: total traded size

This is like tracking a bodybuilder's weekly progress instead of every rep: less granular, but easier to reason about.

Below, we model bars with a struct and print a tiny price series.

```cpp
#include <iostream>
#include <vector>
#include <iomanip>

struct Bar {
    double open;
    double high;
    double low;
    double close;
    int volume;
};

int main() {
    std::vector<Bar> bars = {
        {100.0, 101.2, 99.8, 100.9, 1200},
        {100.9, 102.0, 100.5, 101.7, 1500},
        {101.7, 101.9, 100.8, 101.0, 1100}
    };

    std::cout << std::fixed << std::setprecision(2);
    for (size_t i = 0; i < bars.size(); ++i) {
        const Bar& b = bars[i];
        std::cout << "Bar " << i
                  << " O=" << b.open
                  << " H=" << b.high
                  << " L=" << b.low
                  << " C=" << b.close
                  << " V=" << b.volume << "\n";
    }

    return 0;
}
```

Signals From Features

Feature → signal

A feature is a computed value derived from market data. A signal is a decision hint derived from features.

Example:

feature: 3-bar simple moving average
signal: buy if close is above the average, otherwise stay flat

This is intentionally simple. The point is not that moving averages are magic. The point is to practice turning a market idea into deterministic C++ logic.

```cpp
#include <iostream>
#include <vector>
#include <iomanip>

struct Bar {
    double close;
};

double simpleMovingAverage(const std::vector<Bar>& bars, size_t endIndex, size_t window) {
    double sum = 0.0;
    for (size_t i = endIndex + 1 - window; i <= endIndex; ++i) {
        sum += bars[i].close;
    }
    return sum / static_cast<double>(window);
}

int main() {
    std::vector<Bar> bars = {{100.0}, {101.0}, {102.0}, {101.5}, {103.0}};
    const size_t window = 3;

    std::cout << std::fixed << std::setprecision(2);

    for (size_t i = window - 1; i < bars.size(); ++i) {
        double sma = simpleMovingAverage(bars, i, window);
        std::string signal = bars[i].close > sma ? "BUY_BIAS" : "FLAT";

        std::cout << "close=" << bars[i].close
                  << " sma=" << sma
                  << " signal=" << signal << "\n";
    }

    return 0;
}
```

Feature Or Signal?

In an algorithmic trading system, which statement best describes the relationship between a feature and a signal?

Backtest First

Test before you trade

A backtest replays historical data and asks: "What would this strategy have done?"

A minimal backtest needs:

  • historical prices
  • strategy rules
  • position state: flat or long
  • trade accounting
  • final profit and loss

This screen keeps the accounting simple on purpose. The next lesson, Risk Management in C++, will go deeper on position sizing and controlling downside.

```cpp
#include <iostream>
#include <vector>
#include <iomanip>

struct Bar {
    double close;
};

double sma(const std::vector<Bar>& bars, size_t endIndex, size_t window) {
    double sum = 0.0;
    for (size_t i = endIndex + 1 - window; i <= endIndex; ++i) {
        sum += bars[i].close;
    }
    return sum / static_cast<double>(window);
}

int main() {
    std::vector<Bar> bars = {{100}, {101}, {102}, {99}, {98}, {100}, {103}, {104}};
    const size_t window = 3;

    bool longPosition = false;
    double entryPrice = 0.0;
    double realizedPnl = 0.0;

    std::cout << std::fixed << std::setprecision(2);

    for (size_t i = window - 1; i < bars.size(); ++i) {
        double average = sma(bars, i, window);
        double price = bars[i].close;

        if (!longPosition && price > average) {
            longPosition = true;
            entryPrice = price;
            std::cout << "BUY at " << price << "\n";
        } else if (longPosition && price < average) {
            longPosition = false;
            realizedPnl += price - entryPrice;
            std::cout << "SELL at " << price
                      << " tradePnL=" << price - entryPrice << "\n";
        }
    }

    if (longPosition) {
        double finalPrice = bars.back().close;
        realizedPnl += finalPrice - entryPrice;
        std::cout << "CLOSE at " << finalPrice
                  << " tradePnL=" << finalPrice - entryPrice << "\n";
    }

    std::cout << "Total PnL=" << realizedPnl << "\n";
    return 0;
}
```

Backtest Reality Check

True or false: If a strategy makes money in a simple backtest, it is guaranteed to make money in live trading.

Execution Boundary

Strategy vs execution

Keep these two concerns separate:

Strategy:  "I want to buy."
Execution: "How do I send, track, modify, or cancel the order?"

A clean C++ design often has a boundary between the strategy engine and the broker/exchange adapter.

Why this matters:

  • you can backtest strategy logic without connecting to a broker
  • you can swap execution providers without rewriting the strategy
  • you can log every decision and every order event
  • you reduce bugs caused by mixing decision logic with API details

This is similar to separating frontend state from API calls in a web app.

Execution Boundary

Decision Hint

Fill in the blank: In our trading loop, a computed decision hint such as BUY_BIAS, SELL_BIAS, or FLAT is called a ______.

Your First System

What you can build now

You now have the skeleton of a C++ algorithmic trading system:

  1. represent market data with typed structures
  2. compute features from historical prices
  3. convert features into strategy signals
  4. replay historical data in a basic backtest
  5. separate strategy decisions from order execution concerns

The big lesson: algorithmic trading is not one giant trick. It is a pipeline of small, testable decisions.

Next, we'll build on this by focusing on Risk Management in C++: how to keep a strategy from taking too much exposure when the game gets chaotic.

Your First System

Open interactive view →