{"id":37658623,"url":"https://github.com/omyllymaki/bank-transaction-analyzer","last_synced_at":"2026-01-16T11:45:26.826Z","repository":{"id":37038906,"uuid":"190860282","full_name":"omyllymaki/bank-transaction-analyzer","owner":"omyllymaki","description":"Desktop application for analysis and visualization of bank transaction data.","archived":false,"fork":false,"pushed_at":"2024-06-14T13:37:40.000Z","size":24124,"stargazers_count":13,"open_issues_count":3,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-06-14T15:00:48.980Z","etag":null,"topics":["bank","financial-analysis","gui","pyqt5","transaction-management","visualization"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/omyllymaki.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-08T07:45:48.000Z","updated_at":"2024-06-14T13:37:44.000Z","dependencies_parsed_at":"2023-11-12T10:27:27.418Z","dependency_job_id":"d819bdab-d381-41e4-a4e3-7be9134b9aae","html_url":"https://github.com/omyllymaki/bank-transaction-analyzer","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/omyllymaki/bank-transaction-analyzer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omyllymaki%2Fbank-transaction-analyzer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omyllymaki%2Fbank-transaction-analyzer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omyllymaki%2Fbank-transaction-analyzer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omyllymaki%2Fbank-transaction-analyzer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/omyllymaki","download_url":"https://codeload.github.com/omyllymaki/bank-transaction-analyzer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/omyllymaki%2Fbank-transaction-analyzer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28478365,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T06:30:42.265Z","status":"ssl_error","status_checked_at":"2026-01-16T06:30:16.248Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bank","financial-analysis","gui","pyqt5","transaction-management","visualization"],"created_at":"2026-01-16T11:45:26.095Z","updated_at":"2026-01-16T11:45:26.820Z","avatar_url":"https://github.com/omyllymaki.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bank Transaction Analyzer\n\nIt was a dark and rainy night, Jan 3 2019, when I decided to finally get rid of misc set of excel files that I used\nto analyze and monitor my bank transactions. As a result of that decision, this tool was born. I still use this tool,\nand also add new features every now and then. Hopefully this will be helpful for others as well. \n\n# What is this?\n\nBank Transaction Analyzer provides configurable analysis and visualization of bank transaction data.\n\nBy default, the analyzer works with Nordea internet bank data (both old and new format) but can be customized to work \nwith other banks and data formats too.\n\nUser-defined configuration is used to configure analysis of the data. \n\nMain features of the tool include:\n* Combining data from multiple files to one dataset\n* Flexible regexp search\n* User-defined categories and labels for transactions\n* User-defined automated checks\n* Adding notes to transactions\n* All kinds of data visualizations\n\n# Before usage\n\n* Install Python \u003e= 3.8.\n* Install requirements.\n\nFor Ubuntu users there is installation script: ```./install.sh```.\n\n# Basic usage\n\n* Export your data from Nordea internet bank \n  * Old internet bank: Tilit / Tilitapahtumat ja tilin tiedot / Tapahtumaluettelo\n  * New internet bank: Talous / tilit / Tapahtumat ja tiedot / CSV\n* Start GUI program from command line by typing ```python3 main.py [-- config config_path]``` or simply \n```./run.sh [config_path]``` if you are using virtualenv with Ubuntu.\n* Load data with load button which opens file dialog where you can choose multiple files for analysis.\n* Set filter values and press Enter to apply filtering.\n* Change tabs to see different views and analyses for your filtered data.\n\n**Events**\n* Events tab table can be sorted (left click) or grouped (right click) by any column by clicking corresponding column name.\n* Add free form notes to events in Events tab; these are saved automatically.\n\n**Checks**\n* Left click check name (left table) to see more detailed check results in table format (right table).  \n\nNote:\nSome simulated test data is also provided (in test_data folder). This data can be used to test application.\n\n# Configuration\n\nConfig file is used for app configuration. It contains\n\n* General configs\n* Drop data\n* Categories\n* Labels\n* Checks\n* Notes\n\nYou can make your own configurations by creating a file with same format as in config.json example file or just by \ndirectly modifying it.\n\n**Drop data**\n\nDrop data specifies which items should be always filtered out. E.g. \"target\": [\"Liisa\", \"Mikko\"] would filter out all \nthe rows where target is Liisa or Mikko. You can add new items to drop data by modifying config file directly or from \nEvents tab by right clicking event you want to add to drop_data list.\n\n**Categories**\n\nEvents are classified to different categories.  E.g. one could create category \"Transport expenses\" by selecting \n\"target\" as \"vr|taksi|abc|teboil|neste\" and \"max_value\" as 0. Every event can have only one category.\n\nYou can make your own category by creating new item in config file or by selecting suitable filter values from GUI and \npressing \"Create category from existing filters\" button. If an event matches to multiple categories, then the \nlast category in the file will be used as the category of event.\n\n**Labels**\n\nLabels work like categories with the difference that event can have multiple labels.\n\nYou can make your own label by creating new item in config file or by selecting suitable filter values from GUI and \npressing \"Create label from existing filters\" button.\n\n**Checks**\n\nChecks can be used to create automate checks for your data.\n\nYou can make a check by creating new item in config file. Every check needs type (class name) and arguments. All the \npossible check types are listed in file src/data_processing/checks/checks.py. As an example, \n\n```\n {\n      \"type\": \"StandardCheck\",\n      \"arguments\": {\n        \"name\": \"Monthly sum\",\n        \"filtering\": null,\n        \"grouping\": [\n          \"year\",\n          \"month\"\n        ],\n        \"aggregation\": \"sum\",\n        \"reference_values\": -900,\n        \"criteria\": \"larger\"\n      }\n }\n```\n\nwould define check called \"Monthly sum\". This check would group data by year and month, calculate sum for every\n(year, month) pair, and then compares each value to reference_values (-900). Criteria is \"larger\", so every value\nneeds to be larger than reference value in order to pass the check.\n\nStandardCheck is suitable for checking many things. It contains:\n* optional filtering (use any field accepted by src/data_processing/data_filtering/filter_data)\n* optional grouping (use any column name)\n* optional aggregation (use any string accepted by pandas aggregate, e.g. \"sum\", \"count\" or \"median\")\n* comparison between calculated values and reference values (accepted options are \"larger\", \"smaller\" and \"equal\")\n\n**Notes**\n\nNotes contains free notes for events. The notes will be saved to config file automatically based on notes user has \nadded in tabs \"Events\" and \"Events filtered out\". The content of the file will be loaded when app launches and all the \nexisting notes are shown in GUI.\n\n# Screenshots (with simulated test data provided)\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"screenshots/income_outcome.jpg\" width=\"800px\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"screenshots/year_comparison.jpg\" width=\"800px\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"screenshots/distributions.jpg\" width=\"800px\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"screenshots/heatmap.jpg\" width=\"800px\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"screenshots/events.jpg\" width=\"800px\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"screenshots/events_grouped.jpg\" width=\"800px\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"screenshots/checks.jpg\" width=\"800px\" /\u003e\n\u003c/p\u003e\n\n# Advanced\n\n## Using application with non-default data format\n\nBy default the analyzer works with Nordea internet bank data, with certain data format. However, the application can be \nused with other data formats too. This is done by implementing custom Loader and Transformer class.\n\nLoader loads the raw data from files. It needs to inherit and implement LoaderInterface class.\n\nTransformer collects relevant information from raw data and converts it to specified format that can be handled by \napplication. It needs to inherit and implement TransformerInterface class. Output of Transformer is validated. It needs \nto pass validation checks defined in src/data_processing/validation.py file:\n\n```\nschema = pandas_schema.Schema([\n        Column('value', decimal_validation + nan_validation),\n        Column('time', datetime_validation + nan_validation),\n        Column('bank', string_validation + nan_validation),\n        Column('target', string_validation),\n        Column('message', string_validation),\n        Column('event', string_validation),\n        Column('account_number', string_validation),\n    ])\n```\n\nWhen custom Loader and Transformer classes are created, they can be used by adding bank to DataPreprocessor class\n(src/data_processing/data_preprocessing.py).\n\n## Custom checks\n\nAll the check types are listed in /src/data_processing/checks/checks.py. New check type can be added just by \nimplementing a new class in this file. Note that any check needs to inherit and implement Check which is interface for \nchecks. After the class is created, it can be used via configuration by setting type field as class name.   \n\n## Docker\n\nGrant the Docker container access to the host system's X server, needed by QT.\n```xhost +local:docker```\n\nThen use docker commands to build image and run container. You can also use docker-compose file and simply run\n```docker-compose up```\n\nNote that volume mappings should be modified to map your own config file and data to container.\n\n\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fomyllymaki%2Fbank-transaction-analyzer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fomyllymaki%2Fbank-transaction-analyzer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fomyllymaki%2Fbank-transaction-analyzer/lists"}