SkillAgentSearch skills...

GhostfolioSidekick

A continuous running Docker container (a sidecar) to automatically import files from several brokers & crypto exchanges. And more.... See the readme.md for more information

Install / Use

/learn @VibeNL/GhostfolioSidekick
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

GhostfolioSidekick

Build & deploy application

Quality Gate Status

Shield: Buy me a coffee

Deep Wiki

A continuous running Docker container (a sidecar) to automatically import files from several brokers & crypto exchanges. The program checks every hour if any new transactions are found and inserts them in ghostfolio. It can also correct & remove transactions in case they have changed (for example a different exchange rate) or the source file was deleted.

Additionally, for self-hosted instances, it can maintain symbols automatically.

  • Set trackinsight property of symbols
  • Create manual symbols
  • Delete symbols that are no longer used

( more to come? Help is always welcome! )

Setup

Ghostfolio

  • Create an account in ghostfolio using anonymous option save your KEY.
  • Create the relevant accounts in ghostfolio.

Folder structure

FileImporterPath should point to a folder with the following structure:

  • Account Name
    • File1.csv
  • Account Name 2
    • File2.csv
    • File3.csv

Assuming you configured an account with the name 'Trading 212' and an account with 'De Giro' in ghostfolio, the following structure should be used. For example:

  • Trading 212
    • Export2023.csv
  • De Giro
    • Export2022.csv
    • Export2023.csv

Configuration File

A single json file csv file that contains mapping to convert currencies and symbols to a symbol that can be found via ghostfolio. Also allows the following symbol settings

  • Setting Trackinsight on symbols
  • Adding / Updating Manual symbols
{
    "settings" : {
		"performance.primarycurrency": "USD", // default "EUR"
		"dataprovider.preference.order": "COINGECKO,YAHOO", // default "YAHOO,COINGECKO"
		"delete.unused.symbols": false // default is true. Note generated symbols like INTEREST and FEE are always deleted since they can't be reused.
	},
	"platforms":[
		{ "name": "De Giro", "url":"https://www.degiro.nl/" }
	],
	"accounts":[
		{ "name": "De Giro", "currency":"EUR", "platform":"De Giro", "sync-activities": true, "sync-balance": false } // sync-activities is true by default, sync-balance is true by default
	],
	"mappings":[
		{ "type":"currency", "source":"GBX", "target":"GBp"},
		{ "type":"symbol", "source":"USDC", "target":"usd-coin"},
		{ "type":"symbol", "source":"BTC", "target":"bitcoin"}
	],
	"symbols":[
		{ "symbol": "VDUC.L", "trackinsight": "VUSC" },
		{ "symbol": "VFEM.L", "trackinsight": "VDEM" },
		{ "symbol": "DE0001102333", "manualSymbolConfiguration": { "currency":"EUR", "isin":"DE0001102333","name":"Bond Germany Feb 2024","assetSubClass":"BOND","assetClass":"EQUITY" } },
		{ "symbol": "PhysicalGoldEuroPerKilogram", "manualSymbolConfiguration": { "currency":"EUR", "isin":"PhysicalGoldEuroPerKilogram","name":"Physical Gold EUR/KG","assetSubClass":"PRECIOUS_METAL","assetClass":"COMMODITY", "scraperConfiguration":{ "url": "<url>", "selector":"<selector>", "locale":"<locale>"} } }
	],
	"benchmarks":[
		{ "symbol": "^AEX" },
		{ "symbol": "^SPX" },
	]
}

Settings

use.dust.threshold (Experimental)

This settings does control if a workaround is used for dust (very small amount that cannot be sold or due to rounding errors). The amount is the total value of the assets (thus quantity times unitprice). Unitprice is converted to the currency defined by use.dust.currency.

For crypto specifically, another setting will take presidence. See use.crypto.workaround.dust.threshold. This due to the likelyness of higher values for the dust of cryptocurrencies.

use.crypto.workaround.dust.threshold (Experimental)

This settings does control if a workaround is used for dust (very small amount that cannot be sold or due to rounding errors). The amount is the total value of the assets (thus quantity times unitprice). Unitprice is converted to the currency defined by use.dust.currency.

use.crypto.workaround.stakereward.add.to.last.buy (Experimental)

This settings does control if a workaround is used for staking rewards. If set to true, the staking reward is added to the last buy activity.

Platform and Account

Creates platforms and accounts if not yet created

Fields are identical to the UI

Benchmarks

Add a symbol as a benchmark

Mappings

Change an identifier from the imported files to be compatible with Ghostfolio (for example certain symbols may not be found by Ghostfolio, so we can substituting the identifier with one that is recognized).

| Fieldname | Type | Description | |--|--|--| | type | one of: 'currency', 'symbol' | The type of mapping to be applied | | source | any string | the name of the symbol as it appears in the csv files | | target | any string | the name of the symbol to use within Ghostfolio |

Symbols

Maintaining symbols in ghostfolio

| Fieldname | Type | Description | |--|--|--| | symbol | any string | The name of the symbol| | trackinsight | any string | The trackinsight key to be set | | manualSymbolConfiguration | ManualSymbolConfiguration | see ManualSymbolConfiguration. Will be created if it does not exists |

ManualSymbolConfiguration

| Fieldname | Type | Description | |--|--|--| | currency | any string | The currency of the symbol | | isin | any string | The ISIN to be set | | name | any string | The name of the symbol | | assetSubClass | one of: 'CRYPTOCURRENCY', 'ETF', 'STOCK', 'MUTUALFUND', 'BOND', 'COMMODITY', 'PRECIOUS_METAL', 'PRIVATE_EQUITY'| Same list as Ghostfolio | | assetClass | one of: 'CASH', 'COMMODITY', 'EQUITY', 'FIXED_INCOME', 'REAL_ESTATE' | Same list as Ghostfolio | | scraperConfiguration| object with url, selector and optional locale | The scraperconfiguration as used in Ghostfolio (NOTE: no support for headers yet)|

Supported formats

The goal is to support all platforms as best as possible. Due to the continuous growth of Ghostfolio, new features may be added when possible.

| Platform | Source of the files | Documentation | |--|--|--| | Bitvavo (Broker) | Export of transaction history | | | Bunq (Bank) | Export CSV (Semicolom delimited) | | | Coinbase (Broker) | Export of transaction history | | | De Giro | Export of account history (Language dependend, NL and PT supported currently) | Documentation | | Generic importer | See below | | | Nexo (Broker) | Export of transaction history | | | NIBC (Bank) | Export CSV (Semicolom delimited) | | | Scalable Capital (Prime only) | The CSV files export via the transaction view | | | Trading Republic | Montly Statements and individual invoices | Documentation | | Trading 212 | Export of transaction history | Documentation |

Generic import format

Beside the supported exchanges and brokers there is also a generic format. This format is only usefull for stocks at the moment, not for cryptocurrency:

| Field | Value(s) | | ----- | ----- | | ActivityType | BUY ,SELL, DIVIDEND and INTEREST | | Symbol | The symbol to search | Date | The date, yyyy-MM-dd | | Currency | The currency of the unitprice and fee | | Quantity | The amount of units | | UnitPrice | The paid price per unit | | Fee | The total fee paid for the transaction. Is optional | | Tax | The total tax on the transaction, is used to adjust the unitprice. Is optional | | Description | A description, not used in ghostfolio itself. Is optional | | Id | The transaction id. Is optional |

For stock splits there is a seperate format | Field | Value(s) | | ----- | ----- | | Symbol | The symbol to search | Date | The date, yyyy-MM-dd | | StockSplitFrom | The number of stock in the old situation | | StockSplitTo | The number of stock in the new situation |

Example

File1: ActivityType,Symbol,Date,Currency,Quantity,UnitPrice,Fee BUY,US67066G1040,2023-08-07,USD,0.0267001000,453.33,0.02

File2: Symbol,Date,StockSplitFrom,StockSplitTo US67066G1040,2023-08-07,1,3

Run in Docker

The docker image is named: vibenl/ghostfoliosidekick

Example docker-compose.yml:

ghostfoliosidekick:
	image: vibenl/ghostfoliosidekick:latest
	container_name: Ghostfolio-Ghostfoliosidekick
	hostname: ghostfoliosidekick
	security_opt:
		- no-new-privileges:true
	environment:
		- GHOSTFOLIO_URL=url
		- GHOSTFOLIO_ACCESTOKEN=abc
		- FILEIMPORTER_PATH=/var/lib/data
		- CONFIGURATIONFILE_PATH=/var/lib/data/config.json
	restart: always
	volumes:
		- /volume1/docker/ghostfolio/sidekick:/var/lib/data:r
	depends_on:
	ghostfolio:
		condition: service_started

Settings

| Envs |Description | |--|--| |GHOSTFOLIO_URL | The endpoint for your ghostfolio instance. | |GHOSTFOLIO_ACCESTOKEN | The token as used to 'login' in the UI | |FILEIMPORTER_PATH | The path to the files (see [Import Path]) | |DATABASE_PATH | The path to the database file. If it is only a path the file will be named 'ghostfolio.db'. In case this variable is not specified, it will be placed in the FILEIMPORTER_PATH folder | |CONFIGURATIONFILE_PATH | (optional) The path to the config file, for example '/files/config/config.json' | |TROTTLE_WAITINSECONDS | (optional) The time in seconds between calls to Ghostfolio. Defaults to no waittime. |

Contributing

  • Feel free to submit any issue or PR's you think necessary
View on GitHub
GitHub Stars35
CategoryDevelopment
Updated1d ago
Forks8

Languages

C#

Security Score

90/100

Audited on Apr 1, 2026

No findings