Skip to content

Instantly share code, notes, and snippets.

@shotasenga
Last active June 3, 2025 13:02
Show Gist options
  • Save shotasenga/c461a672d9c9f927ce213a0c3e9e1895 to your computer and use it in GitHub Desktop.
Save shotasenga/c461a672d9c9f927ce213a0c3e9e1895 to your computer and use it in GitHub Desktop.
Export transactions from Wealthsimple to a CSV file for YNAB import
// ==UserScript==
// @name Export Wealthsimple transactions to CSV for YNAB
// @namespace https://shotasenga.com/
// @version 2025053000
// @description Export transactions from Wealthsimple to a CSV file for YNAB import
// @author Shota Senga
// @match https://my.wealthsimple.com/app/activity*
// @icon https://www.google.com/s2/favicons?sz=64&domain=wealthsimple.com
// @grant none
// ==/UserScript==
/*
* DISCLAIMER:
* This script extracts sensitive financial information (transaction data) from Wealthsimple.
* Ensure that you use this script in a secure environment and handle the extracted data responsibly.
* The developer of this script is not responsible for any issues or troubles that arise from its use.
*/
(function () {
"use strict";
waitUntilElementExists("//h1[contains(., 'Activity')]", (element) => {
const button = document.createElement("button");
button.innerText = "Export transactions";
button.onclick = exportTransactions;
element.parentElement.appendChild(button);
});
async function exportTransactions() {
const transactions = [];
for (const button of x(
`//button[contains(., 'Chequing')][contains(., '$')]`
)) {
const payee = button.querySelector("p").innerText;
const amount = x(`.//p[contains(., '$')]`, button).next().value
.innerText;
button.click();
await nextTick();
const [date, _] = Array.from(
x(
`.//p[contains(., 'Date')]/following-sibling::*//p`,
button.parentElement.parentElement
)
).map((el) => el.innerText);
transactions.push({
payee,
amount,
date: formatDateForYNAB(date),
});
}
const csv = [];
csv.push("Date, Payee, Amount");
for (const transaction of transactions) {
csv.push(
[transaction.date, transaction.payee, transaction.amount]
.map(escapeCsvField)
.join(",")
);
}
// save as a file
const blob = new Blob([csv.join("\n")], { type: "text/csv" });
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "transactions.csv";
a.click();
}
function* x(xpath, root = document) {
const xpathResult = document.evaluate(
xpath,
root,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
);
for (let i = 0; i < xpathResult.snapshotLength; i++) {
yield xpathResult.snapshotItem(i);
}
}
function nextTick() {
return new Promise((resolve) => setTimeout(resolve, 0));
}
function waitUntilElementExists(xpath, callback) {
const observer = new MutationObserver(() => {
const element = x(xpath).next().value;
if (element) {
observer.disconnect();
callback(element);
}
});
observer.observe(document.documentElement, {
childList: true,
subtree: true,
});
}
function escapeCsvField(field) {
return `"${field}"`;
}
function formatDateForYNAB(str) {
// "August 19, 2024" to "2024-08-19" using RegExp
const [, month_s, day_s, year] = str.match(/(\w+) (\d+), (\d+)/);
const month = (new Date(Date.parse(`${month_s} 1, 2020`)).getMonth() + 1)
.toString()
.padStart(2, "0");
const day = day_s.padStart(2, "0");
return `${year}-${month}-${day}`;
}
})();
@shotasenga
Copy link
Author

Instruction

  1. Install Tampermonkey https://www.tampermonkey.net/
  2. Open the raw script link to install

Once you install the script, open the "Activity" page in your browser. The "Export Transaction" button should appear on top-right.

Screenshot 2024-08-31 at 3 51 22 PM

DISCLAIMER

  • This script extracts sensitive financial information (transaction data) from Wealthsimple.
  • Ensure that you use this script in a secure environment and handle the extracted data responsibly.
  • The developer of this script is not responsible for any issues or troubles that arise from its use.

@shotasenga
Copy link
Author

I've created a bookmarklet version of this so you can run it on any browsers without installing an extension.

@shotasenga
Copy link
Author

Update the script for the wording changes ('CAD' to '$')

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment