Trading bot
DRY_RUN
v0.1.0 · d3b61f2 arrancado 2026-09-11 03:16 UTC último ciclo nunca último sync nunca sqlite:///./trading.db auto-update OFF

Estrategia vigente: sma_cross

Cruce de medias móviles con filtro de tendencia, sobre barras diarias, solo posiciones largas, una posición por símbolo. Elegida por ser explicable y tener pocos parámetros. No se espera que sea rentable por sí sola: su función es validar toda la tubería (datos → señal → riesgo → orden).

Los valores concretos de cada parámetro se leen de .env / config.py; el panel web los muestra a la derecha de esta página. Los nombres son los de las variables de entorno.

Entrada (BUY)

Se cumple todo a la vez, evaluado al cierre de la barra diaria:

  1. SMA_FAST cruza por encima de SMA_SLOW, o lo hizo dentro de las últimas ENTRY_WINDOW barras y sigue por encima.
  2. El cierre está por encima de SMA_TREND (filtro de tendencia de largo plazo).
  3. El volumen del día supera VOLUME_FILTER_RATIO × su media de 20 días.

La orden se ejecuta en el primer ciclo con mercado abierto tras la señal, como orden de mercado con bracket: stop-loss a STOP_ATR_MULT × ATR(ATR_PERIOD) bajo el precio y take-profit a TAKE_PROFIT_ATR_MULT × ATR por encima.

Salida (SELL)

Cualquiera de estas:

  • SMA_FAST cruza por debajo de SMA_SLOW.
  • El precio toca el stop-loss (bracket en Alpaca; en backtest se simula con el mínimo del día).
  • El precio toca el take-profit (bracket; en backtest con el máximo del día).
  • Han pasado MAX_HOLD_DAYS días hábiles desde la entrada.

EXIT_MODE elige entre take_profit (bracket con stop y take-profit fijos, el actual) y trailing (solo stop, que sube con el máximo alcanzado menos STOP_ATR_MULT × ATR; en vivo se actualiza la pata stop del bracket una vez al día). El backtest de cartera compara ambos; el modo vigente se cambia solo con ese reporte.

Regla de empate en backtest: si en la misma barra el mínimo toca el stop y el máximo toca el take-profit, se asume que el stop se ejecutó primero (lo conservador).

Ejecución

La señal se calcula sobre el cierre, pero la orden se envía a las 9:35 ET del día siguiente. En ese momento se vuelve a leer el último precio y se recalculan stop, take-profit y cantidad con él. Si el precio se ha alejado más de MAX_GAP_PCT del cierre de la señal, la entrada se descarta. Las salidas por cruce o por tiempo cancelan primero las patas del bracket y luego venden la cantidad real que Alpaca reporta en la posición.

Tamaño de posición

cantidad = min( equity × RISK_PER_TRADE_PCT / (precio − stop) , equity × MAX_POSITION_PCT / precio )

Es decir, se arriesga como máximo un porcentaje fijo del equity por operación, medido como distancia al stop, y ninguna posición supera un porcentaje fijo del equity.

Reglas de riesgo que pueden vetar una señal

MAX_OPEN_POSITIONS, DAILY_LOSS_LIMIT_PCT, MAX_DRAWDOWN_PCT, MAX_DAY_TRADES, mercado abierto según el reloj de Alpaca y kill switch. Cada regla es una función pura con su test en tests/test_risk_rules.py.

Versiones de la estrategia

Versión Fecha Cambio Backtest
1.0 2026-09-10 Cruce exacto en la barra del cruce (sin reporte guardado)
1.1 2026-09-10 Entrada permitida hasta ENTRY_WINDOW barras tras el cruce PORTFOLIO-IS_2020-07-27_2022-12-30.md, PORTFOLIO-OOS_2021-11-29_2026-09-10.md

Regla: cada fila nueva exige un reporte en docs/backtests/ y una entrada en CHANGELOG.md.

Nota sobre datos: el plan gratuito de Alpaca (feed IEX) entrega barras diarias desde el 27-07-2020, no desde 2019. Los backtests "desde 2019" empiezan en realidad en esa fecha.

Lectura del primer reporte (v1.1, take_profit): fuera de muestra +14.6 % con drawdown máximo −2.9 % y 93 operaciones, frente a +63.1 % de SPY. Protege capital pero no bate al índice; el modo trailing fue mejor en muestra y peor fuera de muestra, así que se mantiene take_profit.

Lo que esta estrategia no hace

  • No opera en corto ni con apalancamiento.
  • No usa datos intradía para decidir, solo para ejecutar.
  • No ajusta parámetros por símbolo. Cualquier optimización se hace en backtest con --split y se documenta antes de desplegarse.

trading-bot v0.1.0 · 2026-09-11 03:16 UTC