Formato JSON de Cartera

Portfolio Toolkit utiliza un formato JSON estructurado (Versión 2) para almacenar datos de cartera. Este formato soporta transacciones multi-moneda, seguimiento de costos FIFO e historial completo de transacciones.

Resumen de Estructura JSON

El archivo JSON de cartera tiene cuatro secciones principales:

  1. Metadatos de Cartera: Información básica sobre la cartera

  2. Transacciones: Array plano de todas las transacciones (depósitos, retiros, compras, ventas)

  3. Divisiones: Array de eventos de división de acciones (opcional)

Estructura Básica

{
  "name": "Nombre de Cartera",
  "currency": "EUR",
  "transactions": [
    // Array de objetos de transacción
  ],
  "splits": [
    // Array de objetos de división de acciones (opcional)
  ]
}

Campos de Metadatos de Cartera

name

  • Tipo: String

  • Requerido: Sí

  • Descripción: Nombre de visualización para la cartera

  • Ejemplo: "Mi Cartera de Inversiones"

currency

  • Tipo: String

  • Requerido: Sí

  • Descripción: Moneda base para la cartera (código ISO 4217)

  • Soportadas: EUR, USD, CAD, GBP, etc.

  • Ejemplo: "EUR"

Estructura de Transacciones

Cada transacción en el array transactions debe incluir los siguientes campos:

Campos Principales

ticker

  • Tipo: String o null

  • Requerido: Sí

  • Descripción: Símbolo del activo (ej., «AAPL») o null para transacciones de efectivo

  • Ejemplos: "AAPL", "GOOGL", null

date

  • Tipo: String

  • Requerido: Sí

  • Formato: YYYY-MM-DD

  • Descripción: Fecha de la transacción

  • Ejemplo: "2025-06-12"

type

  • Tipo: String

  • Requerido: Sí

  • Valores: "buy", "sell", "deposit", "withdrawal"

  • Descripción: Tipo de transacción

quantity

  • Tipo: Number

  • Requerido: Sí

  • Descripción: Número de acciones (valores) o cantidad (efectivo)

  • Ejemplo: 10 (acciones), 1000.00 (cantidad de efectivo)

price

  • Tipo: Number

  • Requerido: Sí

  • Descripción: Precio por acción (valores) o 1.00 (efectivo)

  • Ejemplo: 150.25 (precio de acción), 1.00 (efectivo)

Campos de Moneda y Conversión

currency

  • Tipo: String

  • Requerido: Sí

  • Descripción: Moneda de la transacción

  • Ejemplo: "USD", "EUR", "CAD"

total

  • Tipo: Number

  • Requerido: Sí

  • Descripción: Cantidad total en moneda de la transacción

  • Cálculo: quantity × price

  • Ejemplo: 1500.00

exchange_rate

  • Tipo: Number

  • Requerido: Sí

  • Descripción: Tipo de cambio de moneda de transacción a moneda base

  • Formato: Cuántas unidades de moneda de transacción por 1 unidad de moneda base

  • Ejemplo: 1.056 (tasa EUR/USD)

subtotal_base

  • Tipo: Number

  • Requerido: Sí

  • Descripción: Cantidad de transacción en moneda base antes de comisiones

  • Cálculo: total ÷ exchange_rate

  • Ejemplo: 1420.45

fees_base

  • Tipo: Number

  • Requerido: Sí

  • Descripción: Comisiones de transacción en moneda base

  • Ejemplo: 2.50

total_base

  • Tipo: Number

  • Requerido: Sí

  • Descripción: Costo total en moneda base incluyendo comisiones

  • Cálculo: subtotal_base + fees_base (compra) o subtotal_base - fees_base (venta)

  • Ejemplo: 1422.95

Tipos de Transacciones

Compra de Acciones (Buy)

{
  "ticker": "AAPL",
  "date": "2025-06-12",
  "type": "buy",
  "quantity": 10,
  "price": 150.00,
  "currency": "USD",
  "total": 1500.00,
  "exchange_rate": 1.056,
  "subtotal_base": 1420.45,
  "fees_base": 2.50,
  "total_base": 1422.95
}

Venta de Acciones (Sell)

{
  "ticker": "AAPL",
  "date": "2025-06-15",
  "type": "sell",
  "quantity": 5,
  "price": 155.00,
  "currency": "USD",
  "total": 775.00,
  "exchange_rate": 1.058,
  "subtotal_base": 732.58,
  "fees_base": 2.00,
  "total_base": 730.58
}

Depósito de Efectivo

{
  "ticker": null,
  "date": "2025-06-10",
  "type": "deposit",
  "quantity": 1000.00,
  "price": 1.00,
  "currency": "EUR",
  "total": 1000.00,
  "exchange_rate": 1.00,
  "subtotal_base": 1000.00,
  "fees_base": 0.00,
  "total_base": 1000.00
}

Retiro de Efectivo

{
  "ticker": null,
  "date": "2025-06-20",
  "type": "withdrawal",
  "quantity": 500.00,
  "price": 1.00,
  "currency": "EUR",
  "total": 500.00,
  "exchange_rate": 1.00,
  "subtotal_base": 500.00,
  "fees_base": 5.00,
  "total_base": 505.00
}

Estructura de Divisiones de Acciones

El array splits es opcional y contiene eventos de división de acciones que ajustan automáticamente las posiciones históricas. Cada objeto de división incluye los siguientes campos:

Campos de División

ticker

  • Tipo: String

  • Requerido: Sí

  • Descripción: Símbolo de la acción que experimentó la división

  • Ejemplo: "EVTL", "AAPL", "GOOGL"

date

  • Tipo: String

  • Requerido: Sí

  • Formato: YYYY-MM-DD

  • Descripción: Fecha en que la división de acciones entró en vigor

  • Ejemplo: "2024-09-23"

ratio

  • Tipo: String

  • Requerido: Sí

  • Descripción: Proporción de división legible por humanos

  • Formato: "nuevo:viejo" (ej., «2:1» para una división de 2 por 1)

  • Ejemplos: "2:1" (división), "4:1" (división), "1:10" (división inversa)

split_factor

  • Tipo: Number

  • Requerido: Sí

  • Descripción: Factor numérico para multiplicar las acciones existentes

  • Cálculo: nuevas_acciones = acciones_antiguas × split_factor

  • Ejemplos: 2.0 (división 2:1), 0.1 (división inversa 1:10)

Tipos de División

División Directa de Acciones (2:1)

{
  "ticker": "AAPL",
  "date": "2024-08-31",
  "ratio": "4:1",
  "split_factor": 4.0
}

Efecto: 100 acciones se convierten en 400 acciones, el precio se ajusta de $200 a $50

División Inversa de Acciones (1:10)

{
  "ticker": "EVTL",
  "date": "2024-09-23",
  "ratio": "1:10",
  "split_factor": 0.1
}

Efecto: 1000 acciones se convierten en 100 acciones, el precio se ajusta de $1 a $10

Procesamiento de Divisiones

Cuando se procesa una división:

  1. Ajuste Automático: Todas las posiciones mantenidas antes de la fecha de división se ajustan automáticamente

  2. Preservación FIFO: El sistema mantiene el seguimiento de la base de costos FIFO

  3. Acciones Fraccionarias: Para divisiones inversas, las acciones fraccionarias se convierten a efectivo

  4. Creación de Transacciones: El sistema crea transacciones de venta/compra para representar la división

Nota

Las divisiones se procesan automáticamente al cargar la cartera. Las transacciones originales permanecen sin cambios, pero los cálculos de posición efectivos tienen en cuenta todas las divisiones.

Ejemplo Completo de División

{
  "splits": [
    {
      "ticker": "AAPL",
      "date": "2022-08-31",
      "ratio": "4:1",
      "split_factor": 4.0
    },
    {
      "ticker": "EVTL",
      "date": "2024-09-23",
      "ratio": "1:10",
      "split_factor": 0.1
    }
  ]
}

Ejemplo Completo

Aquí hay un archivo JSON de cartera completo con divisiones:

{
  "name": "Sample Multi-Currency Portfolio",
  "currency": "EUR",
  "transactions": [
    {
      "ticker": null,
      "date": "2025-06-01",
      "type": "deposit",
      "quantity": 5000.00,
      "price": 1.00,
      "currency": "EUR",
      "total": 5000.00,
      "exchange_rate": 1.00,
      "subtotal_base": 5000.00,
      "fees_base": 0.00,
      "total_base": 5000.00
    },
    {
      "ticker": "AAPL",
      "date": "2025-06-05",
      "type": "buy",
      "quantity": 20,
      "price": 150.00,
      "currency": "USD",
      "total": 3000.00,
      "exchange_rate": 1.056,
      "subtotal_base": 2840.91,
      "fees_base": 5.00,
      "total_base": 2845.91
    },
    {
      "ticker": "SHOP",
      "date": "2025-06-08",
      "type": "buy",
      "quantity": 15,
      "price": 80.00,
      "currency": "CAD",
      "total": 1200.00,
      "exchange_rate": 0.639,
      "subtotal_base": 766.82,
      "fees_base": 8.18,
      "total_base": 775.00
    },
    {
      "ticker": "AAPL",
      "date": "2025-06-12",
      "type": "sell",
      "quantity": 5,
      "price": 160.00,
      "currency": "USD",
      "total": 800.00,
      "exchange_rate": 1.058,
      "subtotal_base": 756.33,
      "fees_base": 3.00,
      "total_base": 753.33
    }
  ],
  "splits": [
    {
      "ticker": "AAPL",
      "date": "2024-08-31",
      "ratio": "4:1",
      "split_factor": 4.0
    },
    {
      "ticker": "EVTL",
      "date": "2024-09-23",
      "ratio": "1:10",
      "split_factor": 0.1
    }
  ]
}

Validation Rules

The following validation rules apply:

Required Fields

  • All transaction fields listed above are required

  • No field can be null except ticker for cash transactions

  • Split fields are required when splits array is present

Data Types

  • Dates must be in YYYY-MM-DD format

  • Numbers must be positive (except split_factor which can be any positive number)

  • Strings must not be empty

  • Split ratios must follow «new:old» format

Logical Consistency

  • Cash transactions (ticker: null) must have price: 1.00

  • total must equal quantity × price

  • Exchange rates must be positive

  • For base currency transactions, exchange_rate should be 1.00

  • Split dates must be valid dates

  • Split factors must be positive numbers

  • Split ratios must match the split_factor calculation

Split-Specific Rules

  • Split dates should be before any dependent transactions

  • Split factors must be consistent with ratios (e.g., «2:1» → 2.0, «1:10» → 0.1)

  • Tickers in splits must correspond to actual stock transactions

  • Multiple splits for the same ticker must be in chronological order

Common Mistakes

Incorrect Exchange Rate Direction

// ❌ Wrong: Using USD/EUR instead of EUR/USD
{
  "currency": "USD",
  "exchange_rate": 0.946  // This is USD/EUR, not EUR/USD
}

// ✅ Correct: Using EUR/USD
{
  "currency": "USD",
  "exchange_rate": 1.056  // This is EUR/USD
}

Conversión de Comisiones Faltante

// ❌ Incorrecto: Comisiones en moneda de transacción
{
  "currency": "USD",
  "fees_base": 2.50  // Debería convertirse a moneda base
}

// ✅ Correcto: Comisiones en moneda base
{
  "currency": "USD",
  "exchange_rate": 1.056,
  "fees_base": 2.37  // 2.50 USD ÷ 1.056 = 2.37 EUR
}

Totales Inconsistentes

// ❌ Incorrecto: total_base no incluye comisiones
{
  "subtotal_base": 1000.00,
  "fees_base": 5.00,
  "total_base": 1000.00  // Debería ser 1005.00 para compra
}

// ✅ Correcto: total_base incluye comisiones
{
  "subtotal_base": 1000.00,
  "fees_base": 5.00,
  "total_base": 1005.00  // Para transacciones de compra
}

Factor de División Incorrecto

// ❌ Incorrecto: El factor de división no coincide con la proporción
{
  "ticker": "AAPL",
  "ratio": "2:1",
  "split_factor": 0.5  // Debería ser 2.0 para una división 2:1
}

// ✅ Correcto: El factor de división coincide con la proporción
{
  "ticker": "AAPL",
  "ratio": "2:1",
  "split_factor": 2.0  // 2 acciones nuevas por 1 acción antigua
}

// ✅ Correcto: División inversa
{
  "ticker": "EVTL",
  "ratio": "1:10",
  "split_factor": 0.1  // 1 acción nueva por 10 acciones antiguas
}

Mejores Prácticas

  1. Códigos de Moneda Consistentes: Usa códigos de moneda ISO 4217 (EUR, USD, CAD)

  2. Tipos de Cambio Precisos: Usa tipos de cambio de la fecha real de la transacción

  3. Incluir Todas las Comisiones: Contabiliza todos los costos de transacción en fees_base

  4. Orden Cronológico: Ordena las transacciones por fecha para facilitar la depuración

  5. Validación: Usa el script de validación para verificar el formato de tu cartera

Herramientas y Utilidades

Portfolio Toolkit proporciona varias utilidades para trabajar con archivos JSON:

# Validar formato de cartera
python tests/validate_examples.py

# Analizar y validar cartera usando CLI
portfolio-toolkit portfolio parse examples/portfolio_example.json

# Mostrar resumen de cartera con posiciones actuales
portfolio-toolkit portfolio summary examples/portfolio_example.json

# Mostrar análisis de rendimiento de cartera
portfolio-toolkit portfolio performance examples/portfolio_example.json

# Convertir cartera a diferentes formatos
portfolio-toolkit portfolio export examples/portfolio_example.json --format csv

También puedes usar el CLI para trabajar con datos de cartera de forma interactiva:

# Mostrar todos los comandos de cartera disponibles
portfolio-toolkit portfolio --help

# Validar formato de cartera y verificar errores
portfolio-toolkit portfolio validate examples/portfolio_example.json

# Mostrar historial detallado de transacciones
portfolio-toolkit portfolio transactions examples/portfolio_example.json

Para más información sobre comandos CLI, ve la Referencia CLI.