/* 2020-01-09 - get the gains generated by my automated ETC trading. 2020-10-23 - fix problem because API requires windowing to handle more than 50 rows, implemented windowing. 2020-12-02 - change to persist transactions and handle pairs as provided by commandline parameter. 2020-12-04 - handle commandline inlcuding verbosity of output. */ const yargs = require('yargs/yargs') const { hideBin } = require('yargs/helpers') const argv = yargs(hideBin(process.argv)).argv const key = 'SOOOJ7OhVCOpJE4DAWz8v5B25UpdYya9buF8DFAkHzmUab5E9i0PlEPh'; // API Key const secret = 'UytAbgU8ty3n5a+JhaoIlcfh8zM4OBGY6PCC+Cfg2NI4waVzM52BBp9qmmyczrTDQpeha8q3nHeE/p7wNWKiVA=='; // API Private Key const KrakenClient = require('kraken-api'); const kraken = new KrakenClient(key, secret); const fs = require('fs') const storeData = (data, path) => { try { fs.writeFileSync(path, JSON.stringify(data)); } catch (err) { console.error("error in storeData ",err); } } const loadData = (path) => { try { return JSON.parse(fs.readFileSync(path, 'utf8')); } catch (err) { console.error("error in loadData ",err); return false; } } const utcToLocal = (utc) => { return new Date(utc.getTime() - (utc.getTimezoneOffset() * 60000)); } (async () => { try { // get the pair to process from the first parameter and fall back if not provided. let thePair=argv.pair; if (thePair===undefined) { thePair="XXMRZUSD"; } thePair=thePair.toUpperCase(); // the pairs are always upper case. console.log("Processing pair : ", thePair); let dataFile = argv.dataFile; if (dataFile===undefined) { dataFile = "allTrades.json"; } let allTrades=loadData(dataFile); let params={ ofs : 0 }; let maxTimestamp=0; allTrades.forEach(dta=>{if (dta.time>maxTimestamp) {maxTimestamp=dta.time;} }); params.start=maxTimestamp; console.log("Max-Timestamp : ",maxTimestamp); if (!argv.skipRequestTrades) { let allTransactions = await kraken.api('TradesHistory', params); let allTradeIDs=Object.keys(allTransactions.result.trades); let numTrans=allTradeIDs.length; console.log("Number of new Transactions : ",numTrans); for (let i=0;i ${Number(theTrade.cost).toFixed(2).padStart(9," ")}(-${Number(theTrade.fee).toFixed(3).padStart(5," ")})`);} // selling adds $$$ to our Account, buying takes money out of the account let multiplier=theTrade.type==="buy"?-1:1; sumUSD += Number(theTrade.cost) * multiplier; sumCommission += Number(theTrade.fee); } } let allBalances=await kraken.api('Balance'); let pairQuote = await kraken.api('Ticker', { pair : thePair }); // find the currency by looking for "startsWith" type match in the symbol in the pair. // (not sure if that always works, but it works for all cases I checked it so far). let theCurrency=undefined; Object.keys(allBalances.result).forEach((currency)=>{ if (thePair.indexOf(currency)===0) { theCurrency=currency; } }); console.log("# trades : ", numTrades); console.log("SUM USD : ", sumUSD); console.log("SUM fees : ", sumCommission); let netGain = sumUSD - sumCommission; console.log("Net Gain : ", netGain); let numCoinsHeld = Number(allBalances.result[theCurrency]); console.log("# coins Held : ", numCoinsHeld, " [", theCurrency,"]"); let sellPrice = Number(pairQuote.result[thePair].b[0]); console.log("Current Price : ", sellPrice); let worthHeldCoins = numCoinsHeld * sellPrice; console.log("Worth held coins : ", worthHeldCoins); let netLiq = netGain + worthHeldCoins; console.log("Net Liquidation Gain : " , netLiq); } catch (ex) { console.error("General Error: ", ex.message, "\n", ex.stack); } })();