Skip to content

Commit

Permalink
2.5 - Added Sparkline
Browse files Browse the repository at this point in the history
  • Loading branch information
transilvlad committed Sep 1, 2021
1 parent 22f5fb3 commit e05c63b
Show file tree
Hide file tree
Showing 14 changed files with 618 additions and 437 deletions.
41 changes: 20 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,18 @@ _Please do keep in mind at this point there are a lot of differences between thi


## Change list
- Version 1.1.0
- Version 1.1
- Refactored the code a bit.
- Added more logging (some disabled).
- Fixed buggy calculations.
- Added additional data type validations.
- Anything else I forgot.

- Version 1.1.1
- Fixed float leftovers for liquidated coins.

- Version 1.2.0
- Version 1.2
- Removed Profit sheet and loops.
- Added profit details to Dashboard.
- Added new graphs to Dashboard sheet.

- Version 1.2.1
- Disabled API calls without a key.
- Changed the recommended ordering A-Z for mathematical sense
- Improved defaults.
Expand All @@ -56,8 +52,6 @@ _Please do keep in mind at this point there are a lot of differences between thi
- 98% complete rewrite.
- Dynamic sheets formula used for all stats.
- Corrected all calculations _(I hope)_.

- Version 2.0.1-5
- Added formula for FIAT exchange rates.
- Added daily flux for given asset.
- Made trades have equality between buy adn sell fiat value.
Expand All @@ -66,36 +60,41 @@ _Please do keep in mind at this point there are a lot of differences between thi

- Version 2.1
- Added CryptoCompare API for FIAT rates.

- Version 2.1.1-5
- Fixed flux and stable coins fiat values.
- Added flux interval choice between daily and hourly.
- Added flux volume.

- Version 2.1.6-7
- Made Flux multi-sheet by using active sheet.
- Improved Flux update error messages.

- Version 2.1.8-9
- Use secondary API (key contingent) if first fails for Coins update.
- Made room for new ATH percentage bar indicator in Coins column L.

- Version 2.2
- Fixed ATH not updating when using CryptoCompare API.
- Made flux fall-back to CryptoCompare API if CoinGecko API request failed.

- Version 2.2.1
- Update ATH every time it's lower than 24h high.

- Version 2.2.1
- Update ATH every time it's lower than 24h high.

- Version 2.2.2-6
- Updated sheet formulas.
- Added error returning to UI.
- Limit error return to a single API.
- Fixed CryptoCompare add fiat values
- Removed successful update dialog.
- Added free money columns for Interest, Referrals and Airdrops in Coins.

- Version 2.3
- Added Wallet tracking for staking wallets.
- Added Wallet tracking for staked and unstaked amounts.
- Upgraded wallet to be multi currency.
- Upgraded wallet with FIAT values and added tracking of Wallet coins into Coins workbook.
- Added Profit/Loss column to wallet workbooks.
- Fixed Airdrop and Interest for wallets display in Coins.
- Made Dashboard Fees graph show wallet fees as well.
- Minor content updates.

- Version 2.4
- Updated Flux to display both Overall (Invested, Average & Profit/Loss) and just from Last liquidation. This should aid you in retaining past profits by keeping track of your current investment run.
- Updated Flux graphs.

- Version 2.5
- Added Sparkline to Coins workbook with separate update menu option.


## Planned updates
Expand Down
20 changes: 20 additions & 0 deletions source/API.gs → source/API.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,26 @@ function apiCoins(ui, fiat, ids, tickers) {
return market;
}

/**
* Gets coins historical date for Coins workbook Sparkline.
* <p>This requires a CryptoCompare API key to be configured.
*/
function apiSparkline(ui, coin) {
var sparkline = [];

var key = getCryptoCompareKey();
if(key == "") {
ui.alert('This operation requires a CryptoCompare API key in Settings workbook.');
} else {
sparkline = cryptoSparkline(ui, key, coin);
if (sparkline.length == 0) {
sparkline = geckoSparkline(ui, coin);
}
}

return sparkline;
}

/**
* Gets coin vs fiat exchnage rate.
* <p>This is an implementation wrapper for API change capability.
Expand Down
27 changes: 27 additions & 0 deletions source/APICoinGecko.gs → source/APICoinGecko.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,30 @@ function geckoCoins(ui, fiat, ids) {
return market;
}

/*
* Gets coin historical data for Sparkline.
*/
function geckoSparkline(ui, coin) {
var fiat = getFiat();
var coins = getCoins();

enableCache();
var json = importJson("https://api.coingecko.com/api/v3/coins/" + coins[coin] + "/market_chart?vs_currency=" + fiat + "&days=7&interval=hourly");

var sparkline = [];
if(typeof(json) === "string") {
// It be annoying to alert so much here for not much benefit.
//ui.alert('CoinGecko API error: ' + json);

} else {
for(var i in json[0][1]) {
sparkline.push(json[0][1][i][1]);
}
}

return sparkline;
}

/**
* Gets coin vs fiat exchnage rate from CoinGecko API for given date.
*/
Expand Down Expand Up @@ -67,6 +91,9 @@ function geckoFlux(ui, fiat, coin, limit, interval) {
/**
* Debug.
*/
function geckoSparklineDebug() {
Logger.log(geckoSparkline(SpreadsheetApp.getUi(), "ata"));
}
function geckoFluxDebug() {
Logger.log(geckoFlux("usd", "btc", 48, "daily"));
}
36 changes: 30 additions & 6 deletions source/APICryptoCompare.gs → source/APICryptoCompare.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,29 @@ function cryptoCoins(ui, key, fiat, tickers) {
return market;
}

/*
* Gets coin historical data for Sparkline.
*/
function cryptoSparkline(ui, key, coin) {
var fiat = getFiat();

enableCache();
var json = importJson("https://min-api.cryptocompare.com/data/v2/histohour?api_key=" + key + "&fsym=" + coin + "&tsym=" + fiat + "&limit=168&extraParams=cryptoBooks2");

var sparkline = [];
if(typeof(json) === "string") {
ui.alert('CryptoCompare API error: ' + json);

} else if(typeof(json) === "object" && json.length > 5 && json[5].length > 1 && json[5][1].hasOwnProperty("Data")) {
for (j = 0; j < json[5][1]["Data"].length; j++) {
sparkline.push(json[5][1]["Data"][j]["close"]);
}

}

return sparkline;
}

/**
* Gets coin vs fiat exchnage rate from CryptoCompare API for given date.
*/
Expand Down Expand Up @@ -85,16 +108,17 @@ function cryptoFlux(ui, key, fiat, coin, limit, interval) {
* Debug.
*/
function cryptoCoinsDebug() {
var key = getCryptoCompareKey();
Logger.log(cryptoCoins(key, "usd", "btc,eth,ltc"));
Logger.log(cryptoCoins(SpreadsheetApp.getUi(), getCryptoCompareKey(), "usd", "btc,eth,ltc"));
}

function cryptoSparklineDebug() {
Logger.log(cryptoSparkline(SpreadsheetApp.getUi(), getCryptoCompareKey(), "ada"));
}

function cryptoRateDebug() {
var key = getCryptoCompareKey();
Logger.log(cryptoRate(key, "usd", "btc", new Date("04/10/2021")));
Logger.log(cryptoRate(SpreadsheetApp.getUi(), getCryptoCompareKey(), "usd", "btc", new Date("04/10/2021")));
}

function cryptoFluxDebug() {
var key = getCryptoCompareKey();
Logger.log(cryptoFlux(key, "usd", "btc", 48, "daily"));
Logger.log(cryptoFlux(SpreadsheetApp.getUi(), getCryptoCompareKey(), "usd", "btc", 48, "daily"));
}
184 changes: 92 additions & 92 deletions source/Cache.gs → source/Cache.js
Original file line number Diff line number Diff line change
@@ -1,92 +1,92 @@
/**
* Cache handling.
* <p>Reference: https://developers.google.com/apps-script/reference/cache/cache
*/
var cacheDisabled;

/**
* Disables cache.
*/
function disableCache() {
cacheDisabled = true;
Logger.log("disableCache");
}

/**
* Enables cache.
*/
function enableCache() {
cacheDisabled = undefined;
Logger.log("enableCache");
}

/**
* Sets cache entry.
* <p>Default 10 min.
* <p>Maximum duration the value will remain in the cache, in seconds.
* <p>The minimum is 1 second and the maximum is 21600 seconds (6 hours).
*
* @param key Cache key.
* @param value Cache value.
* @param duration Retention duration.
*/
function setCache(key, value, duration) {
if(isCache()) {
duration = parseInt(duration);
if(duration == 0 || isNaN(duration)) {
duration = 600;
}
var cacheService = CacheService.getUserCache();

key = key.length > 250 ? key.substring(0, 250) : key;
cacheService.put(key, JSON.stringify(value), duration);

return true;
}

return false;
}

/**
* Gets cache entry.
*
* @param key Cache key.
*/
function getCache(key) {
if(isCache()) {
var cacheService = CacheService.getUserCache();

key = key.length > 250 ? key.substring(0, 250) : key;
var items = cacheService.get(key);

if(!items) {
return null;
}

return JSON.parse(items);
}
}

/**
* Delete cache entry.
*/
function deleteCache(key) {
if(isCache()) {
var cacheService = CacheService.getUserCache();

key = key.length > 250 ? key.substring(0, 250) : key;
cacheService.remove(key);
}
}

/**
* Is cache enabled.
*/
function isCache() {
if(cacheDisabled == true) {
Logger.log("isCache:: Is disabled");
return false;
}

return true;
}
/**
* Cache handling.
* <p>Reference: https://developers.google.com/apps-script/reference/cache/cache
*/
var cacheDisabled;

/**
* Disables cache.
*/
function disableCache() {
cacheDisabled = true;
Logger.log("disableCache");
}

/**
* Enables cache.
*/
function enableCache() {
cacheDisabled = undefined;
Logger.log("enableCache");
}

/**
* Sets cache entry.
* <p>Default 10 min.
* <p>Maximum duration the value will remain in the cache, in seconds.
* <p>The minimum is 1 second and the maximum is 21600 seconds (6 hours).
*
* @param key Cache key.
* @param value Cache value.
* @param duration Retention duration.
*/
function setCache(key, value, duration) {
if(isCache()) {
duration = parseInt(duration);
if(duration == 0 || isNaN(duration)) {
duration = 600;
}
var cacheService = CacheService.getUserCache();

key = key.length > 250 ? key.substring(0, 250) : key;
cacheService.put(key, JSON.stringify(value), duration);

return true;
}

return false;
}

/**
* Gets cache entry.
*
* @param key Cache key.
*/
function getCache(key) {
if(isCache()) {
var cacheService = CacheService.getUserCache();

key = key.length > 250 ? key.substring(0, 250) : key;
var items = cacheService.get(key);

if(!items) {
return null;
}

return JSON.parse(items);
}
}

/**
* Delete cache entry.
*/
function deleteCache(key) {
if(isCache()) {
var cacheService = CacheService.getUserCache();

key = key.length > 250 ? key.substring(0, 250) : key;
cacheService.remove(key);
}
}

/**
* Is cache enabled.
*/
function isCache() {
if(cacheDisabled == true) {
Logger.log("isCache:: Is disabled");
return false;
}

return true;
}
Loading

0 comments on commit e05c63b

Please sign in to comment.