From 96d9559ebe4d837c027dbca4a39899db08ea746c Mon Sep 17 00:00:00 2001 From: Chris Fiel Date: Fri, 15 May 2026 15:37:31 +0800 Subject: [PATCH] Fix/SELL fee added to cash balance instead of subtracted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When creating a SELL activity with a non-zero fee, the cash balance on the account was credited by (quantity * unitPrice) + fee instead of (quantity * unitPrice) - fee, inflating the cash balance by 2x the fee. The previous logic added the fee to the gross magnitude before negating the entire amount for BUY/FEE. SELL (and DIVIDEND/INTEREST/LIABILITY when carrying a fee) therefore received +gross + fee. Compute the signed gross amount first, then subtract the fee unconditionally — fees always reduce cash regardless of activity direction. --- CHANGELOG.md | 6 ++++++ apps/api/src/app/activities/activities.service.ts | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f23e1af95..363c224c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Fixed the cash balance computation for `SELL` activities to subtract the fee instead of adding it (the previous logic inflated the account's cash balance by twice the fee) + ## 3.3.0 - 2026-05-14 ### Added diff --git a/apps/api/src/app/activities/activities.service.ts b/apps/api/src/app/activities/activities.service.ts index 58b9c11a4..95e5aa05b 100644 --- a/apps/api/src/app/activities/activities.service.ts +++ b/apps/api/src/app/activities/activities.service.ts @@ -214,15 +214,15 @@ export class ActivitiesService { }); if (updateAccountBalance === true) { - let amount = new Big(data.unitPrice) - .mul(data.quantity) - .plus(data.fee) - .toNumber(); + let amount = new Big(data.unitPrice).mul(data.quantity).toNumber(); if (['BUY', 'FEE'].includes(data.type)) { amount = new Big(amount).mul(-1).toNumber(); } + // Fees always reduce cash regardless of the activity direction + amount = new Big(amount).minus(data.fee).toNumber(); + await this.accountService.updateAccountBalance({ accountId, amount,