Completed the assignment
This commit is contained in:
parent
2e7953c4d1
commit
79e11d88ad
19
package.json
19
package.json
|
@ -4,9 +4,22 @@
|
||||||
"description": "_We're looking at your programming ability. It must not only work, it should be maintainable._",
|
"description": "_We're looking at your programming ability. It must not only work, it should be maintainable._",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node index.js",
|
"start": "node src/index.js",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"test": "jest --coverage --verbose"
|
||||||
},
|
},
|
||||||
|
"bin": "src/index.js",
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC"
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"any-date-parser": "^1.5.3",
|
||||||
|
"axios": "^1.2.0",
|
||||||
|
"commander": "^9.4.1",
|
||||||
|
"cryptocompare": "^1.0.0",
|
||||||
|
"csv-parser": "^3.0.0",
|
||||||
|
"dotenv": "^16.0.3",
|
||||||
|
"node-fetch": "2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"jest": "^29.3.1"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
const csv = require('csv-parser');
|
||||||
|
const {
|
||||||
|
convertEpochToDate
|
||||||
|
} = require('../helpers/epoch');
|
||||||
|
|
||||||
|
const results = []
|
||||||
|
|
||||||
|
async function analyse(file, flag) {
|
||||||
|
fs.createReadStream(file)
|
||||||
|
.pipe(csv())
|
||||||
|
.on('data', (data) => results.push(data))
|
||||||
|
.on('end', () => {
|
||||||
|
if(flag == 'coin'){
|
||||||
|
const uniqueCoins = [...new Set(results.map(item => item.token))];
|
||||||
|
return uniqueCoins
|
||||||
|
}
|
||||||
|
else if(flag == 'date'){
|
||||||
|
const lastDate = results[results.length - 1].date
|
||||||
|
const date = convertEpochToDate(lastDate)
|
||||||
|
return date
|
||||||
|
}
|
||||||
|
process.exit(1)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = analyse
|
|
@ -0,0 +1,62 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
const csv = require('csv-parser');
|
||||||
|
const { getRates } = require('../helpers/rates');
|
||||||
|
const {
|
||||||
|
convertDateToEpoch,
|
||||||
|
convertEpochToDate
|
||||||
|
} = require('../helpers/epoch');
|
||||||
|
|
||||||
|
const results = [], amountStore = {};
|
||||||
|
|
||||||
|
async function calculate(file, tokens, date) {
|
||||||
|
let tokenArr = tokens.split(',')
|
||||||
|
const USDConvStore = await getRates(tokenArr);
|
||||||
|
|
||||||
|
function USDConvStoreFn(parentCurreny, value){
|
||||||
|
const ans = value / USDConvStore[parentCurreny]
|
||||||
|
return ans.toFixed(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
let dateToEpoch
|
||||||
|
if(date){
|
||||||
|
dateToEpoch = convertDateToEpoch(date);
|
||||||
|
}
|
||||||
|
let pick = 0
|
||||||
|
fs.createReadStream(file)
|
||||||
|
.pipe(csv())
|
||||||
|
.on('data', (data) => {
|
||||||
|
if(dateToEpoch){
|
||||||
|
if(data.timestamp > dateToEpoch){
|
||||||
|
results.push(data);
|
||||||
|
pick++
|
||||||
|
console.log(pick)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
results.push(data);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on('end', () => {
|
||||||
|
const uniqueCoins = [...new Set(results.map(item => item.token))];
|
||||||
|
|
||||||
|
uniqueCoins.forEach(coin => {
|
||||||
|
amountStore[coin] = 0
|
||||||
|
})
|
||||||
|
|
||||||
|
results.map(result => {
|
||||||
|
if (result.transaction_type == "DEPOSIT" && result.token in USDConvStore) {
|
||||||
|
result.amount = USDConvStoreFn(result.token, result.amount)
|
||||||
|
amountStore[result.token] += +result.amount
|
||||||
|
}
|
||||||
|
else if(result.transaction_type == "WITHDRAWAL" && result.token in USDConvStore) {
|
||||||
|
result.amount = USDConvStoreFn(result.token, result.amount)
|
||||||
|
amountStore[result.token] -= +result.amount
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
Object.keys(amountStore).forEach(key => amountStore[key] === 0 && delete amountStore[key]);
|
||||||
|
console.table(amountStore)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = calculate
|
|
@ -0,0 +1,17 @@
|
||||||
|
require('any-date-parser');
|
||||||
|
|
||||||
|
function convertDateToEpoch(date) {
|
||||||
|
const ndate = new Date.fromAny(date);
|
||||||
|
const epoch = ndate.getTime();
|
||||||
|
return epoch/1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertEpochToDate(date) {
|
||||||
|
const ndate = new Date(date*1000);
|
||||||
|
return ndate;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
convertDateToEpoch,
|
||||||
|
convertEpochToDate
|
||||||
|
};
|
|
@ -0,0 +1,15 @@
|
||||||
|
const cc = require('cryptocompare')
|
||||||
|
cc.setApiKey(process.env.CRYPTO_COMPARE_API_KEY);
|
||||||
|
|
||||||
|
const getRates = async (rateList) => {
|
||||||
|
try {
|
||||||
|
return cc.price('USD', rateList)
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getRates
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#!/bin/sh
|
||||||
|
require('dotenv').config();
|
||||||
|
global.fetch = require('node-fetch')
|
||||||
|
|
||||||
|
const {program} = require('commander');
|
||||||
|
const calculate = require('./functions/calculate');
|
||||||
|
|
||||||
|
program
|
||||||
|
.version('0.0.1')
|
||||||
|
.argument('<file>', 'transactions to analyse')
|
||||||
|
.option('-t, --tokens <tokens>', 'token/s to evaluate')
|
||||||
|
.option('-d, --date <date>', 'date to start from')
|
||||||
|
.parse();
|
||||||
|
|
||||||
|
const options = program.opts();
|
||||||
|
const [file] = program.args;
|
||||||
|
|
||||||
|
if (!file) {
|
||||||
|
console.log('No transactions file provided');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options.tokens) {
|
||||||
|
console.log('No token specified. So will analyse all tokens');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options.date) {
|
||||||
|
console.log('No date specified. So will analyse from the beginning');
|
||||||
|
}
|
||||||
|
|
||||||
|
calculate(file, options.tokens, options.date);
|
Loading…
Reference in New Issue