Skip to content

Commit

Permalink
Allow Ghostfolio to update cash balance (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
dickwolff committed Jul 12, 2024
1 parent 74f78a3 commit d45da7e
Show file tree
Hide file tree
Showing 9 changed files with 35 additions and 27 deletions.
5 changes: 4 additions & 1 deletion .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@ DEBUG_LOGGING = false
#GHOSTFOLIO_URL="http://192.168.1.x:3333"

# Your Ghostfolio secret (with which you log in)
#GHOSTFOLIO_SECRET = ""
#GHOSTFOLIO_SECRET = ""

# Update Cash balance when automatically importing
#GHOSTFOLIO_UPDATE_CASH=false
2 changes: 1 addition & 1 deletion GitVersion.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
next-version: 0.15.0
next-version: 0.16.0
assembly-informational-format: "{NuGetVersion}"
mode: ContinuousDeployment
branches:
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ The repository contains a sample `.env` file. Rename this from `.env.sample`.
- This can be retrieved by going to Accounts > select your account and copying the ID from the URL

![image](https://user-images.githubusercontent.com/5620002/203353840-f5db7323-fb2f-4f4f-befc-e4e340466a74.png)
- Optionally you can set the `GHOSTFOLIO_UPDATE_CASH` variable to `TRUE` to automatically update your Ghostfolio account cash balance after processing the activities.
- Optionally you can enable debug logging by setting the `DEBUG_LOGGING` variable to `TRUE`.

You can now run `npm run start [exporttype]`. See the table with run commands below. The tool will open your export and will convert this. It retrieves the symbols that are supported with YAHOO Finance (e.g. for European stocks like `ASML`, it will retrieve `ASML.AS` by the corresponding ISIN).
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "export-to-ghostfolio",
"version": "0.15.0",
"version": "0.16.0",
"type": "module",
"description": "Convert multiple broker exports to Ghostfolio import",
"scripts": {
Expand All @@ -18,14 +18,14 @@
"@types/jest": "^29.5.11",
"@types/node": "^20.14.10",
"jest": "^29.7.0",
"ts-jest": "^29.1.5",
"ts-jest": "^29.2.2",
"ts-node": "^10.9.2",
"tsx": "^4.16.2",
"typescript": "^5.5.3"
},
"dependencies": {
"@types/cli-progress": "^3.11.6",
"cacache": "^18.0.3",
"cacache": "^18.0.4",
"chokidar": "^3.6.0",
"cli-progress": "^3.12.0",
"closest-match": "^1.3.3",
Expand Down
7 changes: 5 additions & 2 deletions src/converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ async function createAndRunConverter(converterType: string, inputFilePath: strin
if (!process.env.GHOSTFOLIO_ACCOUNT_ID) {
return errorCallback(new Error("Environment variable GHOSTFOLIO_ACCOUNT_ID not set!"));
}

console.log(`[i] Starting Export to Ghostfolio v${packageInfo.version}`);

// If DEBUG_LOGGING is enabled, set spaces to 2 else null for easier to read JSON output.
const spaces = process.env.DEBUG_LOGGING === "true" ? 2 : null;
const spaces = `${process.env.DEBUG_LOGGING}`.toLocaleLowerCase() === "true" ? 2 : null;

const converterTypeLc = converterType.toLocaleLowerCase();

Expand All @@ -42,6 +42,9 @@ async function createAndRunConverter(converterType: string, inputFilePath: strin
// Map the file to a Ghostfolio import.
converter.readAndProcessFile(inputFilePath, async (result: GhostfolioExport) => {

// Set cash balance update setting according to settings.
result.updateCashBalance = `${process.env.GHOSTFOLIO_UPDATE_CASH}`.toLocaleLowerCase() === "true"

console.log("[i] Processing complete, writing to file..")

// Write result to file.
Expand Down
14 changes: 7 additions & 7 deletions src/converters/abstractconverter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { SecurityService } from "../securityService";
export abstract class AbstractConverter {

protected securityService: SecurityService;

protected progress: cliProgress.MultiBar;

constructor(securityService: SecurityService) {
Expand Down Expand Up @@ -37,7 +37,7 @@ export abstract class AbstractConverter {

const contents = fs.readFileSync(inputFile, "utf-8");

this.processFileContents(contents,successCallback, errorCallback);
this.processFileContents(contents, successCallback, errorCallback);
}

/**
Expand All @@ -46,7 +46,7 @@ export abstract class AbstractConverter {
* @param record The record to check
* @returns true if the record should be skipped, false otherwise.
*/
abstract isIgnoredRecord(record: any): boolean;
abstract isIgnoredRecord(record: any): boolean;

/**
* Process export file contents.
Expand Down Expand Up @@ -105,18 +105,18 @@ export abstract class AbstractConverter {
* @param index The index of the line in the input file.
*/
protected logQueryError(query: string | undefined, index: number) {

let message = `\n[e] An error ocurred while trying to retrieve {query} (line ${index + 2})!\n`;

if (query) {
message = message.replace("{query}", `symbol ${query}`);
} else {
message = message.replace("{query}", `an empty symbol`);
}

console.log(message);
console.log(message);
}

private camelize(str): string {
return str.replace(/[^a-zA-Z ]/g, "").replace(/(?:^\w|[A-Z]|\b\w)/g, function (word, index) {
return index === 0 ? word.toLowerCase() : word.toUpperCase();
Expand Down
24 changes: 12 additions & 12 deletions src/converters/investimentalConverter.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import dayjs from "dayjs";
import { parse } from "csv-parse";
import { InvestimentalRecord } from "../models/investimentalRecord";
import { AbstractConverter } from "./abstractconverter";
import { SecurityService } from "../securityService";
import { GhostfolioExport } from "../models/ghostfolioExport";
import YahooFinanceRecord from "../models/yahooFinanceRecord";
import customParseFormat from "dayjs/plugin/customParseFormat";
import { GhostfolioOrderType } from "../models/ghostfolioOrderType";
import { GhostfolioActivity } from "../models/ghostfolioActivity";
import { InvestimentalRecord } from "../models/investimentalRecord";
import { GhostfolioOrderType } from "../models/ghostfolioOrderType";

export class InvestimentalConverter extends AbstractConverter {

Expand Down Expand Up @@ -86,7 +86,7 @@ export class InvestimentalConverter extends AbstractConverter {
bar1.increment();
continue;
}

let security: YahooFinanceRecord;
try {
security = await this.securityService.getSecurity(
Expand Down Expand Up @@ -115,9 +115,9 @@ export class InvestimentalConverter extends AbstractConverter {
bar1.increment();
}

this.progress.stop()
this.progress.stop()

successCallback(result);
successCallback(result);
});
}

Expand Down Expand Up @@ -153,24 +153,24 @@ export class InvestimentalConverter extends AbstractConverter {
let totalValue = 0;
let lastFee = 0;
let lastPrice = 0;

for (const record of orderRecords) {
if (record.updateType === "Fil") {
let newlyExecutedVolume = remainingVolume - record.volume;
if (record.status === "Inactive") {
newlyExecutedVolume = record.volume;
}
}
executedVolume += newlyExecutedVolume;
totalValue += newlyExecutedVolume * (record.price || lastPrice);
totalValue += newlyExecutedVolume * (record.price || lastPrice);
}

lastFee = record.fee || lastFee;
lastPrice = record.price || lastPrice;
remainingVolume = record.volume;
}

const lastRecord = orderRecords[orderRecords.length - 1];

if (executedVolume > 0) {
const averagePrice = totalValue > 0 ? Number((totalValue / executedVolume).toFixed(4)) : lastPrice;
return {
Expand All @@ -181,7 +181,7 @@ export class InvestimentalConverter extends AbstractConverter {

};
}

return null;
}

Expand Down
2 changes: 1 addition & 1 deletion src/models/ghostfolioActivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ export class GhostfolioActivity {
currency: string;
dataSource: string;
date: string;
symbol: string
symbol: string;
}
1 change: 1 addition & 0 deletions src/models/ghostfolioExport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { GhostfolioActivity } from "./ghostfolioActivity";
class GhostfolioExport {
meta: GhostfolioMeta;
activities: GhostfolioActivity[];
updateCashBalance?: boolean;
}

class GhostfolioMeta {
Expand Down

0 comments on commit d45da7e

Please sign in to comment.