Algorithmic Thinking
9 min read
Turn your discretionary strategy into If/Then logic -- the foundation for automation, backtesting, and elite-level clarity.
9 min read
Turn your discretionary strategy into If/Then logic -- the foundation for automation, backtesting, and elite-level clarity.
Prereq: Build a Simple Trading Strategy. Next: Building a Trade Plan.
Professional traders don't guess.
They follow systems — rules built on logic, probability, and repeatability. Even discretionary traders improve dramatically when they think like algos.
The goal isn't to build a robot. The goal is to make your decision-making repeatable, measurable, and scalable.
In this lesson you will learn:
It's not about coding.
Algorithmic thinking means turning your trading ideas into conditional logic:
"If X and Y and Z happen → Then I enter. If not → I wait."
It removes doubt. It removes noise. It builds confidence and repeatability — but only if every predicate reduces to numbers a script could compute.
If BTC is in a bullish 1H structure (close > EMA(200, 1H) sustained for 24 bars) And the most recent swing low (lowest of last 20 bars, offset 1) is broken intra-bar And price reclaims that broken low with a bullish engulfing close within 3 bars Then enter long with a stop below that swept low.
That's not the same lesson as "long on a bullish reclaim." Every clause has a number.
Take one setup you trade. Break it into testable steps where each predicate has (a) a data series, (b) a math expression, (c) a threshold, and (d) a lookback.
MSS = a higher-low gets violated in an uptrend. The discretionary version is "structure breaks"; the operational version is below. See Understanding Order Flow and DOM for the underlying microstructure.
IF
- HTF bias = (close[1H] > EMA(200, 1H) for last 24 bars)
AND
- Swing low broken: low[i] < min(low[i-20:i-1]) within last 5 bars
AND
- Reclaim: next close > broken low within 3 bars
AND
- Engulfing: close > open AND close > high[i-1] AND open < low[i-1]
THEN
- Enter long at engulfing-bar close
- Stop below the broken low
- Target: 2R or previous swing high (whichever is closer)
This is strategy as a process. Not a feeling.
Warning: writing "MSS" or "BOS" in pseudocode does not make it algorithmic. Until every predicate reduces to numbers a script can compute, you have a checklist, not an algorithm.
Predicates like support holds, structure breaks, delta shifts, liquidity is taken read like rules but are pattern judgments. To make them algorithmic, name:
If you can't fill in all four, you're still discretionary — just with extra steps.
Filters tighten execution and remove weak trades. They also add degrees of freedom — and every degree of freedom you add inflates your in-sample fit and your live drawdown.
Possible additional IF clauses, each with the four-part rule above:
You can also define rules for:
Every extra filter cuts in-sample drawdown and tends to inflate live drawdown. Three filters with strong individual rationale beat seven filters tuned together.
Once your strategy is defined in clean If/Then steps, you can move it down the formalization ladder.
| Stage | Tool | Code required | Notes |
|---|---|---|---|
| Single-symbol equity-curve sanity check | TradingView Pine v5 | Light | No realistic fees, no partial fills |
| Vector-style multi-symbol research | vectorbt | Yes (Python) | Fast, no event-driven realism |
| Event-driven, broker-realistic | NautilusTrader | Yes (Python/Rust) | Production-grade backtest + live |
| Classic event-driven | Backtrader | Yes (Python) | Mature, slower, large community |
| Cloud-hosted | QuantConnect | Yes (C#/Python) | Comes with data, fees, slippage models |
(Pine reference: tradingview.com/pine-script-reference/v5.)
//@version=5
strategy('MSS Long', overlay=true)
htf_bull = request.security(syminfo.tickerid, '60',
close > ta.ema(close, 200))
swept_level = ta.lowest(low, 20)[1]
swept = low < swept_level and close > swept_level
engulf = close > open and close > high[1] and open < low[1]
if htf_bull and swept and engulf
strategy.entry('long', strategy.long)
sl = low[1]
strategy.exit('x', from_entry='long', stop=sl,
profit=close + (close - sl) * 2)
Same rule in Python pseudocode (data-frame style):
df['htf_bull'] = (df['close_1h'] > df['ema200_1h']).rolling(24).min().astype(bool)
df['swept_lvl'] = df['low'].rolling(20).min().shift(1)
df['swept'] = (df['low'] < df['swept_lvl']) & (df['close'] > df['swept_lvl'])
df['engulf'] = (df['close'] > df['open']) & \
(df['close'] > df['high'].shift(1)) & \
(df['open'] < df['low'].shift(1))
entries = df['htf_bull'] & df['swept'] & df['engulf']
# stop = df['low'].shift(1); target = entry + 2 * (entry - stop)
What is missing from both snippets and must be added before any capital is at risk:
For all of those, move out of Pine and into NautilusTrader, vectorbt, or Backtrader.
Gates before live capital:
A rule-based system loses money more efficiently than a discretionary trader. Three traps to name:
Typical decay of a live edge versus its backtested Sharpe ratio. Source: Lopez de Prado, Advances in Financial Machine Learning, ch. 11 (deflated Sharpe).
Tweak slowly and retest is the textbook in-sample optimization loop. Without an out-of-sample fold or a walk-forward window, you're not validating an edge — you're memorizing the past.
Systematization is not monotonically good. The human still wins when:
Pure systems lock you to the past distribution. Humans can update faster — at the cost of consistency. Mature traders ride both.
| Approach | Consistency | Regime-adapt | Backtestable | Capital scale |
|---|---|---|---|---|
| Pure discretionary | Low | High | No | Low |
| Pure systematic | High | Low | Yes | High |
| Hybrid (rules + override budget) | Medium-High | Medium | Partial | High |
The hybrid row is where most professional discretion actually lives: a written rule set, plus a small, budgeted number of overrides per month, journalled so you can later separate skill from luck.
Many traders say, "I'm a discretionary trader."
But if you have no logic behind your discretion, you have no audit trail.
Untrained discretion = unmeasured judgment — you can't tell whether the call was skill or luck. Algorithmic thinking gives you the audit trail.
That audit trail is the entire reason to do this work, even if you never automate. It also lets you track and optimize setups over time.
Once your logic is written:
If you override, the override only counts if it was budgeted in advance. Surprise overrides are not discretion — they're tilt with a story.
Algorithmic thinking means turning trading ideas into conditional logic — "if X and Y and Z happen, then I enter; otherwise I wait" — where every predicate (X, Y, Z) reduces to a numeric rule a script could compute.
No. Pseudocode and a spreadsheet are enough to capture rule logic. Coding (Pine, Python) only becomes necessary when you want backtests with fees, slippage, and walk-forward analysis, or when you want to automate.
Pick one setup. For each clause, name the data series, the math expression, the threshold, and the lookback window. If a clause refuses to collapse to those four parts, it is still pattern-recognition — flag it as discretionary rather than dressing it up as code.
Systematic trading executes a written rule set the same way every time, which gives high consistency and a backtestable record at the cost of regime adaptability. Discretionary trading uses human pattern judgment, which adapts faster to novel regimes but produces no audit trail unless explicitly journalled.
On consistency, yes. On returns, not necessarily. Pure systems are locked to the historical distribution they were fit on; humans can update faster when regime shifts have no in-sample analog. Most professional traders run a hybrid with a budgeted override allowance.
For multi-symbol, fee-accurate, walk-forward analysis, use vectorbt for vectorised research, NautilusTrader or Backtrader for event-driven realism, or QuantConnect for cloud-hosted backtests with built-in data and slippage models.
Pick the setup you took most often last month. Write its IF/THEN with every predicate operationalized to a number — data series, math, threshold, lookback. If a predicate refuses to collapse to math, you've found the part of your edge that's still pattern-recognition. Flag it, and either define it or accept it stays discretionary.
From there, the natural next lesson is Building a Trade Plan, which folds the rule set into a complete written playbook (risk, psychology, evidence-of-edge).