Backtest Forensics/ What we check

What we need from you, and the eight checks we run

So you can tell before you write whether there is a job here. If we aren't the right people for it, we would rather you knew now.

Fixed scope, fixed price · $2,500 – $25,000 · report in 1–6 weeks · no retainer, no lock-in

dvt@arcobaleno.cloud → Start with a free 30-minute call. If what you have isn't enough to reproduce anything, we'll say so on that call and turn the work down.

What we need from you

Three things. If one is missing, say so on the call: it changes what is worth doing, and sometimes it means there is no job, which we will tell you.

  1. The code that produced the number. Ideally where it lives (for example GitHub), and which version produced the number.
  2. The data it ran on, or access for us to download it.
  3. The claim itself, written down — the number, the period it covers, the assets, and where it appears: an investor one-pager, a slide deck, a spreadsheet, a governance proposal.
For your engineers: file formats, data sizes and run times

This part is for whoever writes your code. None of it is a rule: it is what makes an audit quick and cheap rather than slow and expensive, and anything in the middle column simply means we say so in the quote.

IdealWorkableAsk us first
File formatParquetCSV, a database exportdata we have to keep downloading live; a platform you can't export from
Data sizeUp to ~1 GB1–4 GB, adds a day or two or is requoted; 4–25 GB, requoted on a larger machinelarger than ~25 GB
How detailedDaily or hourly pricesminute bars; tick data or L2 order-book snapshots up to ~25 GB, requotedtick or L2 data over ~25 GB
CodePython, with its history (e.g. Git)R, MATLAB, C++a program we can't open; a signal you can't show us
Run timeUnder 2 hours a run2–6 hours, adds dayslonger than that

Run time matters more than people expect. FC-1 alone means running your test at least twice, and every version we try in FC-6 is another run. A six-hour backtest is not a six-hour job.

On confidentiality: tell us if any part of the strategy can't be shown to us — we can usually work around a part we can't open, and it is far better known before we start than halfway through. Your code and data are deleted when we deliver, unless you ask us to keep them.

What we can and can't audit

The eight checks work in any market. Knowing how a particular market works is a different thing, so here is where our knowledge stops.

  • Strongest Crypto perpetual futures (perps). Funding, mark versus last price, margin tiers, delistings, fee tiers and liquidation cascades. Eight of the ten findings we have published against ourselves come from here; the other two are a DeFi liquidity pool and a study of an options market.
  • Covered Crypto spot, stocks, futures. The method carries over directly, and most of what an audit finds is in how the test was done, not in what was traded.
  • Flagged Things we haven't worked with ourselves — adjusting stock prices for dividends and splits, company accounts as they were known at the time, exchange holidays and trading halts, the cost of borrowing a stock to bet against it, and options pricing. If your result depends on one of these, we say so in writing before quoting, and you decide.
  • Declined Where there is nothing to reproduce — no code, no data, or a strategy nobody has run in months and nobody knows the expected output of. That is code recovery, not an audit, and we don’t sell it. We also decline when the core of the strategy is hidden from us and that is where the return comes from, and when the person commissioning the audit is not the person who carries the loss.

Outside crypto we hold no market data of our own: you send yours or we buy it in, and we tell you which, and what it costs, before any work starts.

The eight checks, in plain English

Every audit asks the same eight questions, numbered FC-1 to FC-8 so each finding in your report points at one of them. Open any check for an everyday example.

FC-1Can anyone else get the same answer?
Does the same number come back when someone else runs your code? Read the example: the recipe ›Close ×

Think of a recipe. You bake a cake and it comes out perfect. You give the recipe to a friend, they follow it exactly, and something different comes out. Then the recipe was never the whole story — something in your kitchen was doing work nobody wrote down.

The strategy is the recipe. The number is the cake. So we take the recipe to a different kitchen and bake it. More often than anyone expects, a different cake comes out — and then the number was never really about the strategy. It was about that one computer, on that one day.

And if nobody else can get your number, every change you make afterwards — bigger size, new settings — is being judged against something that wobbles.

FC-2Who did not make it this far?
Was the list of assets built as it looked back then, or from today's survivors? Read the example: the fishing net ›Close ×

You go fishing with a net. The holes are big, so the little fish swim straight through. You pull it up, look in, and every fish is a big one. You could easily decide that all fish are big. The net told you that, and the net was wrong.

A plan needs a list of things it was allowed to buy, and nearly everyone builds that list the same way: ask the computer, today, what is available — then run the test back across the last five years. That list is a net with big holes. Anything that died along the way slipped through and is not in it, so the test only ever buys things it already knows survived. Nothing warns you. An absence does not announce itself.

The ones that slip through the net are the ones that failed. So the one thing their test can never show you is what failure costs.

FC-3Did anyone check what it costs?
Where did the trading-cost figure come from, and was it ever measured? Read the example: the ATM charge ›Close ×

You take money out of the ATM and it charges you $2. Once? You would shrug. But this plan goes to the ATM five times a day, every day, for six years. Now the $2 is not a detail on the receipt. It is the single biggest thing in the plan, and it can turn a winner into a loser on its own.

So how does anyone know it is $2? Somebody said so. They looked at a different machine, a while ago, and wrote it down, and it has been copied from document to document ever since. Nobody has looked at a receipt. And it was never one number anyway — taking out $20 and taking out $2,000 are not charged the same way, and the figure people quote is nearly always the $20 one.

In our own work we found one counted about twenty times too big. Three strategies had already been switched off because of it.

A cost that was copied instead of measured goes wrong in both directions. It flatters plans that do not work, and it quietly kills plans that do — and the ones it kills do not complain. They just go quiet.

FC-4Is one bad day in the wash?
Was every line of data checked, or could one bad day be carrying the result? Read the example: the red sock ›Close ×

A full load of whites, and one red sock goes in with them. Everything comes out pink. And here is the real problem: the damage is not in the sock any more. It is spread thinly across everything, and there is nothing left to pull out and throw away. Every item is a bit pink, and a bit pink is easy to live with.

Market data arrives from outside, and now and then a row is broken. Not slightly. Ridiculously. One day’s figure came in thousands of times bigger than that market had ever moved in a day, went into the wash with thirty months of ordinary days, and came out as a result of nearly 200% a year.

Every safety check passed, because they all checked what came out of the machine rather than what went into it. By then there is no bright red sock, just a faintly rosy month — and a rosy month is not suspicious, it is what everybody was hoping for. Worse, checking two rows and checking every row look identical when you read the code. The only difference is how many it ran on.

Anything checked by sampling is unchecked. The row that breaks everything is the strange one, and the strange row is exactly what a sample is least likely to hold.

FC-5Was it looking at an old photo?
How old was the picture of the market when the strategy made its call? Read the example: the photo of an empty room ›Close ×

A strategy decides from a picture of the market — who wants to buy, who wants to sell. That picture is always slightly old. A second or two.

Most days that changes nothing. On the day everybody runs for the door, it is the whole story. The strategy sees a large crowd of buyers, which looks like safety — but that crowd left a few seconds ago. The signal was not broken. It was reading a photo of a room that was already empty. And that is not bad luck: it is what the strategy does every time the market moves faster than its picture updates.

Which means it will happen again — and your own backtest cannot tell you how often, because it is the thing that recorded those days as wins.

FC-6How many times did you guess?
How many versions were tried before this one was shown to you? Read the example: guess which hand ›Close ×

I hide a candy in one hand and you guess. Wrong. Guess again. Wrong. Keep going. On the ninth try you get it, and I write down: guessed right. I do not write down the eight misses. Read my notes and you are a mind reader.

Someone builds the plan, then tries it forty different ways and writes up the one that came out best. The other thirty-nine leave no trace. So the number you are shown is doing two jobs at once: it is the score, and it is also the reason this version is the one in front of you. Pick the highest of forty and of course it is high.

Trade count hides the same trick. Two thousand trades that all landed in the same six panic weeks are six answers, said loudly. So we set days aside before the searching starts and let the plan try them — once. Peek, adjust, peek again, and those days are part of the search too.

Trying lots of things is not cheating — everybody does it. That is exactly why the only real test is data set aside before the searching started, and why you only get one shot at it.

FC-7Could you actually have bought it?
Could every trade really have happened, at that price and that size? Read the example: the cookie swap ›Close ×

Imagine telling a playground: “I will swap my sandwich for anyone’s cookie.” Who says yes? The ones with the bad cookies. Whoever has the good cookie keeps it.

A strategy that waits for a good price has the same problem: the moments it gets that price are often the moments everyone else is leaving — which is why the price came to it. Add two more: the shelf said $10, but there was one left and you wanted fifty; and by the time you got to the register it was gone. A backtest usually writes down the shelf price, because on paper nothing runs out and nobody else is in the store.

And the days that made most of the money are usually the fastest, wildest ones — which are exactly the days when the price on paper is least likely to have been real.

FC-8How sure are you, really?
Is the headline one exact number, or a range that might include zero? Read the example: the best of forty-one ›Close ×

Imagine someone takes 41 photos of themselves and shows you the best one. The photo is real. Nobody faked it. But it is not how they normally look — it is their luckiest try out of 41.

And a player who scores 8 shots out of 10 is not an 80% shooter. That was one afternoon. So when a result says 61.4%, the question is simply: if you ran it all again, what would you get? If the honest answer is anywhere between 45 and 75, that is not a number. It is a direction — which is still worth something, but it is a different thing to tell an investor.

A number with no wiggle room written next to it is a promise nobody has tested.

The formal checklist, and the free tools behind four of the checks

They come from mistakes we have actually hit in our own research — not from a textbook. All eight are published on our front page as case studies against ourselves, with the dated internal document each one came from.

The tools behind four of them (FC-1, FC-4, FC-6, FC-8) are public: fctools, free for anyone to use (MIT licence), with a checksum and a signature so your team can confirm the download is ours. Run them on your own work before you send it — anything they catch is cheaper found by you.

  1. FC-1Does it repeat?

    We run your code twice, on two different machines, and see whether the same number comes back. Nothing else means anything until this does.

    What going wrong looks likeThe author cannot get their own headline number out again — far more common than anyone expects, and usually a hidden setting that changes how the program orders its work from run to run.
  2. FC-2Are the dead ones missing?

    Was the list of assets built as it looked back then, or from the ones still trading today? And if something was already patched to fix this, does the patch actually test the thing it claims to?

    What going wrong looks likeThe names that disappeared are absent from the test — and the ones that disappear are usually the losers, so the record flatters itself.
  3. FC-3Are the costs real?

    Where did the fee figure come from? Is it charged correctly — once for the whole portfolio, or once per position? Was it measured at the order sizes you would actually trade, or read off a screen?

    What going wrong looks likeOne cost assumption appears in three documents with three different numbers, and nobody has measured which is right.
  4. FC-4Is the data clean?

    Was every line of data checked, or just a sample? We run the checks that already exist across the whole set rather than the slice someone looked at.

    What going wrong looks likeA single bad price carries thirty months of apparent return, and removing it removes the strategy.
  5. FC-5Is the data current?

    Do the filters meant to exclude stale data actually look at a date? We read what the code does, not what it is called.

    What going wrong looks likeA filter named for keeping data recent that never reads a date. It counts lines and wears the name.
  6. FC-6Was it cherry-picked?

    How many versions were tried before this one, and was this one chosen before or after seeing how it performed? Is there any data it has genuinely never been run on?

    What going wrong looks likeHundreds of versions tested, the best one reported, and nothing held back to check it against. The result is the search.
  7. FC-7Could you have traded it?

    Could every position in the result actually have been bought and sold, at the price used, in the size assumed — and using only what was knowable at that moment?

    What going wrong looks likePositions opened and closed at prices that existed, in sizes that did not. Or open positions quietly dropped at the end instead of valued, which turns a loss into a profit.
  8. FC-8What is really being claimed?

    Is the headline a single number or a range? We work out its likely range and ask whether that range is wide enough to include zero.

    What going wrong looks likeA figure quoted to two decimal places that is really a range — and a perfectly reasonable alternative way of running the same code lands somewhere else entirely.

How an audit actually runs

Start to finish, for a full audit. A Triage is steps 1 to 3 and stops there. Here is what the finished report looks like.

  1. We take delivery and freeze it. Your code and data go into a separate copy, sealed with a digital fingerprint so any later change would show. We never work in your live code.
  2. FC-1 first, before anything else. Run it clean, end to end, twice. If the number won't come out, we stop here and tell you — everything downstream would be worthless.
  3. We compare against your claim. Our number against the number in your document. Any gap is itself a finding, and often it is the finding.
  4. We work FC-2 through FC-8 in order. Simple and quick first, subtle last. Each check is a script we run, not a read-through of your code.
  5. Every finding gets a number. Not "costs look understated" but "costs are understated by this much, which moves the headline from here to here". A finding without a number is an opinion.
  6. You get the report, each finding with the script that demonstrates it. It opens with a one-page summary that shows how much each problem changes your claim, then takes the eight checks in order, FC-1 to FC-8. See a sample.
  7. One call to walk through it. No ongoing obligation, in either direction.
The fee is for the work, not for finding something

An audit that finds nothing wrong is a real and useful outcome: it is what you are buying the right to conclude. We would rather agree that now than argue about it later.

If a Triage uncovers something bigger, we stop and re-quote

We don't silently absorb it, and we don't silently bill for it.

Two things people often tell us

Both are usually true. Neither one settles the question.

“But our data comes straight from the exchange”

Usually true. It is also not the reassurance it sounds like, because a charting website is not where the data lives. It is a window onto somebody else’s copy.

The history can change after you have looked at it. Exchanges cancel bad trades and repair them days later. Data providers fill in gaps after the fact. The chart you built the plan on is not always the chart you would draw today, and nothing tells you when a past price has changed.

The same coin does not have one price. One exchange’s price is not another’s. And a coin that gets removed simply stops appearing in the search box — which is FC-2, built into the interface.

A chart cannot tell you what trading costs. A chart shows each period's opening, highest, lowest and closing price, and how much traded. That is a record of what the market did, not of what you would have paid. So the fee in the test did not come from the exchange at all. It came from a document.

And fees were never one number. They are tiered by volume and account level, and they change across the years a test covers. A test that quietly assumes every order waited patiently for a good price, when the strategy would in fact have had to pay up to trade at once, is wrong in the flattering direction every single time. Perps also pay funding, a real recurring cost that is often left out altogether.

Official is not the same as checked, and a display is not the same as the record.

“But we have the order book”

That is, every buy and sell order waiting at each price, often as L2 snapshots. It is better than most people arrive with, and it genuinely helps. With it, what a trade would have cost stops being a guess and becomes something you can measure.

Having it and using it are different things. The question is what the code did with it. Did it work through the waiting orders, one price at a time, until the whole order was filled? Or did it read the best price and assume the whole thing went through there? The second is the common case, and in the output the two look identical.

It shows what was on offer, not what you would have got. Your own order moves the price. Somebody else was reaching for the same thing. And the days that make most of the money are the fast ones, when there are fewest orders waiting and the picture you are reading is most out of date.

And it leaves the other seven checks exactly where they were. A perfect order book says nothing about which assets were on the list, how many versions were tried before this one, or whether a single broken figure is carrying the result.

Better data does not audit itself. It moves the place where the mistake can hide.

Still not sure whether it fits?

That is what the first call is for, and it is free. Tell us what the strategy is and what you have. If there isn't enough there to reproduce anything, we'll tell you on that call and turn the work down — before any money changes hands.

Backtest forensics · Oslo
dvt@arcobaleno.cloud →

Prices, and the ten findings we published against our own research, are on the front page.

Research due-diligence and code-audit services only. This is not investment advice, not a recommendation to buy or sell anything, and not an offer to manage money. Our findings say whether a stated result can be reproduced from the material supplied — they are not an opinion on how any strategy will perform in future. The case studies referred to describe defects found in our own internal research; no client work is described.