Skip to content

Commit

Permalink
Merge pull request #233 from ZIMkaRU/bugfix/fix-win-loss-vs-account-b…
Browse files Browse the repository at this point in the history
…alance-report

Fix win/loss vs account balance report
  • Loading branch information
prdn authored Aug 31, 2022
2 parents af3b3b6 + 1b94e19 commit c73823f
Show file tree
Hide file tree
Showing 6 changed files with 207 additions and 45 deletions.
5 changes: 4 additions & 1 deletion workers/loc.api/generate-csv/csv.job.data.js
Original file line number Diff line number Diff line change
Expand Up @@ -641,14 +641,17 @@ class CsvJobData extends BaseCsvJobData {
)

const csvArgs = getCsvArgs(args)
const suffix = args?.params?.isVSPrevDayBalance
? 'balance'
: 'deposits'

const jobData = {
userInfo,
userId,
name: 'getWinLossVSAccountBalance',
fileNamesMap: [[
'getWinLossVSAccountBalance',
'win-loss-vs-account-balance'
`win-loss-percentage-gains-vs-${suffix}`
]],
args: csvArgs,
propNameForPagination: null,
Expand Down
5 changes: 4 additions & 1 deletion workers/loc.api/sync/balance.history/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ class BalanceHistory {
auth: _auth = {},
params = {}
} = {},
isSubCalc = false
opts = {}
) {
const auth = await this.authenticator
.verifyRequestUser({ auth: _auth })
Expand All @@ -488,6 +488,9 @@ class BalanceHistory {
end = Date.now(),
isUnrealizedProfitExcluded
} = params ?? {}
const {
isSubCalc = false
} = opts ?? {}

if (Number.isInteger(timeframe)) {
return this._getWalletsGroupedByOneTimeframe(
Expand Down
7 changes: 1 addition & 6 deletions workers/loc.api/sync/helpers/group-by-timeframe.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,7 @@ module.exports = async (
const isLastIter = i === 0
const nextItem = data[i - 1]

if (
item &&
typeof item === 'object' &&
Number.isInteger(item[dateFieldName]) &&
typeof item[symbolFieldName] === 'string'
) {
if (Number.isInteger(item?.[dateFieldName])) {
subRes.unshift(item)
}

Expand Down
12 changes: 9 additions & 3 deletions workers/loc.api/sync/movements/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ class Movements {
exclude = ['user_id'],
isExcludePrivate = true,
isWithdrawals = false,
isDeposits = false
isDeposits = false,
isMovementsWithoutSATransferLedgers = false
} = params ?? {}

const user = await this.authenticator
Expand Down Expand Up @@ -83,8 +84,13 @@ class Movements {
isExcludePrivate
}
)

if (isMovementsWithoutSATransferLedgers) {
return movementsPromise
}

const ledgersOrder = this._getLedgersOrder(sort)
const ledgersPromise = this._getLedgers({
const ledgersPromise = this.getSubAccountsTransferLedgers({
auth: user,
start,
end,
Expand Down Expand Up @@ -123,7 +129,7 @@ class Movements {
* Consider the `SA(nameAccount1->nameAccount2)` transfers
* as internal movements for win/loss and tax calculations
*/
_getLedgers (params = {}) {
getSubAccountsTransferLedgers (params = {}) {
const {
auth = {},
start = 0,
Expand Down
172 changes: 147 additions & 25 deletions workers/loc.api/sync/win.loss.vs.account.balance/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use strict'

const {
calcGroupedData
calcGroupedData,
groupByTimeframe
} = require('../helpers')

const { decorateInjectable } = require('../../di/utils')
Expand Down Expand Up @@ -31,25 +32,45 @@ class WinLossVSAccountBalance {
timeframe = 'day',
start = 0,
end = Date.now(),
isUnrealizedProfitExcluded
isUnrealizedProfitExcluded,
isVSPrevDayBalance
} = params ?? {}
const args = {
auth: user,
params: {
timeframe,
/*
* We have to get day timeframe data for all timeframes
* and then pick data for non-day timeframes due to accuracy issue
*/
timeframe: 'day',
start,
end,
isUnrealizedProfitExcluded
}
}

const {
firstWalletsVals,
walletsGroupedByTimeframe,
withdrawalsGroupedByTimeframe,
depositsGroupedByTimeframe,
plGroupedByTimeframe
} = await this.winLoss.getDataToCalcWinLoss(args)

const getWinLossPercByTimeframe = isVSPrevDayBalance
? this._getWinLossPrevDayBalanceByTimeframe(
{
isUnrealizedProfitExcluded,
firstWalletsVals
}
)
: this._getWinLossVSAccountBalanceByTimeframe(
{
isUnrealizedProfitExcluded,
firstWalletsVals
}
)

const groupedData = await calcGroupedData(
{
walletsGroupedByTimeframe,
Expand All @@ -58,29 +79,46 @@ class WinLossVSAccountBalance {
plGroupedByTimeframe
},
false,
this._winLossVSAccountBalanceByTimeframe(
{ isUnrealizedProfitExcluded }
),
getWinLossPercByTimeframe,
true
)
groupedData.push({
const pickedRes = timeframe === 'day'
? groupedData
: (await groupByTimeframe(
groupedData,
{ timeframe, start, end },
null,
'mts',
null,
(data = []) => data[0]
)).map((obj) => {
const res = obj?.vals ?? {}
res.mts = obj.mts

return res
})
pickedRes.push({
mts: start,
perc: 0
})
const res = this.winLoss.shiftMtsToNextTimeframe(
groupedData,
pickedRes,
{ timeframe, end }
)

return res
}

_winLossVSAccountBalanceByTimeframe ({
isUnrealizedProfitExcluded
_getWinLossVSAccountBalanceByTimeframe ({
isUnrealizedProfitExcluded,
firstWalletsVals
}) {
let firstWalletsVals = {}
let firstPLVals = 0
let prevMovementsRes = 0
let firstPLVals = {}
let prevMovementsRes = {}
let percCorrection = 0
let prevPerc = 0
let firstWallets = 0
let prevWallets = 0

return ({
walletsGroupedByTimeframe = {},
Expand All @@ -92,22 +130,27 @@ class WinLossVSAccountBalance {
const isFirst = (i + 1) === arr.length

if (isFirst) {
firstWalletsVals = walletsGroupedByTimeframe
firstPLVals = plGroupedByTimeframe
firstWallets = Number.isFinite(firstWalletsVals[symb])
? firstWalletsVals[symb]
: 0
prevWallets = firstWallets
}

prevMovementsRes = this.winLoss.sumMovementsWithPrevRes(
prevMovementsRes,
const newMovementsRes = this.winLoss.sumMovementsWithPrevRes(
{},
withdrawalsGroupedByTimeframe,
depositsGroupedByTimeframe
)

const movements = Number.isFinite(prevMovementsRes[symb])
? prevMovementsRes[symb]
: 0
const firstWallets = Number.isFinite(firstWalletsVals[symb])
? firstWalletsVals[symb]
const newMovements = Number.isFinite(newMovementsRes[symb])
? newMovementsRes[symb]
: 0
const hasNewMovements = !!newMovements
prevMovementsRes = this.winLoss.sumMovementsWithPrevRes(
hasNewMovements ? {} : prevMovementsRes,
newMovementsRes
)

const wallets = Number.isFinite(walletsGroupedByTimeframe[symb])
? walletsGroupedByTimeframe[symb]
: 0
Expand All @@ -118,7 +161,13 @@ class WinLossVSAccountBalance {
? plGroupedByTimeframe[symb]
: 0

const realized = (wallets - movements) - firstWallets
if (hasNewMovements) {
firstWallets = prevWallets + newMovements
}

prevWallets = wallets

const realized = wallets - firstWallets
const unrealized = isUnrealizedProfitExcluded
? 0
: pl - firstPL
Expand All @@ -129,10 +178,83 @@ class WinLossVSAccountBalance {
!Number.isFinite(winLoss) ||
firstWallets === 0
) {
return { perc: 0 }
return { perc: percCorrection }
}

if (newMovements) {
percCorrection = prevPerc
}

const perc = ((winLoss / firstWallets) * 100) + percCorrection
prevPerc = perc

return { perc }
}
}

_getWinLossPrevDayBalanceByTimeframe ({
isUnrealizedProfitExcluded,
firstWalletsVals
}) {
let prevPerc = 0
let prevWallets = 0
let prevPL = 0
let prevMultiplying = 1

return ({
walletsGroupedByTimeframe = {},
withdrawalsGroupedByTimeframe = {},
depositsGroupedByTimeframe = {},
plGroupedByTimeframe = {}
} = {}, i, arr) => {
const symb = 'USD'
const isFirst = (i + 1) === arr.length

if (isFirst) {
prevWallets = Number.isFinite(firstWalletsVals[symb])
? firstWalletsVals[symb]
: 0
prevPL = Number.isFinite(plGroupedByTimeframe[symb])
? plGroupedByTimeframe[symb]
: 0
}

const movementsRes = this.winLoss.sumMovementsWithPrevRes(
{},
withdrawalsGroupedByTimeframe,
depositsGroupedByTimeframe
)

const movements = Number.isFinite(movementsRes[symb])
? movementsRes[symb]
: 0
const wallets = Number.isFinite(walletsGroupedByTimeframe[symb])
? walletsGroupedByTimeframe[symb]
: 0
const pl = Number.isFinite(plGroupedByTimeframe[symb])
? plGroupedByTimeframe[symb]
: 0

const realized = (wallets - movements) - prevWallets
const unrealized = isUnrealizedProfitExcluded
? 0
: pl - prevPL

const winLoss = realized + unrealized

prevWallets = wallets
prevPL = pl

if (
!Number.isFinite(winLoss) ||
prevWallets === 0
) {
return { perc: prevPerc }
}

const perc = (winLoss / firstWallets) * 100
prevMultiplying = ((prevWallets + winLoss) / prevWallets) * prevMultiplying
const perc = (prevMultiplying - 1) * 100
prevPerc = perc

return { perc }
}
Expand Down
Loading

0 comments on commit c73823f

Please sign in to comment.