An unseeded result is not a result, it is one draw from a distribution of results

The short answer

A result is checkable only if a reader can recreate it, and that needs four things almost nobody publishes: every random seed, the replication count, the data snapshot (source, period, adjustment convention and the date it was pulled) and the software environment. Measured on this page: the same code on the same data, run twelve times without a fixed seed, moved its reported lower bound by 0.0168, which is 9 per cent of the interval's own width. With a seed, twelve runs were identical. The seed costs one line. Everything else on this page costs about an hour, and it is an hour you cannot spend retrospectively.

This is the least interesting subject in quantitative work and the one that decides whether any of the rest of it means anything. A number nobody can recreate is not evidence. It is a claim with arithmetic attached.

Reproducing is not replicating, and the difference decides what you need

Two words get used interchangeably and they are not the same requirement. Reproducing a result means taking the same data and the same code and arriving at the same answer. Replicating it means running a fresh study, on your own data and your own implementation, and reaching the same conclusion.

Reproduction is a disclosure problem. Replication is a truth problem. The uncomfortable consequence is that a result can be perfectly reproducible and entirely wrong, because reproducing a mistake reproduces it exactly. Reproducibility is therefore not a claim of correctness. It is the precondition for anyone being able to find out.

Where the randomness actually enters

Most people setting out to make work reproducible think of simulation, and stop there. Randomness enters a quantitative workflow in more places than that, and every one of them moves the answer.

Sources of run to run variation, and what each one needs
SourceWhat it does to the answerWhat fixes it
Bootstrap and resamplingMoves every reported intervalA stated seed and replication count
SimulationMoves every percentile and tail figureA stated seed and run count
Shuffles and permutation testsMoves the reported significance directlyA stated seed
Random train and test splitsMoves the entire out of sample resultA seed, or a rule rather than a draw
Set and dictionary orderingChanges floating point summation orderSorting before aggregating
Parallel executionChanges the order results are combined inDeterministic reduction, or single threading

The last two are the ones that surprise people, because no random number generator is involved. Floating point addition is not associative: summing the same values in a different order can give a slightly different total. Usually that is invisible. At a threshold, it is the whole decision.

The measurement

Rather than assert that an unseeded result moves, here is the measurement. A fixed series of 500 observations, a bootstrap of 400 replications, a ninety five per cent interval on the mean. The same code, the same data, twelve times over, each run landing on its own random draw exactly as an uncontrolled run would.

Twelve runs of identical code on identical data Twelve horizontal interval bars stacked vertically. Each is a ninety five per cent interval produced by the same code on the same data, each run given its own different seed to stand in for an uncontrolled run. The bars start and end at visibly different places, showing the answer moves from run to run. Same code, same data, twelve uncontrolled runs zero -0.08 +0.16 The lower bound alone moved 0.0168, which is 9 per cent of the interval's own width.
Computed, not illustrative. Nothing changed between these twelve runs except which random draw each one happened to get.
The first six of twelve runs. Identical code, identical data, each run on a different random draw.
 Lower boundUpper boundWidth
Run 1-0.0523+0.13690.1892
Run 2-0.0433+0.13340.1767
Run 3-0.0499+0.13400.1839
Run 4-0.0495+0.12830.1778
Run 5-0.0458+0.11770.1635
Run 6-0.0600+0.12240.1824

Across all twelve, the lower bound ranged from -0.0600 to -0.0433 and the upper from +0.1177 to +0.1369. The interval's own width varied between 0.1635 and 0.1895. Publishing any one of those twelve as the answer, with no indication that eleven others were equally available, is the ordinary practice.

Running the identical procedure with a seed fixed at a stated value produced identical output on all twelve runs, at -0.0490 to +0.1236. The fix is one line and it is free.

How many replications is enough, measured

A seed makes a result repeatable. It does not make it stable, in the sense of being insensitive to the arbitrary choice of seed. That is a separate question with its own measurable answer: run the whole procedure repeatedly on different draws, and see how much the reported figure moves at each replication count.

How many replications before the answer stops moving Five bars of sharply decreasing height. As the number of bootstrap replications rises, the spread of the reported lower bound across eight independent runs falls, but it falls slowly and never reaches zero. Spread of the reported lower bound across eight uncontrolled runs 0.03281000.01004000.00631,0000.00565,0000.002620,000 Two hundred times the work cut the wobble by roughly 13 times. A seed removes it entirely at no cost.
Computed. More replications narrow the wobble, which is why the replication count must be reported alongside the number.
Spread of the reported lower bound across eight independent uncontrolled runs
ReplicationsSpread of the answerRelative to the 100 case
1000.032781.00
4000.010000.30
1,0000.006280.19
5,0000.005630.17
20,0000.002620.08

The shape of that table is the useful part. Going from 100 to 20,000 replications is two hundred times the computation and cut the wobble by roughly 13 times, because the error falls with the square root of the count. There is no replication number at which the answer stops moving, only one at which it stops moving in the digits you intend to quote. That is the number to find, and it is why the replication count belongs next to the result.

The instrument that agreed with itself perfectly

This article nearly shipped with a fabricated result, and the way it happened is worth the space because it is exactly the failure the subject is about.

The first version built its series like this:

series = [random.Random(11).gauss(0, 1) for _ in range(500)]

That rebuilds the generator on every iteration from the same seed, so it returns five hundred identical values. Every bootstrap sample of a constant series has the same mean, so every interval came out with zero width, and every run agreed with every other run to the last digit.

The output looked like a flawless demonstration of reproducibility. It was a broken instrument reporting nothing at all. What caught it was not the code review but the number: an interval of exactly zero width is not a good result, it is an impossible one.

The fix in the shipped script is two lines, and the second matters more than the first: seed once outside the comprehension, then assert the series is not degenerate before anything is built on it. The control now reports 500 distinct values at a standard deviation of 1.0169, and the assertion fails the build if that ever stops being true.

The general rule this illustrates has nothing to do with this particular bug. A result that looks impossibly clean is a defect report. Perfect agreement, a zero variance, a correlation of exactly one, a p-value of exactly zero: each is far more likely to be an instrument reporting on itself than a discovery.

The data snapshot, which is the hard one

Seeds are easy. The genuinely difficult part of reproducibility in market work is that the data moves underneath you, and naming a period does not pin it down.

Why the same request returns different data later
CauseEffect on a repeat request
Provider revisionHistorical values are corrected after the fact
Corporate action adjustmentA back-adjusted series is rewritten from the start every time a new action occurs
Index reconstitutionCurrent membership is not historical membership, so an index-based study silently changes
Symbol changesA ticker is not a stable key, so a join by symbol breaks across time
Coverage extensionHistory is added backwards, changing every full-sample statistic

The consequence is specific: a period is not a snapshot. Two people who both say they used the last ten years, from the same provider, can hold materially different data. What identifies a snapshot is the source, the period, the adjustment convention and the date it was pulled, and the only fully reliable version is to keep the file.

The minimum disclosure

Everything a published number rests on Five nested layers narrowing downward. The claim sits on the code, which sits on the randomness, which sits on the data, which sits on the environment. A reader given only the top layer cannot check any of the four beneath it. The claimthe number you publishThe codeversion, and every parameterThe randomnessevery seed, and the replication countThe datasource, period, adjustment convention, snapshot dateThe environmentlanguage and library versions A claim published without the four layers under it cannot be checked, only believed.
Most published results disclose the top layer alone. The disclosure that makes a number checkable is the other four.

Everything above reduces to a short list. It is worth applying to your own work first, where it is hardest to pass.

What a checkable claim states
DiscloseBecause without it
Every seedThe reader cannot tell your result from the eleven others you might have got
The replication countThey cannot tell whether your digits are stable
Data source and snapshot dateThey cannot obtain the same data
Adjustment conventionTheir series will differ from yours at every corporate action
The cleaning ruleThey cannot tell which observations you kept
Every parameterThey are guessing at the specification
The number of variants triedThey cannot judge the result's significance at all
Language and library versionsThey cannot resolve a disagreement in the last digits

The seventh row is the one that carries the most information and is almost never present, because nobody records it as they go. It is also the only item on the list that cannot be reconstructed afterwards: seeds can be re-run, data can be re-pulled, versions can be looked up, but the count of discarded attempts exists only if somebody wrote it down at the time.

When the data cannot be shared, which is most of the time

The standard advice is to publish the data alongside the result, and for market work that advice is frequently impossible to follow. Exchange and vendor data is licensed, and a licence to use it is not a licence to redistribute it. Anyone working from a paid feed is contractually unable to do the thing reproducibility guides tell them to do.

Treating that as the end of the matter is the common response and it is wrong, because the licence blocks one specific item on the list and leaves the rest untouched. What can be published without redistributing anything is considerable.

What survives a licence that forbids redistributing the data
PublishWhat it lets a reader do
The code that fetches and processes itObtain the same data themselves and run the identical pipeline
The exact identifiers and date rangeRequest precisely the same rows rather than approximately the same ones
A checksum of the file you usedConfirm their copy matches yours before blaming the method
Summary statistics of the inputDetect immediately that their data differs from yours, and how
A synthetic series with matched propertiesRun and test the pipeline end to end without your data at all
The intermediate result, not the raw rowsCheck your inference even when the inputs are withheld

The checksum line does more work than it looks. Most failed reproductions in practice are not disagreements about method at all: they are two people holding different data and arguing about the analysis. A hash published next to the result resolves that in seconds, and it discloses nothing about the contents of the file.

The synthetic-series line matters for a different reason. A pipeline that runs on generated data of the right shape is a pipeline somebody can execute, inspect and find a bug in, even if they can never reproduce your exact number. That is a large fraction of the value, and it survives any licence.

The order that makes all of this nearly free

Everything on this page is cheap while the work is happening and expensive or impossible afterwards. That asymmetry, rather than any principle, is the practical argument.

The same item, recorded at the time against reconstructed later
ItemCost at the timeCost afterwards
SeedOne lineImpossible, the run is gone
Snapshot date and sourceA commentGuesswork, and the data has since moved
A copy of the input fileSeconds and some diskOften unobtainable at any price
Parameters as named constantsA habit, no extra timeArchaeology through old code
Library versionsOne command, captured to a fileApproximate at best
The count of variants triedOne line per attemptGenuinely impossible

Read the right-hand column and the ordering becomes obvious. The items that cannot be recovered are the ones to set up before the first run, not after the interesting result appears, because by then the thing worth recording has already happened and gone unrecorded.

The last row deserves its own emphasis because it is the only item on the list that is irrecoverable in principle rather than merely in practice. A seed can be regenerated by re-running. A dataset can sometimes be re-purchased. The number of ideas you tried and discarded on the way to this one exists nowhere except in a note you did or did not make at the time, and without it nobody, including you, can say what the surviving result is worth.

What this looks like in practice, and what it costs

The smallest version that genuinely works is a single file that runs end to end and regenerates the result, with the seed at the top, the data source and snapshot date in a comment, and every parameter as a named constant rather than a number buried in the middle of a line. That is not a research infrastructure. It is an afternoon, and it puts a result ahead of most of what gets published.

It is worth being honest that full reproducibility, in the sense of bit-identical results on another machine in five years, is expensive and frequently unattainable. That is not an argument against the attempt. The realistic goal is weaker and far more useful: a reader should be able to see exactly what was done, and could redo it in principle. That is achievable at almost no cost, and it is enough for somebody to find the step they disagree with, which is the entire point.

There is also a self-interested case, and for most people it is the persuasive one. The reader who most often fails to reproduce your work is you, several months later, looking at a number you no longer remember producing. Everything here is cheaper to do while you are doing the work than to reconstruct afterwards, and reconstruction usually turns out to be impossible.

Frequently asked questions

What is the difference between reproducibility and replication?

Reproducibility is the same data and the same code producing the same answer. Replication is a fresh study reaching the same conclusion by its own route. They need entirely different things: the first needs disclosure, the second needs the finding to be real. A result can be perfectly reproducible and completely wrong, because reproducing an error reproduces it faithfully.

Why does an unseeded result count as no result?

Because it is one draw from a distribution of possible answers, and the reader has no way to know where in that distribution it fell. On the measurement on this page the lower bound moved by roughly a fifth of the interval's own width across twelve runs of identical code. Reporting one of those twelve without saying so presents a sample as a finding.

Does setting a seed make a result correct?

No, and treating it that way is the common mistake. A seed makes a result checkable, not right. It removes one specific source of variation so that any remaining disagreement between you and a checker is attributable to something real rather than to chance.

How many replications should I run?

Enough that the answer is stable at the precision you intend to report. That is measurable rather than a matter of convention: run the whole procedure several times and see how much the reported figure moves. If it moves in the digits you are quoting, you are quoting too many digits or running too few replications.

Why is the data snapshot so difficult?

Because a market data history is not fixed. Providers revise it, and a series adjusted for corporate actions is rewritten every time a new action occurs, so the same request today returns different numbers from last year. Naming a period is therefore not enough. The snapshot date, the source and the adjustment convention all have to be stated.

Does the software environment really change numerical results?

Yes, in the last digits, and that is enough when a decision sits at a threshold. Library versions change algorithms and defaults, and floating point addition is not associative, so the same operations summed in a different order give slightly different answers. It rarely changes a conclusion and it regularly changes whether two people's numbers match exactly.

Is this not excessive for an individual trader's own research?

The opposite. The person who most often fails to reproduce your work is you, six months later, trying to remember what you ran. Everything on this page is cheaper to do at the time than to reconstruct afterwards, and reconstruction is usually impossible.

What is the smallest useful version of all this?

A single file that runs end to end and regenerates the result, with the seed set at the top, the data source and snapshot date named in a comment, and the parameters as named constants rather than numbers buried in the code. That alone puts a result ahead of most published work.

If full reproducibility is unattainable, what is the realistic goal?

That a reader can tell exactly what was done and could redo it in principle. Perfect bit-for-bit reproduction across machines and years is expensive and often impossible. Complete disclosure is neither, and it delivers most of the value, because it lets a reader find the step they disagree with.

How should I read a result that discloses none of this?

As unverifiable rather than as false. Most published results are unverifiable, and most of those are produced in good faith by people who simply never recorded what they did. Treating unverifiable as dishonest is both unfair and useless. Treating it as uncheckable is accurate, and it tells you how much weight to put on it.

How these numbers were produced. A synthetic series of 500 observations was generated from a generator seeded once at 11, and asserted non degenerate (500 distinct values, standard deviation 1.0169) before use. Each interval is a percentile bootstrap of the mean at 400 replications. The variation shown is produced by giving each run its own distinct seed. That reproduces exactly what an uncontrolled run does, while leaving this page byte identical on every rebuild, which a genuinely unseeded demonstration would not be. The seeded comparison instead fixes one seed at 20260919 across all twelve runs. The replication ladder reports the spread of the lower bound across eight differently seeded runs at each count. Computed on Python 3.9.6. Every figure is reproducible from that description, and the build script for this page regenerates all of them.

The position is stated as at September 2026. Nothing here is personal financial advice; take advice on your own circumstances.

Related guides

How many trades before you can tell an edge from luck

Read →

Benchmarking against the right null

Read →

Reading a published strategy claim

Read →

Ready to go deeper than this article?

Bharath Shiksha is a 90-volume curriculum across 6 stages, from chart reading at ₹14,999 through capital raising, or the full bundle at ₹1,49,999. Recording what you actually did, while you are doing it, is the least glamorous habit in research and the one that separates a result from a recollection.

Take the free diagnostic →