Creating Daily and Minutely MA - Practical Assignment

Hi carlos. Heres the INDEX.JS Code

global.fetch = require("node-fetch");
const GeminiAPI = require("gemini-api").default;

const secret = "3tCsg7JfkYAebKdtfnAv9JWG8AFT";
const key = "account-vQ9nv4dTXUMI9ugKQ4vT";
const restClient = new GeminiAPI({key, secret, sandbox:true});
const indicators = require("./indicators.js");


indicators.hourlyMovingAverage("BTC", "USD", 100, function(result){
  console.log("MA hourly: ", result)
});

indicators.dailyMovingAverage("BTC", "USD", 360, function(result){
  console.log("MA daily: ", result)
});

indicators.minutelyMovingAverage("BTC", "USD", 60, function(result){
  console.log("MA minutely: ", result)
});

here is the indicators.js Code

const CCAPIKey = "14faf0c094ded9546b142ec0aa4944643f01af10322ea42aae5e997efd378218";
const CC = require("cryptocompare")
CC.setApiKey(CCAPIKey);

module.exports = {

  hourlyMovingAverage:function movingAverage(cryptoAsset, fiatCurrency, hours, callback){
    if(hours>169){
      console.error("Only up to 169 hours allowed!")
      return
    }
    // 1 get data from CC
    CC.histoHour(cryptoAsset, fiatCurrency)
    .then(data => {

    // 2 calculate MA from past hours
      data = data.reverse()
      var sum = 0;
      for(var i =0;i<hours;i++){
        sum+=data[i].close;
      }
    var movingAverage = sum/hours;
    callback(movingAverage);
  })
    .catch(console.error);
  }

, dailyMovingAverage:function movingAverage(cryptoAsset, fiatCurrency, days, callback){
  if(days>365){
    console.error("Only up to 365 days allowed!")
    return
  }
  // 1 get data from CC
  CC.histoDay(cryptoAsset, fiatCurrency)
  .then(data => {

  // 2 calculate MA from past hours
    data = data.reverse()
    var sum = 0;
    for(var i =0;i<days;i++){
      sum+=data[i].close;
    }
  var movingAverage = sum/days;
  callback(movingAverage);
})
  .catch(console.error);
}

, minutelyMovingAverage:function movingAverage(cryptoAsset, fiatCurrency, minutes, callback){
  if(days>365){
    console.error("Only up to 169 minutes allowed!")
    return
  }
  // 1 get data from CC
  CC.histoMinute(cryptoAsset, fiatCurrency)
  .then(data => {

  // 2 calculate MA from past hours
    data = data.reverse()
    var sum = 0;
    for(var i =0;i<minutes;i++){
      sum+=data[i].close;
    }
  var movingAverage = sum/minutes;
  callback(movingAverage);
})
  .catch(console.error);
}

};

The error code switches between one of the following:

“Days is not defined” // or
" daily.indicators is not a function" (same with minetyl)
looking forward to see what i didnt get right in this exercise… appreciate your help. Have a good start for this week.

This code line should be:const indicators = require("./indicators");

try it and let me know how it goes :face_with_monocle:

Carlos Z

thank you i changed it. It still says days is not defined tho…

Screen Shot 2021-03-22 at 12.38.40 PM

On this function, you have a conditional IF to compare the days variable agains 365, but does the days variable is defined in the function parameters? (it use minutes instead of days)

If you have any more questions, please let us know so we can help you! :slight_smile:

Carlos Z.

thanks dude it worked…
Screen Shot 2021-03-23 at 5.42.01 PM

i do have one more question regarding the amount of days/minutes/hours you can put in the if function.

If i put in

if(days>365){
    console.error("Only up to 365 days allowed!")
    return
  }

and then put for example this variable (number 360) in the index.js file

indicators.dailyMovingAverage("BTC", "USD", 360, function(result){
  console.log("MA daily: ", result)
});

i would get the following error code for the daily MA:

Screen Shot 2021-03-23 at 5.46.55 PM

So if i then go ahead and change the number of the if function in the indicators file from 360 to lets say 150

if(days>150){
    console.error("Only up to 150 days allowed!")
    return
  }

and follow up with a smaller variable number like 30 days in the index.js file …

indicators.dailyMovingAverage("BTC", "USD", 30, function(result){
  console.log("MA daily: ", result)
});

… it works perfectly fine.

My question : why? what is the threshold / size of a number that is allowed by the program? My bad if this was explained in an earlier step of this course and i happened to miss it. i just cant wrap my head around it… Thank you carlos for your patience.

1 Like

Javascript TypeError object represents the error when the operation could not be performed, typically (but not exclusively) when the value is not of the expected type.

You can read more about it here: https://appdividend.com/2019/12/03/javascript-typeerror-example-solve-typeerror-in-javascript/

It can be solve by converting the variable into a number . https://www.w3schools.com/js/js_number_methods.asp

Carlos Z

1 Like

i keep getting this error and am not sure how to remedy this… any help please? Thanks!



const CCAPIKey = "4d5544b720ff20f1160be416ddf5b0855ef157384233f86168650e7e27174b0b"
const CryptoCompareAPI = require("cryptocompare");
CryptoCompareAPI.setApiKey(CCAPIKey);

module.exports = {
  hourlyMovingAverage:function(cryptoAsset,fiatCurrency,hours,callback){
if(hours>169){
  console.error("only up to 169 hours allowed!");
  return
}
CryptoCompareAPI.histoHour(cryptoAsset, fiatCurrency)
.then(data => {
  data = data.reverse();
  var sum = 0;
  for(var i = 0;i<hours;i++){
    sum+=data[i].close;
  }
var movingAverage = sum/hours;

callback(movingAverage);
})
.catch(console.error)}

minutelyMovingAverage:function(cryptoAsset,fiatCurrency,minutes,callback){
if(minutes>1400){
  console.log("only up to 1440 minutes allowed!")
}

CryptoCompareAPI.histoMinute(cryptoAsset, fiatCurrency)
.then(data => {
  data = data.reverse();
  var sum = 0;
  for(var i = 0;i<minutes;i++){
    sum+=data[i].close;
  }
var movingAverage = sum/minutes;

callback(movingAverage);
})
.catch(console.error)
}

  dailyMovingAverage:function(cryptoAsset,fiatCurrency,days,callback){
if(days>365){
  console.error("only up to 365 days allowed!");
}

CryptoCompareAPI.histoDay(cryptoAsset, fiatCurrency, {limit:"none"})
.then(data => {
  data = data.reverse()
  var sum = 0;
  for(var i = 0;i<days;i++){
    sum+=data[i].close;
  }
var movingAverage = sum/days;

callback(movingAverage);
})

.catch(console.error);
}}

type or paste code here



![image|633x208](upload://qQgIynpY3Gy1BLnDwsQ4ba1QC39.png)
1 Like

image

1 Like

Put a comma in the circled area. Do the same for the other functions.
The functions in indicators.js should each be separated by a comma.

coding_help

2 Likes

Hey @VincentC. @Uyan…glad to see you guys are supporting each others :slight_smile:

As @Uyan as mention, you have to use a comma between each function, the basic structure is:

module.exports = {
 objectName: function(){
 //do something
 return result;
},
 objectName2: function(){
 //do something
 return result;
 }
} 

Also there is a better way that can be easy to maintain and read at long term.

First you have to write a function like:

functions example
/*
// @dev Create new trade order
// @var _amount, float
// @var _price, int
// @var _side, string
// @var _symbol string
*/
function newOrder(_data, callback){
  geminiClient.newOrder({amount:_data.amount,
    price:_data.price,
    side:_data.side,
    symbol:_data.symbol,
    options:_data.options})
    .then(_res => {
      callback(_res)
    })
  .catch(console.error);
}
/*
//Get all trading symbols Ex: "btcusd"
*/
function getAllSymbols(callback){
  geminiClient.getAllSymbols()
  .then(_res => {
    callback(_res)
  })
  .catch(console.error);
}
/*
//get market price and data from a symbol Ex: "btcusd"
// @var _symbol string
*/
function getTicker(_symbol, callback){
  geminiClient.getTicker(_symbol)
  .then(_res => {
    callback(_res)
  })
  .catch(console.error);
}

Then you just need to export the name of the functions, that way you have a easy to read and maintain code, and you will avoid typos like that one you did between each object exported.

module.exports =
{
  newOrder,
  getAllSymbols,
  getTicker
}

Hope this helps.
Carlos Z

1 Like

DID IT!!
image

1 Like

indicators.js

module.exports = {
dailyMovingAverage: function(cryptoAsset, fiatCurrency, days, callBack){
if (days > 31){
console.error(“Only up to 31 days allowed!”);
return;
}
// 1 get data from cryptocompare (CC)
CryptoCompareAPI.histoDay(cryptoAsset, fiatCurrency)
.then(data => {
// 2 calculate MA from n past days
data = data.reverse()
let sum = 0;
for (var index = 0; index < days; index++) {
sum+=data[index].close;
}
let movingAverage = sum/days;
callBack(movingAverage);
})
.catch(console.error);
},

hourlyMovingAverage: function(cryptoAsset, fiatCurrency, hours, callBack){
if (hours > 169){
console.error(“Only up to 169 hours allowed!”);
return;
}
// 1 get data from cryptocompare (CC)
CryptoCompareAPI.histoHour(cryptoAsset, fiatCurrency)
.then(data => {
// 2 calculate MA from 100 past hours
data = data.reverse()
let sum = 0;
for (var index = 0; index < hours; index++) {
sum+=data[index].close;
}
let movingAverage = sum/hours;
callBack(movingAverage);
})
.catch(console.error);
},

minutelyMovingAverage: function(cryptoAsset, fiatCurrency, minutes, callBack){
if (minutes > 1441){
console.error(“Only up to 1441 minutes allowed!”);
return;
}
// 1 get data from cryptocompare (CC)
CryptoCompareAPI.histoMinute(cryptoAsset, fiatCurrency)
.then(data => {
// 2 calculate MA from 1000 past minutes
data = data.reverse()
let sum = 0;
for (var index = 0; index < minutes; index++) {
sum+=data[index].close;
}
let movingAverage = sum/minutes;
callBack(movingAverage);
})
.catch(console.error);
}
}

1 Like

I keep getting this error and I am not sure on what to do or what needs to be fixed, any help would be appreciated.

The error in powershell:

PS E:\Atom Stuff fnoo> node index.js
TypeError: Cannot read property 'close' of undefined
    at E:\Atom Stuff fnoo\indicators.js:64:20
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
Minutely MA: 4162.754200000001
Hourly MA: 3891.8482

Code of the section: index.js

global.fetch = require("node-fetch");
const GeminiAPI = require("gemini-api").default;
const secret = "NMWhhwLiixjgPucEtbJFPt4ExaK";
const key = "account-kJGpYiaMOqtxZkiAQbho";
const restClient = new GeminiAPI({key, secret, sandbox:true});
const indicators = require("./indicators.js");

indicators.hourlyMovingAverage("ETH","USD",100,function(result){
    console.log("Hourly MA:", result)
});

indicators.minutelyMovingAverage("ETH","USD",100,function(result){
    console.log("Minutely MA:", result)
});

indicators.dailyMovingAverage("ETH","USD",100,function(result){
    console.log("Daily MA:", result)
});

Code of the section: indicators.js

const CCAPIKey = "e65acb6b14ab3b11775e6d7d421ca589464d41257812fedb4a55fd0f0d6bb2d8"
const CryptoCompareAPI = require("cryptocompare");
CryptoCompareAPI.setApiKey(CCAPIKey);


module.exports = {

  hourlyMovingAverage: function movingAverage(cryptoAsset, fiatCurrency, hours, callback){

    if(hours>169){
      console.error("Only up to 169 hours")
      return
    }


    CryptoCompareAPI.histoHour(cryptoAsset, fiatCurrency)
    .then(data => {

      data = data.reverse()
      var sum = 0;
      for(var i = 0;i<hours;i++){
      sum+=data[i].close;
    }

    var movingAverage = sum/hours;
    callback(movingAverage);

  })
  .catch(console.error);
  }

, minutelyMovingAverage:function movingAverage(cryptoAsset,fiatCurrency, minutes, callback){
  if (minutes>169){
    console.error("Only up to 169 minutes allowed!")
    return
  }

  CryptoCompareAPI.histoMinute(cryptoAsset, fiatCurrency)
  .then(data => {

    data = data.reverse()
    var sum = 0;
    for(var i = 0;i<minutes;i++){
      sum+=data[i].close;
    }
    var movingAverage = sum/minutes;
    callback(movingAverage);
  })
  .catch(console.error);
}

, dailyMovingAverage:function movingAverage(cryptoAsset,fiatCurrency, days, callback){
  if (days>364){
    console.error("Only up to 365 days allowed!")
    return
  }

  CryptoCompareAPI.histoDay(cryptoAsset, fiatCurrency)
  .then(data => {

    data = data.reverse()
    var sum = 0;
    for(var i = 0;i<days;i++){
      sum+=data[i].close;
    }
    var movingAverage = sum/days;
    callback(movingAverage);
  })
  .catch(console.error);
}

};
1 Like

Hey @Denzel, hope you are ok.

I was not able to understand why the error message, the code was completely good, i double checked the code to find out why, but i did not find any error.

So i just delete the function entirely, copy/paste the minute function and just change the minute argument to days and run the code again, the error just disappear.

let me know if you could do the same and works for you :face_with_monocle:

image

Carlos Z

Just tried your recommendation and things are still the same, which is weird. Could it be an error in installation or a version mismatch? Ill try to continue the course however I can, thanks for your help.

1 Like

Could be one posibility, my node version is v16.0.0.

The trick I have is nvm which I use to switch between different node versions.

https://itnext.io/nvm-the-easiest-way-to-switch-node-js-environments-on-your-machine-in-a-flash-17babb7d5f1b

Still I’ll be around if you need any assistance :nerd_face:

Carlos Z

global.fetch = require (“node-fetch”);
const GeminiAPI = require (“gemini-api”).default;
const secret = “2GxkM3sHHFWY48EpdxVLrSzjTq8F”;
const key = “account-NSzewmv9B4b0i2kzQPza”;
const indicators = require ("./indicators.js");
/* const restClient = new GeminiAPI ({key, secret, sandbox:true});
restClient.newOrder ({amount:10, price:1100, side:“buy”, symbol:“ethusd”})
.then (response => console.log (response))
.catch (error => console.log (error)); */

indicators.minuteMovingAverage(“BTC” , “USD” , 1440 , function(result){
console.log(“Minute Moving Average is:”, result)
})
indicators.hourlyMovingAverage (“BTC”, “USD”, 100, function(result){
console.log (“Hourly Moving Average is:”, result)
})
indicators.dailyMovingAverage(“BTC”, “USD”, 31, function(result){
console.log(“Daily Moving Average is:”, result)
});
// 3 check continuously if price is crossing 100 MA => BUY/SELL/HODL

my indicators.js looks like this:
const CCAPIKEY = “9587d57e52f021966c44742c2e36c09c9b48049c3b7e966badef0edb408bdcff”
const CryptoCompareAPI = require (“cryptocompare”);
CryptoCompareAPI.setApiKey (CCAPIKEY);

module.exports = {

hourlyMovingAverage : function(cryptoAsset, fiatCurrency, hours, callback){
if(hours > 169){
console.error(“Only up to 169 hours allowed!”)
return
}
// Print MA of the last 100 hours close price going backwards from now
CryptoCompareAPI.histoHour(cryptoAsset, fiatCurrency)
.then(data => {
data = data.reverse()
var sum = 0;
for(var i = 0; i < hours; i++){
sum += data[i].close;
}
var movingAverage = sum/hours;
callback(movingAverage);
})
.catch(console.error)
},

dailyMovingAverage: function(cryptoAsset, fiatCurrency, days, callback){
if(days > 365){
console.error(“Only up to 365 days allowed!”)
return
}
// Print MA of the last 100 hours close price going backwards from now
CryptoCompareAPI.histoDay(cryptoAsset, fiatCurrency , {limit:“none”})
.then(data => {
data = data.reverse()
var sum = 0;
for(var i = 0; i < days; i++){
sum += data[i].close;
}
var movingAverage = sum / days;
callback(movingAverage);
})
.catch(console.error)
},

minuteMovingAverage : function(cryptoAsset , fiatCurrency , minutes , callback){
if(minutes > 1440){
console.error(“Only up to 1440 minutes allowed!”)
return
}
// Print MA of the last 100 hours close price going backwards from now
CryptoCompareAPI.histoMinute(cryptoAsset, fiatCurrency)
.then(data => {
data = data.reverse()
var sum = 0;
for(var i = 0; i < minutes; i++){
sum += data[i].close;
}
var movingAverage = sum/minutes;
callback(movingAverage);
})
.catch(console.error)
}
}

1 Like

powershell_OJ8KD93pbU

1 Like
Daily MA:  45945.064999999995
Hourly MA:  46303.062399999995
Minutely MA:  46993.73098999996
1 Like

indicators.js:

module.exports = {

//Daily MA
dailyMovingAverage:function(cryptoAsset,fiatCurrency,days,callback){

if(days>365){
console.log(“Only up to 365 days allowed”)
}
CryptoCompareAPI.histoDay(cryptoAsset, fiatCurrency, {limit:“none”})
.then(data => {

data = data.reverse(i)
var sum = 0;
for(var i = 0;i<days;i++){
sum+=data[i].close;
}

var movingAverage = sum/days;
callback(movingAverage);
})
.catch(console.error)
},

//Hourly MA
hourlyMovingAverage:function(cryptoAsset,fiatCurrency,hours,callback){

if(hours>169){
console.log(“Only up to 169 hours allowed”)
}
CryptoCompareAPI.histoHour(cryptoAsset, fiatCurrency)
.then(data => {

data = data.reverse(i)
var sum = 0;
for(var i = 0;i<hours;i++){
sum+=data[i].close;
}

var movingAverage = sum/hours;
callback(movingAverage);
})
.catch(console.error)
},

//Minutely MA
minutelyMovingAverage:function(cryptoAsset,fiatCurrency,minutes,callback){

if(minutes>1440){
console.log(“Only up to 1440 minutes allowed”)
}
CryptoCompareAPI.histoMinute(cryptoAsset, fiatCurrency)
.then(data => {

data = data.reverse(i)
var sum = 0;
for(var i = 0;i<minutes;i++){
sum+=data[i].close;
}

var movingAverage = sum/minutes;
callback(movingAverage);
})
.catch(console.error)
}
}

index.js:

indicators.minutelyMovingAverage(“BTC”,“USD”,1000,function(result){
console.log("MinMA: ", result)
})
indicators.hourlyMovingAverage(“BTC”,“USD”,169,function(result){
console.log("HourMA: ", result)
})
indicators.dailyMovingAverage(“BTC”,“USD”,200,function(result){
console.log("DayMA: ", result)
})

1 Like