Not waiting for the next open

Rereading yesterday’s director-buying post, the Burberry example bothered me: the notice came out at 13:00 on a Friday, and Gecko didn’t buy until Monday’s open. How often does that happen? Most of the time, it turns out - two-thirds of the big director buys are announced while the market is open, and on 5-minute prices the shares kept rising, by about 0.7% on average, between just after the announcement and the next open.

So I had Gecko backtest buying a few minutes after each announcement instead. It made +£6,358 against +£5,360 waiting for the next open, and it held up when I made it harder: notices only reach the FCA archive about 12 minutes after they’re published, but buying 5, 15 or 25 minutes later made almost no difference, and measuring the stop from the actual entry price didn’t make the gap go away either. Burberry would have been bought at 13:20 that Friday at 1,111p rather than 1,156p on Monday.

Gecko now watches the FCA archive every two minutes through the trading day and sends a director-buy tip to the paper account as soon as one appears. The post is updated with the new numbers and a chart of the Burberry trade. (Director buying)

A real edge at last - and the cost of trading it

The directors’ notices finished downloading overnight - ten years, 33,000 of them - and they gave Gecko something the chart patterns never did: an effect that held on stocks it had never seen. When directors make large open-market purchases, the shares go on to beat the market. It’s modest and it has shrunk since 2021, but it’s the first edge Gecko has found from outside the price chart. (Director buying)

The rest of the day went on one of Tom Hougaard’s strategies, the Advanced School Run: put a buy order above and a sell order below the DAX’s 4th five-minute bar, each one the other’s stop. On five-minute bars the answer was blurred, because a single bar often hit both the entry and the stop, so I had Gecko download one-minute bars back to 2012 for the DAX, the Dow, the Euro Stoxx 50, the Nikkei and the Hang Seng - about thirteen million of them, downloading from yesterday afternoon through the night. That settled it. Before costs the strategy really does have an edge, about +0.15R a trade on the DAX, and much the same in Europe and Asia.

Then I measured what it would actually cost me to trade it. IBKR’s historical bid and ask prices showed a DAX CFD spread of about 4 points at 9:20, and with commission a round trip comes to about 6.5 points - almost exactly the size of the edge. After costs it makes nothing anywhere. The only way it might pay is through futures, which I don’t have permission to trade yet. (Advanced School Run)

Late last night I also added the head-and-shoulders top to yesterday’s post, the version most people picture, as a short sale after a rise. It did slightly better on the stocks Gecko was developed on and lost on every version on the ones it hadn’t seen, so the verdict stays a fail, both ways up. And the homepage got simpler: each finding now has its title and a short teaser, and the list of recent backtests that just repeated the findings is gone. (Head and shoulders)

Directors' dealings, and one more famous shape crossed off

Today I started on an idea with an economic reason behind it rather than another chart shape: directors buying shares in their own company. UK rules mean every dealing by a director has to be announced publicly, and the FCA keeps the lot in a free archive going back to 2013. I pulled all of 2025’s notices for the stocks Gecko follows - about 3,400 of them - and had Gecko sort every dealing by what it really was.

The surprise was how little of it is a director actually putting their own money in. Most “dealings” are share awards, bonus shares, monthly employee plans and directors’ fees paid in shares. Under one in ten are genuine purchases on the open market. Even so, that left 208 sizeable buys (£50k or more) across 104 stocks in a single year, and 88 of them involved the chief executive or finance director. My first sorting rules got a third of the “buys” wrong, until I separated out the plan purchases dressed up as buys. The full ten years of notices are downloading overnight, so next I can test what the share price actually does in the weeks after a director buys.

I also finished the Schwager chapter on tops and bottoms with the head and shoulders, the most famous pattern of them all. I built it exactly by the book, including his two warnings: don’t buy before the neckline breaks, and only trust it after a big fall. Gecko found 955 of them and they look the part, but they lost a little after costs and were no better than buying on random days. Even the twelve cleanest-looking ones went anywhere from -19% to +34%. One more shape crossed off. (Head and shoulders)

Shapes don't predict, news does

Today was the day I tested the chart patterns everyone talks about. I started with an idea of my own, SWBO (sideways breakout): find a stock that has gone sideways in a tight range, wait for it to break out and stay out for a day or two, then buy. The confirmation idea did help a little, but after costs the best version just about broke even, on shares and on index CFDs. On the indices one version looked great until the random-entry test showed the profit was just the market rising.

Then the classics. The cup and handle, from O’Neil’s book, turned out to be codeable, and the cups Gecko found looked convincing to my eye, but there were only 24 in ten years and they didn’t lead anywhere. Bull flags were easy to find, nearly 2,000 of them, but on their own they were a coin toss. Finally I asked whether a proper academic definition would do better: Lo, Mamaysky and Wang’s ten patterns from the Journal of Finance. Precise and reproducible, but the results flipped depending on one smoothing setting. (Cup and handle, Bull flags, Textbook chart patterns)

The pattern behind the patterns: the only time a shape made money, there was a volume spike hiding inside it. Shapes don’t predict; news does. So technical analysis has to work with fundamentals, not instead of them. To find out what news actually sits behind each EVS spike, I’ve started labelling 50 of them by hand, and Gecko now keeps the headlines for every spike day so it builds its own news history.

Reading Tom Hougaard’s Best Loser Wins made me wonder about trending versus ranging markets. Gecko now measures whether the FTSE is trending or going sideways and updates it every night. EVS trades did noticeably better when the market was going nowhere, though using that as a filter throws away too many good trades. Also today: I fixed missing 5-minute candles caused by TWS dropping connections, caught a false BARC alert from IBKR, and added a reading list to the About page.

EVS Drift - an edge that survives

Today I thought about the 5th candle metric, volume. I wondered about exceptional volume spikes and what they might mean in the story of a stock. I set Claude off on another quest for my newly named, but vaguely defined strategy of “EVS”. Sometimes a vague idea can lead to something.

And it did. EVS Drift: when a stock trades far more shares than usual and closes well up, buy at the next open, put a wide stop underneath, and hold for 20 days. Entering at the open means a gap is my price, not my slippage, and the wide stop means a normal wobble doesn’t knock me out - both lessons from TFM.

It’s the first strategy since the fill flaw with an edge that survives honest fills and real CFD costs: +0.18R a trade over ten years, and it beat every one of 1,000 random-entry tests - the timing really is the edge. I tried everything to make it stronger - shorts, trend filters, trailing stops, breakeven stops, longer holds - and every one made it worse. Sometimes the simple version is the right one. (EVS Drift)

Also today: Gecko now scans for EVS tips every evening and can place them as a CFD bracket - a market order at the open, a stop, and a market-on-close that only wakes up on day 20. Every backtest now shows its Sharpe and Sortino ratios, the homepage shows news for the stocks I’m involved in (with Gecko’s own volume-spike alerts at the top), and there’s a glossary. Next: the first EVS paper trade, and a second strategy to sit alongside it.

The fill flaw

Paper trading showed me that I also naively assumed every backtest would fill exactly at my stop entry price. In reality the market often opens beyond it, and I pay the gapped price - the same on the way out. Another thing that killed my profits: modelled honestly, TFM loses money. I tried stop-limit orders, wider stops, entering at the next open, lower reward:risk and even trading it within the day on 15-minute candles - none of them made money. (the fill flaw)

On a brighter note: every backtest now has a written record of what it tested and found, and a first look at exceptional volume spikes (EVS) turned up something interesting - big spikes cluster around events like the Brexit vote, COVID and the 2022 mini-budget, and stocks tended to keep drifting up after an upward spike. And I started this journal.

reconstructed

Stamp Duty

Since paper testing I realised that I naively ignored Stamp Duty - 0.5% on every UK share purchase - and that wiped my profits: £22,251 became a £39,306 loss. I pivoted to CFDs, as they don’t attract Stamp Duty, and registered for CFD trading permissions on IBKR. (shares vs CFDs)

reconstructed

The whole loop runs for the first time

An amazing day in Gecko’s life. For the first time the whole thing ran end to end: the evening job updated the candles, Gecko generated the day’s tips, and I clicked a button to place their orders in IBKR - three paper bracket orders (CBG, OCDO and PAY), sent by Gecko itself. Months of work, and it finally trades.

Also added five candidate stocks and email summaries. Later that evening, grading every trade on 15 factors pointed to VWAP: only taking signals that closed on the right side of the day’s VWAP lifted profit by 54%. (the VWAP filter)

Gecko also started recording the paper account’s fills, ready for the forward test.

reconstructed

First paper trades

Started paper trading TFM’s tips on IBKR, keying the orders in by hand the evening before. To help a senior developer with ageing eyes key them in accurately, each tip now shows a mock-up of IBKR’s own order screen - the same fields, in the same order, with the values already filled in.

Also loaded IBKR’s tick-size bands, so tip prices are rounded to steps IBKR will accept.

reconstructed

The first tips

The tips page showed its first real tips: eight of them, for BATS, OCDO, PAY, VOD and WIZZ - each with an entry, a stop, a target and a size. Three came from the 8:1 favourite and five from the stacked 3:1 version. Gecko had gone from testing the past to suggesting what to do tomorrow.

reconstructed

From testing the past to tipping tomorrow

The 8:1 reward:risk backtest had just given TFM’s best profit factor yet (1.43, later 1.36 once position sizes were capped), so I froze strategy development and turned to something new: running the same strategy code on the very latest data from that day’s trading session, to see what it would trade tomorrow.

Created the swing_tip table: Gecko now turns TFM’s signals into actual trade tips, each with an entry, a stop, a target and an expiry.

reconstructed

Stacking improvements

Aiming for the second-nearest support/resistance zone and leaving out small caps gave the best result yet: £16,845 over ten years. (stacking improvements)

reconstructed

The reward:risk ladder

Re-checking TFM’s conditions every day while an order waits - and cancelling it if they lapse - doubled the average R. Then ran the reward:risk ladder from 1.5:1 to 8:1: 3:1 gave the most total profit. (the ladder)

reconstructed

Four more strategies, no edge

Surveyed four other strategy families - new high/low breakouts, Bollinger band bounces, moving-average pullbacks and RSI(2) pullbacks - each with two kinds of target at 2:1 and 1.5:1. None had an edge. TFM remained the one to pursue.

reconstructed

Results dates

Looked for UK company results dates. Alpha Vantage only covers companies that also have a US listing, so I loaded dates for 12 big names (back to 1996). A full calendar via IBKR would cost $49 a month - not worth it yet.

reconstructed

Cleaning the data

A candle density check found two problems: real gaps that could be re-fetched (FUTR, GRI) and six stocks that are simply too thinly traded. Took those six out of the core basket - 110 stocks left. Also noted an idea for later: linking news events to price moves.

Also created a news_event table for that idea.

reconstructed

Slow down and plan

Decided to stop running patchy backtests and re-plan the whole series methodically: one baseline, then change exactly one thing at a time, on a wider set of stocks and a longer history.

Gecko now saves permutation test results too: shuffling a strategy’s trade directions 1,000 times to see whether the real result could just be luck.

reconstructed

Gecko gets a face

A major moment: Gecko got a front end. For the first time I could browse it in a web browser instead of reading database tables and logs - pages for backtests and their trades (with a chart for each trade), instruments and groups, candles, exchange holidays, strategies, jobs and tools. Backtests now also keep a log of each trade’s story and notes on why signals were skipped, so the pages had plenty to show.

reconstructed

Every trade saved

Created the backtest_trade table: every individual trade a backtest takes is now saved, not just the totals - so I can see exactly which trades won and lost, and why. Also experimented with ATR-sized stop losses. (ATR experiments)

reconstructed

TFM overtakes ORB

Tuned TFM beat ORB’s best-ever result on every measure, and a permutation test said its direction calls beat 98.9% of random shuffles. (TFM overtakes ORB)

Added the iShares FTSE 100 ETF (ISF) as a stand-in for the whole market, so strategies can check which way the market is trending.

reconstructed

TFM baseline - and a bug that mattered

A bug meant TFM’s EMA and MACD had to cross on the very same day to trigger a trade. Fixing it turned the baseline from a small loss into a profit. (TFM backtests #145-151)

reconstructed

A much wider universe

Added FTSE 250 and FTSE SmallCap stocks alongside the FTSE 100 ones, tagged into groups, so strategies are tested on far more than a handful of big names.

reconstructed

ORB's edge was an illusion - on to TFM

Found that every ORB backtest up to #130 had only ever taken long trades - a bug silently dropped the shorts. With both directions, 42 stocks and 10 years, ORB’s edge disappeared: 81,402 trades, flat. Decided to stop grinding ORB and focus on TFM, which also suits a day job far better: check after the close, place an order for the next day. (ORB at scale)

reconstructed

Working with Claude

Started using Claude to help refactor the code.

reconstructed

Started the Gecko blog

Started this blog, to write up what each backtest was testing and what it found.

reconstructed

Prices have rules

Learned that IBKR only accepts prices on set steps (“ticks”) that vary by stock and price. Added each stock’s minimum tick and market rule so Gecko’s orders land on valid prices.

reconstructed

TFM learns to short

TFM can now take short trades as well as long ones.

reconstructed

Teaching Gecko the market calendar

Moved exchange holidays into the database and made the candle job cope with half days and odd days - like 16 August 2019, when the LSE opened late after a technical fault.

(The exchange holiday table itself went in on 1 August.)

reconstructed

VWAP arrives

Added VWAP (volume-weighted average price) to Gecko and improved the backtest reports.

reconstructed

A first promising exit

A new exit strategy for TFM gave a profit factor of 1.65. Small sample, early code - but the first number that made me sit up.

Also started grouping stocks with tags, and added more FTSE stocks - the first step towards testing across baskets rather than one stock at a time.

reconstructed

TFM works end to end - and makes zero trades

Trend Following Momentum (TFM) now runs end to end. The first backtest made no trades at all: entries sat so close to resistance that every exit plan failed validation. A useful lesson in how one rule can silently block everything.

reconstructed

Entry, stop loss and take profit as separate pieces

Big refactor: every strategy is now three independent pieces - the entry, the stop loss and the take profit - so I can swap one without touching the others.

reconstructed

Investors Chronicle tips

Added a table for Investors Chronicle stock tips, with a utility that looks up each tip’s stock and adds it to Gecko’s list of instruments - a way to check whether published tips actually work.

reconstructed

Backtests get saved

Created the backtest_run table: every backtest now leaves a permanent record of its settings and results, instead of scrolling past in a terminal.

reconstructed

Knowing what data I have

Added timeframes (daily, 5-minute and so on) as proper data, and a “candle coverage” view so I can see at a glance which stocks have prices for which periods.

reconstructed

First strategy: the Opening Range Breakout

Coded my first strategy, the Opening Range Breakout (ORB), and split the strategy code from the backtesting code. Also set up backups for the Postgres database, as the candle data is starting to matter.

reconstructed

Gecko begins

Made the first commit of Gecko: a Java project to test trading ideas properly, rather than by watching charts and keeping pretend trades in my head.

reconstructed

The first tables

Before any strategy code, the database: an instrument table for the stocks and a candle table for their prices. Everything Gecko does still starts from those two tables.