Nodejs MetaAPI Cloud / Calculate Moving Average
P粉715274052
P粉715274052 2023-09-03 09:12:59
0
2
386

I am making a trading bot using metaapi.cloud and I am trying to calculate moving average (fast/exponential) but it returns me invalid values, here is my code:

async movingAverage(symbol, period, type = "S") { let candles = (await this.account.getHistoricalCandles(symbol, this.params.timeframe, null, period)).map(c => c.close); const result = []; let sum = 0; if (type === "S") { for (let i = 0; i < period; i ) { sum = candles[i]; } result.push(sum / period); for (let i = period; i < candles.length; i ) { sum = sum - candles[i - period] candles[i]; result.push(sum / period) } } else if (type === "E") { const weight = 2 / (period 1); for (let i = 0; i < period; i ) { sum = candles[i]; } sum /= period; result.push(sum); for (let i = period; i < candles.length; i ) { sum = (candles[i] * weight) (sum * (1 - weight)); result.push(sum); } } else { // throwError() } return result; } 

Here’s how I use it:

async onTick(infos) { let sma = await this.movingAverage(infos.symbol, this.params.fast, "S"); console.log('SMA ' sma[0]); } 

Now when I test it, the SMA should return "1906.6963" but it gives me "1900.7813" Maybe I'm using the wrong way to calculate them? If anyone has a solution! Thanks in advance.

P粉715274052
P粉715274052

reply all (2)
P粉071743732
  • SMA looks correct, EMA has many different patterns. Since you didn't post a sample dataset, it's hard to guess what is being passed from the server, but there could be a lot of values that cannot be converted, such as NaN, null, empty strings or numbers with commas, exponents, etc. Just replaced the candles with an array with wrong values. Do some filtering and then do the calculation
  • Consider period > dataset. In this case, set period to length.

In the example below, set period to 1 to see all values processed, and set period to a very large number to see the entire average.

There are definitely other edge cases that I haven't thought of. For brevity, the following examples use SMA.

async function movingAverage(symbol, period, type = "S") { let candles = [1,2,3,"","",4, "0",0, null, "99,9123", undefined,"0.123e5", "wrongval", 9, 10, 20, 100] .map(d => parseFloat((d ?? "").toString().replace(",","."))) .filter(d => +d || +d === 0); const result = []; if (candles.length <= 0){return result} let sum = 0; period = Math.min(candles.length, period) || 1; for (let i = 0; i < period; i++) { sum += candles[i]; } result.push(sum / period); for (let i = period; i < candles.length; i++) { sum = sum - candles[i - period] + candles[i]; result.push(sum / period) } return result; } movingAverage("SPX",500).then(x => document.getElementById("result").textContent = x)
    P粉563446579

    I found the problem. It comes from MetaTrader's api, "getHistoricalCandles" not working as expected. What is written in the api is:

    getHistoricalCandles(symbol, timeframe, startTime, limit) symbol: symbol to retrieve candles for TimeFrame: define the timeframe according to which the candles must be generated StartTime: time to start loading candles from. Note that candles are loaded in backward direction, so this should be the latest time, **leave it empty to request latest candles** Limit: maximum of candles to retrieve, must be less or equals to 1000

    The problem here is the StartTime parameter, it definitely doesn't work like they say it does, when I leave it empty, or when I putDate.now()it retrieves Candles from 5 hours ago, in order to retrieve the absolute last candle, I have to enterDate.now() 10000000000, so this may be a time zone error that cannot be solved for now since it comes from the api side.. .

      Latest Downloads
      More>
      Web Effects
      Website Source Code
      Website Materials
      Front End Template
      About us Disclaimer Sitemap
      php.cn:Public welfare online PHP training,Help PHP learners grow quickly!