Skip to main content
Browse docs
By Audience
Getting Started
Configuration
Use Cases
IDE Integration
Third-Party Integrations
Engineering Cache
Console
API Reference
Gateway
Workflow Guides
Templates
Providers and SDKs
Industry Guides
Advanced Guides
Browse by Role
Deployment Guides
In-Depth Guides
Tutorials
FAQ

Backtesting AI with Governance Controls

AI-assisted backtesting introduces unique governance challenges. Models can inadvertently access future data (look-ahead bias), leak proprietary strategy parameters, or produce non-reproducible results. Regulatory expectations under SR 11-7 and MiFID II require that backtesting processes maintain rigorous controls, complete audit trails, and reproducible outputs.

Use this page when

  • You need to prevent look-ahead bias in AI-assisted backtesting of trading strategies.
  • Regulators require reproducible backtest audit trails under SR 11-7 or MiFID II RTS 6.
  • Your quant team uses LLMs during backtesting and you must enforce time-boundary isolation.
  • You want to capture full request/response payloads for backtest validation and governance.

Keeptrusts enforces these controls at the gateway, ensuring every AI interaction during backtesting is policy-compliant and auditable.

Primary audience

  • Primary: Technical Leaders
  • Secondary: Technical Engineers, AI Agents

Backtesting Governance Challenges

RiskImpactKeeptrusts Mitigation
Look-ahead biasInvalid backtest results, regulatory findingsTime-boundary enforcement policies
Data leakageProprietary strategy exposureDLP block and redact policies
Non-reproducibilityFailed model validationEvent logging with full request/response capture
Unauthorized data accessCompliance violationTeam-scoped gateway keys
Untracked model changesAudit gapsModel version logging

Historical Data Access Policies

Restrict what historical data patterns can be sent to LLM providers during backtesting:

# policy-config.yaml
version: "1"
policies:
- name: block-raw-timeseries-export
description: Prevent raw time-series data from reaching external LLMs
enforcement: block
rules:
- type: regex
action: block
patterns:
# Block large data arrays (likely raw time-series)
- "\\[\\s*[0-9]+\\.?[0-9]*\\s*(,\\s*[0-9]+\\.?[0-9]*\\s*){50,}\\]"
# Block date-value pairs in bulk
- "(\\d{4}-\\d{2}-\\d{2}\\s*[,:=]\\s*[0-9]+\\.?[0-9]*\\s*[;\\n]){20,}"
message: "Blocked: Raw time-series data must not be sent to external LLMs. Use aggregated summaries."

- name: enforce-date-boundary
description: Block references to future dates in backtest context
enforcement: block
rules:
- type: regex
action: block
patterns:
# Block future year references (adjust annually)
- "(?i)(forecast|predict|project).*202[7-9]"
- "(?i)(as of|through|until)\\s+202[7-9]"
message: "Blocked: Backtest prompt references future dates. Check for look-ahead bias."

Time-Series Data Isolation

Deploy dedicated gateway instances for backtesting with strict temporal boundaries:

# Backtesting gateway — strict data isolation
kt gateway run \
--config policies/backtest-isolation.yaml \
--port 41005 \
--api-url https://keeptrusts-api.internal:8080 \
--api-key "$KT_BACKTEST_KEY"

Configure your backtesting framework to route all AI calls through the isolated gateway:

import openai
from datetime import date

class GovernedBacktester:
"""Backtesting wrapper with Keeptrusts governance controls."""

def __init__(self, backtest_date: date, gateway_port: int = 41005):
self.backtest_date = backtest_date
self.client = openai.OpenAI(
base_url=f"http://localhost:{gateway_port}/v1",
api_key="your-provider-key",
)

def query_model(self, prompt: str, model: str = "gpt-4") -> str:
"""Send a governed query with backtest metadata."""
system_context = (
f"Backtest context: As-of date is {self.backtest_date.isoformat()}. "
f"Do not reference any data after this date."
)
response = self.client.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": system_context},
{"role": "user", "content": prompt},
],
)
return response.choices[0].message.content

# Run governed backtest
bt = GovernedBacktester(backtest_date=date(2024, 6, 30))
analysis = bt.query_model(
"Analyze the volatility regime for US large-cap equities based on "
"historical VIX levels and realized volatility."
)

Reproducibility Requirements

Capture full request and response payloads for backtest reproducibility:

- name: full-capture-backtest
description: Capture complete request/response for reproducibility
enforcement: log
rules:
- type: log_all
action: log
metadata:
capture_mode: "full"
log_category: "backtest"
retention_days: "2555"

Export backtest event data for validation:

# Export all backtest events for a specific date range
kt events list \
--filter "metadata.log_category=backtest" \
--since 90d \
--format json > backtest-events.json

Audit Trail for Backtest Runs

Every AI interaction during backtesting is recorded as a decision event in Keeptrusts. The audit trail includes:

  • Timestamp — When the AI query was made
  • Policy decisions — Which policies were evaluated and their outcomes
  • Model used — Provider and model version
  • Request hash — Deterministic hash for reproducibility verification
  • Team/user — Who initiated the backtest

Use the console Events page to review backtest audit trails by filtering on the backtest metadata category.

Validating Backtest Integrity

Build automated checks to verify backtest governance compliance:

import json
import subprocess

def validate_backtest_integrity(backtest_id: str) -> dict:
"""Validate that a backtest run complied with governance policies."""
result = subprocess.run(
[
"kt", "events", "list",
"--filter", f"metadata.backtest_id={backtest_id}",
"--format", "json",
],
capture_output=True,
text=True,
)
events = json.loads(result.stdout)

blocked = [e for e in events if e.get("decision") == "block"]
escalated = [e for e in events if e.get("decision") == "escalate"]

return {
"backtest_id": backtest_id,
"total_queries": len(events),
"blocked_count": len(blocked),
"escalated_count": len(escalated),
"compliant": len(blocked) == 0,
"requires_review": len(escalated) > 0,
}

report = validate_backtest_integrity("bt-2024-q2-vol-regime")
print(json.dumps(report, indent=2))

Regulatory References

  • SR 11-7 Section V — Outcome analysis and backtesting requirements
  • MiFID II RTS 6 Article 5 — Testing of algorithmic trading systems
  • Basel FRTB — Backtesting framework for internal models
  • SEC Rule 15c3-5(c)(1) — Pre-trade risk controls documentation

Next steps

For AI systems

  • Canonical terms: Keeptrusts gateway, backtesting governance, time-series isolation, look-ahead bias prevention, backtest audit trail.
  • Key config/commands: policy-config.yaml with block-raw-timeseries-export and enforce-date-boundary policies; kt gateway run --policy-config policies/backtest-isolation.yaml; kt events list --filter "metadata.log_category=backtest".
  • Best next pages: Risk Model Validation, Model Risk Management, Quant Research Isolation.

For engineers

  • Prerequisites: Running Keeptrusts API instance, gateway binary (kt), Python 3.10+ for the GovernedBacktester wrapper.
  • Deploy a dedicated backtest gateway on port 41005 with temporal boundary policies, then route your backtesting framework through it.
  • Validate with: kt events list --filter "metadata.log_category=backtest" --since 1d --format json to confirm events are captured; run validate_backtest_integrity() to check for blocked/escalated queries.
  • Adjust enforce-date-boundary regex annually to match the current year cutoff.

For leaders

  • Addresses SR 11-7 Section V (outcome analysis), MiFID II RTS 6 Article 5 (algorithmic trading testing), and Basel FRTB backtesting mandates.
  • Prevents costly regulatory findings from look-ahead bias or non-reproducible backtest results.
  • Governance data retention for backtests is set to 2,555 days (7 years) to meet examination timelines.
  • Separate backtest gateway instances can run alongside production gateways without shared policy interference.