Javascript bot programming using Gemini API, NodeJS and CryptoCompare - DISCUSSION

Made a quick little script for getting the current price and MA(9), MA(20), MA(50) and MA(100) from CoinGecko-API (https://www.npmjs.com/package/coingecko-api).

The reason for using CoinGecko is simple: It is free and CryptoCompare is not (only for limited calls).

You’ll need to npm install coingecko-api for this and do additional audit request on two packages!!

// Get CoinGecko API
const CoinGecko = require(‘coingecko-api’);
const CoinGeckoClient = new CoinGecko();

// Formatter for formatting currency
const formatter = new Intl.NumberFormat(‘en-US’, {
style: ‘currency’,
currency: ‘USD’,
minimumFractionDigits: 2
});

// Dates in unixtimestamps
var currentDate = Math.floor(Date.now() / 1000);
var dateMinus100Hours = currentDate - 360000;

// Helper function to transform unixtempstamps into readable dates
// Coingecko does not return hourly data which is accurate on the exact hour
// which is why I set the hour to 00 in the return value
function Unix_timestamp(t)
{
var dt = new Date(t);
var day = paddy(dt.getDate(), 2);
var month = paddy(dt.getMonth()+1, 2);
var year = dt.getFullYear();
var hr = paddy(dt.getHours(), 2);
var m = “0” + dt.getMinutes();
var s = “0” + dt.getSeconds();
return year + ‘-’ + month + ‘-’ + day + ’ ’ + hr + ‘:00’; // + m.substr(-2) + ‘:’ + s.substr(-2);
}

// Padding function for adding leading zero’s
function paddy(num, padlen, padchar) {
var pad_char = typeof padchar !== ‘undefined’ ? padchar : ‘0’;
var pad = new Array(1 + padlen).join(pad_char);
return (pad + num).slice(-pad.length);
}

// Call to CoinGecko to fetch the latest 100 hours price for bitcoin
// Also calculate the MA9, MA20, MA50 and MA100
function fetchMovingAverages(cryptoAsset, bOnlyMAs, callback) {

// results will be the string passed to the callback function
// with all the gathered information
var results = “”;

CoinGeckoClient.coins.fetch(cryptoAsset,
{
tickers: false,
market_data: true,
community_data: false,
developer_data: false,
localization: false,
sparkline: false
})
.then(coinData => {
results += “--------------------------------\r\n”;
results += cryptoAsset + " " + formatter.format(coinData.data.market_data.current_price.usd) + “\r\n”;
results += “--------------------------------\r\n”;

CoinGeckoClient.coins.fetchMarketChartRange(
  cryptoAsset,
  {
    from: dateMinus100Hours,
    to: currentDate
  }
).then(coinData =>
  {
    //console.log("--------------------------------");
    //console.log(cryptoAsset);
    //console.log("--------------------------------");
    // coinData has data section with prices section
    var prices = coinData.data.prices.reverse(); // from newest to oldest
    var sum100 = 0;
    var sum9 = 0;
    var sum20 = 0;
    var sum50 = 0;

    // Loop over prices and return readable data to the console log
    prices.forEach((item, i) => {
      var timeStamp = Unix_timestamp(item[0]);
      var priceInUSD = formatter.format(item[1]);
      sum100 += item[1];
      if (i < 9) sum9 += item[1];
      if (i < 20) sum20 += item[1];
      if (i < 50) sum50 += item[1];
      if (bOnlyMAs == false) results += timeStamp + " " + priceInUSD;
    });

    var movingAverage100 = formatter.format(sum100/100);
    var movingAverage9 = formatter.format(sum9/9);
    var movingAverage20 = formatter.format(sum20/20);
    var movingAverage50 = formatter.format(sum50/50);
    results += "MA(9) = " + movingAverage9 + "\r\n";
    results += "MA(20) = " + movingAverage20 + "\r\n";
    results += "MA(50) = " + movingAverage50 + "\r\n";
    results += "MA(100) = " + movingAverage100 + "\r\n";

    callback(results);
  }
).catch(error =>
  {
    console.log(error)
  }
);

})
.catch(error => {console.log(error)});
}

// Actual call to fetch information
fetchMovingAverages(‘bitcoin’, true, function(results)
{
console.log(results);
}
);

fetchMovingAverages(‘ethereum’, true, function(results)
{
console.log(results);
}
);

fetchMovingAverages(‘mantra-dao’, true, function(results)
{
console.log(results);
}
);

1 Like

The result :slight_smile:

1 Like

Error #1 :
“PS C:\Users…\JavaScript\bot> node index.js
(node:6120) UnhandledPromiseRejectionWarning: #
(node:6120) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 3)
(node:6120) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.”

Fix #1 :
“restClient.newOrder({amount:10,price:100,side:“buy”,symbol:“btcusd”})
.then(response => console.log(response))
.catch(error => console.log(error));”


Error #2 :
“PS C:\Users…\JavaScript\bot> node index.js
{
result: ‘error’,
reason: ‘MissingAccounts’,
message: ‘Expected a JSON payload with accounts’
}”

Fix #2 :
If you use a Primary API key, you should not get this error. I was using a Master API key, which need an extra parameter in the “newOrder” function specifying the account. Thus, I created a second API key, but this time I picked a Primary API key, and I modified the code to :

“restClient.newOrder({amount:10,price:100,side:“buy”,symbol:“btcusd”, account:“primary”})
.then(response => console.log(response))
.catch(error => console.log(error));”

1 Like

Note : the second API key having a primary scope might not be needed. To be tested.

Great job @Dhardesh !

Do you know the difference between these 2 wrapper :

I’m trying to use the CoinGecko API as well. I can’t connect to it though. I am using the other wrapper, which seems more recent. I installed “yarn add @coingecko/cg-api-ts” and “yarn add node-fetch”.


Code:
const CoinGeckoAPI = require("@coingecko/cg-api-ts");
const nodeFetch = require(“node-fetch”);
const cg = new CoinGeckoAPI(nodeFetch);


Error:
const cg = new CoinGeckoAPI(nodeFetch);
^
TypeError: CoinGeckoAPI is not a constructor
at Object. (C:…\CoinGecko\index.js:4:12)
e[90m at Module._compile (internal/modules/cjs/loader.js:1133:30)e[39m
e[90m at Object.Module._extensions…js (internal/modules/cjs/loader.js:1153:10)e[39m
e[90m at Module.load (internal/modules/cjs/loader.js:977:32)e[39m
e[90m at Function.Module._load (internal/modules/cjs/loader.js:877:14)e[39m
e[90m at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12)e[39m
e[90m at internal/main/run_main_module.js:18:47e[39m


Any suggestions?

I quickly researched the two projects. The coingecko-api looks much more mature than the cg-api-ts. The first one in already past its 1.0 version, while the latter is still in beta. So I personally would prefer to use a more mature API to communicate with.

As to your error: try adding global.fetch = require(“node-fetch”); as first line in your code. Then maybe you don’t have to create a const nodeFetch line and can just use fetch.

Ivan used the same line because it was needed for CryptoCompare to run.

1 Like

Thanks! That makes sense for the maturity.

No luck with global.fetch… I might try your way. What are the 2 other audit packages you mentioned?

Not sure anymore. But when you install the npm you’ll get a warning that two requirements need to be audited. It also states the additional command to execute right after it.

1 Like

@filip I haven’t found a way to continue this course on Mac. The problem I’m facing is with Yarn and gemini-api.

I have this structure in my folder named “algotrading”:
index.js
node_modules
package-lock.json
package.json

The folder “node_modules” has “yarn” folder in it. So I understand the Yarn is installed.

Now when I run the command:
[algotrading]$ yarn add gemini-api

I get this result:
-bash: yarn: command not found
[algotrading]$

What I’m missing here? Thanks!

What do you mean by “The forum swaps out quotes, so if you copy, replace the quotes.”. Do you mean to delete the quotes?

1 Like

This was just in response to a code snippet that had left quote and right quotes, and the IDE did not like that. I was considering running through this on my mac to try and help out.
Does your mac say anything about using zsh instead of bash?

Fixed using this in my Mac terminal:

I didnt have an account on Gemini, but decided to create one to be able to follow along before trying to do the same at another exchange. I get stuck at the SMS verification part of signing up. I inserted my phone number, no SMS , sent code again, but still no SMS.

Anyone else with this problem? I understand that it’s a US exchange and that most things in the US suck and require this and that, but cmon, if I give the number why cant your crappy system send that friggin SMS to register?

No way im ever giving a penny to Gemini.

1 Like

This link https://exchange.sandbox.gemini.com is not working. Get a blank page both from Safari and Google Chrome

It worked when I changed VPN to Sweden

I noticed that account must proceed key

const key = “account-xxxxxxxxxxxxxxxxxx”;

2 Likes

hi team,

pls assist. I am stuck trying to download yarn gemini api, see the error message below.
This is the task in lesson 12.

1 Like

Hey Team, i was doing so well up till now. Got this error appearing after i try and activate the API after node index.js this error appears for me. Anyone have any ideas what is going wrong for me?

Thank you all in advance.

Also i use Binance more that Gemini is there a way of using that instead?

all good i fixed it. For anyone who wanted to know it was due because my API secret was typed wrong.

All good now.

ROB

Hi there, could you help me out with how to install this on my machine? I can see instructions for the api side but need some help with the NPM Side.

Rob.