ML-driven Small-Cap Strategy Discovery: RF → Feature Selection → Decision Tree → Rules
| Fase | Notebook/Script | Descripción | Output | Estado |
|---|---|---|---|---|
| 1. Datos + Features | 01_eda.ipynb |
EDA + calidad datos | data/eda_summary.csv |
✅ |
| 2. Calibración Riesgo | batch_calibrate.py |
Csl + BP por activo | data/universe_admitted.csv |
✅ |
| 3. Feature Engineering | 03_feature_engineering.ipynb |
~20 indicadores OHLCV | data/features/*.csv |
✅ |
| 4. Triple Barrier Labeling | 04_labeling.ipynb |
Etiquetado {0,1,2} | data/labeled/*.csv |
✅ |
| 5. RF + Feature Selection | 05_strategy_builder.ipynb |
RF → Top N features | Feature importances | ✅ |
| 6. Decision Tree + Rules | 05_strategy_builder.ipynb |
Tree (depth=3/4) | data/strategies_candidates.json |
✅ |
| 7. Backtest + OOS | 06_backtest_strategies.ipynb |
Train⇆Test (70/30) | data/strategies_library.json |
✅ |
smallcap-quant-ml/
├── config/
│ ├── settings.py # Todos los parámetros
│ └── tickers_smallcap.txt # Lista inicial
├── scripts/
│ └── batch_calibrate.py # Calibración Csl + BP
├── notebooks/
│ ├── 01_eda.ipynb # EDA puro
│ ├── 03_feature_engineering.ipynb # ~20 indicadores
│ ├── 04_labeling.ipynb # Triple Barrier
│ ├── 05_strategy_builder.ipynb # RF + Tree + Reglas
│ └── 06_backtest_strategies.ipynb # Backtest + Validación OOS
├── src/
│ ├── data.py # Carga datos
│ ├── features.py # ~20 indicadores
│ ├── risk.py # **BACKTESTER + Risk** (Csl, SIZE, TP/SL)
│ ├── labeling.py # Triple Barrier
│ ├── strategy_builder.py # RF → Tree → Rules (NUEVO)
├── docs/
│ └── legacy/
│ └── model.py # Legacy LightGBM stub
├── data/
│ ├── calibration_all.csv # 22 tickers probados
│ ├── universe_admitted.csv # Activos admitidos (Csl+BP ok) ✅
│ └── ... (labeled, strategies, library)
└── README.md
scripts/batch_calibrate.py: Csl = MEDIANA, BP verificado independiente.- Output:
data/universe_admitted.csv(9 tickers admitidos).
run_backtest_loop(df, entry_signal, c_sl, ...): Motor independiente de estrategias.calculate_performance_metrics(trades, capital): Win Rate, PF, Sharpe, DD.- Se reutiliza en Fases 10-12 para backtest de estrategias extraídas.
- ~20 indicadores: RSI, ATR, EMA20/50, distancias %, VWAP, MACD, RVOL, Gap%, ADX, ROC, Momentum, Volatilidad, Bollinger, etc.
- El motor de triple barrier sigue decidiendo si la operación termina en SL, TP o timeout.
- Para el entrenamiento del modelo, el target se binariza a: 1 = TP, 0 = SL o timeout.
- Regla de desempate conservadora: SL gana si ambos se tocan simultáneamente.
- RF → Feature Importance → Top N → Decision Tree → Extract Rules.
- Filtra: P(TP) > 0.5, n_samples >= 30.
- Calcular ~20 indicadores para todos los tickers admitidos.
- Output:
data/features/*.csv.
- Etiquetar entradas para cada activo.
- Output:
data/labeled/*.csv. - Estado actual: ya existen archivos
data/labeled_*.csven la raíz, pero los nuevos resultados se escriben endata/labeled/.
- Ejecutar
05_strategy_builder.ipynb: RF → Top 5 features → Tree → Reglas. - Ejecutar
06_backtest_strategies.ipynb: Backtest train/test + validación OOS. - Output final:
data/strategies_library.json(estrategias validadas).
Copia y ejecuta este bloque completo en tu terminal. Al terminar, abre VSCode o tu editor favorito y ejecuta los notebooks:
# 1. Clonar el repositorio
git clone https://github.com/elbrujo325/smallcap-quant-ml.git
cd smallcap-quant-ml
# 2. Crear entorno virtual
python3 -m venv .venv
source .venv/bin/activate
# 3. Instalar dependencias (automático + setuptools + wheel para reproducibilidad)
./scripts/setup_env.sh
# 4. Instalar el paquete en modo editable (para desarrollo)
python3 -m pip install -e .
# 5. Verificar que todo está correcto
python -c "import src; print('✅ src version:', src.__version__)"
python src/features.py
python src/labeling.py
# 6. Generar universo admitido (calibración de riesgo)
python scripts/batch_calibrate.py
# 7. Listo para abrir en VSCode o Jupyter
# Sigue los pasos abajo para ejecutar los notebooks-
Abre VSCode:
code .O abre tu editor de código favorito en la carpeta
smallcap-quant-ml. -
Abre Jupyter Lab o Notebook:
jupyter lab # o jupyter notebook -
Ejecuta los notebooks en este orden:
notebooks/01_eda.ipynb— Exploración y calidad de datosnotebooks/03_feature_engineering.ipynb— Cálculo de ~20 indicadoresnotebooks/04_labeling.ipynb— Triple barrier labelingnotebooks/05_strategy_builder.ipynb— Random Forest → Feature selection → Reglasnotebooks/06_backtest_strategies.ipynb— Backtest y validación OOS
Si Jupyter no carga el kernel correcto automáticamente, usa:
# Registrar kernel personalizado
python -m ipykernel install --user --name=smallcap-quant-ml --display-name "smallcap-quant-ml (.venv)"
# Luego en VSCode/Jupyter, selecciona este kernel antes de ejecutar las notebooksClonar y entrar al repositorio:
- Descarga el código fuente desde GitHub a tu laptop local
Crear y activar entorno virtual:
- Aísla las dependencias de este proyecto del resto del sistema
- Necesario para reproducibilidad
Instalar dependencias:
./scripts/setup_env.sh: script automatizado que instala pip, setuptools, wheel y todos los requisitos- Manual:
python3 -m pip install -r requirements.txtsi quieres hacerlo paso a paso - Opcional:
python3 -m pip install -e .para trabajar con el package en modo desarrollo
Verificaciones rápidas (smoke tests):
- Comprueba que todos los módulos principales carguen correctamente
- Ejecuta tests simples en
src/features.pyysrc/labeling.py
Generar universo admitido:
python scripts/batch_calibrate.pycalibra Csl y verifica Buying Power- Genera
data/universe_admitted.csvque necesitan los notebooks
Ejecutar notebooks en orden:
Todos los parámetros en config/settings.py:
from config.settings import DATA, FEATURES, RISK, BACKTEST
# Risk
print(RISK.risk_per_trade) # $100
print(RISK.lookforward_window) # 20
# Features
print(FEATURES.er_k) # 10
print(FEATURES.atr_period) # 50
# Backtest
print(BACKTEST.max_bars) # 40
print(BACKTEST.tp_sl_ratio) # 1.5ÚNICA fuente: Velas OHLCV horarias (Open, High, Low, Close, Volume, timestamp).
NADA se usa de Float, Market Cap, EV, etc. (no existen gratis con granularidad horaria histórica).
- Risk (src/risk.py): Determinístico, ya verificado (Csl, SIZE, TP/SL, BP).
- ML (src/strategy_builder.py): Descubre patrones bajo los cuales el Risk tiene mejor probabilidad de éxito.
- Datos: OHLCV de tickers admitidos.
- Features: ~20 indicadores.
- Simulación: Para cada vela, calcular SIZE, SL, TP usando
src/risk.py. - Etiquetado: Triple Barrier para decidir el outcome, luego target binario para ML (TP vs no-TP) max 40 velas forward.
- Split: 70% train (cronológico inicial), 30% test (final).
- Random Forest: Sobre TODOS los ~20 features → feature_importance.
- Selección: Top 3-5 features por RF.
- Decision Tree: max_depth=3/4, min_samples_leaf=30.
- Reglas: Cada hoja → estrategia si la tasa de TP supera el umbral y n>=30.
- Backtest: Usar
run_backtest_loop()para cada regla (train). - Validación OOS: Backtest en 30% test → PF_test >= 0.70 * PF_train.
- Library: Estrategias validadas guardadas en
data/strategies_library.json.
- No hay walk-forward: Split temporal simple 70/30.
- No hay reinforcement desde OOS: Las reglas se extraen solo del 70% train.
- Backtester reutilizado: No se reimplementa el motor, se llama a
run_backtest_loop(). - Comisiones = 0 por ahora: Añadir cuando tengas datos realistas.
Las estrategias más prometedoras que salieron del pipeline muestran un crecimiento claro, drawdowns contenidos y una relación positiva entre el número de trades y el PnL acumulado. La selección siguiente prioriza combinaciones con PnL positivo, correlación de la curva de equity con el progreso del backtest superior a 0.30 y drawdown moderado.
| Activo | Estrategia | PnL total | Retorno | Corr. equity/trades | Max drawdown |
|---|---|---|---|---|---|
| ABSI | Rule 4 | +4,270 | +42.7% | 0.92 | -7.7% |
| CRMD | Rule 6 | +3,074 | +30.7% | 0.92 | -10.9% |
| EXTR | Rule 7 | +2,324 | +23.2% | 0.85 | -14.0% |
| IMUX | Rule 6 | +2,040 | +20.4% | 0.59 | -8.5% |
Estas curvas no representan una garantía de rendimiento futuro; muestran únicamente el comportamiento histórico de las reglas evaluadas con el backtest actual.




