Test whether a stock factor survives the first executable entry
A stock factor can have a favorable forward-return label while losing money from the first entry that was actually possible. Build a time ledger linking score formation, source availability, processing readiness and executable sessions, then evaluate a predeclared holding rule from the actual entry. A uniform one-row shift cannot establish all of those facts.
This guide follows one fictional US stock with offset-aware January timestamps, a fixed expiry and synthetic prices. CoTrading timing diagnostics remain planned or unverified. No real publication feed, exchange calendar, broker or historical performance series was tested. The deliverable is an auditable entry decision and a separate cost ledger.
Give each event its own timestamp
Record the score’s economic measurement endpoint, the source’s dissemination time, the pipeline’s usable time, the decision cutoff and the intended execution event. A score calculated from Friday’s close can arrive after Monday’s opening. Its formation date alone therefore cannot authorize a Monday-open trade.
Use an explicitly understood timezone. Python’s datetime documentation distinguishes timestamps with timezone information from ambiguous naive objects. The fixture uses explicit minus-five-hour offsets for January events. That is a teaching representation, not a complete exchange calendar or a rule for daylight-saving changes throughout the year.
If availability is known only as a date, do not invent an intraday time to capture an attractive opening move. Apply a conservative documented convention or obtain better evidence. Likewise, a feed timestamp and the moment an account could use its data can differ; preserve processing readiness if that delay matters to the chosen execution model.
Freeze the entry and expiry rule
For this experiment, choose the first supplied open strictly later than availability, provided the instrument is executable and that open is no later than expiry. Strictly later means an event with the exact same timestamp is not automatically accepted. Real systems need a processing and order-submission convention rather than assume instantaneous action.
First means the earliest eligible timestamp, independent of input row order. The implementation filters permitted events and selects the minimum parsed timestamp; it does not return the first matching row encountered. A counterexample extends expiry to January 8 at 16:00 and reverses the rows. The selected event must still be January 6 at 09:30, not the later January 7 opening that happens to occur first in the input.
Expiry is January 6 at 16:00 with the same offset. If no eligible open appears before then, cancel the entry. Do not extend the deadline after observing a later favorable price. The holding rule for an accepted entry is a sale at the supplied following-session open; the example does not search for an optimal holding interval.
Keep selection and executability separate. The stock can remain the preselected factor candidate while an opening is unusable. An execution block does not retroactively reduce the factor score. Preserve candidate, target, rejection and actual fill as different fields so the missing trade can be traced without rewriting the original ranking.
Rebuild the three clocks in the main case
The synthetic score forms January 2 at 16:00. Its usable availability is January 5 at 09:35. The supplied January 5 open is 09:30 at price ten, so it is already past when the score becomes available. A valid entry cannot use that ten-price opening under this contract.
The next supplied open is January 6 at 09:30, price twelve, with permission true. It is later than availability and before expiry, so it becomes the first permitted entry. The following supplied open, January 7 at 09:30, is eleven and supplies the fixed exit. Save all three event rows rather than infer them from a daily date index.
The statistical label from January 5 open ten to January 6 open twelve is plus twenty percent. It may be a valid descriptive label for an analytical score table, depending on its definition, but it is not the return of this available-to-trade implementation. By the time the strategy can enter at twelve, that price move has already occurred.
Reconcile the actual holding and exposure
Start with 1,000 and buy forty shares at twelve, paying a fictional fee of one. Purchase cash outflow is 481, leaving 519. At the fixed next open eleven, sell forty shares and pay another one, receiving 439. Final cash is 958, with no position remaining.
The stock’s actual entry-to-exit gross return is eleven divided by twelve minus one, approximately minus 8.333333%. The account’s price loss is forty and its fees two, giving a net loss of forty-two, or 4.2% of initial capital. Those measures differ because only 480 of the initial 1,000 was invested at entry.
Keep the twenty-percent statistical label, negative stock holding return and negative account return in separately named columns. None should overwrite another simply because a report expects one number called factor return. This distinction is the central acceptance condition: an attractive pre-entry move is not money earned by a later feasible holding.
Test a blocked opening and cancellation
Change January 6 permission to false while keeping the timestamps and prices unchanged. January 5 is still too early and January 7 is after the fixed expiry. The entry search returns no eligible event. It must not jump to January 7 merely to ensure that every selected stock receives a trade.
This counterexample is an execution-availability failure, not a changed signal or a different delay parameter. With no entry there is no executed notional and no fictional fill fee. A production implementation should record the blocked opportunity and the cancellation reason while retaining the original score provenance for later analysis.
If the expiry rule is changed, that is another strategy version requiring new validation. A first-open search and a universal shift by one row are not interchangeable: weekends, late publication, instrument-specific data gaps and permissions can cause different first eligible events. Do not call this single example a proof that every source and training input is free of look-ahead.
Execute the timestamp and cash assertions
Download the complete example, save it as R569.py and run python R569.py with Python 3.12 or later. It uses the standard library and synthetic events only. The repository source is docs/growth/research/round-5/examples/R569.py.
Assertions check the ordering formation before availability before entry, the January 6 entry, the twenty-percent label, final cash 958 and the expired blocked case with no entry. The output exposes the selected event and both return definitions. Review the timestamps and amounts together rather than accept an apparently correct final return with an impossible earlier fill.
Build the real study from evidence
Investor.gov’s order reference explains why an observed price is not a guaranteed execution price. For real data, document the submitted order convention, price source, restrictions, liquidity and costs. A permitted model opening is still an assumption requiring appropriate evidence for the account size and market.
Before expanding across stocks, freeze availability handling, processing margin, market calendar, expiry, holding rule and missing-event policy. Store one row per requested entry, including nonentries, with an explicit reason. Summaries that retain only filled winners conceal the exact coverage failures this time ledger is designed to reveal.
Update the research when a source revises timestamps, an exchange calendar changes or a processing convention changes. Reconstruct one late-publication entry and one cancelled entry from saved artifacts. The completed package demonstrates what could be entered under declared information and execution constraints; it does not choose the most profitable latency or promise that a factor survives delay in real markets.
Audit the event selected by the join
Inspect the event immediately before the chosen entry as well as the entry itself. In this fixture that preceding open is rejected because it occurred five minutes before availability, not because its price was unfavorable. The next event is accepted from the timing and permission fields before its later exit price is evaluated.
Store rejection reasons for every candidate event considered: too early, not executable or after expiry. A later data correction can change which reason applies, so preserve the original event version. Do not overwrite a cancellation with a hypothetical delayed fill when comparing reports. Such a fill can be studied under a new expiry contract, but it is not an explanation of what the original contract did. This event-level record is what makes a time join auditable rather than a hidden spreadsheet shift.
FAQ
Does shifting a signal by one day solve every timing issue?
No. Publication, processing, instrument availability and exchange sessions must be joined explicitly.
Can a positive forward label coexist with a losing feasible trade?
Yes. This synthetic example enters only after the favorable labeled move and then loses on the fixed holding interval.