Qué es
Un panel web para analizar una cartera de fondos de MyInvestor a partir del CSV de órdenes que se descarga desde la web del banco. Calcula cuánto has ganado en cada periodo, cuánto has aportado, cómo ha evolucionado el valor y qué rentabilidad has obtenido, separando siempre lo aportado de lo ganado.
Dirección del panel: oscaragcp.github.io/mi-cartera-myinvestor. Código fuente: github.com/oscaragcp/mi-cartera-myinvestor.
Primeros pasos
- Entra en la web de MyInvestor desde un ordenador (la app no permite exportar).
- Abre la consulta de órdenes u operaciones de fondos y elige el rango de fechas desde tu primera orden hasta hoy. Si dejas fuera órdenes antiguas, el panel no sabrá qué participaciones tenías y las cifras saldrán mal.
- Descarga el archivo
.csv(se llama «Órdenes NNNN.csv»). - Abre el panel y pulsa Subir CSV actualizado, o arrastra el archivo sobre la página.
- Listo: el panel se recalcula al momento y recuerda el archivo la próxima vez que lo abras en ese navegador.
Para actualizarlo más adelante, descarga un CSV nuevo (otra vez desde la primera orden) y súbelo: sustituye al anterior.
El CSV de órdenes
El panel lee el archivo tal como lo genera MyInvestor: texto separado por punto y coma (;), una orden por línea y una primera línea de cabecera. Reconoce las columnas por su nombre, sin importar el orden ni las mayúsculas:
| Columna | Se reconoce si… | Uso |
|---|---|---|
| Fecha de la orden | empieza por «fecha» | Día en que diste la orden, formato dd/mm/aaaa. |
| ISIN | es exactamente «isin» | Identifica el fondo. |
| Importe estimado | empieza por «importe» | Importe y moneda, p. ej. 150.00 EUR. En compras es el dinero aportado. |
| Nº de participaciones | contiene «participaciones» | Participaciones compradas o vendidas. |
| Estado | empieza por «estado» | Solo cuentan las órdenes Finalizada con participaciones. |
- Números: acepta coma o punto decimal (
12,5o12.5). Si un número lleva punto, sus comas se toman como separador de miles (1,234.56). - Las líneas sin fecha válida se ignoran y el panel avisa de cuáles son.
- Las órdenes canceladas, rechazadas o pendientes aparecen en la tabla de órdenes como «No ejecutadas», pero no afectan a los cálculos.
El CSV no dice si una orden es compra o venta. Todas las filas tienen importe y participaciones positivos. El panel lo deduce (ver Cómo interpreta las órdenes) y te deja corregirlo.
Uso del panel
Cabecera
Muestra el archivo cargado y dónde está guardado, cuántas órdenes se han ejecutado, la fecha de la última orden y hasta qué día hay valores liquidativos exactos. Esa fecha es la más antigua entre los fondos que tienes hoy. Si aparece en amarillo, hay días cuyo valor se ha estimado.
Debajo pueden salir avisos: valores estimados, órdenes tomadas como venta automáticamente, participaciones negativas (señal de una compra/venta mal deducida) o líneas del CSV ignoradas.
Filtros
Se aplican a todo el panel y se recuerdan entre visitas.
| Filtro | Qué hace |
|---|---|
| Rango | Todo, Año de cuenta actual (desde el último inicio de tu año de cuenta), Este año, 12 meses y 3 años, o fechas a mano en Desde y Hasta. El rango llega siempre hasta hoy, aunque no haya órdenes recientes. |
| Fondos | Activa o desactiva bloques según la categoría Morningstar de cada fondo: RV desarrollada, RV emergente, Renta fija, Monetario, Mixtos y Otros. Debe quedar al menos uno. |
| Agrupar por | Cómo se cortan los periodos en gráficas y tablas: año de cuenta, año natural, trimestre o mes. Un periodo recortado por el rango se marca con *. El año de cuenta empieza por defecto el día y mes de tu primera orden; puedes cambiarlo en «empieza el» (dd/mm). |
Cifras clave
| Cifra | Significado |
|---|---|
| Ganancia en el rango | Valor final − valor inicial − entradas netas. |
| Valor final | Valor de los fondos el último día del rango (y el valor inicial, si no se parte de cero). |
| Entradas netas | Compras − ventas dentro del rango. |
| Rentabilidad (TWR) | Rentabilidad ponderada por tiempo; anualizada si el rango dura al menos un año. |
| TIR anual | Tasa interna de rentabilidad de tu dinero según cuándo entró. Se muestra con rangos de 6 meses o más. |
| Máxima caída | Mayor caída del índice de rentabilidad desde un máximo previo, dentro del rango. |
Gráficas
| Gráfica | Qué muestra |
|---|---|
| Evolución | Tres vistas: Valor y aportado (valor de la cartera frente a dinero aportado; el hueco es la ganancia), Ganancia acumulada (azul por encima de 0, rojo por debajo) y Rentabilidad (base 100) (cómo habrían crecido 100 € sin efecto de las aportaciones). Líneas verticales en cada inicio de año de cuenta y zona «estimado» cuando no hay precios oficiales. |
| Ganancia por periodo | Barras por periodo. Pulsa una barra para filtrar el panel a ese periodo. |
| De lo aportado al valor final | Cascada: valor inicial + entradas netas + ganancia de cada periodo = valor final. |
| Entradas netas por periodo | Compras − ventas apiladas por bloque. En un traspaso, sale de un bloque y entra en otro. |
| Composición | Valor de cada bloque en el tiempo, en euros o en porcentaje. |
| Rentabilidad mensual | Mapa de calor con el TWR de cada mes. |
| Caída desde máximos | Distancia del índice de rentabilidad a su último máximo, con la peor caída marcada. |
Tablas
- Detalle por periodo: valor inicial, entradas netas, valor final, ganancia, TWR y Dietz de cada periodo, con el total del rango.
- Fondos: participaciones, valor liquidativo, valor final, peso, entradas netas y ganancia de cada fondo en el rango.
- Órdenes: todas las órdenes del CSV con su tipo deducido (compra, venta, traspaso de entrada o salida, no ejecutada), importe, precio y fecha de ejecución. Se puede buscar por fondo o ISIN y filtrar por tipo. El botón Es una compra / Es una venta corrige la deducción; la corrección se guarda.
Descargas
Las tablas de periodos y de órdenes se pueden descargar como CSV (separado por ;, coma decimal, listo para Excel): ganancias-por-periodo.csv y ordenes-clasificadas.csv.
Tema
El panel y esta documentación siguen el modo claro u oscuro de tu sistema.
Cálculos
El panel construye una serie diaria desde la primera orden hasta hoy con el valor de cada fondo (participaciones × valor liquidativo) y el dinero que entra o sale cada día. Todo lo demás sale de ahí.
Ganancia
Lo que aportas no cuenta como ganancia y lo que retiras no cuenta como pérdida. La suma de las ganancias de los periodos es la ganancia del rango.
Rentabilidad ponderada por tiempo (TWR)
Mide cómo lo han hecho los fondos, independientemente de cuándo y cuánto aportaste. Se encadena la rentabilidad de cada día:
índice(día) = índice(día anterior) × (1 + r(día))
donde V es el valor de la cartera y F la entrada neta de ese día. Las compras se suponen invertidas desde el principio del día. Si la cartera vale menos de 1 €, la rentabilidad del día es 0. El TWR de un periodo es índice final / índice inicial − 1. Si el rango dura un año o más, se anualiza: (1 + TWR)1/años − 1.
Dietz modificado
Rentabilidad sobre el capital medio invertido en el periodo: cada aportación pesa según la parte del periodo que estuvo invertida.
TIR (rentabilidad del dinero)
La tasa anual que hace que el valor actual de tus flujos sea cero: el valor inicial y cada compra como salidas de dinero, cada venta como entrada y el valor final como cobro al final del rango. Se resuelve por bisección entre −95 % y +500 % anual. Si no hay solución en ese intervalo o el rango dura menos de 6 meses, se muestra «—».
¿TWR o TIR? El TWR juzga a los fondos y la TIR juzga tu dinero. Si aportaste mucho justo antes de una subida, tu TIR será mayor que el TWR, y al revés.
Máxima caída y rentabilidad mensual
La caída desde máximos es índice / máximo anterior del índice − 1, calculada dentro del rango. La rentabilidad mensual es el TWR de cada mes natural.
Cómo interpreta las órdenes
Compra o venta
Por orden de prioridad:
- Corrección manual hecha con el botón de la tabla de órdenes.
- Columna de tipo de operación, si el CSV la trae (compra/suscripción o venta/reembolso).
- No se puede vender más de lo que se tiene: una orden con más participaciones de las que había es una compra.
- Vacía el fondo: sus participaciones (solas o sumadas las del mismo fondo ese día) igualan, ±0,2 %, las que había. Es una venta.
- Recibe un traspaso: una orden cuyo importe coincide (±2,5 %) con una venta de otro fondo de ese día o de los 10 anteriores es la compra de ese traspaso.
- Venta parcial de un traspaso o reajuste: una orden con céntimos cuyo importe reaparece (±2,5 %) como compra con céntimos de otro fondo en los 10 días siguientes.
- Si no, es una compra. Los importes redondos (300 €, 1.000 €…) se toman siempre como compra, porque el importe de una venta es una estimación (participaciones × precio) con céntimos.
Todo se deduce solo con el CSV que subes: el código no guarda órdenes, ventas ni importes de ninguna cuenta. Un reembolso parcial a la cuenta corriente no deja rastro en el CSV; el panel marca como ¿venta? las órdenes con céntimos que están solas en su día, para que las revises. Si las participaciones de un fondo quedan negativas, el panel avisa, porque seguramente hay una venta tomada como compra.
Traspasos
MyInvestor ejecuta un traspaso como una venta seguida de compras. El panel agrupa las ventas separadas por 3 días o menos y busca compras de otros fondos en los 10 días siguientes cuya suma coincida con lo vendido (±6 %). Si las encuentra:
- Las marca como Traspaso (salida) y Traspaso (entrada).
- Busca la fecha de ejecución común de las ventas: el día, entre 0 y 10 después, en que lo vendido vale lo mismo que lo comprado.
- Mientras el dinero está «en tránsito» entre la venta y la compra, lo cuenta como liquidez del bloque de destino, para que el valor de la cartera no caiga a cero esos días.
Fecha de ejecución y precio
- Compras en euros: de los días 0 a 10 posteriores a la orden, el que tenga un valor liquidativo con el que participaciones × precio se acerque más al importe.
- Compras en otra moneda: el primer valor liquidativo posterior al día de la orden; el importe en euros es participaciones × precio.
- Ventas: el primer valor liquidativo posterior al día de la orden (o la fecha común del traspaso). El importe de una venta es participaciones × precio, porque el «importe estimado» del CSV no es el cobrado. Si se conoce el importe real de un reembolso, se usa ese.
- Si no hay precios oficiales para esas fechas, la ejecución se supone 2 días después de la orden y se marca como est.
Valores liquidativos
El archivo data/navs.json contiene el valor liquidativo diario en euros de cada fondo de data/funds.json, obtenido de Morningstar. Lo regenera la acción de GitHub Actualizar valores liquidativos, que se ejecuta de martes a sábado a las 06:30 UTC (con los precios del día laborable anterior) y también se puede lanzar a mano desde la pestaña Actions. Si falla la descarga de un fondo, se conserva su histórico anterior.
Los fondos publican su valor liquidativo con 1 a 3 días de retraso. Para los días sin precio oficial:
- Si el CSV tiene órdenes posteriores al último precio, el valor se estima interpolando con el precio implícito de esas órdenes (importe / participaciones).
- Si no, se mantiene el último precio conocido hasta hoy.
- Esos días se sombrean como «estimado» en las gráficas. El aviso de la cabecera solo sale si hay órdenes sin precio oficial o si el último precio tiene más de 4 días.
Para cualquier fondo del CSV que no esté en data/navs.json, o del que falten fechas (antes del primer precio guardado o después del último), el panel descarga los valores liquidativos de Morningstar desde tu navegador al abrirlo, junto con su nombre y categoría, y los guarda en caché. Solo se envían a Morningstar los ISIN, nunca el CSV ni importes. Si la descarga falla, ese fondo se valora con los precios de tus órdenes y el aviso lo indica como aproximado.
Privacidad y almacenamiento
- El CSV se lee con JavaScript en tu navegador. No se envía a ningún servidor: la página solo descarga sus propios archivos, la librería de gráficas, las fuentes y los valores liquidativos de Morningstar de los fondos de tu CSV (por ISIN).
- Se guarda en el
localStoragede tu navegador, solo para esta dirección:Clave Contenido panel-csvTexto y nombre del último CSV subido. panel-ajustesCorrecciones manuales de compra/venta e inicio del año de cuenta, ligados a cada cuenta: se guardan con huellas de sus órdenes más antiguas y solo se aplican a un CSV que las contenga. Subir el CSV de otra persona empieza sin ajustes. panel-navcacheValores liquidativos descargados de Morningstar (datos públicos). panel-ui2Filtros y vistas elegidos. - El botón Borrar mis datos de este navegador elimina el CSV y las correcciones. Abrir el panel en modo privado o desde otro dispositivo empieza sin datos.
- El repositorio es público y no contiene datos personales:
.gitignoreexcluye cualquier*.csv, y el código no contiene órdenes, ventas, importes ni fechas de ninguna cuenta: todo se deduce del CSV que sube cada usuario. - Sí son públicos la lista de fondos de
data/funds.jsony sus valores liquidativos.
Arquitectura
HTML, CSS y JavaScript sin compilación ni dependencias instaladas. Las gráficas usan Apache ECharts 5.5.0 desde cdnjs, con jsDelivr de respaldo, y las fuentes Figtree y Bricolage Grotesque de Google Fonts.
| Archivo | Función |
|---|---|
index.html | El panel completo: estilos, motor de cálculo e interfaz en un solo archivo. |
data/funds.json | Fondos precargados (para abrir más rápido): ISIN → SecId de Morningstar, nombre, categoría Morningstar, bloque y fechas de descarga (from, to; to: null = hasta hoy). |
data/navs.json | Valores liquidativos diarios. Formato: {epoch, generated, funds: {ISIN: {name, block, category, secid, nav: [[día, valor], …]}}}, con día = días desde el 01/01/2021. |
scripts/update_navs.py | Descarga los valores liquidativos y reescribe navs.json (Python estándar, sin dependencias). |
.github/workflows/update-navs.yml | Ejecuta el script cada día laborable y hace commit si hay cambios. |
docs/index.html | Esta documentación. |
.nojekyll | Hace que GitHub Pages sirva los archivos tal cual. |
Motor de cálculo
El objeto Engine (dentro de index.html) son funciones puras, sin acceso a la página, que trabajan con días enteros desde el 01/01/2021 (UTC):
| Función | Qué hace |
|---|---|
run(csv, navs, ajustes, hoy) | Proceso completo: lee el CSV, construye los precios, clasifica, ejecuta y genera la serie diaria hasta hoy. |
parseCSV | Lee y valida el CSV. |
buildNav | Precio de un fondo en cualquier día (oficial o estimado). |
classify | Compra o venta de cada orden. |
execute | Traspasos, fecha de ejecución, precio y flujo de cada orden. |
timeline | Valor y flujos diarios por fondo, incluido el dinero en tránsito. |
aggregate | Suma un conjunto de fondos y calcula el índice TWR. |
period, periods | Cifras de un periodo y cortes por año de cuenta, año, trimestre o mes. |
xirr, maxDrawdown | TIR y caída desde máximos. |
La interfaz llama a run al cargar o subir un CSV y recalcula el resto en cada cambio de filtro, con una caché por combinación de bloques.
Mantenimiento
Fondos nuevos
No hace falta hacer nada: el panel descarga solo los precios de cualquier fondo del CSV. Añadirlo a data/funds.json (con secid, name, category —la categoría Morningstar—, block, from y to: null) solo sirve para que la acción diaria lo precargue. El bloque lo decide siempre la categoría (función blockFor del motor).
Corregir una orden
Usa el botón de la tabla de órdenes («Es una venta» / «Es una compra»). La corrección se guarda en tu navegador, ligada a tu cuenta. El código no guarda correcciones de nadie.
Cambiar el panel
- Edita
index.html. (Las fuentes originales del autor separan el motor,engine.js, de la página,index.src.html, y se combinan para generarindex.html. Si las usas, edítalas a ellas y regenera.) - Prueba en local:
python3 -m http.serveren la carpeta del repositorio y abrehttp://localhost:8000. El motor exportamodule.exports, así que también se puede probar con Node:const E = require("./engine.js"); E.run(csv, navs, {}, E.dayOf(2026, 10, 7)). - Revisa también las vistas que no se ven al cargar (por ejemplo, las tres de la gráfica de evolución) y la consola del navegador.
git pull(la acción hace commits a diario), commit y push. GitHub Pages publica en un minuto.
Lecciones aprendidas. Comprueba que una versión existe en el CDN antes de usarla (ECharts 5.5.1 no está en cdnjs). En ECharts 5.5, un visualMap en una serie de línea rompe el dibujado (reading 'coord'); para colorear por signo, usa un degradado con corte en 0. Los elementos con hidden y su propio display necesitan la regla [hidden]{display:none}.
Limitaciones
- Solo fondos de inversión del CSV de órdenes. No incluye acciones, ETF, cuentas ni depósitos.
- No descuenta comisiones cobradas fuera de los fondos (custodia, gestión de carteras automatizadas cobrada en cuenta) ni impuestos. Los gastos internos de cada fondo ya están en su valor liquidativo.
- Los reembolsos parciales a la cuenta corriente (sin traspaso a otro fondo) no se pueden deducir: el panel los señala como ¿venta? y hay que confirmarlos con el botón.
- Las ventas sin traspaso se valoran con el valor liquidativo del primer día hábil tras la orden; el CSV no trae el importe cobrado.
- Fechas de ejecución y precios de venta deducidos: pueden diferir en céntimos de los de tus extractos.
- Órdenes en otras monedas: se valoran con el precio en euros del fondo, no con el tipo de cambio de la orden.
- Los últimos días se valoran con el último precio publicado hasta que llega el oficial.
Preguntas frecuentes
¿Por qué mi ganancia no coincide con la de la app de MyInvestor?
MyInvestor suele mostrar la plusvalía de las posiciones actuales sobre su coste, sin contar lo ya vendido ni lo traspasado. El panel cuenta todo lo ganado desde la primera orden, incluidos fondos que ya no tienes.
Una venta aparece como compra (o al revés).
Búscala en la tabla de órdenes y pulsa «Es una venta» o «Es una compra». Se recalcula todo al momento y la corrección se guarda en tu navegador.
Aparece «participaciones negativas».
Alguna venta se ha tomado como compra antes de ella, o el CSV no empieza en tu primera orden. Revisa las órdenes de ese fondo o descarga el CSV desde el principio.
La zona «estimado» aparece al final de las gráficas.
Los valores liquidativos oficiales tardan 1 a 3 días en publicarse. Hasta entonces se usa el último disponible. Se corrige solo cuando la acción diaria trae los nuevos precios.
¿Puedo ver mis datos en otro dispositivo?
Sí, pero tienes que subir el CSV también allí: cada navegador guarda su propia copia y nada se sincroniza.
¿Por qué el TWR y la TIR son tan distintos?
El TWR ignora cuándo entró el dinero y la TIR no. Si una gran aportación coincidió con una subida o una caída, las dos cifras se separan. Ver Cálculos.
Historial de cambios
| Fecha | Cambio |
|---|---|
| 08/10/2026 | Panel válido para cualquier cuenta. Se eliminan del código las ventas e importes de la cuenta del autor: compras y ventas se deducen solo del CSV (vacía el fondo, traspasos y reajustes entre fondos, columna de tipo si existe). Los valores liquidativos que falten se descargan de Morningstar para cualquier fondo y fecha. Bloques por categoría Morningstar. Año de cuenta desde la primera orden (configurable). Las correcciones manuales quedan ligadas a cada cuenta. Lectura del CSV más robusta (separadores, miles, comillas, líneas de título). |
| 07/10/2026 | Documentación publicada en /docs/. |
| 07/10/2026 | El rango de fechas llega siempre hasta hoy; los días sin precio oficial mantienen el último valor. La fecha de «valores liquidativos exactos» se calcula con los fondos que tienes hoy. Avisos solo cuando los precios llevan más de 4 días sin actualizarse. |
| 07/10/2026 | Arreglada la vista «Ganancia acumulada», que se mostraba vacía. |
| 06/10/2026 | Primera versión pública en GitHub Pages, sin datos personales y con actualización diaria de valores liquidativos. |