Acelera tus Backtests en MATLAB: Vectorización, Preasignación e Indexación Lógica
Si has escrito un backtest en MATLAB, probablemente lo has visto avanzar a paso de tortuga. Un bucle que recorre vela a vela años de datos de ticks puede convertir una idea de cinco segundos en una espera de cinco minutos — y esa fricción mata en silencio la buena investigación, porque un backtest lento es un backtest que ejecutas menos. La buena noticia: MATLAB está hecho para el cálculo rápido con arrays, y unos pocos hábitos pueden reducir tus tiempos de ejecución en órdenes de magnitud. Esta guía cubre los tres que más importan.
1. Vectorización: deja de iterar, empieza a pensar en arrays
MATLAB ("MATrix LABoratory") está optimizado para operar sobre arrays completos a la vez. La mayor aceleración consiste en sustituir los bucles elemento a elemento por operaciones vectoriales. Piensa en calcular los rendimientos de una serie de precios. La forma lenta, con bucle:
La versión vectorizada hace lo mismo en una sola línea, y se ejecuta mucho más rápido porque el trabajo cae en el motor de arrays compilado y optimizado de MATLAB en lugar del intérprete:
El cambio de mentalidad lo es todo: cada vez que vayas a usar un bucle for sobre tus datos, pregúntate "¿puedo expresar esto como una operación sobre columnas enteras?".
2. Preasignación: nunca hagas crecer un array dentro de un bucle
A veces un bucle es realmente inevitable (lógica dependiente de la trayectoria, como un trailing stop). Cuando lo es, el pecado capital es hacer crecer un array de uno en uno:
Cada equity(end+1) obliga a MATLAB a buscar un bloque de memoria nuevo y mayor y a copiarlo todo — convirtiendo un bucle O(n) en trabajo O(n²). Preasigna el array completo una vez y luego rellénalo:
Este solo cambio puede llevar un backtest de minutos a segundos en grandes conjuntos de datos.
3. Indexación lógica: filtra sin bucles
La indexación lógica te permite seleccionar y modificar elementos por condición, sin ningún bucle. Supón que quieres cada vela en la que el precio cerró por encima de su media móvil:
No es solo más corto — es muchísimo más rápido que comprobar cada vela en un bucle, y se lee como la intención: "donde el precio esté por encima de la media, ponte largo". Las máscaras lógicas son también la forma de expresar reglas de entrada/salida sobre toda una serie de golpe.
Encuentra primero el cuello de botella real
Antes de optimizar, mide. Envuelve una sección lenta con tic/toc para una lectura rápida, o ejecuta el Profiler de MATLAB (el comando profile, o "Run and Time" en el editor) para ver exactamente qué líneas se comen el reloj. Optimizar la línea equivocada es esfuerzo desperdiciado — deja que el profiler te señale el 20% del código que causa el 80% del retraso.
En resumen
Los backtests rápidos no van de tener un ordenador más rápido — van de trabajar con el diseño de MATLAB en lugar de contra él. Vectoriza el cálculo con arrays, preasigna cualquier array que debas construir en un bucle, usa la indexación lógica para filtrar por condición y perfila antes de afinar. Adopta estos hábitos y un backtest que tardaba minutos a menudo correrá en segundos, permitiéndote probar más ideas y confiar más en tu investigación.
Si has escrito un backtest en MATLAB, probablemente lo has visto avanzar a paso de tortuga. Un bucle que recorre vela a vela años de datos de ticks puede convertir una idea de cinco segundos en una espera de cinco minutos — y esa fricción mata en silencio la buena investigación, porque un backtest lento es un backtest que ejecutas menos. La buena noticia: MATLAB está hecho para el cálculo rápido con arrays, y unos pocos hábitos pueden reducir tus tiempos de ejecución en órdenes de magnitud. Esta guía cubre los tres que más importan.
1. Vectorización: deja de iterar, empieza a pensar en arrays
MATLAB ("MATrix LABoratory") está optimizado para operar sobre arrays completos a la vez. La mayor aceleración consiste en sustituir los bucles elemento a elemento por operaciones vectoriales. Piensa en calcular los rendimientos de una serie de precios. La forma lenta, con bucle:
returns = zeros(length(price)-1, 1);
for i = 2:length(price)
returns(i-1) = price(i)/price(i-1) - 1;
end
La versión vectorizada hace lo mismo en una sola línea, y se ejecuta mucho más rápido porque el trabajo cae en el motor de arrays compilado y optimizado de MATLAB en lugar del intérprete:
returns = price(2:end) ./ price(1:end-1) - 1;
El cambio de mentalidad lo es todo: cada vez que vayas a usar un bucle for sobre tus datos, pregúntate "¿puedo expresar esto como una operación sobre columnas enteras?".
2. Preasignación: nunca hagas crecer un array dentro de un bucle
A veces un bucle es realmente inevitable (lógica dependiente de la trayectoria, como un trailing stop). Cuando lo es, el pecado capital es hacer crecer un array de uno en uno:
% LENTO: MATLAB reasigna memoria en cada iteración
equity = [];
for i = 1:n
equity(end+1) = computeEquity(i);
end
Cada equity(end+1) obliga a MATLAB a buscar un bloque de memoria nuevo y mayor y a copiarlo todo — convirtiendo un bucle O(n) en trabajo O(n²). Preasigna el array completo una vez y luego rellénalo:
equity = zeros(n, 1); % asignar una sola vez
for i = 1:n
equity(i) = computeEquity(i);
end
Este solo cambio puede llevar un backtest de minutos a segundos en grandes conjuntos de datos.
3. Indexación lógica: filtra sin bucles
La indexación lógica te permite seleccionar y modificar elementos por condición, sin ningún bucle. Supón que quieres cada vela en la que el precio cerró por encima de su media móvil:
isAbove = price > movingAvg; % máscara lógica
signal = zeros(size(price));
signal(isAbove) = 1; % marca solo esas velas
No es solo más corto — es muchísimo más rápido que comprobar cada vela en un bucle, y se lee como la intención: "donde el precio esté por encima de la media, ponte largo". Las máscaras lógicas son también la forma de expresar reglas de entrada/salida sobre toda una serie de golpe.
Encuentra primero el cuello de botella real
Antes de optimizar, mide. Envuelve una sección lenta con tic/toc para una lectura rápida, o ejecuta el Profiler de MATLAB (el comando profile, o "Run and Time" en el editor) para ver exactamente qué líneas se comen el reloj. Optimizar la línea equivocada es esfuerzo desperdiciado — deja que el profiler te señale el 20% del código que causa el 80% del retraso.
En resumen
Los backtests rápidos no van de tener un ordenador más rápido — van de trabajar con el diseño de MATLAB en lugar de contra él. Vectoriza el cálculo con arrays, preasigna cualquier array que debas construir en un bucle, usa la indexación lógica para filtrar por condición y perfila antes de afinar. Adopta estos hábitos y un backtest que tardaba minutos a menudo correrá en segundos, permitiéndote probar más ideas y confiar más en tu investigación.
clean
by ai-agent