From efa1b2dc2d12b783a89ffdc80b9d4c7177c2ccf9 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Tue, 28 Nov 2023 14:13:05 +0200 Subject: [PATCH 01/13] Fix account balances unrealized profit --- workers/loc.api/sync/positions.snapshot/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workers/loc.api/sync/positions.snapshot/index.js b/workers/loc.api/sync/positions.snapshot/index.js index 68c02bc80..151d08d45 100644 --- a/workers/loc.api/sync/positions.snapshot/index.js +++ b/workers/loc.api/sync/positions.snapshot/index.js @@ -273,7 +273,7 @@ class PositionsSnapshot { } = await this._convertPlToUsd( pl, symbol, - end + mts ) positionsSnapshot.push({ @@ -301,7 +301,7 @@ class PositionsSnapshot { ) ? plUsd / pl : await this.currencyConverter - .getPrice(symbol, end) + .getPrice(symbol, mts) tickers.push({ symbol, From 2273adaf91ca825beed772caf4d74bdcab0e03b5 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Thu, 30 Nov 2023 11:51:34 +0200 Subject: [PATCH 02/13] Add lookup query for appropriate starting point for account balances --- workers/loc.api/sync/balance.history/index.js | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/workers/loc.api/sync/balance.history/index.js b/workers/loc.api/sync/balance.history/index.js index 70f6474aa..755ad0108 100644 --- a/workers/loc.api/sync/balance.history/index.js +++ b/workers/loc.api/sync/balance.history/index.js @@ -5,6 +5,7 @@ const moment = require('moment') const { calcGroupedData, + getStartMtsByTimeframe, getMtsGroupedByTimeframe, groupByTimeframe, isForexSymb @@ -484,9 +485,10 @@ class BalanceHistory { const { timeframe = 'day', - start = 0, + start: reqStart = 0, end = Date.now(), - isUnrealizedProfitExcluded + isUnrealizedProfitExcluded, + doNotLookUpForStartMts } = params ?? {} const { isSubCalc = false @@ -502,6 +504,13 @@ class BalanceHistory { ) } + const start = doNotLookUpForStartMts + ? reqStart + : await this.#lookUpStartMts({ + auth, + params: { timeframe, start: reqStart } + }) + const args = { auth, params: { @@ -577,6 +586,32 @@ class BalanceHistory { return res } + + async #lookUpStartMts (args) { + const { auth, params } = args ?? {} + const { + start, + timeframe + } = params ?? {} + + const ledger = await this.dao.getElemInCollBy( + this.ALLOWED_COLLS.LEDGERS, + { + user_id: auth._id, + $lte: { mts: start } + }, + [['mts', -1], ['id', -1]] + ) + + if (!Number.isInteger(ledger?.mts)) { + return start + } + + return getStartMtsByTimeframe( + ledger.mts, + timeframe + ) + } } decorateInjectable(BalanceHistory, depsTypes) From dc17d4d0cc51e4d8b2ea1495277d66c23e2e807e Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Thu, 30 Nov 2023 14:28:29 +0200 Subject: [PATCH 03/13] Consider requested start time point instead of exist --- workers/loc.api/sync/balance.history/index.js | 71 ++----------------- 1 file changed, 7 insertions(+), 64 deletions(-) diff --git a/workers/loc.api/sync/balance.history/index.js b/workers/loc.api/sync/balance.history/index.js index 755ad0108..866144089 100644 --- a/workers/loc.api/sync/balance.history/index.js +++ b/workers/loc.api/sync/balance.history/index.js @@ -5,7 +5,6 @@ const moment = require('moment') const { calcGroupedData, - getStartMtsByTimeframe, getMtsGroupedByTimeframe, groupByTimeframe, isForexSymb @@ -448,29 +447,10 @@ class BalanceHistory { }] } - async _getStartingMts ( - args, - groupedWallets - ) { - if ( - Array.isArray(groupedWallets) && - groupedWallets.length > 0 && - groupedWallets[groupedWallets.length - 1] && - typeof groupedWallets[groupedWallets.length - 1] === 'object' && - Number.isInteger(groupedWallets[groupedWallets.length - 1].mts) - ) { - return groupedWallets[groupedWallets.length - 1].mts - } - - const firstWalletsMts = await this.wallets.getFirstWalletsMts(args) - - if (Number.isInteger(firstWalletsMts)) { - return firstWalletsMts - } - - const { start = 0 } = args?.params ?? {} - - return start + async _getStartingMts (args) { + return Number.isInteger(args?.params?.start) + ? args.params.start + : await this.wallets.getFirstWalletsMts(args) } async getBalanceHistory ( @@ -485,10 +465,9 @@ class BalanceHistory { const { timeframe = 'day', - start: reqStart = 0, + start = 0, end = Date.now(), - isUnrealizedProfitExcluded, - doNotLookUpForStartMts + isUnrealizedProfitExcluded } = params ?? {} const { isSubCalc = false @@ -504,13 +483,6 @@ class BalanceHistory { ) } - const start = doNotLookUpForStartMts - ? reqStart - : await this.#lookUpStartMts({ - auth, - params: { timeframe, start: reqStart } - }) - const args = { auth, params: { @@ -554,10 +526,7 @@ class BalanceHistory { 'currency', this._calcWalletsInTimeframe(firstWallets) ) - const startingMts = await this._getStartingMts( - args, - walletsGroupedByTimeframe - ) + const startingMts = await this._getStartingMts(args) const mtsGroupedByTimeframe = getMtsGroupedByTimeframe( startingMts, end, @@ -586,32 +555,6 @@ class BalanceHistory { return res } - - async #lookUpStartMts (args) { - const { auth, params } = args ?? {} - const { - start, - timeframe - } = params ?? {} - - const ledger = await this.dao.getElemInCollBy( - this.ALLOWED_COLLS.LEDGERS, - { - user_id: auth._id, - $lte: { mts: start } - }, - [['mts', -1], ['id', -1]] - ) - - if (!Number.isInteger(ledger?.mts)) { - return start - } - - return getStartMtsByTimeframe( - ledger.mts, - timeframe - ) - } } decorateInjectable(BalanceHistory, depsTypes) From badfc04f21ffdb71d9735b63c9ee893efeda56b4 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Fri, 1 Dec 2023 12:12:03 +0200 Subject: [PATCH 04/13] Add start param to getSummaryByAsset endpoint --- workers/loc.api/sync/summary.by.asset/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workers/loc.api/sync/summary.by.asset/index.js b/workers/loc.api/sync/summary.by.asset/index.js index c53c96bdd..7db10781c 100644 --- a/workers/loc.api/sync/summary.by.asset/index.js +++ b/workers/loc.api/sync/summary.by.asset/index.js @@ -49,7 +49,7 @@ class SummaryByAsset { const auth = await this.authenticator .verifyRequestUser({ auth: args?.auth ?? {} }) const end = args?.params?.end ?? Date.now() - const start = moment.utc(end) + const start = args?.params?.start ?? moment.utc(end) .add(-30, 'days') .valueOf() From 41b0669ab08e3a5636262788c0e09cf527163a65 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Fri, 1 Dec 2023 12:13:21 +0200 Subject: [PATCH 05/13] Add start to SummaryByAsset params schema --- workers/loc.api/helpers/schema.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/workers/loc.api/helpers/schema.js b/workers/loc.api/helpers/schema.js index dfeab9963..447bd10a3 100644 --- a/workers/loc.api/helpers/schema.js +++ b/workers/loc.api/helpers/schema.js @@ -340,6 +340,10 @@ const paramsSchemaForPerformingLoanApi = { const paramsSchemaForSummaryByAssetApi = { type: 'object', properties: { + + start: { + type: 'integer' + }, end: { type: 'integer' } From f3e2f75a571d6b3eb2688ff76fc15d651f57b8d5 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Fri, 1 Dec 2023 12:14:33 +0200 Subject: [PATCH 06/13] Add test case for getSummaryByAsset endpoint --- ...itional-api-sync-mode-sqlite-test-cases.js | 48 +++++++++++++++++++ workers/loc.api/helpers/schema.js | 1 - 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/test/test-cases/additional-api-sync-mode-sqlite-test-cases.js b/test/test-cases/additional-api-sync-mode-sqlite-test-cases.js index c65f2b6ab..e541b76a6 100644 --- a/test/test-cases/additional-api-sync-mode-sqlite-test-cases.js +++ b/test/test-cases/additional-api-sync-mode-sqlite-test-cases.js @@ -691,6 +691,54 @@ module.exports = ( it('it should be successfully performed by the getSummaryByAsset method', async function () { this.timeout(60000) + const res = await agent + .post(`${basePath}/json-rpc`) + .type('json') + .send({ + auth, + method: 'getSummaryByAsset', + params: { + start, + end + }, + id: 5 + }) + .expect('Content-Type', /json/) + .expect(200) + + assert.isObject(res.body) + assert.propertyVal(res.body, 'id', 5) + assert.isObject(res.body.result) + assert.isArray(res.body.result.summaryByAsset) + assert.isObject(res.body.result.total) + + res.body.result.summaryByAsset.forEach((item) => { + assert.isObject(item) + assert.containsAllKeys(item, [ + 'currency', + 'balance', + 'balanceUsd', + 'valueChange30dUsd', + 'valueChange30dPerc', + 'result30dUsd', + 'result30dPerc', + 'volume30dUsd' + ]) + }) + + assert.containsAllKeys(res.body.result.total, [ + 'balanceUsd', + 'valueChange30dUsd', + 'valueChange30dPerc', + 'result30dUsd', + 'result30dPerc', + 'volume30dUsd' + ]) + }) + + it('it should be successfully performed by the getSummaryByAsset method, 30d period until the end point', async function () { + this.timeout(60000) + const res = await agent .post(`${basePath}/json-rpc`) .type('json') diff --git a/workers/loc.api/helpers/schema.js b/workers/loc.api/helpers/schema.js index 447bd10a3..af5fcecc8 100644 --- a/workers/loc.api/helpers/schema.js +++ b/workers/loc.api/helpers/schema.js @@ -340,7 +340,6 @@ const paramsSchemaForPerformingLoanApi = { const paramsSchemaForSummaryByAssetApi = { type: 'object', properties: { - start: { type: 'integer' }, From 6b68a6c3d975d60789db7fe2cf885885a8ddeeec Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Wed, 6 Dec 2023 08:20:04 +0200 Subject: [PATCH 07/13] Divide start point into two vars --- workers/loc.api/sync/summary.by.asset/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/workers/loc.api/sync/summary.by.asset/index.js b/workers/loc.api/sync/summary.by.asset/index.js index 7db10781c..525c4f685 100644 --- a/workers/loc.api/sync/summary.by.asset/index.js +++ b/workers/loc.api/sync/summary.by.asset/index.js @@ -49,9 +49,10 @@ class SummaryByAsset { const auth = await this.authenticator .verifyRequestUser({ auth: args?.auth ?? {} }) const end = args?.params?.end ?? Date.now() - const start = args?.params?.start ?? moment.utc(end) + const mts30dUntilEnd = moment.utc(end) .add(-30, 'days') .valueOf() + const start = args?.params?.start ?? mts30dUntilEnd const ledgersPromise = this.#getLedgers({ auth, From 7dd049d22bcdd1e56f02ac7725d39b20de95fdae Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Wed, 6 Dec 2023 13:46:43 +0200 Subject: [PATCH 08/13] Use max and min utils from internal lib --- workers/loc.api/sync/data.inserter/data.checker/index.js | 5 +---- .../sync/data.inserter/sync.user.step.manager/index.js | 8 +++----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/workers/loc.api/sync/data.inserter/data.checker/index.js b/workers/loc.api/sync/data.inserter/data.checker/index.js index e6a90cb17..e12af4c60 100644 --- a/workers/loc.api/sync/data.inserter/data.checker/index.js +++ b/workers/loc.api/sync/data.inserter/data.checker/index.js @@ -1,9 +1,6 @@ 'use strict' -const { - min -} = require('lodash') -const { isEmpty } = require('lib-js-util-base') +const { isEmpty, min } = require('lib-js-util-base') const moment = require('moment') const SyncTempTablesManager = require('../sync.temp.tables.manager') diff --git a/workers/loc.api/sync/data.inserter/sync.user.step.manager/index.js b/workers/loc.api/sync/data.inserter/sync.user.step.manager/index.js index 3aaa7c812..91b42c015 100644 --- a/workers/loc.api/sync/data.inserter/sync.user.step.manager/index.js +++ b/workers/loc.api/sync/data.inserter/sync.user.step.manager/index.js @@ -1,13 +1,11 @@ 'use strict' -const { - min, - max -} = require('lodash') const { omit, isEmpty, - merge + merge, + min, + max } = require('lib-js-util-base') const { From 8f27a1dc130bf92f61e4dd8a915917106e709739 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Mon, 11 Dec 2023 17:32:39 +0200 Subject: [PATCH 09/13] Add exchange volume and trading fee values to summary by asset --- ...itional-api-sync-mode-sqlite-test-cases.js | 40 +-- .../loc.api/sync/summary.by.asset/index.js | 235 ++++++------------ workers/loc.api/sync/trades/index.js | 3 +- 3 files changed, 102 insertions(+), 176 deletions(-) diff --git a/test/test-cases/additional-api-sync-mode-sqlite-test-cases.js b/test/test-cases/additional-api-sync-mode-sqlite-test-cases.js index e541b76a6..4271fedb6 100644 --- a/test/test-cases/additional-api-sync-mode-sqlite-test-cases.js +++ b/test/test-cases/additional-api-sync-mode-sqlite-test-cases.js @@ -718,21 +718,21 @@ module.exports = ( 'currency', 'balance', 'balanceUsd', - 'valueChange30dUsd', - 'valueChange30dPerc', - 'result30dUsd', - 'result30dPerc', - 'volume30dUsd' + 'balanceChange', + 'balanceChangePerc', + 'volume', + 'volumeUsd', + 'tradingFees', + 'marginFundingPayment' ]) }) assert.containsAllKeys(res.body.result.total, [ 'balanceUsd', - 'valueChange30dUsd', - 'valueChange30dPerc', - 'result30dUsd', - 'result30dPerc', - 'volume30dUsd' + 'balanceChangeUsd', + 'balanceChangePerc', + 'volumeUsd', + 'tradingFeesUsd' ]) }) @@ -765,21 +765,21 @@ module.exports = ( 'currency', 'balance', 'balanceUsd', - 'valueChange30dUsd', - 'valueChange30dPerc', - 'result30dUsd', - 'result30dPerc', - 'volume30dUsd' + 'balanceChange', + 'balanceChangePerc', + 'volume', + 'volumeUsd', + 'tradingFees', + 'marginFundingPayment' ]) }) assert.containsAllKeys(res.body.result.total, [ 'balanceUsd', - 'valueChange30dUsd', - 'valueChange30dPerc', - 'result30dUsd', - 'result30dPerc', - 'volume30dUsd' + 'balanceChangeUsd', + 'balanceChangePerc', + 'volumeUsd', + 'tradingFeesUsd' ]) }) diff --git a/workers/loc.api/sync/summary.by.asset/index.js b/workers/loc.api/sync/summary.by.asset/index.js index 525c4f685..b17943a34 100644 --- a/workers/loc.api/sync/summary.by.asset/index.js +++ b/workers/loc.api/sync/summary.by.asset/index.js @@ -11,9 +11,8 @@ const depsTypes = (TYPES) => [ TYPES.Authenticator, TYPES.SYNC_API_METHODS, TYPES.ALLOWED_COLLS, - TYPES.Movements, TYPES.Wallets, - TYPES.CurrencyConverter + TYPES.Trades ] class SummaryByAsset { constructor ( @@ -22,26 +21,21 @@ class SummaryByAsset { authenticator, SYNC_API_METHODS, ALLOWED_COLLS, - movements, wallets, - currencyConverter + trades ) { this.dao = dao this.syncSchema = syncSchema this.authenticator = authenticator this.SYNC_API_METHODS = SYNC_API_METHODS this.ALLOWED_COLLS = ALLOWED_COLLS - this.movements = movements this.wallets = wallets - this.currencyConverter = currencyConverter + this.trades = trades - this.movementsMethodColl = this.syncSchema.getMethodCollMap() - .get(this.SYNC_API_METHODS.MOVEMENTS) this.ledgersMethodColl = this.syncSchema.getMethodCollMap() .get(this.SYNC_API_METHODS.LEDGERS) this.ledgersModel = this.syncSchema.getModelsMap() .get(this.ALLOWED_COLLS.LEDGERS) - this.movementsSymbolFieldName = this.movementsMethodColl.symbolFieldName this.ledgersSymbolFieldName = this.ledgersMethodColl.symbolFieldName } @@ -54,24 +48,15 @@ class SummaryByAsset { .valueOf() const start = args?.params?.start ?? mts30dUntilEnd - const ledgersPromise = this.#getLedgers({ + const tradesPromise = this.trades.getTrades({ auth, start, end }) - const withdrawalsPromise = this.movements.getMovements({ - auth, - start, - end, - sort: [['mtsStarted', -1]], - isWithdrawals: true - }) - const depositsPromise = this.movements.getMovements({ + const ledgersPromise = this.#getLedgers({ auth, start, - end, - sort: [['mtsUpdated', -1]], - isDeposits: true + end }) const startWalletsPromise = this.wallets.getWallets({ auth, @@ -83,30 +68,30 @@ class SummaryByAsset { }) const [ + trades, ledgers, - withdrawals, - deposits, startWallets, endWallets ] = await Promise.all([ + tradesPromise, ledgersPromise, - withdrawalsPromise, - depositsPromise, startWalletsPromise, endWalletsPromise ]) const _summaryByAsset = await this.#calcSummaryByAsset({ - start, + trades, ledgers, - withdrawals, - deposits, startWallets, endWallets }) const total = this.#calcTotal(_summaryByAsset) const summaryByAsset = _summaryByAsset.map((item) => ( - omit(item, ['calcedStartWalletBalanceUsd']) + omit(item, [ + 'balanceChangeUsd', + 'tradingFeesUsd', + 'calcedStartWalletBalanceUsd' + ]) )) return { @@ -116,21 +101,15 @@ class SummaryByAsset { } async #calcSummaryByAsset ({ - start, + trades, ledgers, - withdrawals, - deposits, startWallets, endWallets }) { const currencyRes = [] - const currencySet = new Set(endWallets.map((wallet) => ( - wallet.currency + const currencySet = new Set(ledgers.map((ledger) => ( + ledger?.currency ))) - const startRateMap = await this.#getStartRateMapByCandles( - start, - currencySet - ) for (const currency of currencySet) { const startWalletsForCurrency = startWallets.filter((wallet) => ( @@ -152,7 +131,6 @@ class SummaryByAsset { endWalletsForCurrency, 'balance' ) - const calcedEndWalletBalanceUsd = this.#calcFieldByName( endWalletsForCurrency, 'balanceUsd' @@ -162,68 +140,75 @@ class SummaryByAsset { !Number.isFinite(calcedStartWalletBalance) || !Number.isFinite(calcedStartWalletBalanceUsd) || !Number.isFinite(calcedEndWalletBalance) || - !Number.isFinite(calcedEndWalletBalanceUsd) || - calcedEndWalletBalance === 0 || - calcedEndWalletBalanceUsd === 0 + !Number.isFinite(calcedEndWalletBalanceUsd) ) { continue } - // Start rate can't be calced by start wallets - // due to possibility of non-existent ones - const startRate = startRateMap.get(currency) + const calcedActualRate = calcedEndWalletBalance === 0 + ? 0 + : calcedEndWalletBalanceUsd / calcedEndWalletBalance const actualRate = currency === 'USD' ? 1 - : calcedEndWalletBalanceUsd / calcedEndWalletBalance + : calcedActualRate const ledgersForCurrency = ledgers.filter((ledger) => ( ledger[this.ledgersSymbolFieldName] === currency )) - const exchangeLedgers = ledgersForCurrency.filter((ledger) => ( - ledger._category === 5 + const tradesForCurrency = trades.filter((trade) => ( + trade?.baseCurrency === currency )) - const calcedExchangeLedgers = this.#calcFieldByName( - exchangeLedgers, - 'amount' + const marginFundingPaymentLedgers = ledgersForCurrency.filter((ledger) => ( + ledger._category === 28 + )) + const tradingFeeLedgers = ledgersForCurrency.filter((ledger) => ( + ledger._category === 201 + )) + + const volume = this.#calcFieldByName( + tradesForCurrency, + 'execAmount', + { isAbs: true } ) - const calcedExchangeProfitUsd = this.#calcExchangeProfitUsd( - exchangeLedgers, - startRate + const volumeUsd = this.#calcFieldByName( + tradesForCurrency, + 'amountUsd' ) - const calcedVolume30d = this.#calcVolume30d( - ledgersForCurrency + const marginFundingPayment = this.#calcFieldByName( + marginFundingPaymentLedgers, + 'amount' ) - - const valueChange30d = calcedEndWalletBalance - calcedStartWalletBalance - const valueChange30dUsd = valueChange30d * actualRate - const valueChange30dPerc = calcedStartWalletBalanceUsd === 0 - ? 0 - : (valueChange30dUsd / calcedStartWalletBalanceUsd) * 100 - const calcedMovementsByCurrency = this.#calcMovementsByCurrency( - { withdrawals, deposits }, - currency + const calcedTradingFeeLedgers = this.#calcFieldByName( + tradingFeeLedgers, + 'amount' ) - const result30d = ( - valueChange30d - - calcedMovementsByCurrency - - calcedExchangeLedgers + const calcedTradingFeeUsdLedgers = this.#calcFieldByName( + tradingFeeLedgers, + 'amountUsd' ) - const result30dUsd = (result30d * (actualRate - startRate)) + - calcedExchangeProfitUsd - const result30dPerc = calcedStartWalletBalanceUsd === 0 + + const balanceChange = calcedEndWalletBalance - calcedStartWalletBalance + const balanceChangePerc = calcedStartWalletBalance === 0 ? 0 - : (result30dUsd / calcedStartWalletBalanceUsd) * 100 - const volume30dUsd = calcedVolume30d * actualRate + : (balanceChange / calcedStartWalletBalance) * 100 + const balanceChangeUsd = balanceChange * actualRate + + // In the Ledgers amount of fee is negative value, skip sign for UI + const tradingFees = Math.abs(calcedTradingFeeLedgers) + const tradingFeesUsd = Math.abs(calcedTradingFeeUsdLedgers) const res = { currency, balance: calcedEndWalletBalance, balanceUsd: calcedEndWalletBalanceUsd, - valueChange30dUsd, - valueChange30dPerc, - result30dUsd, - result30dPerc, - volume30dUsd, + balanceChange, + balanceChangePerc, + balanceChangeUsd, + volume, + volumeUsd, + tradingFees, + tradingFeesUsd, + marginFundingPayment, // It's used to total perc calc calcedStartWalletBalanceUsd @@ -235,67 +220,22 @@ class SummaryByAsset { return currencyRes } - #calcFieldByName (wallets, fieldName) { - return wallets.reduce((accum, curr) => ( - Number.isFinite(curr?.[fieldName]) - ? accum + curr[fieldName] - : accum - ), 0) - } - - #calcVolume30d (ledgers) { - return ledgers.reduce((accum, curr) => { - const amount = curr?.amount + #calcFieldByName (wallets, fieldName, opts) { + const { isAbs } = opts ?? {} - if (!Number.isFinite(amount)) { + return wallets.reduce((accum, curr) => { + if (!Number.isFinite(curr?.[fieldName])) { return accum } - return accum + Math.abs(amount) - }, 0) - } - - #calcExchangeProfitUsd (ledgers, startRate) { - return ledgers.reduce((accum, curr) => { - const amount = curr?.amount - const amountUsd = curr?.amountUsd - - if ( - !Number.isFinite(amount) || - !Number.isFinite(amountUsd) || - amount > 0 // Take into account the sale - ) { - return accum - } - - const profit = amountUsd - (amount * startRate) + const val = isAbs + ? Math.abs(curr[fieldName]) + : curr[fieldName] - return accum + profit + return accum + val }, 0) } - #calcMovementsByCurrency (movements, currency) { - const { withdrawals, deposits } = movements ?? {} - - const withdrawalsForCurrency = withdrawals.filter((item) => ( - item?.[this.movementsSymbolFieldName] === currency - )) - const depositsForCurrency = deposits.filter((item) => ( - item?.[this.movementsSymbolFieldName] === currency - )) - - const calcedWithdrawals = this.#calcFieldByName( - withdrawalsForCurrency, - 'amount' - ) - const calcedDeposits = this.#calcFieldByName( - depositsForCurrency, - 'amount' - ) - - return calcedWithdrawals + calcedDeposits - } - #getLedgers (args) { const { auth, @@ -320,11 +260,10 @@ class SummaryByAsset { #calcTotal (summaryByAsset) { const initTotal = { balanceUsd: 0, - valueChange30dUsd: 0, - valueChange30dPerc: 0, - result30dUsd: 0, - result30dPerc: 0, - volume30dUsd: 0, + balanceChangeUsd: 0, + balanceChangePerc: 0, + volumeUsd: 0, + tradingFeesUsd: 0, calcedStartWalletBalanceUsd: 0 } @@ -335,17 +274,16 @@ class SummaryByAsset { curr, [ 'balanceUsd', - 'valueChange30dUsd', - 'result30dUsd', - 'volume30dUsd', + 'balanceChangeUsd', + 'volumeUsd', + 'tradingFeesUsd', 'calcedStartWalletBalanceUsd' ] ) if (accum.calcedStartWalletBalanceUsd !== 0) { - accum.valueChange30dPerc = (accum.valueChange30dUsd / accum.calcedStartWalletBalanceUsd) * 100 - accum.result30dPerc = (accum.result30dUsd / accum.calcedStartWalletBalanceUsd) * 100 + accum.balanceChangePerc = (accum.balanceChangeUsd / accum.calcedStartWalletBalanceUsd) * 100 } return accum @@ -361,19 +299,6 @@ class SummaryByAsset { : accum[propName] } } - - async #getStartRateMapByCandles (start, currencySet) { - const startRates = await this.currencyConverter.convertByCandles( - [...currencySet].map((ccy) => ({ ccy, multip: 1, rate: 0 })), - { - symbolFieldName: 'ccy', - mts: start, - convFields: [{ inputField: 'multip', outputField: 'rate' }] - } - ) - - return new Map(startRates.map(({ ccy, rate }) => [ccy, rate])) - } } decorateInjectable(SummaryByAsset, depsTypes) diff --git a/workers/loc.api/sync/trades/index.js b/workers/loc.api/sync/trades/index.js index f718fd07e..fc5bdac03 100644 --- a/workers/loc.api/sync/trades/index.js +++ b/workers/loc.api/sync/trades/index.js @@ -88,7 +88,7 @@ class Trades { feeCurrency, symbol } = _trade - const symb = splitSymbolPairs(symbol)[1] + const [baseCurrency, symb] = splitSymbolPairs(symbol) const isFeeInUsd = feeCurrency === 'USD' const isPriceInUsd = symb === 'USD' @@ -131,6 +131,7 @@ class Trades { _trade.calcAmount = calcAmount _trade.feeUsd = feeUsd _trade.feeForCurrConv = feeForCurrConv + _trade.baseCurrency = baseCurrency return _trade }) From 793f8383b44075b694c0838b984fb8ed7f2b79cc Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Wed, 13 Dec 2023 07:55:54 +0200 Subject: [PATCH 10/13] Fix passing params to trades for summary by asset --- workers/loc.api/sync/summary.by.asset/index.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/workers/loc.api/sync/summary.by.asset/index.js b/workers/loc.api/sync/summary.by.asset/index.js index b17943a34..b1447346d 100644 --- a/workers/loc.api/sync/summary.by.asset/index.js +++ b/workers/loc.api/sync/summary.by.asset/index.js @@ -50,8 +50,10 @@ class SummaryByAsset { const tradesPromise = this.trades.getTrades({ auth, - start, - end + params: { + start, + end + } }) const ledgersPromise = this.#getLedgers({ auth, From c226e930c6febf0deb5d34cc84a717d2d4bd506b Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Wed, 13 Dec 2023 08:32:57 +0200 Subject: [PATCH 11/13] Include all currencies where balance >= 0.01 usd --- .../loc.api/sync/summary.by.asset/index.js | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/workers/loc.api/sync/summary.by.asset/index.js b/workers/loc.api/sync/summary.by.asset/index.js index b1447346d..283fdb493 100644 --- a/workers/loc.api/sync/summary.by.asset/index.js +++ b/workers/loc.api/sync/summary.by.asset/index.js @@ -109,9 +109,14 @@ class SummaryByAsset { endWallets }) { const currencyRes = [] - const currencySet = new Set(ledgers.map((ledger) => ( - ledger?.currency - ))) + const currencySet = new Set([ + ...ledgers.map((ledger) => ( + ledger?.currency + )), + ...endWallets.map((wallet) => ( + wallet?.currency + )) + ]) for (const currency of currencySet) { const startWalletsForCurrency = startWallets.filter((wallet) => ( @@ -199,6 +204,16 @@ class SummaryByAsset { const tradingFees = Math.abs(calcedTradingFeeLedgers) const tradingFeesUsd = Math.abs(calcedTradingFeeUsdLedgers) + if ( + calcedEndWalletBalanceUsd < 0.01 && + volume <= 0 && + balanceChange <= 0 && + tradingFees <= 0 && + marginFundingPayment <= 0 + ) { + continue + } + const res = { currency, balance: calcedEndWalletBalance, From 7369fd9052548d55559077f608015c7450b13cf7 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Wed, 13 Dec 2023 11:50:48 +0200 Subject: [PATCH 12/13] Bump version up to 4.13.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8b7ff1c72..6a0f20956 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bfx-reports-framework", - "version": "4.12.0", + "version": "4.13.0", "description": "Bitfinex reports framework", "main": "worker.js", "license": "Apache-2.0", From ae98304dd37880e38b3aa04ac26738cc0a253be8 Mon Sep 17 00:00:00 2001 From: Vladimir Voronkov Date: Wed, 13 Dec 2023 15:32:16 +0200 Subject: [PATCH 13/13] Update bfx-report-ui sub-module --- bfx-report-ui | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bfx-report-ui b/bfx-report-ui index c707a10f3..ad73b589b 160000 --- a/bfx-report-ui +++ b/bfx-report-ui @@ -1 +1 @@ -Subproject commit c707a10f3b064fb1ecff263ea7e7a2efc3167fad +Subproject commit ad73b589b065caba5c352c0da6fdeae37e7a038e