Regarding: https://github.com/gvasquez95/binance-trader/issues/8
I'm concerned that the actual "inner" await (in every single invocation of getPriceChange) isn't blocking asynchronous invocation of the about 1.5k calls this method has on the outer loop (getPriceChanges). As if it was blocking, then the loop would be serial processing.
From the performance view and timing, I'd say it is working as expected, as it takes just some seconds to complete the whole process but, I'd like a programming ACK of the assumptions, if possible, please.
Block codes for those that don't want to get into GitHub and, prefer the code more visible here:
Outer loop:
async function getPriceChanges (since, breakpoint) {
const changes = []
for (const [i, ticker] of tickers.entries()) {
if (!ticker.includes('BIDR') && !ticker.includes('BIFI')) {
changes.push(getPriceChange(ticker, since, breakpoint))
}
}
const res = await Promise.all(changes)
let symbol
let maxChange = 0
let slope = 0
for (const ticker of res) {
if (ticker.percentChange > maxChange && ticker.slope > Math.pow(10, -1 * NUM_DECIMALS)) {
maxChange = ticker.percentChange
symbol = ticker.symbol
slope = ticker.slope
}
}
return { symbol, maxChange: Math.round(100 * maxChange) / 100, slope: round(slope, NUM_DECIMALS) }
}
Inner getPriceChange function:
async function getPriceChange (symbol, since, breakpoint) {
const params = {
TableName: DYNAMODB_TABLE,
ProjectionExpression: '#timestamp, price',
KeyConditionExpression: 'symbol = :symbol and #timestamp > :timestamp',
ExpressionAttributeNames: {
'#timestamp': 'timestamp'
},
ExpressionAttributeValues: {
':symbol': symbol,
':timestamp': since
}
}
const res = await documentClient.query(params).promise()
const prev = []
const recent = []
const trendData = []
for (const data of res.Items) {
if (data.timestamp < breakpoint) {
prev.push(data.price)
} else {
trendData.push({ x: trendData.length, y: data.price })
recent.push(data.price)
}
}
let sumPrev = 0
let sumRecent = 0
for (const price of prev) { sumPrev += price }
for (const price of recent) { sumRecent += price }
const avgPrev = sumPrev / prev.length
const avgRecent = sumRecent / recent.length
const trend = createTrend(trendData, 'x', 'y')
return { symbol, percentChange: (100 * (avgRecent - avgPrev)) / avgRecent, slope: trend.slope }
}
Update: Function execution takes about 30 seconds in a Node.js 14.x AWS Lambda environment, configured with 624 MB RAM and, from a cost perspective the both the DynamoDB query (ReadRequests) costs and Lambda executions are 1/50th of the actual DynamoDB Batch Put operations (WriteRequest), so optimizing the query should be a needed goal.