Created
January 31, 2021 09:59
-
-
Save jdc-cunningham/05b227cde9f12683da6661156b6bab77 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const processBuySells = (activePortfolio, fills) => { | |
const btcBuys = []; | |
const btcSells = []; | |
// transfers, this is a special case | |
if (parseInt(activePortfolio) === 1) { | |
const transferredArr = JSON.parse(process.env.TRANSFERRED_BTC_ARR); | |
transferredArr.forEach(transfer => { | |
btcBuys.push({ | |
size: parseFloat(transfer.size), | |
price: parseFloat(transfer.price)}); | |
}); | |
} | |
// sort values by ascending date | |
// https://stackoverflow.com/questions/8837454/sort-array-of-objects-by-single-key-with-date-value | |
fills.sort(function(a, b) { | |
var x = a['created_at']; var y = b['created_at']; | |
return ((x < y) ? -1 : ((x > y) ? 1 : 0)); | |
}); | |
// first loop to get data sorted | |
for (let i = 0; i < fills.length; i++) { | |
const fill = fills[i]; | |
if (fill.side === 'buy') { | |
btcBuys.push({ | |
size: parseFloat(fill.size), | |
price: parseFloat(fill.price) | |
}); | |
} else if (fill.side === 'sell') { | |
btcSells.push({ | |
size: parseFloat(fill.size), | |
price: parseFloat(fill.price), | |
dateTime: fill.created_at | |
}); | |
} else { | |
miscBtc += parseFloat(fill.size); | |
} | |
}; | |
let usdGains = 0; | |
const sellGainLoss = []; | |
const processSell = (sellSize, sellPrice, sellDateTime) => { | |
const prevUsdGains = usdGains; | |
if (sellSize <= btcBuys[0].size) { | |
const firstBtcBuy = btcBuys[0]; | |
const buyPrice = firstBtcBuy.price; | |
const sellCost = sellPrice * sellSize; | |
usdGains += (sellCost - (sellSize * buyPrice)); | |
if (firstBtcBuy.size <= sellSize) { | |
btcBuys.shift(); | |
} else { | |
firstBtcBuy.size = firstBtcBuy.size - sellSize; | |
} | |
} else { // selling 5 from 3, 4 | |
let filledSize = 0; | |
/** | |
* the sellSize is larger than several buy rows | |
* so we have to iterate over multiple rows while keeping track | |
* of how much of the row is used, until the sellSize is filled | |
* if the entire row is used, you drop it eg. shift | |
* if the row is partially used, update the size | |
*/ | |
while (filledSize < sellSize) { | |
const curFillSize = sellSize - filledSize; | |
const curBuyRow = btcBuys[0]; // 3, +3 to soldAmnt | |
const buyPrice = curBuyRow.price; | |
let sellCost = 0; | |
if (curBuyRow.size <= curFillSize) { | |
sellCost = sellPrice * curBuyRow.size; | |
usdGains += (sellCost - (curBuyRow.size * buyPrice)); | |
filledSize += curBuyRow.size; | |
btcBuys.shift(); | |
} else { | |
sellCost = sellPrice * curFillSize; | |
usdGains += (sellCost - (curFillSize * buyPrice)); | |
filledSize += curFillSize; | |
curBuyRow.size = curBuyRow.size - curFillSize; | |
} | |
} | |
} | |
sellGainLoss.push({ | |
size: sellSize, | |
price: sellPrice, | |
usdGain: (usdGains - prevUsdGains), | |
sellDateTime | |
}); | |
}; | |
for (let i = 0; i < btcSells.length; i++) { | |
const btcSell = btcSells[i]; | |
processSell(btcSell.size, btcSell.price, btcSell.dateTime); | |
} | |
// this is an excerpt from here: https://github.com/jdc-cunningham/cbp-cost-basis-fifo/blob/master/methods/process.js |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment