Swiss Equity Backtesting: A Point-in-Time Audit Before You Trust the Curve
The short answer
Do not approve a Swiss-equity strategy because its historical return curve is attractive. Approve the research process only after you can show that every input existed when the simulated decision was made, the security universe reflects what could actually have been traded then, the fill model respects SIX trading phases and plausible costs, and the final strategy was not selected by repeatedly looking at the same test period. If any one of those proofs is missing, label the result exploratory and do not present it as evidence of expected live performance.
This is a technical due-diligence guide for people building, reviewing, or buying quantitative research—not an investment recommendation. Its reusable asset is a point-in-time review matrix and a small, executable Python gate for a trade ledger. The code can catch timestamp, membership, price, spread, and cost inconsistencies in a CSV. It cannot prove that the strategy is profitable, that a data vendor is complete, or that the historical universe has no missing delisted securities.
The distinction matters. A backtest is a counterfactual simulation, not a time machine. The SEC’s US investment-adviser marketing rule treats hypothetical performance as a category that needs sufficient assumptions, criteria, risks, and limitations for its intended audience; the rule is US-specific and is not Swiss legal advice. In a 2022 enforcement matter, the SEC described a backtest/live mismatch involving different securities and insufficiently correlated substitutes. That case does not establish a universal error rate. It is a concrete reminder to test whether the simulated instruments and the instruments actually available to the operator match. (SEC final rule, 2020; SEC administrative proceeding, 2022)
What the result already visible on the chart leaves unanswered
A cumulative-equity chart compresses a long chain of choices into one line: which securities entered the universe, when a signal became knowable, what price could be executed, how fees and spread were charged, how corporate actions were handled, how many versions were tried, and which period was reserved for final evaluation. A chart can be calculated correctly from a flawed chain. It can also be a helpful diagnostic when the chain is transparent. The question is not “Are backtests useless?” It is “What claims can this specific backtest support, given its data and procedure?”
The CFA Institute’s backtesting and simulation reading identifies look-ahead and survivorship bias as issues and discusses rolling-window methods, historical simulation, fat tails, and structural breaks. Its point is not that one validation recipe removes uncertainty; it is that the design of the test controls what the result means. A rolling or walk-forward design is closer to the sequence of real decisions than repeatedly optimizing on the whole period, but it still inherits errors in timestamps, universe construction, execution assumptions, and data quality.
One real user question makes the gap tangible. In an October 2026 r/algotrading discussion, a poster compared a rotation strategy on today’s Dow constituents with one using historical membership and asked whether researchers use point-in-time constituents or accept survivorship bias. Other comments raised the more specific issue that a dataset may drop a security’s price history after delisting. This is useful evidence of a practical question, not evidence that a particular backtest result is typical: it is one public thread, self-reported, with no independently audited data. (Discussion and question)
The same question applies to Swiss equities, but the answer cannot be copied from a US index example. A SIX-listed security may be a blue chip, a mid- or small-cap, a secondary listing, a right, or a separate trading line. The operational universe and liquidity assumptions need to match the instrument and period under study. A SIX liquidity and order-book guide explains why a “listed on SIX” label alone does not tell a reviewer whether an assumed order size, spread, market phase, or venue is plausible. It is a practical guide, not a source for historical tick data or a claim about any specific instrument today.
A four-proof rule for deciding whether a backtest is ready to review
Treat these as independent gates. A strong answer in one column never compensates for a missing answer in another. For example, a careful walk-forward split does not repair an index universe made from constituents that survived until today. A point-in-time constituent file does not fix a signal calculated from a revised financial statement that was unavailable at the decision timestamp. A plausible spread model does not remove parameter selection after the “holdout” results were inspected.
| Proof | Review question | Minimum evidence | A fail-closed answer |
|---|---|---|---|
| Information timing | Could this exact feature or event have been observed before the decision? | Original publication/availability timestamp, timezone, revision policy, and a lag rule | “We use the fiscal-period date” is not enough when publication was later |
| Tradable universe | Was this security in the eligible set on that date, with identity and delisting history intact? | Effective-dated membership, stable security identifier, listing/delisting and corporate-action records | Today’s members reused across the past = exploratory only |
| Execution | Could the stated fill and size plausibly have occurred in that phase and market? | Order type, next eligible event/bar, spread, fees, slippage, size/depth and sensitivity | Same-bar close fills with no execution evidence = reject headline performance |
| Research selection | Was the final rule chosen without repeatedly using the final test period? | Trial log, frozen design choices, untouched evaluation window, walk-forward or other justified procedure | Unknown number of trials or reused holdout = selection risk remains |
The decision rule is intentionally conservative: “unknown” is not “pass.” Unknown means the result is still a research artifact. That does not mean the idea is false; it means the evidence is not yet fit to carry a claim about live behavior.
Proof one: reconstruct when information became usable
For each input, distinguish at least four times: the economic period it describes, the time an issuer or source published it, the time your data vendor received or revised it, and the first time your simulated process could have used it. These are not interchangeable. A company’s annual result may describe a year ending in December and be published months later. If a backtest joins that value to December rows without a publication lag, it gives the historical strategy information earlier than a real operator had.
Store timestamps with explicit timezone offsets. Define a decision time rather than relying on a date label. If a daily strategy makes a decision using the official close, state whether the order is assumed to be submitted after that close and filled at the next eligible market event. If a feature depends on a filing, use the filing’s public availability time—not the fiscal year end. If the vendor backfills a corrected value, preserve the vintage that was available at the time or disclose the lag and its rationale. If historical vintages do not exist, mark that feature as non-point-in-time and exclude it from a strict historical claim.
An effective rule can be expressed as:
feature_is_eligible = source_available_at <= strategy_decision_at
fill_is_eligible = fill_event_at > strategy_decision_at
These comparisons are necessary, not sufficient. A timestamp can be syntactically valid but semantically wrong because it is an ingestion date rather than a public release date, because a local time was parsed as UTC, or because the exchange calendar was ignored. Keep the raw vendor timestamp, normalized UTC timestamp, exchange-local display time, and transformation rule in the audit trail. Never silently replace a missing timestamp with midnight or the period-end date.
The CFA Institute discussion of backtesting describes look-ahead bias as using information that would not have been available at the time. The operational implication is to make availability part of the data model, not a footnote in the report. Add it to feature rows, join keys, and test assertions so that a future data refresh cannot quietly alter the past.
A practical timestamp audit
Pick a handful of signals from the most profitable and least profitable parts of the curve. For each, trace the complete lineage backwards: output trade, signal row, feature values, upstream record, source publication, vendor capture, revisions, and timezone conversion. Then run the same pipeline with all inputs cut off at a historical timestamp. The earlier output should not change when information published after that timestamp is removed. If it does change, the pipeline has a leak or a hidden dependency. Record the exact cutoff and data snapshot hash so someone else can repeat the check.
Do not confuse a “lagged feature” with proof of availability. Shifting a series by one bar is useful for detecting same-bar mistakes, but it does not answer whether the source was available at that bar. For monthly or irregular data, the correct lag may depend on publication schedules. A rule such as “always lag one day” can still leak when the actual release arrives later, and can be unnecessarily conservative when a timestamped release was genuinely available sooner. The documented availability event should decide.
Proof two: build the universe that existed then
Survivorship bias is not just forgetting companies that failed. It can enter through the list of current constituents, the list of securities that still have complete price data, ticker reuse, renamed issuers, mergers, secondary lines, rights, suspended instruments, and vendor symbol mappings. If the database contains only securities that remain active today, a historical strategy may never see the failures, acquisitions, delistings, or exits it would have encountered. If the security identifier changes but the code joins on ticker alone, the test may splice two different instruments into one apparent history.
For a changing index or screening universe, define membership as an interval with an effective start and end. Preserve both the announcement date and effective date where available. A future announced index change must not enter the eligible universe before the decision system could reasonably know it; the actual effective date matters for tradability. For a broad screen that is not an index, define the screen inputs and their timestamps too. If the research uses a fixed universe, state why that universe was knowable at the beginning of the test and what it excludes. Swiss event data also needs its own scope: a SIX Exchange Regulation communiqué describes specific reporting processes for certain own-share buyback and price-stabilisation transactions. It does not give a backtest dataset or execution history; it is a reminder to identify which market-event record a vendor has captured before interpreting a price series.
Delisted-security treatment needs an explicit event policy. A missing quote after delisting is not a neutral return. Depending on the instrument and event, the position may receive cash, a successor security, a final tradable price, a cancelled instrument, or another corporate-action outcome. The data vendor may provide a delisting return, may stop the series, or may fold an event into adjusted prices. Do not infer which behavior occurred from a smooth chart. Read the vendor’s data dictionary, compare selected event records with primary exchange or issuer notices, and document any unresolved gap.
Ticker is a label; it is not a durable identity key. Maintain a mapping table with stable instrument ID, issuer ID where appropriate, listing venue, currency, share class, ticker validity interval, and corporate-action links. On a ticker change, use the mapping valid for the historical date. For a merger or separate trading line, decide whether the strategy could have held both securities and how positions are translated. If your data source cannot support that distinction, narrow the claim instead of assuming the mapping is harmless.
The community thread above illustrates a real dispute about current versus historical membership; the CFA Institute’s model-validation monograph explains that testing only surviving companies can omit failed firms from the evaluation. Neither source provides a Swiss-security membership database. For that, obtain a point-in-time file from a data provider or the exchange, and test its completeness against records for additions, removals, suspensions, delistings, and corporate actions.
Proof three: model Swiss execution, not just prices
Daily OHLC data can be enough for a broad research question, but it often cannot establish a precise fill. A candle’s high and low do not tell you the order-book depth, queue position, auction imbalance, bid-ask spread at the decision, or whether an order could have participated in the stated phase. Closing auction, continuous trading, and post-close trading are different mechanisms. A close printed during an auction is not automatically an executable price for an order submitted after the auction has ended.
SIX describes its order-book trading models, including the Central Limit Order Book, and explains that market models determine how orders are matched and how trading periods are structured. Its trading-hours materials also distinguish opening, continuous, closing-auction, and Trading-at-Last phases for applicable segments. These official sources support a market-mechanics check; they do not prove that a particular historical order would have filled. (SIX on-order-book trading; SIX trading hours)
For a daily close-based signal, a defensible baseline is to compute the signal using information available at the close and then model an order at the next eligible event. For a bar-only simulation, that might mean next-session open plus a disclosed slippage rule. But “next open” is still an approximation: opening auctions, limit constraints, market gaps, order size, and the data vendor’s adjusted/unadjusted price convention all matter. Treat it as a scenario, not as a verified fill.
At minimum, report a cost stack separately: commission and exchange fees; bid-ask spread; slippage or market impact; financing or borrow where applicable; currency conversion where the strategy crosses currencies; and cash or corporate-action effects. State whether the spread is charged one-way or round-trip. If you use basis points, define the denominator and side. Use multiple plausible assumptions and show whether the qualitative conclusion survives. Do not select a single cost rate because it preserves a desired result.
The liquidity guide recommends checking the actual bid, ask, visible size, recent volume, trading phase, and news context. That is a useful operational checklist. SIX itself publishes market-data information and describes its order books; actual historic order book data may require access beyond public pages. (SIX market data) If you only have bars, write “bar-based proxy” rather than “realistic execution.”
Use sensitivity as a diagnostic, not as a rescue
Re-run the same frozen strategy under a small, predeclared grid of execution assumptions: baseline spread/slippage, a wider-cost scenario, and a stressed liquidity case. The exact values should come from the instrument, order size, venue, period, and available data—not from a universal percentage. If the result flips sign under a modest plausible change, that is a material finding. It does not prove the strategy is bad; it tells the reviewer that the historical edge is execution-sensitive and the current data is insufficient to make a stronger claim.
Avoid a common mistake: calibrating transaction costs on the same period and then presenting the most favorable estimate as a neutral assumption. Document where each cost came from, whether it is observed or modeled, how it changes by turnover and liquidity, and whether cost assumptions were chosen before the final test. If you cannot observe historical spreads, say that. A transparent imperfect model is more useful than a precise-looking number with no provenance.
Proof four: count the experiments that selected the winner
If you tried many rules, thresholds, lookback windows, universes, cost assumptions, and feature sets, the best historical curve is also the result of a selection process. Reporting only the winning variant hides the search. The exact number of trials may be hard to reconstruct in old research, but “we tried a few” is not an audit trail. Record each meaningful variant, the data period used to choose it, and whether the final period influenced the choice.
Separate the design period from a final evaluation period that is not used to revise the strategy. Once you inspect the holdout result and modify the rule in response, that period has become part of development; it is no longer untouched. A walk-forward process can mimic repeated decision-making by fitting on past windows and evaluating on subsequent windows. It can reduce the temptation to pick parameters from the whole history, but it still needs point-in-time data and explicit rules for when models are refit. Rolling windows can also produce unstable estimates when markets experience structural breaks or fat-tailed returns; the CFA reading explicitly notes these limitations.
The peer-reviewed work by Bailey, Borwein, López de Prado, and Zhu on the probability of backtest overfitting proposes combinatorially symmetric cross-validation as a framework for analyzing how strategy selection may overfit. This is not a magic score that turns a backtest into a forecast. The method answers a particular question under its design and assumptions. It does not repair missing delisted prices, wrong timestamps, unmodeled spreads, or an out-of-scope market. A result should say what procedure was used, how many variants were compared, and which parts of the sample were exposed during development.
The SEC’s discussion of hypothetical performance is useful here as an audience and disclosure lens: the Commission notes that backtests can be optimized with hindsight. Its marketing rule applies to covered US investment advisers, not automatically to a Swiss publisher or investor. The methodological point travels more broadly: readers need assumptions, selection criteria, risk, limitations, and a clear label distinguishing hypothetical from realized performance.
An original reusable asset: the point-in-time backtest review matrix
Use the matrix below at the beginning of a review, before debating the headline return. The statuses are PASS, FAIL, and UNKNOWN; unknown never silently becomes pass. A reviewer should be able to attach a file, query, version, or screenshot to every pass. The matrix is original synthesis, not a statistically validated scoring model. It has no weighted total because a high score in one category should not cancel a fatal leak in another.
flowchart TD
A[Define the claim and audience] --> B{Point-in-time inputs proven?}
B -- no / unknown --> X[Restrict scope or label exploratory]
B -- yes --> C{Historical universe and identities complete?}
C -- no / unknown --> X
C -- yes --> D{Execution phase and cost model defensible?}
D -- no / unknown --> X
D -- yes --> E{Selection process and holdout documented?}
E -- no / unknown --> X
E -- yes --> F[Independent review and reproducible run]
F --> G[State remaining uncertainty beside the claim]
| Gate | Evidence to attach | Automated check | Manual challenge | Stop condition |
|---|---|---|---|---|
| Decision timeline | Feature source, publication time, vendor capture, timezone conversion | available_at <= decision_at |
Was available_at a public release or just ingestion? |
Any material feature arrives after decision |
| Security identity | Stable ID and dated ticker/listing map | No ambiguous ticker join | Could a symbol represent a different issuer or line? | Unresolved identity splice |
| Universe membership | Effective-dated inclusion and removal events | Decision time inside membership interval | Does the file contain securities that later failed or left? | Today-only constituent list reused historically |
| Corporate actions | Split, dividend, merger, delisting treatment | Price/quantity continuity assertions | Does the vendor already adjust this series? | Double adjustment or missing event outcome |
| Order timing | Signal and fill timestamps, order type, phase | Fill strictly after decision | Could the order participate in this auction/session? | Same-event fill without evidence |
| Cost realism | Commission, spread, slippage and sensitivity source | Nonnegative costs and valid quotes | Does the cost scale with size and liquidity? | Costs omitted or selected after looking at outcome |
| Selection discipline | Variant log, frozen code/config, split dates | Test-set access recorded | Was this holdout reused after inspection? | Final evaluation was used to tune the winner |
| Reproducibility | Data version/hash, code commit, run config | Repeat run emits same trades | Can an independent implementation reproduce key rows? | Missing input or run cannot be recreated |
Do not convert this into “seven out of eight means good.” The matrix is a gate map, not a risk probability. One failed stop condition can invalidate the headline claim even when every other row passes. Conversely, an unknown cost source might be a fixable data gap rather than evidence that the strategy itself has no merit. The output should name the exact uncertainty and the least costly way to resolve it.
A compact Python CSV gate you can adapt
The following standard-library script checks each trade row for a few common point-in-time and quote inconsistencies. Save it as audit_trades.py and run python audit_trades.py trades.csv. The CSV requires the named columns. Date-times must be ISO 8601 strings with a timezone offset; the script rejects naive timestamps rather than guessing. member_to is inclusive in the data convention used here; adapt that rule if your source defines effective end dates differently.
#!/usr/bin/env python3
"""Fail-closed checks for an illustrative point-in-time trade CSV.
Required columns:
trade_id,decision_at,signal_available_at,fill_at,data_available_at,
member_from,member_to,bid,ask,fill_price,cost_bps
This is a data gate, not a backtest engine, execution simulator, or proof of profit.
"""
import csv
import sys
from datetime import datetime
from decimal import Decimal, InvalidOperation
from pathlib import Path
def instant(value, field, row_number, issues):
try:
parsed = datetime.fromisoformat(value.replace("Z", "+00:00"))
if parsed.tzinfo is None or parsed.utcoffset() is None:
raise ValueError("timezone offset missing")
return parsed
except (ValueError, AttributeError):
issues.append(f"row {row_number}: invalid timezone-aware {field}")
return None
def decimal(value, field, row_number, issues):
try:
number = Decimal(value)
if not number.is_finite():
raise InvalidOperation
return number
except (InvalidOperation, TypeError):
issues.append(f"row {row_number}: invalid numeric {field}")
return None
def audit(path):
required = {
"trade_id", "decision_at", "signal_available_at", "fill_at",
"data_available_at", "member_from", "member_to", "bid", "ask",
"fill_price", "cost_bps",
}
findings = []
with Path(path).open(newline="", encoding="utf-8-sig") as handle:
reader = csv.DictReader(handle)
missing = required - set(reader.fieldnames or [])
if missing:
raise SystemExit("missing columns: " + ", ".join(sorted(missing)))
rows = list(reader)
for number, row in enumerate(rows, start=2):
issues = []
decision = instant(row["decision_at"], "decision_at", number, issues)
signal = instant(row["signal_available_at"], "signal_available_at", number, issues)
fill = instant(row["fill_at"], "fill_at", number, issues)
data = instant(row["data_available_at"], "data_available_at", number, issues)
start = instant(row["member_from"], "member_from", number, issues)
end = instant(row["member_to"], "member_to", number, issues) if row["member_to"].strip() else None
if decision and signal and signal > decision:
issues.append("signal became available after decision")
if decision and data and data > decision:
issues.append("input data became available after decision")
if decision and fill and fill <= decision:
issues.append("fill is not strictly after decision")
if decision and start and decision < start:
issues.append("security not yet in eligible universe")
if decision and end and decision > end:
issues.append("security already outside eligible universe")
bid = decimal(row["bid"], "bid", number, issues)
ask = decimal(row["ask"], "ask", number, issues)
price = decimal(row["fill_price"], "fill_price", number, issues)
cost = decimal(row["cost_bps"], "cost_bps", number, issues)
if bid is not None and bid <= 0:
issues.append("bid must be positive")
if ask is not None and ask <= 0:
issues.append("ask must be positive")
if bid is not None and ask is not None and ask < bid:
issues.append("ask is below bid; inspect crossed/incorrect quote")
if price is not None and price <= 0:
issues.append("fill_price must be positive")
if cost is not None and cost < 0:
issues.append("cost_bps must not be negative")
if issues:
findings.append((row.get("trade_id", f"line-{number}"), issues))
print(f"rows_checked={len(rows)} rows_flagged={len(findings)}")
for trade_id, issues in findings:
print(f"{trade_id}: " + "; ".join(issues))
return 1 if findings else 0
if __name__ == "__main__":
if len(sys.argv) != 2:
raise SystemExit("usage: python audit_trades.py trades.csv")
raise SystemExit(audit(sys.argv[1]))
The script deliberately refuses to invent a timezone, membership end, or execution price. It flags rows where source data or decision timing is contradictory, and returns a nonzero exit code if any row is flagged. It does not decide whether the member_from and member_to values themselves are complete or historically correct. It does not confirm a spread was available at the fill time, estimate queue priority, handle partial fills, model corporate actions, calculate returns, or detect that a researcher tried dozens of strategies and only saved one. Those require other files and review steps.
Example fixture and method note
To explain expected behavior, create four synthetic rows: one clean row; one where the signal timestamp is after the decision; one where the security’s membership interval starts after the decision; and one with a fill timestamp equal to the decision. Run the script and confirm that the first row passes and the other three are flagged. This is a deterministic fixture, not market data, a performance study, or evidence about Swiss shares. The method is a four-row hand-authored unit test on 25 October 2026; all market observations are excluded; the test only checks the stated validation conditions. It cannot estimate how frequently real datasets contain these errors. The limitation should stay beside the example whenever someone reuses it.
That fixture is useful because it tests the review tool, not a trading idea. A team can add a row for a crossed quote, negative costs, missing offset, or fill before decision and assert the expected flag. Keep the fixture in version control with the code and make it part of continuous integration. Then a future refactor that accidentally permits a naive timestamp or same-event fill fails early. A green unit test means the gate behaves as designed on those examples; it does not mean a production feed has been independently verified.
What this script cannot see—and what to add next
The checker sees only rows that are already in the trade CSV. If a bankrupt company has disappeared from the source universe entirely, no row can tell you that it should have been there. Add a second, effective-dated universe file containing every eligible instrument at each rebalance, plus its provenance and membership dates. Compare the point-in-time universe with the actual index or screening methodology for selected dates. Sample both additions and removals, and deliberately include names that later delisted. If you do not have a delisted-security source, say so and narrow the result to the covered universe; do not describe it as a full-market backtest.
Likewise, the script cannot establish historical spread or order-book availability. To make that claim, connect the trade to a quote or order-book record with a timestamp, venue, phase, and size context. If this data is unavailable, run a sensitivity analysis with a range that the research team can defend from market data or broker records, then report the result as modeled. Do not call it a measured spread. SIX’s public descriptions of order books and its data services clarify the market concepts and potential records, but the open web page is not a substitute for a licensed historical feed or a filled order audit.
It also cannot identify research selection leakage. Save a machine-readable experiment registry: strategy identifier, code commit, data snapshot, configuration hash, date range, objective metric, whether the run was exploratory or confirmatory, and who saw the output. A final test period is no longer untouched once anyone uses its outcome to choose a variant. If legacy work did not preserve this registry, disclose that the number of trials is unknown. The Deloitte model-risk discussion emphasizes problem definition, independent validation, and ongoing model operations in an investment-management setting. That is consulting guidance, not a guarantee; the reusable lesson is to assign someone other than the strategy author to challenge the model’s purpose, data, assumptions, and operation.
Finally, code-level checks do not certify economic logic. A row can pass every timestamp condition and still use an inappropriate benchmark, an impossible short, an unsupported corporate-action assumption, or a strategy whose edge disappears out of sample. The validator is a smoke alarm for a handful of mechanical conditions. A smoke alarm that stays quiet does not prove there is no fire; independent source checks and outcome-level review remain necessary.
Contradictions and where this recommendation fails
There is a tension between the appeal of realistic data and the cost of obtaining it. A full point-in-time universe, adjusted corporate-action history, archived fundamentals, and historical order books can be expensive or unavailable for some Swiss instruments. A smaller researcher may reasonably start with a narrow liquid subset, a bar-level execution proxy, and a clearly labeled exploratory test. The recommendation is not “never research until every data limitation is solved.” It is “do not let a narrow proxy silently stand in for a claim about a broader universe or live fills.”
There is also no single universally correct out-of-sample protocol. A fixed holdout, rolling-window evaluation, and combinatorially symmetric cross-validation answer different questions and have different assumptions. The CFA Institute material notes that rolling backtests still face distributional properties and structural breaks; Bailey and coauthors propose PBO analysis for the selection problem. Neither means that a reviewer can pick one method by fashion and claim validity. Choose the method that matches how the strategy is developed and used, pre-register the choices where practical, then state what it cannot establish.
Execution assumptions can be both too optimistic and too pessimistic. A fixed spread may overstate costs for a large liquid order during normal conditions, yet understate them for a small-cap during stress. A market-order assumption can be unsuitable when the actual process uses limits; a limit-order assumption can be unrealistic if it assumes every touched price fills. Preserve scenarios instead of collapsing uncertainty into a single convenient value.
The SEC’s hypothetical-performance rule is sometimes cited as if it were a global backtesting standard. It is not. It governs covered US investment-adviser advertising. The SEC enforcement example is one specific proceeding, not a survey of all managers. Deloitte’s model governance content is a firm’s professional guidance, not independent empirical proof that any framework prevents model failure. CFA Institute readings are educational materials, not exchange data. SIX is authoritative for its own market structure and data offerings, but not for your vendor’s historical completeness. The reader should retain each source’s scope rather than flatten these into a universal “regulatory consensus.”
A practical review workflow
Start by writing the decision the analysis is supposed to support. “Does the strategy merit a paper-trading phase?” is materially different from “Can the presenter advertise a performance history?” or “Should a client allocate capital?” Define the audience, market, instrument set, horizon, and the exact claim. This prevents a generic chart from answering a broader question than the evidence can bear.
Freeze the inputs before reviewing the output. Record the code commit, data vendor and package version, extraction timestamp, relevant tables, corporate-action policy, timezone policy, exchange calendar, configuration, and output hash. Use immutable snapshots where possible. If the source data is corrected later, preserve the original dataset and run a separate corrected-data comparison rather than silently overwriting the file that produced the reported result.
Sample records by risk, not just convenience. Inspect trades around the most profitable segment, the worst drawdown, delistings, ticker changes, market opening and closing phases, earnings or other releases, and periods with wider spreads. A random sample can complement this targeted challenge, but it will not replace event-focused checks. Record each sampled row and why it was selected so the reviewer can distinguish a targeted stress test from a representative estimate.
Run the mechanical gates first: timestamp ordering, universe interval, identifier joins, quote validity, nonnegative cost inputs, and reproducibility. Then review the strategy’s economic premise and execution. Finally challenge the selection process: parameter count, variants tested, stopping rule, holdout exposure, regime sensitivity, and any benchmark selection. Keep a findings log with owner, evidence, disposition, and retest date. If a finding is closed by changing data or code, rerun the full pipeline and preserve both the previous and new results.
The SIX trading guide can support the market-model part of this review; SIX’s market-data page describes order-book, price, volume, turnover, and historical-data offerings. Those links help a team ask the right data questions. They do not mean that every record is open-access, that every historical field has the same coverage, or that a simulated order would certainly have executed as modeled.
Failure modes that routinely survive a polished report
Period-end joins. A database labels fundamentals by fiscal period and the strategy treats the period end as the publication time. The cure is an availability timestamp and a documented lag; if the original time is unknown, the feature is not point-in-time verified.
Current index members in old years. The analyst downloads today’s constituents, then applies them to the entire backtest. The plot may be reproducible and still omit companies that left or failed. Rebuild effective-dated membership or explicitly restrict the claim.
Ticker-only joins. A symbol is reused, changed, or assigned to another share class. The system connects histories that belong to different instruments. Use stable IDs and dated mapping tables; isolate unresolved rows instead of guessing.
Delisting as missing data. The price series stops and the engine drops the position without a realized outcome. Confirm the vendor’s convention and model the corporate event. A missing final value is not automatically zero risk or a harmless exclusion.
Same-close fill. The signal uses closing data and the simulated trade is filled at that same close, although the order could not have been submitted before the price was known. Move the fill to the next eligible event or provide an actual execution model that justifies the assumption.
Closing-auction confusion. An ordinary daily close is treated as proof that an order could fill in the closing auction. Check the actual market phase, order submission cutoff, order type, auction participation, and instrument segment. If those timestamps are not available, label the fill as an approximation.
A single cost number. Fees are included but spread, slippage, liquidity, or turnover are not. A headline net return can still be optimistic. Publish a cost stack and sensitivity, and label observed versus modeled inputs separately.
The holdout that was no longer held out. The team inspects final-period results, modifies the strategy, then continues to call the same period “out of sample.” It is now part of development. Freeze a new evaluation design or admit that the original holdout was consumed.
The winning variant without its siblings. A report shows the best configuration but not how many variants were tested. The selection process is hidden. Keep a trial registry; if history is missing, state that the search count is unknown and lower confidence accordingly.
A successful unit test mistaken for data validation. A script catches four planted bad rows, then the team says the data is clean. The test shows only that the code caught those examples. It does not measure real-feed error rates or prove the absence of other errors.
A reviewer’s checklist before approving the claim
- [ ] The claim, audience, market, security universe, horizon, and intended decision are explicit.
- [ ] Every material feature has a point-in-time availability rule, not merely a period label.
- [ ] Raw timestamps, timezone conversion, revisions, and vendor vintages are documented.
- [ ] Universe membership is effective-dated and includes additions, removals, delistings, and identity changes where available.
- [ ] Stable identifiers are used; ticker changes and separate trading lines have a mapping policy.
- [ ] Corporate actions and missing delisting outcomes are investigated, not silently dropped.
- [ ] Signal time is separated from fill time; fill occurs only after the decision under a stated market phase and order type.
- [ ] Bid, ask, size, fees, spread, slippage, and any currency or financing assumptions are shown as observed or modeled.
- [ ] Cost sensitivity is predeclared and the result is not reported only under the most favorable scenario.
- [ ] Strategy variants, parameter searches, stopping rules, and holdout exposure are documented.
- [ ] The final evaluation period did not feed back into the selected rule—or is honestly labeled as reused.
- [ ] Data snapshots, code commit, config, and outputs can be recreated by another reviewer.
- [ ] A reviewer independent of the strategy author challenges the data lineage and the economics.
- [ ] Limitations are adjacent to the performance claim, not buried after the reader has formed an impression.
If any item is unknown, write down what evidence would resolve it and whether the result can support the intended decision in the meantime. “Needs a better data source” is a useful conclusion. “The curve looks convincing” is not a substitute.
Evidence and method notes
Sourced facts: the SEC’s 2020 US marketing rule addresses hypothetical performance disclosures for covered investment advisers; its 2022 proceeding describes a specific strategy whose backtest and live version used different securities and insufficiently correlated substitutes. CFA Institute’s 2026 educational reading discusses backtesting, rolling windows, survivorship, look-ahead bias, and distributional concerns. SIX’s own pages describe trading models, phases, order-book mechanics, and market-data services. Deloitte provides a consulting perspective on independent model validation and lifecycle governance. Each source supports only the claims within its scope.
Community evidence: a single r/algotrading discussion in October 2026 asks how researchers handle historical constituents and survivorship. It is included to expose a real unresolved user question, not as a representative survey or a verified test result.
Original asset and test method: the review matrix and CSV validator are original reusable synthesis. The example test uses four synthetic rows, hand-authored on 25 October 2026, with one clean case and three planted timing/membership violations. No real price series, broker fills, Swiss tickers, or investor returns were sampled. The example is excluded from any claim about performance or prevalence; its limitations are that the checker does not verify source completeness, market-wide universe membership, actual order-book execution, corporate-action outcomes, or research-selection history.
Video search: the research search did not return a relevant, transcript-verifiable video on point-in-time backtesting or Swiss execution. No video claim is used. A video should be added only after its captions or transcript have been checked; a thumbnail or title alone is not evidence.
Recommendation: treat missing proof as a scope limitation, not as a verdict on an idea. Narrow the universe, improve the data, or label the output exploratory. Do not promise a ranking, future return, or live result from a historical simulation.
Sources
- SEC, Investment Adviser Marketing, final rule (2020) — US rule and Commission discussion of hypothetical/backtested performance, assumptions, criteria, and risks.
- SEC, CMG Capital Management Group proceeding (2022) — a specific enforcement example involving backtest/live security mismatch and records.
- CFA Institute, Backtesting and Simulation (2026) — educational treatment of rolling-window backtests, survivorship, look-ahead, fat tails, and structural breaks.
- CFA Institute Research Foundation, Investment Model Validation — model-validation discussion including survivorship and look-ahead bias.
- Bailey, Borwein, López de Prado & Zhu, The Probability of Backtest Overfitting — research framework for assessing selection/overfitting risk; not a general-purpose validity certificate.
- Deloitte, Model Risk Management at Investment Management Organizations — consulting guidance on model development, validation, and operations; vendor perspective, not independent proof.
- SIX, On-order-book Trading and SIX Market Data — exchange descriptions of market models, order books, and data services.
- SIX Exchange Regulation, Communiqué No. 5/2022 — scope-specific reporting context for certain own-share buyback and price-stabilisation transactions; not a backtesting dataset. Linked in the universe section above.
- SIX liquidity: spreads and order books — practical guide to questions a reviewer should ask about liquidity and execution; not a historical data feed. It is linked above where the scope is introduced.
- r/algotrading, “Survivorship bias can really wreck a backtest” — anecdotal user discussion and open question, not a representative dataset.
Top comments (0)