diff --git a/CHANGELOG.md b/CHANGELOG.md index 8be159930..c14452d4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,14 @@ 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 colorization of the change from all time high in the benchmark component when values round to zero +- Fixed the market condition of the benchmarks when values round to zero +- Fixed an issue where values incorrectly rounded to negative zero in the value component + ## 3.19.0 - 2026-07-02 ### Added diff --git a/apps/api/src/services/benchmark/benchmark.service.spec.ts b/apps/api/src/services/benchmark/benchmark.service.spec.ts index 833dbcdfc..0e7119b04 100644 --- a/apps/api/src/services/benchmark/benchmark.service.spec.ts +++ b/apps/api/src/services/benchmark/benchmark.service.spec.ts @@ -12,4 +12,16 @@ describe('BenchmarkService', () => { expect(benchmarkService.calculateChangeInPercentage(2, 2)).toEqual(0); expect(benchmarkService.calculateChangeInPercentage(2, 1)).toEqual(-0.5); }); + + it('getMarketCondition', async () => { + expect(benchmarkService.getMarketCondition(0)).toEqual('ALL_TIME_HIGH'); + expect(benchmarkService.getMarketCondition(-5.90736454893e-9)).toEqual( + 'ALL_TIME_HIGH' + ); + expect(benchmarkService.getMarketCondition(-0.1)).toEqual('NEUTRAL_MARKET'); + expect(benchmarkService.getMarketCondition(-0.19996)).toEqual( + 'BEAR_MARKET' + ); + expect(benchmarkService.getMarketCondition(-0.2)).toEqual('BEAR_MARKET'); + }); }); diff --git a/apps/api/src/services/benchmark/benchmark.service.ts b/apps/api/src/services/benchmark/benchmark.service.ts index 56a629163..99ceaf21e 100644 --- a/apps/api/src/services/benchmark/benchmark.service.ts +++ b/apps/api/src/services/benchmark/benchmark.service.ts @@ -24,7 +24,7 @@ import { Injectable, Logger } from '@nestjs/common'; import { SymbolProfile } from '@prisma/client'; import { Big } from 'big.js'; import { addHours, isAfter, subDays } from 'date-fns'; -import { uniqBy } from 'lodash'; +import { round, uniqBy } from 'lodash'; import ms from 'ms'; import { BenchmarkValue } from './interfaces/benchmark-value.interface'; @@ -220,9 +220,11 @@ export class BenchmarkService { public getMarketCondition( aPerformanceInPercent: number ): Benchmark['marketCondition'] { - if (aPerformanceInPercent >= 0) { + const performanceInPercent = round(aPerformanceInPercent, 4); + + if (performanceInPercent >= 0) { return 'ALL_TIME_HIGH'; - } else if (aPerformanceInPercent <= -0.2) { + } else if (performanceInPercent <= -0.2) { return 'BEAR_MARKET'; } else { return 'NEUTRAL_MARKET'; diff --git a/libs/ui/src/lib/benchmark/benchmark.component.html b/libs/ui/src/lib/benchmark/benchmark.component.html index a950f0c44..d60eba7c4 100644 --- a/libs/ui/src/lib/benchmark/benchmark.component.html +++ b/libs/ui/src/lib/benchmark/benchmark.component.html @@ -135,9 +135,15 @@ class="d-inline-block justify-content-end" [class]="{ 'text-danger': - element?.performances?.allTimeHigh?.performancePercent < 0, + round( + element?.performances?.allTimeHigh?.performancePercent, + 4 + ) < 0, 'text-success': - element?.performances?.allTimeHigh?.performancePercent === 0 + round( + element?.performances?.allTimeHigh?.performancePercent, + 4 + ) === 0 }" [isPercent]="true" [locale]="locale()" diff --git a/libs/ui/src/lib/benchmark/benchmark.component.ts b/libs/ui/src/lib/benchmark/benchmark.component.ts index 0b78ffa0d..0d9aba0ca 100644 --- a/libs/ui/src/lib/benchmark/benchmark.component.ts +++ b/libs/ui/src/lib/benchmark/benchmark.component.ts @@ -33,7 +33,7 @@ import { ActivatedRoute, Router, RouterModule } from '@angular/router'; import { IonIcon } from '@ionic/angular/standalone'; import { addIcons } from 'ionicons'; import { ellipsisHorizontal, trashOutline } from 'ionicons/icons'; -import { isNumber } from 'lodash'; +import { isNumber, round } from 'lodash'; import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; import { GfEntityLogoComponent } from '../entity-logo/entity-logo.component'; @@ -92,6 +92,7 @@ export class GfBenchmarkComponent { protected isLoading = true; protected readonly isNumber = isNumber; protected readonly resolveMarketCondition = resolveMarketCondition; + protected readonly round = round; protected readonly translate = translate; private readonly destroyRef = inject(DestroyRef); diff --git a/libs/ui/src/lib/value/value.component.ts b/libs/ui/src/lib/value/value.component.ts index 9c3330466..dffcb89e7 100644 --- a/libs/ui/src/lib/value/value.component.ts +++ b/libs/ui/src/lib/value/value.component.ts @@ -168,7 +168,9 @@ export class GfValueComponent implements AfterViewInit, OnChanges { } } - if (this.formattedValue === '0.00') { + if (/^-?0([.,]0*)?$/.test(this.formattedValue)) { + // Remove algebraic sign of values rounding to zero + this.formattedValue = this.formattedValue.replace(/^-/, ''); this.useAbsoluteValue = true; } }