Implementing Trading Algorithms
Read at your own pace. Code execution, quizzes, progress tracking, and the AI tutor are available in the interactive view with JavaScript enabled.
Strategy Layer Begins
Why this lesson matters
In Course Introduction and Setting Up Development Environment, you built a C++ workspace. In Data Handling and Management in C++, you shaped market data into useful objects. In Connectivity with Financial Market APIs, you learned how the app can receive prices and send requests.
Now we add the brain of the system: the trading algorithm.
A trading algorithm should answer a focused question:
Given the latest market data and current strategy state, what action should we consider next?
For this lesson, we will keep the scope tight:
- Convert market data into signals
- Convert signals into order intents
- Keep simple position state
- Make the algorithm deterministic and testable
We will not deeply tune speed, backtest years of history, or build full risk controls yet. Those are coming in later lessons.

Algorithm Boundaries
Keep the algorithm small and honest
A common mistake is making the strategy function do everything:
- Parse market data
- Call APIs
- Calculate indicators
- Place orders
- Log results
- Manage reconnection
That becomes hard to debug.
Instead, treat the trading algorithm as a clean middle layer:
Market data object -> Strategy logic -> Order intent
The algorithm should not need to know whether prices came from a CSV, WebSocket, or REST API. You already handled those ideas in earlier lessons.
A useful C++ mental model
Design strategy code so it is close to a pure decision engine:
- Inputs: recent prices, latest tick/bar, current position
- Internal state: indicator values, previous signal, last action
- Output:
BUY,SELL, orHOLDintent
This makes your strategy easier to inspect before it ever touches real money.

SMA Crossover
First concrete strategy: moving average crossover
A simple algorithmic idea is:
- Calculate a short moving average
- Calculate a long moving average
- If short average rises above long average: bullish signal
- If short average falls below long average: bearish signal
This is not a recommendation to trade this strategy live. It is a clean learning example because it forces us to implement:
- Recent price storage
- Indicator calculation
- Signal generation
- Action output
The code below uses fixed sample prices and prints the decision at each step.
```cpp
#include <iostream>
#include <vector>
#include <iomanip>
#include <string>
std::string signalFromSMA(const std::vector<double>& prices, int shortWindow, int longWindow) {
if (prices.size() < static_cast<size_t>(longWindow)) {
return "HOLD";
}
double shortSum = 0.0;
for (int i = prices.size() - shortWindow; i < static_cast<int>(prices.size()); ++i) {
shortSum += prices[i];
}
double longSum = 0.0;
for (int i = prices.size() - longWindow; i < static_cast<int>(prices.size()); ++i) {
longSum += prices[i];
}
double shortAvg = shortSum / shortWindow;
double longAvg = longSum / longWindow;
if (shortAvg > longAvg) return "BUY";
if (shortAvg < longAvg) return "SELL";
return "HOLD";
}
int main() {
std::vector<double> stream = {100, 101, 102, 103, 102, 104, 106, 105, 107, 109};
std::vector<double> seen;
const int shortWindow = 3;
const int longWindow = 5;
for (double price : stream) {
seen.push_back(price);
std::string signal = signalFromSMA(seen, shortWindow, longWindow);
std::cout << "Latest price: " << std::setw(6) << price
<< " | Decision: " << signal << '\n';
}
return 0;
}
```
Signal Question
In a clean algo trading design, what should the strategy layer usually output?
Avoid Signal Spam
Signals are not automatically orders
Suppose your SMA logic says BUY for 20 ticks in a row. Should your system send 20 buy orders?
Usually, no.
The strategy needs state so it knows what it already did. A basic stateful strategy tracks:
- Current position: flat, long, or short
- Previous signal
- Whether a new action is actually needed
This separates a market opinion from a trade action.
Bullish signal + already long -> HOLD
Bullish signal + currently flat -> BUY
Bearish signal + currently long -> SELL
That distinction is one of the biggest steps from “indicator code” to “trading algorithm code.”

Stateful Strategy
Add position-aware decisions
Now let’s upgrade from raw signal output to an order-intent engine.
The strategy below:
- Reads a sequence of prices
- Calculates short/long SMA signals
- Tracks whether we are
FlatorLong - Sends
BUYonly when moving from flat to long - Sends
SELLonly when exiting a long position
This is still intentionally simple, but it demonstrates the core pattern used in larger trading systems.
```cpp
#include <iostream>
#include <vector>
#include <string>
using std::string;
enum class Position { Flat, Long };
enum class Intent { Hold, Buy, Sell };
string toString(Intent intent) {
switch (intent) {
case Intent::Buy: return "BUY";
case Intent::Sell: return "SELL";
default: return "HOLD";
}
}
double averageLast(const std::vector<double>& prices, int window) {
double sum = 0.0;
for (int i = prices.size() - window; i < static_cast<int>(prices.size()); ++i) {
sum += prices[i];
}
return sum / window;
}
Intent decide(const std::vector<double>& prices, Position& position) {
const int shortWindow = 3;
const int longWindow = 5;
if (prices.size() < static_cast<size_t>(longWindow)) {
return Intent::Hold;
}
double shortAvg = averageLast(prices, shortWindow);
double longAvg = averageLast(prices, longWindow);
bool bullish = shortAvg > longAvg;
bool bearish = shortAvg < longAvg;
if (bullish && position == Position::Flat) {
position = Position::Long;
return Intent::Buy;
}
if (bearish && position == Position::Long) {
position = Position::Flat;
return Intent::Sell;
}
return Intent::Hold;
}
int main() {
std::vector<double> stream = {100, 101, 102, 103, 104, 103, 102, 101, 100, 99, 101, 103};
std::vector<double> prices;
Position position = Position::Flat;
for (double price : stream) {
prices.push_back(price);
Intent intent = decide(prices, position);
std::cout << "Price " << price << " -> Intent: " << toString(intent) << '\n';
}
return 0;
}
```
State Matters
True or false: If a strategy already holds a long position, a repeated bullish signal should always create another buy order.
Strategy Interface
Make algorithms swappable
As your application grows, you may want to try different strategies:
- Moving average crossover
- Breakout logic
- Mean reversion logic
- News or event-driven logic
Instead of hardcoding one strategy everywhere, define a small interface. The rest of the application can call onPrice(...) without caring which strategy is underneath.
This is useful C++ design: keep the calling code stable while the algorithm changes.
```cpp
#include <iostream>
#include <memory>
#include <vector>
#include <string>
enum class Intent { Hold, Buy, Sell };
std::string toString(Intent intent) {
if (intent == Intent::Buy) return "BUY";
if (intent == Intent::Sell) return "SELL";
return "HOLD";
}
class Strategy {
public:
virtual ~Strategy() = default;
virtual Intent onPrice(double price) = 0;
};
class ThresholdStrategy : public Strategy {
private:
double buyAbove;
double sellBelow;
bool longPosition = false;
public:
ThresholdStrategy(double buyAbove, double sellBelow)
: buyAbove(buyAbove), sellBelow(sellBelow) {}
Intent onPrice(double price) override {
if (!longPosition && price > buyAbove) {
longPosition = true;
return Intent::Buy;
}
if (longPosition && price < sellBelow) {
longPosition = false;
return Intent::Sell;
}
return Intent::Hold;
}
};
int main() {
std::unique_ptr<Strategy> strategy = std::make_unique<ThresholdStrategy>(105.0, 101.0);
std::vector<double> prices = {100, 102, 106, 108, 104, 100, 103, 107};
for (double price : prices) {
Intent intent = strategy->onPrice(price);
std::cout << "Price: " << price << " | Intent: " << toString(intent) << '\n';
}
return 0;
}
```
Intent Blank
Fill in the blank: A strategy should usually create an order ______ before the execution layer sends anything to a broker.
Algorithm Checklist
What you can now build
You now have the core structure of an implementable trading algorithm in C++:
- Market data enters as clean objects
- Indicators summarize recent behavior
- Strategy state prevents repeated accidental actions
- The algorithm outputs
BUY,SELL, orHOLDintent - The rest of the app can call a stable strategy interface
Before moving on, check your algorithm
Ask these questions:
- Does it make the same decision for the same input sequence?
- Does it separate signal generation from API execution?
- Does it track position state?
- Does it print/log decisions clearly enough for inspection?
- Can the strategy be swapped without rewriting the whole app?
In the next lesson, Optimization and Performance Tuning, we’ll focus on making these components faster and more efficient without changing their meaning.
