Yuri Korolev
New York
iInfo
Yuri Korolev
New York
04

Quant

Systems & Data2024
Quant — Systems & Data

Context

I started this in my freshman year, and I started it by losing money. I was trading options on not much more than a feeling about which way something was going, which is a description of gambling rather than of trading, and the account agreed. What I had that most people losing money on options do not have is a degree that was teaching me to build software. If I could not do this by instinct, I could at least build something that did it by rule, on real data, the same way every time, and find out whether the rule was any good before it cost me anything.

Most trading ideas die in the plumbing rather than in the market. Testing one properly means fetching the data, cleaning it, computing the indicators, writing a backtest that fills honestly, and then wiring all of it to a broker — and that is the same work every time, for every idea, before you have learned a single thing about whether the idea was worth having. So the system is built the other way round. The plumbing exists once, and a strategy is a file that plugs into it: a class with an on_bar method, inheriting the data, the fills, the risk sizing, the charts and the live execution without having to ask for any of them.

It has been running on paper accounts for a few months now. Every trade it takes posts to a Discord channel — the entry, the exit, the price, the reason it closed, what the account is worth afterwards — so the thing tells me what it is doing whether or not I am sitting in front of it, and I find out about a bad exit on my phone rather than out of a log file a week later.

Details

Role
Developer and Researcher
Team
Solo, after a two-person start
Timeline
2024 — present
Deliverables
Data pipeline, backtester, live runner, two dashboards
Status
Running on paper and evaluation accounts

Tech stack

Infrastructure
AWS Lightsail·Ubuntu·systemd·Tailscale
Engine
Python·FastAPI·WebSockets·SQLite
Data
Databento·Parquet·pandas·NumPy
Research
Walk-forward·Monte Carlo·Permutation tests·Regime gating
Interface
React·TypeScript·Vite·Tailwind·Lightweight Charts
Alerts
Discord webhooks

Final artifacts

Quant — Three strategies on paper, ten hours into the session
Three strategies on paper, ten hours into the session
Quant — Two strategies backtested as one book
Two strategies backtested as one book
Quant — Every paper fill, and what it cost
Every paper fill, and what it cost

Key design moments

01

The dorm laptop stopped being the server

For the first stretch of this the whole system ran on a spare laptop on a desk in my dorm room. It worked, in the sense that it was running, and it was never once out of my mind: a closed lid, a dropped connection, a roommate moving it, an update deciding two in the morning was a good time to restart. A trading loop that stops halfway through a position is worse than one that never started. So it moved onto an AWS box — the smallest Lightsail instance there is, in Ohio because that is the region nearest the exchange, with a static IP, the firewall cut back to SSH from my own address, and the runner registered as a systemd service so a reboot brings it back without me. The dashboard is reached over Tailscale rather than through an open port, which means I can look at it from my phone without the internet being able to. What stayed on my laptop is everything heavy: the years of one-minute bars, the backtests, the optimisation runs. Those want a real machine for an hour at a time and they want it for free, and the box only has to hold one live loop and one broker connection, which is why it costs what it costs. I set out to buy peace of mind and came away having learned AWS properly, which was the better half of the trade.

Quant — The dorm laptop stopped being the server
The dorm laptop stopped being the server
02

Starting again in Python

The first version of all of this was TypeScript from end to end, written with another developer I was working with at the time. Then I stepped away from it for a while, and when I came back I was on my own and had to read it as a stranger would. Rewriting the backend in Python was the decision I put off longest and should have made first. It is not that the language is better. It is that every library this problem needs already exists there — pandas and NumPy and Parquet, the broker and data vendor SDKs, the statistics — and, more than that, so does everything anyone has written about the problem. Every paper, every notebook, every answer to the exact question I was stuck on, all in Python. The interface stayed TypeScript, where it is the right tool and where React and a charting library do in an afternoon what would otherwise take a week. What the split bought was speed: an idea now goes from a sentence to a tested result in a fraction of what it used to take, and the honest part of that figure is not the language, it is that rewriting the thing alone was how I finally understood every piece of it.

Quant — Starting again in Python
Starting again in Python
03

It had to be able to tell me what it was doing

The system runs on a machine I never look at, which is the whole point of the machine and also the problem with it. A log file you have to go and open is a log file you do not open. So every entry and every exit posts to a Discord channel the moment it happens: the instrument, the side, the size, the price it went in at, and the stop and the target it is going to be judged against — then, at the other end, where it actually closed, in dollars and in points, with the account value and the strategy's running total underneath. The line I read first is the mode, because it says which account this was, a test run or a paper account or a prop firm evaluation, and a message that does not say that is a message you can misread badly. Two rules hold the whole thing up, and both of them are about the trading loop rather than about the messages: the notifier can never raise, because a listener that throws gets dropped and the alerts would go quiet without telling me, and the post is fire and forget, because a webhook having a slow afternoon must not be able to stall a bar. What it changed most is how I find bugs. Exits recorded at the entry price, a position the venue had already closed that the runner still thought was open — those are a fortnight of not noticing in a log, and about four seconds of noticing on a phone.

Quant — It had to be able to tell me what it was doing
It had to be able to tell me what it was doing

Impact

62%Less time from an idea to a tested strategy
$0A month to run it
99%Uptime, by my own count

All three of those are mine rather than anybody's measurement, and the third is the softest: nothing is monitoring the box but me, so read the uptime as an impression rather than a reading. The zero is real and slightly misleading — the backtests run on a laptop I already owned, and the instance that runs live is the smallest one AWS sells, which is enough for one strategy loop and one broker connection and not much else. The 62% is measured against my own habit, an idea to a tested result, before and after the framework existed. What I have deliberately not put here is a return. Every account value on this page is simulated — practice accounts and prop firm evaluations, not a dollar of it real — the system has been running on them for months rather than years, and quoting a P&L off that would be the same mistake I started out making: taking a number that came out well as evidence that the method was sound.

Reflections

The thing I actually learned is that a backtest will tell you whatever you want to hear. My first genuinely exciting results were the ones I had fitted, and I could not see it, because a curve that goes up is very persuasive when you are the one who drew it. Most of the work since has gone into making the system harder to fool than I am: walk-forward rather than one optimisation over the whole history, Monte Carlo and permutation tests to ask whether the result survives its own trades being shuffled, a regime gate so a strategy only trades in the conditions it was actually good in. Nearly everything that passes those is boring, and nearly everything that looked brilliant does not pass them. That is the useful finding.

What is next is the part I have been putting off, which is real money at a size where being wrong is unpleasant. Paper accounts fill in ways real ones do not, and I know that a fill I never had to pay for is worth less as evidence than I want it to be. The thing I would do differently is the language, and not for the reason it sounds like: the mistake was not picking TypeScript, it was picking what I was already comfortable with instead of spending an afternoon finding out what everyone solving this problem was using and why. That afternoon would have saved a year.