Lesson 3: Parsing Buy and Sell Signals in 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 Text To Intent
Why this lesson matters
In Lesson 2: Reading Gmail API in C++, you got message IDs and decoded Gmail body text.
Now the job changes:
email body text -> trading signal object
A message like:
ALERT: BUY AAPL qty=25
should become something your C++ program can reason about:
- direction:
BUY - symbol:
AAPL - quantity:
25
This is the bridge between mailbox data and the trading pipeline we introduced in Lesson 1: Introduction to API in C++.

Define The Signal
Parse into a small contract
Before writing parsing code, decide the shape of the result.
For this lesson, we will use a compact signal model:
Field Example Meaningdirection
BUY
Trading action
symbol
AAPL
Instrument ticker
quantity
25
Number of shares/contracts
This keeps your parser honest. It should not return vague text. It should return either:
- a valid structured signal, or
- a clear failure.
That mindset matters in algorithmic trading because ambiguous text can become expensive behavior.

First Regex Parser
Match one known alert format
Start with a narrow format you control:
ALERT: BUY AAPL qty=25
A regular expression is useful here because the signal has repeated structure:
- fixed prefix:
ALERT: - direction:
BUYorSELL - ticker symbol: uppercase letters
- quantity: digits after
qty=
This standalone example parses one email body and prints the structured result.
```cpp
#include <algorithm>
#include <iostream>
#include <regex>
#include <string>
struct Signal {
std::string direction;
std::string symbol;
int quantity;
};
std::string upper(std::string s) {
std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) {
return std::toupper(c);
});
return s;
}
int main() {
std::string body = "ALERT: BUY AAPL qty=25";
std::regex pattern(
"^\\s*ALERT:\\s*(BUY|SELL)\\s+([A-Z]{1,5})\\s+qty=(\\d+)\\s*$",
std::regex::icase
);
std::smatch match;
if (std::regex_match(body, match, pattern)) {
Signal signal{
upper(match[1].str()),
upper(match[2].str()),
std::stoi(match[3].str())
};
std::cout << "Parsed signal" << std::endl;
std::cout << "direction=" << signal.direction << std::endl;
std::cout << "symbol=" << signal.symbol << std::endl;
std::cout << "quantity=" << signal.quantity << std::endl;
} else {
std::cout << "No valid trading signal found" << std::endl;
}
return 0;
}
```
Parser Responsibility
A Gmail message body contains this text:
ALERT: SELL MSFT qty=10
What is the parser's main responsibility in this lesson?
Normalize Then Validate
Two separate checks
A strong parser does not stop at "the regex matched."
Use two phases:
1. Normalize
Make equivalent inputs consistent:
-
buy->BUY -
aapl->AAPL - extra leading/trailing spaces -> ignored
2. Validate
Reject values that should not become trading instructions:
- quantity is
0 - symbol is empty or too long
- direction is not
BUYorSELL - message format is not recognized
In trading systems, this separation is important: normalization makes data consistent; validation keeps bad data out.

Parsing Guarantees
True or false:
If a message contains the word BUY anywhere in the email body, the program should treat it as a valid buy signal.
Handle Bad Messages
Most messages are not signals
Your Gmail inbox may contain newsletters, confirmations, promotions, and normal emails.
So your parser should expect failures as normal behavior:
promo: buy one get one free -> reject
ALERT: HOLD AAPL qty=10 -> reject
ALERT: BUY AAPL qty=0 -> reject
ALERT: SELL TSLA qty=5 -> accept
A good rule for this stage:
If the message is unclear, do not trade.
For now, we only parse and log. Later lessons can connect the accepted signal to REST or FIX-style API workflows.

Regex Direction
Complete the direction group in this regex fragment:
ALERT:\s*(____)\s+([A-Z]{1,5})\s+qty=(\d+)
It should match only the two supported actions.
Batch Parse Emails
Connect to Lesson 2 output
In Lesson 2, your program decoded Gmail body text.
Now imagine you have several decoded bodies in a std::vector<std::string>. The parser can scan them, accept valid signals, and skip everything else.
This standalone example uses std::optional<Signal> so a parse can cleanly mean either:
-
Signalexists, or - no valid signal exists.
```cpp
#include <algorithm>
#include <iostream>
#include <optional>
#include <regex>
#include <string>
#include <vector>
struct Signal {
std::string direction;
std::string symbol;
int quantity;
};
std::string upper(std::string s) {
std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c) {
return std::toupper(c);
});
return s;
}
std::optional<Signal> parseSignal(const std::string& body) {
std::regex pattern(
"^\\s*(ALERT:\\s*)?(BUY|SELL)\\s+([A-Z]{1,5})\\s+(qty=)?(\\d+)\\s*$",
std::regex::icase
);
std::smatch match;
if (!std::regex_match(body, match, pattern)) {
return std::nullopt;
}
Signal signal{
upper(match[2].str()),
upper(match[3].str()),
std::stoi(match[5].str())
};
if (signal.quantity <= 0) {
return std::nullopt;
}
return signal;
}
int main() {
std::vector<std::string> decodedBodies = {
"ALERT: BUY AAPL qty=25",
"promo: buy shoes today",
"SELL TSLA qty=0",
"BUY MSFT 10",
"ALERT: HOLD NVDA qty=2"
};
int accepted = 0;
for (const auto& body : decodedBodies) {
std::cout << "Message: " << body << std::endl;
auto signal = parseSignal(body);
if (signal) {
++accepted;
std::cout << " ACCEPTED -> "
<< signal->direction << " "
<< signal->symbol << " qty="
<< signal->quantity << std::endl;
} else {
std::cout << " rejected" << std::endl;
}
}
std::cout << "Accepted signals: " << accepted << std::endl;
return 0;
}
```
Lesson Wrap
What you can now do
You have moved from decoded Gmail text to structured trading intent.
You practiced how to:
- define a small
Signalmodel - parse
BUYandSELLalerts - normalize direction and symbol text
- validate quantity and format
- reject unclear messages safely
- batch-process decoded email bodies
The key lesson: parsing is a safety boundary. It protects the rest of your trading pipeline from vague or malformed input.
Next, Lesson 4: Working with REST APIs in C++ will focus on API calls beyond Gmail, but this signal object will remain the kind of clean data you want to pass forward.
