feat(portfolio): store and publish instrument sector and issuer (WealthLedger/main#48) (#148)
This commit was merged in pull request #148.
This commit is contained in:
+29
@@ -0,0 +1,29 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { PrismaService } from '../../../../prisma/prisma.service';
|
||||
|
||||
@Injectable()
|
||||
export class PositionClassificationRepository {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
read(key: string) {
|
||||
return this.prisma.tbankInstrumentClassification.findUnique({
|
||||
where: { provider_instrumentKey: { provider: 'tbank', instrumentKey: key } },
|
||||
});
|
||||
}
|
||||
|
||||
save(key: string, data: {
|
||||
assetUid?: null | string;
|
||||
brandFetchedAt?: Date | null;
|
||||
brandName?: null | string;
|
||||
brandUid?: null | string;
|
||||
sector?: null | string;
|
||||
sectorFetchedAt?: Date;
|
||||
}) {
|
||||
return this.prisma.tbankInstrumentClassification.upsert({
|
||||
where: { provider_instrumentKey: { provider: 'tbank', instrumentKey: key } },
|
||||
create: { provider: 'tbank', instrumentKey: key, ...data },
|
||||
update: data,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Money } from '../../../../common/money.types';
|
||||
import type { Classification } from '../application/position-classification.service';
|
||||
import type { PortfolioDto, PortfolioPositionDto } from '../presentation/portfolio.dto';
|
||||
|
||||
import {
|
||||
@@ -35,9 +36,10 @@ function mapPortfolio(
|
||||
cash: TbankMoney[],
|
||||
metadata: ReadonlyMap<string, { data?: null | TbankInstrument }>,
|
||||
lastSuccessfulAt: string,
|
||||
classification: ReadonlyMap<string, Classification> = new Map(),
|
||||
): PortfolioDto {
|
||||
const positions = upstream
|
||||
.map((position) => mapPosition(position, metadata.get(metadataKey(position))?.data ?? null))
|
||||
.map((position) => mapPosition(position, metadata.get(metadataKey(position))?.data ?? null, classification.get(metadataKey(position))))
|
||||
.filter((position): position is PortfolioPositionDto => position !== null);
|
||||
const balances = new Map<string, ReturnType<typeof decimal>>();
|
||||
for (const value of cash) {
|
||||
@@ -63,6 +65,7 @@ function mapPortfolio(
|
||||
function mapPosition(
|
||||
position: NonNullable<TbankPortfolio['positions']>[number],
|
||||
metadata: null | TbankInstrument,
|
||||
classification?: Classification,
|
||||
): null | PortfolioPositionDto {
|
||||
const quantity = decimal(position.quantity ?? {});
|
||||
if (isZero(quantity)) return null;
|
||||
@@ -96,6 +99,8 @@ function mapPosition(
|
||||
isin: metadata?.isin?.trim() || null,
|
||||
ticker: metadata?.ticker?.trim() || null,
|
||||
logoName: metadata?.brand?.logoName?.trim() || null,
|
||||
sector: classification?.sector ?? null,
|
||||
issuer: classification?.issuer ?? null,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user