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.
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)I found the problem. It comes from MetaTrader's api, "getHistoricalCandles" not working as expected. What is written in the api is:
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 put
Date.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.. .