【问题标题】:Calculate average in NodeJS from API从 API 计算 NodeJS 中的平均值
【发布时间】:2020-07-14 09:42:53
【问题描述】:

我有一个脚本,它每隔 30 分钟从Binance API 获取数据,并在终端中显示。 我想计算数组中每个资产的平均值。

这是Node-Schedule package - const j = schedule.scheduleJob('* * * * *'

小例子:var array = ["ADABTC", "AEBTC", "AIONBTC"] 我想分别计算 "ADABTC""AEBTC""KAVABTC" 的平均值。

完整代码

const { MongoClient } = require('mongodb');
const schedule = require('node-schedule');
const fetch = require('node-fetch');

const symbols = ["ADABTC", "AEBTC", "AIONBTC", "ALGOBTC", "ARDRBTC", "ARKBTC", "ATOMTC"]

const getBTCData = async symbol => { 
    let data = await fetch(`https://api.binance.com/api/v3/klines?symbol=${symbol}&interval=30m&limit=1`).then(res => res.json());
    const btcusdtdata = data.map(d => {
        return {
            Volume: parseInt(d[5]),
            Timespan: 30,
        }
    });
    console.log(btcusdtdata);
};

const sleep = ms => new Promise(res => setTimeout(res, ms));

const j = schedule.scheduleJob('* * * * *', async() => {
    for (let symbol of symbols) {
        await getBTCData(symbol);
        await sleep(4000);
    }
});

目标:如果我每 30 分钟收到一次资产,我如何计算这部分的平均交易量 - Volume: parseInt(d[5]),

【问题讨论】:

  • 此 API 将为我们提供给定交易品种(和区间)的一些统计数据,例如开盘价、最高价、最低价、收盘价等。您是否希望确定单个数据点的平均价格?还是您希望每 30 分钟获取一次价格,然后平均这些价格,比如当天?
  • @TerryLennox 你好!我想计算音量的平均值,这就是为什么我有'parseInt(d[5])。我将更新我的问题以使其更正确。我想获得每个资产的平均交易量,然后对即将到来的资产进行平均。就像在脚本工作 2 小时后,我为每个资产有 4 个数字,我想计算每个资产的这 4 个数字的平均值。
  • 啊,是的,非常好。感谢您的详细更新!
  • @TerryLennox 期待任何关于如何制作它的建议。感谢您的评价
  • @TerryLennox 如果你有时间我想和你个人聊天,根据你的 SO 个人资料,我想你可以让我对 nodejs 后端系统有所了解。但我真的希望我们能先解决我的第一个问题。

标签: javascript node.js average


【解决方案1】:

收集平均值(和其他统计数据)的一种简单方法是创建一个以符号为键的地图。

我们会为每个交易品种保留历史记录,然后在每次获得新数据点时计算交易量的平均值。

示例可能如下所示(出于演示目的,我已将调用频率更新为每 10 秒一次!)

const schedule = require('node-schedule');
const fetch = require('node-fetch');

const symbols = ["ADABTC", "AEBTC", "AIONBTC", "ALGOBTC", "ARDRBTC", "ARKBTC", ]

const symbolSummary = {};

const getBTCData = async symbol => { 
    let data = await fetch(`https://api.binance.com/api/v3/klines?symbol=${symbol}&interval=30m&limit=1`).then(res => res.json());
    const btcusdtdata = data.map(d => {
        return {
            Volume: parseInt(d[5]),
            Timespan: 30,
            symbol
        }
    });
    console.log(btcusdtdata);
    return btcusdtdata;
};

const appendBTCDataToSummary = (btcData, summary) => {
    if (!summary[btcData.symbol]) {
        summary[btcData.symbol] = { history: [], symbol: btcData.symbol };
    }
    let symbolHistory = summary[btcData.symbol].history;
    symbolHistory.push(btcData);
    summary[btcData.symbol].averageVolume = symbolHistory.reduce((average, row) => {
        // Calculate the average volume by scaling each volume entry by 1 / length.
        return average + (row.Volume) * (1 / symbolHistory.length);
    }, 0)
    summary[btcData.symbol].dataPoints = symbolHistory.length;
}

const sleep = ms => new Promise(res => setTimeout(res, ms));

const j = schedule.scheduleJob('* * * * *', async() => {
    for (let symbol of symbols) {
        let btcData = await getBTCData(symbol);
        appendBTCDataToSummary(btcData[0], symbolSummary);
        // We must back off between calls as per api terms of use.
        await sleep(4000);
    }

    console.log("Symbol summaries:", Object.values(symbolSummary).map(summary => { 
        return { symbol: summary.symbol, AverageVolume: summary.averageVolume, DataPoints: summary.dataPoints };
    }));
});

【讨论】:

  • 感谢您的回答!我今天将对其进行测试,看看它是如何工作的,我会为您回复!超级感谢!
  • 乍一看,在我的测试中,它看起来很锋利。工作正常,没有任何问题。我想指出的只有一个标记是缺少'等待睡眠(4000)或至少(2000)。解释:在 Binance API 中写道,假设延迟至少为 2 秒,否则您可能会收到最长 72 小时的 IP 禁令。我只是为另一个将代码用于其目的的人指出这一点。另一方面,它完美地工作。绝对喜欢并点赞。谢谢楼主,非常感谢!
  • 啊,是的,我明白了。这就说得通了。我会在睡眠电话中补充一下,如果我们不想要禁令,这基本上是一个要求!
  • 嘿,可以和你聊天吗?
  • 当然..我在这里创建了一个聊天..chat.stackoverflow.com/rooms/217864/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-14
  • 2017-02-06
  • 2012-06-19
相关资源
最近更新 更多