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.
- 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 csvoption
- Node.js (v22 or higher recommended)
No installation is required, npx will download and install on the fly the latest release of the package.
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]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.
{
"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
}
}
}
}account: The account identifier to filter transactionsfrom_date: Optional start date for filtering transactions (ISO format)
accounts.{accountId}.model: The model identifier for the accountaccounts.{accountId}.acct_id: The account identifier for the accountaccounts.{accountId}.bank_id: The bank identifier for the accountaccounts.{accountId}.currency: The currency code (e.g., EUR, USD)
models.{modelName}.encoding: File encoding (e.g., utf-8, latin1)models.{modelName}.delimiter: CSV delimiter charactermodels.{modelName}.date_format: Date format using Luxon format tokensmodels.{modelName}.from_line: First line to process (1-based)models.{modelName}.to_line: Last line to process (1-based)models.{modelName}.columns: Column mapping configurationmodels.{modelName}.mapping: Operation type mapping 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)
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 theStatementTypelabels (e.g.Achat,Dividende,Virement Ă,Paiement carte de dĂ©bit...). When not provided or unmatched, the type defaults toCredit(amount >= 0) orDebit(amount < 0). The type is used for CSV (Portfolio Performance) output; the OFX output remains generic (Debit/Credit by amount sign).
{
"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
}
}
}
}{
"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
}
}
}
}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.
csv2ofx model input.csv output.[ofx|csv]- Convert a CSV file using the default model (OFX output):
csv2ofx default transactions.csv output.ofx- Convert a CSV file using a specific model (OFX output):
csv2ofx bank-export bank_data.csv output.ofx- Convert a CSV file and filter by date:
csv2ofx default transactions.csv output.ofx --from-date 2026-01-01- Convert a CSV file and filter by account:
csv2ofx default transactions.csv output.ofx --account savings- Generate PortfolioPerformance CSV output:
csv2ofx default transactions.csv output.csv --format csv--model model_id- Optional input data model--format ofx|csv(default:ofx) – Choose output format.csvproduces 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.
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.
The generated OFX file will include:
- Account information
- Transaction list with dates, amounts, and references
- Memos combining category and labels
- Final balance
Contributions are welcome! Please fork the repository and submit a pull request.
This project is licensed under the MIT License.