Documentación1.0 (latest)
PáginasBacktests · 16 / 29

Backtests

Usa el botón Test (Ejecución de código) del IDE de QuantCraft para abrir Run backtest. Allí defines los símbolos, los datos de precios, los datos fundamentales opcionales, la ventana de simulación, el saldo inicial y los costes de ejecución, y (si tu script los usa) los parámetros de entrada para una ejecución única. El motor invoca los callbacks del ciclo de vida de tu estrategia. Los resultados aparecen en Resultados de las pruebas; OHLCV explica la forma de las barras.

En la parte superior del cuerpo del cuadro puedes usar Load o Save para reutilizar un preajuste de ejecución (.qcs). Todo lo demás se agrupa en hasta tres pestañas para que repases el formulario antes de iniciar el backtest.

Pestañas del cuadro Run backtest

PestañaQué configuras
ScriptSolo se muestra cuando el script declara entradas params.NAME. Valores de los parámetros, además de Optimize (cuadrícula de fuerza bruta o búsqueda genética). Consulta Parámetros de entrada y Optimización.
Symbol & dataPrice feed (feed del bróker conectado o QuantCraft B2), Symbol source, Asset class, Bar timeframe (feed del bróker) / Timeframe (B2), Additional timeframes (optional) para rt.get_bar, Min bars (optional) (feed del bróker), Uses fundamentals (select if your strategy requires fundamental data), Include Fama-French factors (global) e Include calendar data (dividends, splits, earnings dates) (Premium / excepción de datos gratuitos; activado por defecto).
SimulationFecha de inicio / fin (por defecto: el último mes), warmup bars (por defecto 45), starting balance (por defecto 100.000), modelos de comisión y deslizamiento. Consulta Modelo de cuenta.

Reloj / símbolo principal: no hay control de símbolo principal en el cuadro. Con Selected symbols, el reloj de barras usa una constante SYMBOL de tu script (si ese ticker está en la lista cargada); si no, el primer símbolo cargado. Con Screener no hay símbolo de reloj en absoluto: el conjunto de símbolos cambia durante la ejecución, así que lee el historial de cada ticker mediante sus propios desplazamientos bar.close[i]. Consulta Ciclo de vida de la estrategia.

Temporizador / on_timer: el cuadro Run backtest no configura un intervalo de temporizador. on_timer es para ejecuciones forward / bulk / chart-forward que exponen un control de temporizador, no para los backtests del IDE.


Fuente de precios (feed del bróker o B2)

En la pestaña Symbol & data, elige el feed de precios:

  • Feed del bróker conectado — están disponibles marcos temporales intradía y diarios (requiere una cuenta de bróker conectada con credenciales configuradas en la aplicación).
  • QuantCraft B2 — en un plan gratuito solo están disponibles los marcos temporales OHLCV diario (d), semanal (w) y mensual (m); Premium desbloquea el intradía y marcos temporales B2 ampliados. Debes haber iniciado sesión en QuantCraft para que se pueda enviar un token de sesión para los OHLCV de B2 (y para los datos fundamentales cuando estén activados).

La elección se guarda en los preajustes de ejecución (.qcs) como ohlcvSource ("alpaca" o "b2").


Marco temporal de las barras y clase de activo (solo feed del bróker)

Cuando la fuente de precios es el feed del bróker conectado, puedes configurar:

CampoPropósito
Bar timeframeResolución de las velas de la ejecución — p. ej. 1 día, 1 hora, 4 horas, 1 semana y varias barras de minutos (1 / 5 / 15 / 30 min).
Asset classUS equity o Crypto — determina en qué lista de símbolos buscas y cómo obtiene los datos el bróker.
Min bars (optional)Si se define, una vez aplicado el rango de fechas el motor conserva solo las N barras más recientes. Déjalo vacío para usar todo el rango que implican tus fechas de inicio y fin.

Cuando la fuente de precios es B2, solo eliges Timeframe: Daily, Weekly o Monthly en un plan gratuito; Premium añade el intradía y marcos temporales B2 ampliados (consulta los códigos B2 en Datos OHLCV y de barras).


Marcos temporales adicionales (opcional)

Usa Additional timeframes en Symbol & data para cargar tamaños de barra adicionales junto a tu marco temporal principal. En el código de la estrategia, léelos con rt.get_bar(Timeframe.X, shift) — consulta Datos OHLCV y de barras y Ciclo de vida de la estrategia.

  • Selecciona de forma múltiple cualquier marco temporal extra que tu estrategia necesite (p. ej. diario cuando tu barra principal es de 5 minutos).
  • El marco temporal principal también está disponible mediante rt.get_bar sin listarlo en Additional timeframes.
  • Devuelve None si ese marco temporal no tiene búfer para la ejecución, en una fuente Screener o cuando los datos no están disponibles.
  • En un backtest, get_bar solo ve las barras hasta el paso actual y siempre lee las barras del símbolo de reloj — para el historial de otro ticker usa los desplazamientos bar.close[i] de ese ticker.
  • Los ajustes se pueden guardar en los preajustes de ejecución (.qcs) en secondaryTimeframes.

Símbolos

Fuente de símbolos

Symbol source en la pestaña Symbol & data decide qué tickers opera el backtest:

FuenteQué hace
Selected symbolsOpera la lista fija que eliges, más lo que añadas con Paste tickers.
ScreenerVuelve a ejecutar un filtro a medida que avanza el backtest y opera lo que coincidía en ese punto de la simulación.

Con Screener seleccionado, configuras el propio filtro:

AjusteQué hace
Screener sourceScreener preset o Python script.
Sort column / DirectionCómo se clasifican las coincidencias del preajuste antes de aplicar el límite.
Rank directionPara scripts — qué extremo de tu puntuación rank() se toma primero.
LimitCuántos símbolos operar en cada rebalanceo. 0 toma todas las coincidencias.
Refresh interval (days)Con qué frecuencia se vuelve a ejecutar el filtro, en días naturales simulados. Los scripts requieren 7 días o más.
Keep tickers with an open positionMantiene un símbolo operable después de que deje de coincidir, para poder seguir gestionando una posición abierta.

Límites de un backtest guiado por screener: requiere fechas de inicio y fin explícitas; no se admiten marcos temporales adicionales; un filtro por script de Python requiere un Refresh interval de 7 días o más; y Debug Test no admite una fuente Screener (se detiene con un mensaje que te pide cambiar a Selected symbols). Con los datos fundamentales activados, cada símbolo filtrado obtiene los suyos automáticamente. Los resultados incluyen una pestaña Screener Output junto a Logs, que muestra cada rebalanceo como una fecha plegable con los símbolos operados en esa ventana. Consulta Screener para crear filtros y para los detalles de punto en el tiempo y sesgo de supervivencia.

Selected symbols

En Symbol & data, elige uno o más tickers para la ejecución:

  • Con el feed del bróker conectado, la lista procede del universo de activos de tu bróker (acciones o cripto según Asset class). Puedes buscar y seleccionar varios.
  • Con B2, la lista procede del mismo catálogo que las rutas de datos fundamentales del servidor.

Reglas:

  • Se requiere al menos un símbolo.
  • Los símbolos se normalizan a mayúsculas para la ejecución.
  • Caracteres válidos: letras, dígitos, . y - (típicos de los sufijos de mercado como BRK.B o RHM.XETRA).

El primer símbolo en el orden de tu selección es el símbolo de reloj predeterminado, salvo que tu estrategia defina un SYMBOL = "..." de nivel superior que coincida con un ticker cargado. El cuadro no tiene un control separado de símbolo principal.


Datos fundamentales (opcional)

En Symbol & data, marca Uses fundamentals (select if your strategy requires fundamental data) cuando tu estrategia lea el argumento fundamentals en on_bar / on_tick (backtest), o en on_timer en una ejecución forward, o use lógica que tenga en cuenta los datos fundamentales.

La casilla se muestra cuando las funciones de datos fundamentales están activadas para tu versión, pero está desactivada (con una indicación de Premium) salvo que tengas Premium o esté habilitado el acceso a datos gratuitos. Cuando los datos fundamentales están activados:

  • Debes haber iniciado sesión (se envía el token de QuantCraft para cargar los archivos de datos fundamentales de B2).
  • Elige uno o más lotes de datos fundamentales en la selección múltiple (rutas como fundamentals/AAPL.json.gz). El cuadro muestra la ruta normalizada bajo cada selección.

Importante: los símbolos OHLCV y los símbolos de datos fundamentales son independientes. Puedes hacer un backtest de RNMBY mediante el feed del bróker mientras cargas los datos fundamentales de RHM.XETRA — la interfaz te recuerda que, en ese caso, debes pasar el ticker correcto a fundamentals.current(..., symbol="RHM.XETRA") (o equivalente) en el código.

Cuando se seleccionan varios lotes de datos fundamentales, el motor construye un mapa por ruta. El lote principal de datos fundamentales usado para las instantáneas alineadas con las barras es, por defecto, el símbolo operado (o el primer lote por orden alfabético); en ejecuciones multisímbolo y Screener, pasa siempre symbol= en fundamentals.current / get_data_with_offset, ya que el principal puede no ser el ticker en el que estás.


Factores de Fama-French (opcional)

En Symbol & data, marca Include Fama-French factors (global) cuando tu estrategia lea rentabilidades mensuales globales de factores mediante fama_french.qc. Consulta Factores de Fama-French para la API completa.

Cuando los factores están activados:

  • Necesitas Premium (o acceso a datos gratuitos cuando esté habilitado) y debes haber iniciado sesión.
  • La casilla está activada por defecto cuando la restricción de datos lo permite. Desmárcala para omitir los datos de factores en esa ejecución.
  • Los símbolos OHLCV, los lotes de datos fundamentales y los factores de Fama-French son independientes — activa la combinación que necesites.
  • No hay argumento de callback factors= — importa quantcraft.fama_french y lee fama_french.qc dentro de los callbacks (on_init, on_bar, on_tick, …).

Datos de calendario y acciones corporativas (opcional)

En Symbol & data, Include calendar data añade a tu backtest el historial de dividendos, el historial de splits, las fechas de resultados y las presentaciones ante la SEC. Está activado por defecto, y tu elección se recuerda para la siguiente ejecución.

Por qué importa

Las barras de precio del backtest no están ajustadas. Sin datos de calendario, un split 4 por 1 aparece como un desplome del 75 % del precio de un día para otro y tu posición simulada se desploma con él. Además, los dividendos nunca llegan, lo que subestima discretamente la rentabilidad total de cualquier posición mantenida mucho tiempo.

Subopciones

Dos subopciones controlan cómo se aplican las acciones a las posiciones abiertas durante la simulación:

SubopciónQué hace
Adjust positions for stock splitsEn la fecha efectiva del split, el número de acciones se multiplica por la proporción y el coste base se divide por ella. Los precios de stop y objetivo también se reescalan. Como qty × entry_price no cambia, tu curva de capital permanece continua a través del split.
Credit dividends to cashEn la fecha ex-dividendo, qty × amount se suma al efectivo en las posiciones largas y se resta en las cortas (los vendedores en corto deben el dividendo al prestamista). Esto fluye al capital y a todas las métricas de rentabilidad pero no a realized_pnl.

Ambas subopciones están activadas por defecto cuando los datos de calendario lo están.

Nota sobre la estimación de la fecha ex-dividendo: EDGAR no publica las fechas ex-dividendo. Salvo que hubiera datos del mercado disponibles, la fecha ex-dividendo se estima a partir de la fecha de declaración (con una precisión de unos ±7 días) y se marca como est. en Resultados de las pruebas. Los dividendos estimados se abonan por defecto; para omitirlos, establece dividendDatePolicy en exact_only (u off) en un preajuste .qcs — el cuadro no tiene un control para ello. Filtra por d.estimated en el código si tu estrategia es sensible a la fecha exacta.

Universos de screener

Los datos de calendario funcionan con una fuente de símbolos Screener. Los calendarios se cargan una vez que el filtro ha resuelto la lista completa de tickers; los símbolos que coinciden pero no tienen barras de precio no generan ninguna petición de calendario. Un filtro amplio puede incluir símbolos sin calendario en el servidor — el registro de la ejecución informa del recuento en lugar de fallar.

Dónde lo ves

  • Panel de salida — una línea [calendar] por cada acción corporativa aplicada durante la ejecución, más una línea de resumen al final.
  • Test Results — las filas Split y Dividend aparecen intercaladas en la tabla de operaciones cerradas (que entonces se titula Closed trades & events), mostrando la proporción o el importe por acción y el impacto en efectivo.

Consulta Datos de calendario para la API completa de BacktestCalendar y el argumento de callback calendar.


Simulación — fechas, saldo y costes de ejecución

Todo lo siguiente está en la pestaña Simulation:

CampoPropósito
Start dateObligatorio (por defecto, hace aproximadamente un mes). Primer día natural UTC incluido en la ventana de ejecución (YYYY-MM-DD).
End dateObligatorio. Último día natural UTC incluido. Debe ser igual o posterior a la fecha de inicio.
Warmup bars (indicators)Barras adicionales cargadas antes de la fecha de inicio (mismo marco temporal que tus barras) para que las medias móviles e indicadores similares tengan historial. Los callbacks siguen ejecutándose solo entre las fechas de inicio y fin. El valor por defecto es 45; introduce 0 para desactivar el calentamiento extra.
Starting balanceObligatorio. Efectivo inicial del PaperAccount simulado (por defecto 100.000).
Commission / slippageCómo se ajustan las ejecuciones por los costes de trading — véase más abajo y Modelo de cuenta.

El cuadro Run backtest no configura un intervalo de temporizador. on_timer solo está disponible en las ejecuciones forward (chart forward test, bulk forward / QuantCloud) cuando se define timerIntervalMs. Consulta Ciclo de vida de la estrategia.

El stop-loss / take-profit / dimensionamiento de riesgo predeterminados opcionales todavía pueden aparecer en los preajustes .qcs cuando están presentes, pero el cuadro Run backtest no expone actualmente entradas de SL/TP / riesgo. Configúralos en el código o mediante preajustes si tus utilidades los admiten — consulta Modelo de cuenta y Preajustes de ejecución (.qcs).

Comisión y deslizamiento

AjustePropósito
Commission modelPor acción (predeterminado), por operación o cero
Commission costCoste por acción o tarifa fija por orden ($) — por defecto 0,001 $ por acción
Minimum trade costMínimo por orden cuando se usa comisión por acción ($) — por defecto 0 $
Slippage modelCuota de volumen (predeterminado), diferencial fijo o cero
Volume limit / Price impactParámetros del deslizamiento por cuota de volumen (volume_limit también reduce la cantidad al abrir)
SpreadDiferencial total por acción para el deslizamiento de diferencial fijo ($)

Los ajustes de simulación se pueden guardar en los preajustes de ejecución (.qcs).


Parámetros del script (ejecución única)

Si tu estrategia importa from quantcraft.inputs import params (las rutas antiguas quantcraft.inputs_module / ide.inputs_module se siguen reconociendo en los scripts existentes) y hace referencia a params.NAME, el cuadro muestra una pestaña Script con una fila por cada nombre descubierto: Parameter, Type (int / float / str / bool) y Value.

Rellena todas las filas antes de empezar — se requiere un valor para cada parámetro declarado. Se envían como cadenas y el motor las convierte antes de cargar tu archivo, así que params.PERIOD (por ejemplo) ya tiene el tipo de Python correcto cuando se ejecuta tu módulo.

En la misma pestaña puedes activar Optimize para una búsqueda en cuadrícula o genética — consulta Optimización. Deja Optimize sin marcar para un backtest único normal.


Qué ocurre al iniciar la ejecución

La aplicación valida el formulario (fechas, símbolos, saldo, datos fundamentales si están activados y tipos de los parámetros del script). Si todo es correcto, inicia un backtest con la configuración ensamblada; el progreso y los registros aparecen en el panel Output, y los resultados estructurados se abren en Test Results.


Referencia rápida

TemaDónde se configura
Feed del bróker o precios B2Symbol & data → feed de precios (ohlcvSource en .qcs).
Marco temporalBar timeframe (feed del bróker) o Timeframe (B2: d / w / m en un plan gratuito; más con Premium).
Marcos temporales adicionalesSelección múltiple Additional timeframes — para rt.get_bar(Timeframe.X, shift).
Clase de activoUS equity / Crypto (solo feed del bróker).
Truncar a las últimas N barrasMin bars (solo feed del bróker, opcional).
Qué operarSymbol source: Selected symbols (selección múltiple) o Screener (filtro basado en datos fundamentales — consulta Screener).
Símbolo de relojSYMBOL del script si está cargado; si no, el primer símbolo (sin control en el cuadro); ninguno con una fuente Screener.
Estados financierosUses fundamentals + selección múltiple de datos fundamentales (automática con una fuente Screener); requiere inicio de sesión.
Rentabilidades de factores globalesInclude Fama-French factors (global) — consulta Factores de Fama-French.
Dividendos, splits, fechas de resultadosInclude calendar data — activado por defecto; consulta Datos de calendario.
Ventana de calendarioStart date / End date en Simulation (obligatorios).
Historial de indicadores antes del inicioWarmup bars en Simulation.
Efectivo inicialStarting balance en Simulation.
Comisión / deslizamientoPestaña Simulation — consulta Modelo de cuenta.
on_timerNo está en Run backtest — ejecuciones forward con timerIntervalMs (Ciclo de vida de la estrategia).
on_tickBacktest: cuatro ticks OHLC sintéticos por barra (sin historial real de ticks). Ejecuciones forward: cada actualización de precio del bróker — consulta Ciclo de vida de la estrategia.
Valores ajustables en el códigoPestaña Script (params.*), valores únicos por ejecución (u Optimize).

Consejos

  • Si los símbolos del feed del bróker nunca se cargan, abre Trade una vez o confirma tu conexión con el bróker; con B2, confirma que has iniciado sesión y que el catálogo de símbolos se cargó.
  • El calentamiento solo extiende el historial cargado — no añade días de trading fuera de tu rango de fechas.
  • No esperes on_timer en el backtest del IDE — no hay control de temporizador en ese cuadro. Usa on_bar / on_tick en su lugar. Los temporizadores se aplican en las ejecuciones forward cuando se configura timerIntervalMs.
  • on_tick en un backtest usa OHLC sintéticos de cada barra (cuatro llamadas por barra) — no datos reales de ticks. Prueba la lógica de ticks en vivo en ejecuciones forward (Ciclo de vida de la estrategia).
  • Haz coincidir los lotes de datos fundamentales con los tickers que realmente lees en el código cuando los tickers de OHLCV y de datos fundamentales difieran.
  • Usa Min bars con moderación — es fácil acortar una ejecución más de lo que pretendías.
16 min de lecturaSugerir una edición ↗
Backtests — Documentación (1.0 (latest)) | QuantCraft