Skip to content

rylorin/csv2ofx

Repository files navigation

csv2ofx

Version Publish License Downloads

Overview

csv2ofx is a tool that converts CSV files to OFX format. This is useful for importing financial data into accounting software that supports OFX files, like GnuCash. Alternatively it can be used to convert any input CSV files to the CSV format used by PortfolioPerformance.

Features

  • Convert CSV files to OFX format
  • Support for multiple CSV formats through configuration
  • Filter transactions by account and date
  • Support for labels and memos
  • Automatic reference generation
  • Configurable date formats and delimiters
  • New: Support for PortfolioPerformance CSV output via --format csv option

📌 Prerequisites

  • Node.js (v22 or higher recommended)

🚀 Installation & Usage

Installation

No installation is required, npx will download and install on the fly the latest release of the package.

Usage

To run csv2ofx from the system command line prompt (not from the Node.js REPL), use the following command:

npx csv2ofx model input.csv output.[ofx|csv]

Configuration

csv2ofx uses a configuration file to define how to parse CSV files and generate OFX output. The configuration is stored in JSON format and supports multiple models for different CSV formats.

Configuration Structure

{
  "account": "my-account",
  "from_date": "2001-01-01"
  "accounts": {
    "my-account": {
      "model": "my-model",
      "acct_id": "123456789",
      "bank_id": "BANK12345",
      "currency": "EUR"
    }
  },
  "models": {
    "my-model": {
      "encoding": "utf-8",
      "delimiter": ";",
      "date_format": "yyyy-LL-dd HH:mm:ssZZ",
      "fromLine": 2,
      "toLine": 1000,
      "mapping": {
        "Market buy": "Achat",
        "Interest on cash": "Intérêts",
        "Dividends": "Dividendes",
        "Deposit": "Dépôt",
        "Spending cashback": "Remboursement de Frais",
        "Card debit": "Retrait"
      },
      "columns": {
        "date": 1,
        "payee": 2,
        "category": 3,
        "amount": 4,
        "memo": 5,
        "label": 6,
        "reference": 7,
        "account": 8
      }
    }
  }
}

Configuration Options

Run Configuration

  • account: The account identifier to filter transactions
  • from_date: Optional start date for filtering transactions (ISO format)

Account Configuration

  • accounts.{accountId}.model: The model identifier for the account
  • accounts.{accountId}.acct_id: The account identifier for the account
  • accounts.{accountId}.bank_id: The bank identifier for the account
  • accounts.{accountId}.currency: The currency code (e.g., EUR, USD)

Model Configuration

  • models.{modelName}.encoding: File encoding (e.g., utf-8, latin1)
  • models.{modelName}.delimiter: CSV delimiter character
  • models.{modelName}.date_format: Date format using Luxon format tokens
  • models.{modelName}.from_line: First line to process (1-based)
  • models.{modelName}.to_line: Last line to process (1-based)
  • models.{modelName}.columns: Column mapping configuration
  • models.{modelName}.mapping: Operation type mapping configuration

Column Configuration

  • columns.date: Column index for the date field (1-based)
  • columns.payee: Column index for the payee field (1-based)
  • columns.category: Column index for the category field (1-based)
  • columns.amount: Column index for the amount field (1-based)
  • columns.memo: Optional column index for the memo field (1-based)
  • columns.label: Optional column index for the label field (1-based)
  • columns.reference: Optional column index for the reference field (1-based)
  • columns.account: Column index for the account field (1-based)

... and for Trading 212 CSV export format to Porfolio Performance CSV import format

  • columns.fee_amount: Column index for the conversion fee amount field (1-based)
  • columns.under_currency: Column index for the underlying currency field (1-based)
  • columns.exchange_rate: Column index for the exchange rate field (1-based)
  • columns.currency: Column index for the operation currency field (1-based)
  • columns.ticker: Column index for the stock ticker symbol field (1-based)
  • columns.isin: Column index for the ISIN security identifier field (1-based)
  • columns.security_name: Column index for the security name/text field (1-based)
  • columns.shares: Column index for the number of shares/units traded field (1-based)
  • columns.price: Column index for the price per unit/shares field (1-based)
  • columns.type: Optional column index for the operation type field (1-based). The value is matched (case-insensitively) against the StatementType labels (e.g. Achat, Dividende, Virement Ă , Paiement carte de dĂ©bit...). When not provided or unmatched, the type defaults to Credit (amount >= 0) or Debit (amount < 0). The type is used for CSV (Portfolio Performance) output; the OFX output remains generic (Debit/Credit by amount sign).

Example Configurations

Basic Configuration

{
  "account": "checking"
  "accounts": {
    "checking": {
      "model": "default",
      "bank_id": "123456789",
      "currency": "EUR"
    }
  },
  "models": {
    "default": {
      "encoding": "utf-8",
      "delimiter": ",",
      "date_format": "yyyy-MM-dd",
      "from_line": 2,
      "columns": {
        "date": 1,
        "payee": 2,
        "category": 3,
        "amount": 4,
        "account": 5
      }
    }
  }
}

Advanced Configuration

{
  "account": "savings",
  "from_date": "2024-01-01",
  "accounts": {
    "savings": {
      "model": "bank-export",
      "bank_id": "987654321",
      "currency": "USD"
    }
  },
  "models": {
    "bank-export": {
      "encoding": "latin1",
      "delimiter": ";",
      "date_format": "dd.MM.yyyy",
      "from_line": 2,
      "to_line": 1000,
      "columns": {
        "date": 1,
        "payee": 2,
        "category": 3,
        "amount": 4,
        "memo": 5,
        "label": 6,
        "reference": 7,
        "account": 8
      }
    }
  }
}

Usage Examples

The command now accepts an optional --format (or -f) argument to choose the output format. The default format is ofx, but you can generate PortfolioPerformance‑compatible CSV files by specifying --format csv.

Basic Usage

csv2ofx model input.csv output.[ofx|csv]

Examples

  1. Convert a CSV file using the default model (OFX output):
csv2ofx default transactions.csv output.ofx
  1. Convert a CSV file using a specific model (OFX output):
csv2ofx bank-export bank_data.csv output.ofx
  1. Convert a CSV file and filter by date:
csv2ofx default transactions.csv output.ofx --from-date 2026-01-01
  1. Convert a CSV file and filter by account:
csv2ofx default transactions.csv output.ofx --account savings
  1. Generate PortfolioPerformance CSV output:
csv2ofx default transactions.csv output.csv --format csv

Options

  • --model model_id - Optional input data model
  • --format ofx|csv (default: ofx) – Choose output format. csv produces a PortfolioPerformance‑compatible CSV file.
  • --account account-id – Optional account filter.
  • --from-date YYYY-MM-DD – Optional start date filter.
  • --to-date YYYY-MM-DD – Optional end date filter.

CSV Format

When generating CSV output, the tool produces a PortfolioPerformance‑compatible file with the following header:

Date;Type;Note;Symbole boursier;ISIN;Nom du titre;Parts;Frais;Impôts / Taxes;Valeur;Devise de l'opération;Taux de change

The parser extracts optional currency conversion fields (exchange rate, fee amount, etc.) from the input file to populate the appropriate columns.

OFX Output

The generated OFX file will include:

  • Account information
  • Transaction list with dates, amounts, and references
  • Memos combining category and labels
  • Final balance

Contributing

Contributions are welcome! Please fork the repository and submit a pull request.

License

This project is licensed under the MIT License.

About

Convert CSV files to OFX or PortfolioPerformance file format

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages