Most hobbyist trading bots die the same way. Someone writes a strategy, backtests it over a favorable stretch of history, tunes the parameters until the equity curve looks beautiful, and deploys it. The curve was beautiful because the parameters were fitted to that exact slice of the past. The market moves on. The bot does not.

TradeBot is a Floodlight Labs research project built around the opposite premise: the strategy is the easy part, and the real engineering problem is the machinery that decides whether a change to the strategy is actually an improvement.

That machinery — the harness — is the product.

What the bot actually does

The trading system itself is deliberately conventional. It’s a Node.js service that consumes 1-minute equity bars from a brokerage data stream (currently running against Alpaca’s paper-trading environment), maintains rolling indicator state, and produces one decision per bar.

The core signal is a moving-average cross: a fast MA crossing a slow MA proposes an entry. But a raw MA cross on 1-minute data fires constantly, and most crosses are noise. So every proposed entry has to survive a gauntlet before it becomes an order:

  • A volume filter — the bar must show real participation, not drift.
  • A volatility floor — no entries when the ATR says nothing is moving.
  • Trend alignment — the signal must agree with a longer-horizon moving average.
  • Time-of-day windows — no trading in the chaotic minutes after the open or before the close.
  • A backoff state machine — if crosses are arriving faster than a cooldown window allows, the market is chopping, and every cross gets skipped until it settles down.

Most signals never make it through. That selectivity turns out to be the profit engine — more on that below.

Around the core, the system carries a set of levers that experiments have earned over time: a mean-reversion mode that only activates in low-trend regimes and fades extended moves back toward the mean, confidence-based position sizing that trades larger when the entry aligns with the daily-scale regime, a breakeven-and-trail stop ratchet, and an equity brake that automatically cuts position sizing after a drawdown and keeps it cut until the curve recovers. Stops are sized from daily ATR rather than 1-minute ATR — positions here are held across sessions, and a stop sized from intraday noise gets clipped by ordinary overnight swings.

Every one of those levers exists in the config as an option that can be switched off, because every one of them started life as a hypothesis.

The harness is the product

Here is the part that makes the project interesting.

Any change to the strategy — a new lever, a parameter shift, a new filter — has to pass through an optimizer and a set of promotion gates before it touches the running profile.

The optimizer is a multi-core hill climber. It starts from the currently promoted parameter set, evaluates the full neighborhood of one-step perturbations across every tunable parameter in parallel worker threads, moves to the best neighbor, and repeats until it finds a peak. Standard stuff. What matters is what it’s climbing on.

Every candidate is backtested across regime-labeled periods spanning more than five years: a bear year, a bull year, a bull half followed by a choppy half, a recent full year — and two windows the climb is never allowed to train on. One is a fully held-out out-of-sample year. The other is the current year-to-date, running right up to today.

A candidate is only promotable if:

  • It beats buy-and-hold — the score is alpha, not raw profit, because a long-biased strategy that merely rides a bull market has learned nothing.
  • It’s profitable on the held-out year it never trained on.
  • It’s profitable on the current window — the market as it exists right now, not as it existed in the training data.
  • It trades enough in every period to be statistically meaningful.
  • It doesn’t trade too much overall. This one earned its place: the observed overfit failure mode is the search teleporting to a hyperactive thousand-trade regime whose “edge” only exists because backtest fills are frictionless. A healthy selective profile trades a few hundred times across all periods. Candidates above the cap are pruned mid-search and blocked at promotion.
  • Its worst single-period drawdown stays under a hard ceiling.

A separate plateau tool exists because hill climbs select peaks, and peaks can be knife-edges. After a promotion, it re-evaluates the entire ±1-step neighborhood of the winning parameters through the exact same scoring pipeline and reports per-parameter sensitivity. A profile that collapses when any parameter drifts by one step isn’t a strategy — it’s a coincidence. Only plateaus are trustworthy.

A commit log full of dead ideas

The discipline that ties it together: every experiment becomes a commit, and the commit message records the verdict — including, especially, the failures. Recent history reads like a lab notebook:

  • loss-streak damper lever (tested: rejected at all probed settings, default off)
  • regime-conditioned loss-streak damper (tested: rejected, damage just migrates)
  • overnight gap-fade leg (tested, rejected on interaction cost)
  • limit-entry reversion experiment (rejected)
  • tunable grind bypass (tested: current setting is the local optimum)

That “damage just migrates” one is representative. The hypothesis was intuitive: after consecutive losses, trade smaller. It’s the kind of rule every trading book recommends. Tested against the gates, it failed at every setting — the losses it avoided in one regime simply reappeared in another. The intuition was fine; the market didn’t care. Without the harness, that lever would be live right now, quietly costing money while feeling prudent.

Meanwhile the ideas that survived promotion are the ones with numbers attached: a breakeven-trail shelf, an equity brake that unlocked an entire bear-market configuration, sizing rules that only apply in the regimes where they help. Each one is in the log with its out-of-sample and current-window results, so any future regression has a paper trail.

Most experiments die. That’s the system working.

What the harness has taught us

A few findings that only fell out of running this loop repeatedly:

The filtered exits are the profit engine. The obvious architecture — enter on signal, exit on a protective ATR stop — underperformed badly. Requiring exits to pass the same filter gauntlet as entries means the system rides winners through noise instead of getting shaken out. The edge wasn’t in predicting entries better; it was in refusing to leave good positions for bad reasons.

Time scale mismatches are silent killers. Stops sized from 1-minute ATR looked reasonable and backtested fine over short windows, but positions held for days kept getting clipped by ordinary overnight movement. The stop needs to live on the same time scale as the hold.

Overfitting has a fingerprint. When the optimizer finds a configuration that trades an order of magnitude more often than usual, the extra trades are almost never edge — they’re the search exploiting frictionless backtest fills. Trade count became a first-class gate.

Peaks lie, plateaus don’t. The single best-scoring parameter set is routinely a knife-edge. The neighborhood around it tells you whether you found structure or noise.

Why this fits Floodlight Labs

TradeBot runs on the same philosophy as everything else in the lab: small surface area, lightweight infrastructure, and systems that improve through operation. It’s a single Node.js codebase on modest hardware, with a multi-core optimizer instead of a compute cluster, and a git log instead of a research team.

But the deeper connection is methodological. Every Floodlight project is ultimately a filtering problem — separating a thin layer of signal from an ocean of noise, whether the noise is parked domains, bot traffic, or plausible-looking backtest results. TradeBot just points that discipline at the hardest noise source of all: a market that actively punishes pattern-matching on the past, and a builder’s own conviction that this idea, surely, is the one that works.

The harness exists because that conviction is wrong more often than it feels like it should be. The commit log keeps the receipts either way.


TradeBot is an internal research project. Nothing here is investment advice, and the system currently trades in a paper environment — the point is the engineering, not the returns.