Cross-sectional Z-score
N
42
τ
15m
r
4s
Snapshot

Projects

Things I've built.

Each one started from the same problem: too much noise, too much latency, too much locked behind paywalls.

Forward test

MODEL040526

A point-in-time, mean-reversion book. It shorts exhausted low-cap pumps an hour past the daily close, on low volume, and runs a decorrelated long overlay that tends to be green on the days the short bleeds.

Most low-cap names mean-revert after a liquidity shock. The model flags a volume and liquidity-migration event: turnover around 6× its trailing-week average, a sharp climb up the cross-sectional liquidity ranks, an idiosyncratic move with a strong close. It enters short at the daily close plus one hour, into a quiet session window so price and volume aren't both fighting the fill.

On top sits a small long sleeve, the mirror signal: it rides strong continuation pumps, but only while BTC and ETH are both in a confirmed uptrend, and sizes itself down as realised volatility climbs. Its job is to hold a slightly negative correlation to the short, so the blended book carries a materially lower drawdown than either leg alone.

It's in forward testing now, on a demo account and a local paper-trading ledger.

Combined book · 3× leverage · in-sample · Bybit · 2023-06 → 2026-06

Strategy 9.50× BTC 2.98× MU 15.5×

BEST MONTH +47.0% · WORST MONTH −7.4% · 22/32 months green

Yes, buy-and-hold Micron beat everything here. That's one stock on a once-in-a-decade run, picked in perfect hindsight. The book compounded to 9.5× across hundreds of small, independent positions, not one concentrated bet.

3× leverage · in-sample · 3-year backtest.
Currently in forward testing.

9.50× In-sample combined · 3×
−21% Worst drawdown
Multi-book Short fade + long overlay

Two months of dead ends, a look-ahead bug that faked a beautiful curve, and learning to stop believing my own good news. The whole build is in Seeking Alpha.

Read the full story
Live

eBaySpy

Like Palantir, but for eBay. It watches the sellers you care about and alerts you when they list, sell, or restock, on a steady daily sweep or the instant a new item appears.

Point eBaySpy at any list of eBay seller usernames and it watches their storefronts for you. The moment one of them lists something, sells out, or restocks, a clean message lands in Telegram with the title, price, photo, and a direct link to buy. No more refreshing a search page to be first to a deal.

You run all of it from a Telegram chat. Add a seller, remove one, check status, or change how often a seller is polled, all from your phone. There is no dashboard, and no config file to touch once it is set up.

It runs two lanes at once. The watch list polls every seller on a steady cycle and reports everything: new listings, items that sold or ended, and restocks. The observe list is the fast lane for sellers you want to beat the crowd on, each polled on its own short interval, down to seconds, so a new listing reaches you the instant it goes up.

It uses the official eBay API, so there is nothing to scrape and nothing to break when the site changes. The whole thing is one quiet Python process that runs unattended for weeks, on a Mac that is usually on or a cheap always-on server.

Example alert · new listing from a tracked seller
2-lane Watch + observe
1 call Per observe check
Seconds Fastest interval
Open the engine

The design goal was to be cheap enough to run hard. An observe check is a single lightweight API call per seller, and full item details are only pulled for listings it has not seen before. So you can poll a seller every few seconds without spending your way through eBay's daily call budget.

  • Every alert carries the title, price, seller, listing type, category, quantity available, a description snippet, the photo, and a link straight to the listing.
  • Listings are de-duplicated in a local SQLite file, so a restart never re-sends an old item.
  • Adding a seller seeds their current inventory silently. You only get alerts for what they list from that point on.
  • Ended alerts are re-checked against eBay before sending, so a transient blip in search results never fires a false sold notification.
  • If a tracked seller renames their account, eBaySpy follows the change and keeps tracking them.

Everything is driven from chat. The watch list has /add, /remove, /list, /status and /check; the observe lane has /observe, /unobserve, /observing and /interval. Access is invite-only, locked to an allowlist that admins manage from the same chat.

  • Ships a one-command macOS installer that runs it as a LaunchAgent: it starts at login, restarts itself if it crashes, and sits in the background with no dock icon and no window.
  • An optional helper wakes the Mac from sleep, runs a check, and lets it sleep again, so tracking carries on overnight without leaving the screen on.
  • For 24/7 tracking it ships a systemd template for any cheap Linux VPS, the natural home for the fastest observe intervals since the box never sleeps.
  • Because it talks to eBay over the API, it runs headless, with no browser to drive and nothing to break on a site redesign.

It works across eBay US, UK, DE, AU and other regional sites, and runs as a single process backed by one SQLite file, with no external database or services. Built on Python 3.11 with asyncio and httpx, it runs the watch loop, the observe scheduler, and the Telegram listener side by side, with graceful shutdown and a tested, linted codebase.

Live

Outlier Detector

A live momentum and relative-strength engine on Bybit perpetuals. Silent by default; it speaks only when a name breaks from the pack.

Outlier Detector watches a manual universe of Bybit USDT futures in real time, ranks them against each other, and highlights the names that keep showing up stronger than the rest.

The point: reduce the lag between noticing movement and understanding whether it matters. Instead of watching dozens of charts, I wanted one system to keep score continuously and make the market easier to read.

It pushes that view into Telegram and gives me a cleaner read on what is leading, what is weakening, and what still looks strong by the close.

Telegram confirmed summary from Outlier Detector showing regime, qualified signals, and ranked leaders.
Confirmed-cycle summary · live Telegram feed
15m Cycle
26 Tests passing
2-state Intrabar / confirmed
Open the engine

Under the hood, the engine keeps a rolling 15-minute view of the market and re-ranks the full universe every cycle. The key idea is simple: early movement and confirmed strength are not the same thing, so the system does not treat them like they are.

The runtime is event-driven. It bootstraps state from REST, stays live over WebSocket candle updates, and splits processing into two paths: one for intrabar reads and one for confirmed closes. A lot of market tools blur those together and end up either too noisy or too late.

  • Bootstraps 15-minute history for a manual universe of Bybit linear USDT contracts, plus BTC macro state over REST.
  • Stays live over Bybit WebSocket kline.15 streams and processes both provisional intrabar updates and confirmed candle closes.
  • Keeps confirmed and provisional price state separate so early reads do not contaminate the close-confirmed path.
  • Uses BTC daily closes from Bybit for regime scoring and Binance futures BTCDOMUSDT as a practical dominance proxy.

The ranking model is cross-sectional. Every cycle, each valid ticker gets scored on momentum, curvature, and Hurst. Those signals are normalised across the whole universe, clipped, and combined into one ranking. I wanted the engine to care about relative strength, not just isolated price movement.

  • Log-return-based volatility-adjusted momentum, return curvature, and Hurst for every valid ticker.
  • Momentum and curvature turned into clipped cross-sectional z-scores before being combined into the composite rank.
  • BTC regime floors plus BTCDOM state adjustments modulate the threshold instead of relying on one fixed cutoff.
  • Hurst as a hard filter, plus a confirmed persistence bonus so one-bar spikes do not dominate the close-confirmed view.
  • Intrabar signals promote through watchlist and emerging only when rank and composite score are strengthening across recent observations.
  • Confirmed signals upgrade to confirmed_strong when leadership survives the close and recent confirmed persistence backs it up.

The part I care about most is that it is not just a signal script. I built the support layer too: SQLite logging for every evaluated row, Telegram alerts and confirmed summaries, replay and smoke tooling, benchmarking, reporting, and universe validation. The repo currently has 26 passing tests.

It is still a work in progress. Right now this is the first step: building a detector I trust. Once I feel I have that layer right, the next step is building further toward a fuller trading system on top of it.

I wrote more about the philosophy behind it, the compromises, and the decisions that shaped the build in Philosophy and Design Choices.