Skip to content

Learn

Stock Strategy Development

Hand-check rolling calculations in AI-generated stock strategy code

Generated stock indicator code needs a numerical truth table before its strategy is evaluated. Use a short price sequence, calculate each intermediate quantity independently and test the threshold on both sides and at equality. A final buy signal alone cannot reveal whether the window, return endpoints or standard-deviation denominator were implemented correctly.

This guide checks a three-observation rolling calculation with Python’s standard library. All prices are synthetic. CoTrading formula-verification features remain planned or unverified. Passing arithmetic does not establish predictive power, stock-selection skill or future returns; it establishes only that the stated calculation matches these boundary fixtures.

Freeze the calculation vocabulary

Define the input as completed positive closes ordered by session. The window contains the current row and the previous two. Three prices span two return intervals, not three. The two-interval return is current close divided by the close two rows earlier minus one; its endpoints must not drift when a library’s rolling API changes.

Name the dispersion measure separately. Here standard deviation is calculated on the three price levels, in price units. It is not the volatility of daily returns. A separate low-volatility stock strategy would first construct returns and then estimate their dispersion; the same function name does not make those two inputs equivalent.

The Python statistics reference distinguishes population and sample standard deviation. The script deliberately computes both for comparison. Record denominator choice rather than assume a familiar library’s default is the intended rule. A sample calculation uses one fewer denominator observation than the population calculation.

Write the independent expected row

Use closes ten, twelve, fourteen, twelve and ten. At index two the three-price window is ten, twelve and fourteen. Its mean is twelve. Deviations are minus two, zero and two; squared deviations sum to eight. Population variance is eight divided by three, while sample variance is eight divided by two.

Population standard deviation is square root of eight-thirds, approximately 1.632993. Sample standard deviation is two. The two-interval return is fourteen divided by ten minus one, forty percent. Current close fourteen is strictly above mean twelve, so the target is one after this completed observation.

These expected values come from the raw window, not by calling the same generated helper twice. Repeating the implementation in the test can preserve the same off-by-one or denominator error. Keep the actual three prices beside every expected quantity so a reviewer can recompute it without trusting the code under examination.

Move the window one observation at a time

At index three the window is twelve, fourteen and twelve. Its mean is thirty-eight divided by three, approximately 12.666667. The current twelve is below it, so the target is zero. The two-interval return starts at index one, whose close is also twelve, giving zero rather than a return measured from the original ten.

At index four the window is fourteen, twelve and ten. Mean is twelve again and current ten is below it. The two-interval return is ten divided by fourteen minus one, negative two-sevenths or approximately minus 28.571429%. Reusing the original start price would incorrectly report zero and could change later strategy logic.

The first two rows have no complete window. Their intermediate quantities are null and the teaching target is zero by an explicit warmup rule. The full signal sequence is [0,0,1,0,0]. This signal convention differs from a sparse-input interface that may preserve null targets; document the selected convention rather than assume they are interchangeable.

Test equality independently from ordinary movement

Use a separate three-close fixture ten, twelve and eleven. Mean is exactly eleven, so strict greater-than returns zero. Replacing the last close with 11.01 gives mean approximately 11.003333 and returns one. Replacing it with 10.99 gives mean approximately 10.996667 and returns zero.

These small changes test the exact comparison operator. They do not optimize a threshold or estimate a meaningful trading edge. A generated implementation using greater-than-or-equal can pass the larger rising/falling sequence but fails the equality row. Boundary cases should be chosen to distinguish plausible incorrect code, not just reinforce the ordinary example.

Keep calculation tolerance separate from trading tolerance. The rule uses an exact strict comparison of its calculated values; the test’s numeric tolerance only compares independently expected intermediate results. Do not turn a verification epsilon into an undeclared no-trade band around the strategy threshold.

Fix a numerical tolerance before running

The acceptance helper uses absolute tolerance 10 to the power minus twelve and zero relative tolerance. Python’s math documentation describes the controls for approximate equality. Explicitly setting relative tolerance to zero prevents an unstated relative allowance from dominating at larger values.

For quantities expected to be exactly representable in this fixture, the script also uses exact assertions, such as mean twelve and sample deviation two. For fractions and square roots, use the declared approximate comparison. Showing six decimals in the article is presentation, not the internal acceptance threshold.

A real dataset can require another tolerance because of source precision or arithmetic scale. Declare that policy before reviewing failures. Do not keep increasing tolerance until an incorrect denominator passes; the population and sample deviations here differ far more than the allowed numerical error.

Run the rolling truth-table file

Download the complete example, save it as R579.py and run python R579.py with Python 3.12 or later. It uses only standard-library statistics and math tools with synthetic prices. The repository source is docs/growth/research/round-5/examples/R579.py.

Assertions connect raw windows, means, two-interval returns, both standard deviations and final targets. They check all three threshold cases and explicitly require the sample and population deviations to differ. The output prints intermediate rows, so a failure can be located before it propagates into an opaque strategy signal.

Test the temporal boundary as well

Every prefix of the five-price input must reproduce the same earlier rows. Appending a very large future close must leave all five original rows unchanged. The function uses trailing slices, so these tests exercise its claimed information boundary rather than just its numerical result on one dataset.

This does not establish that a supplied adjusted price history was available without later revisions. Nor does it test model training data or an execution engine’s shift. Those remain separate layers. The useful claim is specific: this rolling calculation reads only the stated completed input prefix and matches the independent truth table.

Review changes by the first wrong intermediate

When generated code disagrees, compare the included row indices first, then mean, return endpoints, denominator and threshold. Fix the earliest evidenced mismatch. Changing several definitions at once can make the final signal match accidentally while leaving the source of the original error unexplained.

Archive the calculation specification, numeric truth table, tolerance, code version and actual assertion output. Recheck after dependency upgrades, changes in rolling defaults or a new input unit. Completion means each stated quantity and boundary is reproducible; evidence that the indicator is useful for investing requires a separate real-data research design and must not be implied by a passing arithmetic test.

The moving middle window has its own dispersion assertions: sample deviation is square root of four-thirds and population deviation square root of eight-ninths. That checks the roll rather than validating only the first complete window. A separate large-number comparison must reject a difference of 10 to the power minus eight, confirming that zero relative tolerance is genuinely active. These checks connect the written denominator and error policies to actual executable acceptance, not just comments beside a library call.

FAQ

Are three prices the same as a three-interval return?

No. This fixture’s three prices span two intervals and use explicitly stated endpoints.

Can a correct signal prove the standard deviation is correct?

No. Assert intermediate values independently, including the chosen denominator.