AUTONOMOUS SYSTEM · AWS eu-west-2 · LIVE SINCE 2026-07-16
Trading on evidence, not vibes.
A trend-following bot that decides once a day, executes on its own, and reports what it did. Every proposed improvement gets pre-registered, measured out-of-sample, and usually thrown away. Eight have been tested. Eight were rejected. It still runs the boring strategy — that is the one the evidence supports.
The tape, live
Daily candles streaming from Binance. The two moving averages are the bot's entire opinion of the market: when the fast one crosses the slow one at a bar close, it acts.
- EMA 20 · fast
- EMA 100 · slow
- up
- down
02 — WHAT IT RUNS ON
No servers, no babysitting
The whole system is four Lambda functions on a schedule, one DynamoDB table, and enough alarms that it tells me before I notice. It is defined in Terraform end to end, so it can be destroyed and rebuilt from nothing.
-
0
Lambda functions
Paper bot, 4-hour venue bot, shadow bot, status endpoint. Nothing else is running.
-
0
Terraform resources
Every queue, alarm, role and DNS record is code. Remote state in S3.
-
0
CloudWatch alarms
Errors, silence and dead letters each page me by email. Silence is the one that matters.
-
0
DynamoDB table
Single-table design. State, decisions and an append-only fill log share one key space.
-
0
CI workflows
Tests, secret scanning, and separate deploys for backend, infra and site.
-
$0
Per month, all in
The bot costs about $7 a year to operate. That number is the reason the design looks like this.
03 — HOW ONE DECISION HAPPENS
Seven steps, once a day
This is a real sequence, and the order is the whole point: the bot never sees a price that has not finished forming.
-
01
The bar closes
00:00 UTC. EventBridge Scheduler fires the Lambda ten minutes later, not at the boundary — exchanges are late sometimes.
-
02
Only closed candles are read
The in-progress bar is dropped before anything is computed. Reading it is how a backtest quietly starts cheating.
-
03
EMA 20 against EMA 100
Fast above slow means hold long; fast below means stand aside. That is the entire signal.
-
04
Compare with durable state
The target is checked against what DynamoDB says the bot is actually holding, not against what it thinks it did last time.
-
05
Act, if anything changed
An order goes to the Binance demo venue, and the fill comes back with a price and an order id. Both are written down.
-
06
Write the row, then publish
Decision, price, position and equity are persisted. The status Lambda serves them; this page reads them.
-
07
If it goes quiet, it says so
A missing invocation raises an alarm, the same as an error would. A bot that dies silently is worse than one that loses money.
04 — THE PART NOBODY PUTS ON A PORTFOLIO
Eight upgrades tested.
Eight rejected.
Each of these was a good idea with real literature behind it. Each was pre-registered — the pass criteria written down before the result was known — and each failed honestly out of sample. Keeping the list is cheaper than relearning it.
| Candidate | The idea | Why it died |
|---|---|---|
| Volatility targeting | Scale exposure inversely to recent variance. | Cuts drawdown exactly as the literature promises, but Sharpe drops at every target level in the 2022+ regime, and turnover doubles. |
| EMA speed ensemble | Blend several EMA pairs so no single parameter choice can be lucky. | Passed the screen, then failed the honest harness: three of four pre-specified checks rejected it. |
| Regime filter ×3 | Only take the signal when a 200-day trend agrees. | All three variants cut Sharpe. The one that did improve drawdown still cost about 0.05 Sharpe to get it. |
| Mean reversion ×4 | Buy the dip instead of following the trend. | Sharpe 0.29–0.57 on daily bars against roughly 1.0 for plain EMA. On hourly bars: −1.3 to −3.8, and −100% return everywhere. |
| 4-hour timeframe | More bars should mean a faster verdict on whether this works. | More bars, not more independent information. The proof does not arrive sooner. |
| Short leg | Trade the downside too instead of sitting in cash. | Loses money net of costs. Standing aside beat being clever. |
| Maker-only orders | Post limit orders and save the taker fee. | Worth nothing at this size and cadence — and the fee model understated short-side costs, which is its own lesson. |
| Meta-labeler | A model on top of the strategy, sizing each trade by predicted quality. | Zero discrimination: correlation with outcomes −0.01. Not one of 128 events was actually attenuated — the "filter" was a flat 1.3× leverage in disguise, and the five biggest winners all landed at the bottom of its ranking. |
The strategy running today is the one from day one. That is not stubbornness — it is the only candidate that has not yet failed a test.
Built and operated by one person
Infrastructure, strategy research, execution layer and this page. If you want the details, the code and the write-ups are public.