Skip to main content
Williams BalogunGet in touch
Case Study — Flagship / 03 · Personal research

Verdkt

An AI algorithmic trading system for FX & crypto. I built it rigorous enough to prove its own strategy has no edge, then trusted that result instead of betting real money on a hunch.

Role Solo · full-stack, AI & quant researchDiscipline Systematic trading · statisticsYear 2026Status Demo-only, by design
forex-ai-bot — python main.py forex
$ python main.py forex
┌─ Starting Bot ──────────────────────────────┐ │ Forex AI Trading Bot (mode: forex) │ │ session: London · news-gated · demo │ └──────────────────────────────────────────────┘
Scan Results
PAIR D1 SIGNAL AI SETUP EUR_USD ↑ long confirm wait GBP_USD ↑ — skip no-trade USD_CAD ↓ short confirm ARMED AUD_USD ↑ long veto:trend skip USD_JPY · suspended — —
Balance: $9,463.00 Open P/L: -$18.42 Win rate: 51% Total P/L: -$537.10
scanning M15 … next tick 00:47
01 — At a glance

Verdkt is a production-grade, multi-timeframe trading system on MetaTrader 5, and a rigorous investigation into whether a retail mechanical strategy can actually beat the market.

The headline result is an odd one for a trading project. After exhaustive, walk-forward-validated testing, no robust edge was found, and the repo shows exactly how I got there. I would rather ship a negative result I can trust than a backtest that only flatters me.

Role
Solo · full-stack, AI & quant research
Surface
Live bot (FX + crypto) + a research engine
Verdict
No demonstrable edge, so it stays on demo
Stack
PythonMetaTrader5pandas-tanumpyasyncioSQLiteGroqAnthropicTelegram
5yr
walk-forward history across 2021–2026, multi-regime
9+
strategy variants tested end-to-end, no look-ahead
0
that beat the cost / noise floor
+0.10R
the pre-registered bar none could clear
02 — The question

Most retail bots
lie to themselves.

It is easy to build a backtest that prints money. Tune a few parameters against the same slice of history you scored on, and any strategy looks brilliant. That isn't an edge. It's a memory of one lucky window, and it costs real capital the moment the regime turns.

I didn't want a bot that felt profitable. I wanted to know the truth: does mechanical price prediction on liquid FX and crypto have a durable edge, or doesn't it? So I built the system to answer that honestly, and to be hard to fool, including by me.

Rule 01

No look-ahead. Entries decided at bar close, filled next-bar open. The backtest may only know what the live bot knew.

Rule 02

Out-of-sample or it's noise. Any improvement must survive data it never touched, and hold across both halves of the window.

Rule 03

Pre-register the bar. The pass/fail threshold was set before looking at results. No moving the goalposts.

03 — How the bot decides

One law, five gates.

Live loop

Every scan walks the same pipeline. The daily trend is the law; the AI layer advises but can never overrule it.

01

Trend law

D1 direction

The daily trend is the law. Nothing trades against it.

02

Context

H4 · H1

Higher-timeframe structure and momentum decide whether a setup qualifies.

03

Timing

M15

ATR-based entry timing, structure-based (swing) take-profits, trailing lock.

04

Risk gate

Sizing & R:R

Fixed-fractional sizing; R:R and stop distance validated before anything arms.

05

AI review

Gated

An LLM reviews the setup, but code forbids it from overriding the trend law.

risk/manager.py — position sizing
def position_size(balance, risk_pct, stop_distance, pip_value):
 risk_amount = balance * risk_pct # e.g. $100 on a $10k demo
 units = risk_amount / (stop_distance * pip_value)
 return round_to_contract(units) # JPY, USD-quote & crypto aware

# verified: $100 risk · $1,200 BTC stop -> 0.08 BTC -> ~$96 realized at stop
04 — The research engine

Did it actually have an edge?

The most valuable part of the repo isn't the live bot. It's the framework built to answer that question without fooling itself. Two results tell the whole story.

The one “edge,” split by time
0.00R+0.131R−0.017RFirst halfSecond half

The single positive-expectancy configuration the ablation found (trade against D1, pullback-only). Cut the window in half and it flips sign: +0.131R becomes −0.017R. That's what overfitting looks like.

Every strategy family vs. the bar
bar to clear · +0.10R →No-edge baseline (control)-0.039ROpening-range breakout-0.040RSession / time-of-day-0.050RADX regime-matching-0.060RLow-vol mean-reversion-0.070REMA-cross trend-0.080RCrypto ORB (real spread)-0.102R0.00R−0.12R

Out-of-sample expectancy for each hypothesis tested. All cluster at the −0.04R to −0.10R cost / noise floor, indistinguishable from doing nothing and paying the spread. None come near the pre-registered +0.10R bar.

backtest/research — the pre-registered bar
# set BEFORE looking at any results — no moving the goalposts
PASS = dict(
 oos_expectancy_R = 0.10, # must beat the spread by a real margin
 min_trades = 200, # no edge claims on thin samples
 held_out = "> 0", # survive data it never touched
 folds = "majority positive",
)

# a deliberately edgeless baseline scored -0.039R — the framework
# leaks no phantom edge. Nothing real ever cleared the bar.

One lead did look real: an oil→CAD intermarket signal at +0.234R in-sample. A confirmation test across the rest of the CAD complex correctly killed it, exposing a multiple-testing mirage. The system was built to catch exactly that.

That engine outlived the bot. I rebuilt its core as a tool anyone can run in the browser: drop in a trade log and get the same honest verdict, with nothing uploaded. Try Verdkt ↗

05 — Under the hood

The statistical hygiene.

01No-look-ahead harness

Replays the exact live gate stack over historical candles. Entries decided at bar close, filled next-bar open, stops resolved against the level as it stood entering each bar. Scored in R-multiples, so the result is currency-agnostic.

R-multiplesNext-bar fillNo look-ahead
02Walk-forward + held-out

Expanding train/test windows over 5 years of H1 across 6 pairs, plus a held-out final slice, against a pre-registered pass/fail bar. A deliberately edgeless baseline scores ≈ −cost, which proves the framework leaks no phantom edge.

Walk-forwardPre-registeredBaseline control
03Out-of-sample stability split

The entry lab ablates each gate and only trusts a change if it holds in both halves of the window. This caught several “improvements” that were pure regime noise, the difference between an edge and a lucky window.

AblationOOS splitRegime-robust
04Risk-first position sizing

Fixed-fractional risk per trade, correct across JPY crosses, USD-quoted pairs and crypto contract sizing. Verified: $100 risk on a $1,200 BTC stop → 0.08 BTC → ~$96 realized at the stop.

Fixed-fractionalMulti-assetVerified
05AI analyst, hard-gated

A Groq / Anthropic layer reviews each mechanical setup, but is gated by code so it can never trade against the trend rule. Mechanical law and probabilistic opinion stay cleanly separated.

GroqAnthropicCode guardrails
06Broker-agnostic execution

MetaTrader 5 implemented end-to-end behind a provider interface (Deriv / OANDA stubbed), asyncio scan + protection loops, an SQLite decision ledger, and Telegram alerts.

MetaTrader5asyncioSQLite
06 — What it proved

It did what a rigorous system should: it proved its own hypothesis false before real capital was ever at risk.

The finding

Predicting direction on a few liquid instruments from technical indicators has no durable edge, because those markets are too efficient. Real edges come from speed, scale, or structural arbitrage, not chart prediction.

What I'm proud of

Building the discipline to kill my own best idea on the evidence (walk-forward, held-out, pre-registered) instead of shipping a lie that felt good.

The takeaway

The transferable asset was never the bot. It was directing AI to build a full quant stack (data, execution, an AI layer, and an honest research engine) end to end.