Skip to content

Learn

Stock Portfolio Research

Test a winner-derived stock rule on future opportunities

A stock rule summarized from winning trades has already been selected using favorable outcomes. Testing it by collecting only the next winners repeats the same problem. Freeze a future observation scope first, then retain every planned opportunity, including losses, no signals, blocked execution, missing data and still-open positions. The useful question is what happened across that scope, not whether another appealing example can be found.

This guide demonstrates a prospective-test structure with ten synthetic observations. It does not report ten actual future market events, run a model or establish strategy effectiveness. The full-opportunity observation method is an external extension, and no persistent CoTrading scheduler, real account feed or broker replication capability is verified here.

State what the winning sample can and cannot support

At least five profitable completed rounds can be a reference input gate for preparing a candidate. It does not estimate its future win rate, validate a signal or prove that losses were absent. A rule designed around selected winners may simply explain the selection process. Preserve the source cutoff, winner definition and all attempted candidate revisions before beginning a separate observation.

The Bailey and coauthors manuscript on backtest overfitting discusses how repeated searches can select historical noise. This article uses that caution, not the paper’s CSCV or PBO calculation. Collecting a frozen future ledger is useful recordkeeping, but this ten-row illustration does not estimate a statistically reliable probability of success or remove every source of selection bias.

Our candidate is human-v1, supplied manually. The program calls no extraction model and makes no claim that AI learned a rule from actual journal records. The synthetic outcomes are constructed to show how a prospective policy should be applied; their place after a freeze operation in a script does not make them genuine unseen market observations.

Freeze the window, grid and decision policy

Define the observation grid before looking at its results. Here it is one planned opportunity per synthetic session, numbered one through ten, within a fixed single-stock USD scope. All ten positions in that grid must be represented. This is all opportunities under the declared grid, not every possible security, intraday decision or opportunity in the broader market.

The frozen policy requires coverage at least 0.9 and at least four closed outcomes. With those conditions satisfied, negative aggregate closed net profit causes pause_negative; otherwise the status is continue_observation. These thresholds are invented operational choices, not regulatory requirements, confidence levels or sufficient sample sizes for economic validation. Continue means more observation, never approval for live trading.

The Python hashlib documentation supports identifying the serialized policy. The sample computes its digest before constructing outcomes and verifies it is unchanged afterward. This is a local content check, not authenticated preregistration. Real research needs an independently retained freeze record, candidate identity and observation-start evidence rather than merely hashing an editable file after results arrive.

Keep coverage and outcome completeness separate

Coverage in this fixture is the fraction of planned sessions not marked quote_unknown or missing_opportunity. A known no-signal result counts as observed; an absent row does not. market_blocked also counts as an observed execution outcome. An open position has known observation coverage but lacks a closed profit, so it cannot be quietly counted as a zero-return completed trade.

Each row carries the frozen version and a unique session identity. The evaluator rejects duplicates, out-of-window sessions, unsupported statuses and version changes. Missing grid rows are explicitly counted. This prevents a shortened list of successful outcomes from inheriting the full ten-session denominator, and keeps an interrupted observation from being reported as an uneventful complete period.

Coverage is not a trading win rate. A rule can be well observed and lose money, or have positive closed outcomes but too many unknown opportunities to support the declared decision. Preserve the raw status counts so a reader can inspect which prerequisite failed. Do not merge missing input, a valid no-signal condition and a losing closed trade into one negative label.

Calculate closed outcomes without hiding losses

The fixture uses independent one-share opportunity outcomes with entry 100 and fee one on each side. Four closures have exit prices 104, 98, 103 and 99. Their net amounts are respectively 2, minus 4, 1 and minus 3 USD. The sum is minus 4. This is a closed-outcome diagnostic total, not the return or NAV of a funded portfolio with overlapping positions.

The evaluator verifies finite positive prices and finite nonnegative fees before calculating each closed amount. It does not use a missing exit as zero or infer a close for the open position. A separate virtual account ledger is required to analyze simultaneous cash competition, remaining market value and realized versus unrealized account performance. Those economics cannot be recovered by adding selected opportunity profits alone.

Retain blocked and no-signal rows even though they contribute no closed profit. They reveal whether the rule actually had a chance to act and whether execution assumptions limited observation. If a later journal correction changes one close, preserve the original output and rerun under an explicit revision rather than editing only the winning count or decision label.

Read the complete ten-opportunity case

The ledger has four closed outcomes, two no_signal rows, two market_blocked rows, one quote_unknown and one open position. Nine of ten opportunities have known observation status under the coverage definition, so coverage is 0.9. There are four closures and their net total is minus 4, satisfying the declared information thresholds but triggering pause_negative.

Pausing is an operational consequence of this policy, not a proof that the candidate can never work or that every future observation will lose. The open position still carries unresolved economic exposure. The report must keep that fact visible even though the negative closed-total condition already tells this toy policy to stop further use pending review.

Do not respond to the pause by silently changing the rule’s thresholds and continuing the same experiment. A revised candidate receives a new version and a new future scope. Keep the failed observation with the search history; otherwise a sequence of revisions could leave only the last successful-looking branch and conceal the selection that produced it.

Challenge winner-only filtering and missing coverage

Filter the future ledger to its two positive closures. Their combined profit is 3, but only two of ten planned opportunities remain, giving coverage 0.2 and two closed results. The frozen evaluator returns insufficient, rather than accepting the positive subset. This is a selection-mechanism counterexample, distinct from the negative total in the complete case.

Next turn a previously observed blocked row into quote_unknown. Closed results still total minus 4, but coverage drops to 0.8. The outcome becomes insufficient because the policy cannot claim the required observation coverage. An incomplete first-five-session ledger also remains insufficient. The script separately rejects duplicate opportunities and a NaN coverage threshold.

These checks do not turn 90% coverage into universal adequacy. Missingness can be systematic, and four closures remain very little evidence. Inspect what caused the missing observations, whether their concentration relates to the signal, and whether the planned scope still answers the research question. Additional observations should follow the frozen policy rather than a search for enough new winners.

Run and hand off the prospective ledger

Download the complete example, save R647.py and run python R647.py with Python 3.12 or later. It uses only the standard library and synthetic outcomes. Assertions verify the ten-row count, coverage 0.9, four closures, net minus 4, pause, winner-only insufficiency, extra-gap insufficiency, early incompleteness, duplicate rejection and unchanged policy content.

Deliver the policy, candidate version, full grid, status ledger, closed calculations, unresolved open exposure and decision reason. Distinguish pause_negative from insufficient; neither should be rewritten as a profitable strategy endorsement. The goal is a falsifiable and recoverable observation process that preserves unfavorable evidence. Actual long-run effectiveness and product integration remain unverified beyond this independent demonstration.

FAQ

Are five historical winners enough to validate the candidate?

No. They are only a reference preparation gate. This example collects a separate full planned scope and still makes no statistical effectiveness claim.

Can missing opportunities be treated as no signals?

No. Missing rows and unknown quotes reduce coverage. A no-signal result requires an observed evaluation.