Skip to content

Commit

Permalink
7 inconsistent dates timestamps in response (#9)
Browse files Browse the repository at this point in the history
* Fix for date time TZ

* correct enums
  • Loading branch information
bikerpatch authored Jul 19, 2022
1 parent ea4890f commit 9d96dd8
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 40 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Catch errors to do with API rate limit
- [**Stock Time Series Daily node**] - **Bug Fix** Handle non-initialised `msg.payload` in response
- [**Stock Time Series Intraday node**] - **Bug Fix** Handle non-initialised `msg.payload` in response
- [**All nodes**] - **Bug Fix** Fixed date/time conversions to UTC

## [0.2.0] - 18/07/2022

Expand Down
4 changes: 2 additions & 2 deletions src/stock-daily.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ module.exports = (RED) => {
const result = api.util.polish(await api.data.daily(symbol, outputSize, "json"))

msg.payload = {
series: apiUtil.mapSeriesObj(result.data), // backward compat
seriesArray: apiUtil.mapSeriesArray(result.data), // new array
series: apiUtil.mapSeriesObj(result.data, apiUtil.timeseriesType.Date, result.meta.zone), // backward compat
seriesArray: apiUtil.mapSeriesArray(result.data, apiUtil.timeseriesType.Date, result.meta.zone), // new array
data: apiUtil.mapData(result.meta) // backward compat
}

Expand Down
4 changes: 2 additions & 2 deletions src/stock-intraday.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ module.exports = (RED) => {

msg.payload = {
data: apiUtil.mapData(result.meta), // backward compat
series: apiUtil.mapSeriesObj(result[timeSeriesKey]), // backward compat
seriesArray: apiUtil.mapSeriesArray(result[timeSeriesKey]), // new array
series: apiUtil.mapSeriesObj(result[timeSeriesKey], apiUtil.timeseriesType.Timestamp, result.meta.zone), // backward compat
seriesArray: apiUtil.mapSeriesArray(result[timeSeriesKey], apiUtil.timeseriesType.Timestamp, result.meta.zone), // new array
}

Send(msg)
Expand Down
46 changes: 35 additions & 11 deletions src/util/api.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use strict"

const alphavantage = require("alphavantage")
const { DateTime } = require("luxon")

const FLOAT_VARS = ["open", "close", "high", "low", "price", "change", "prev_close"]
const INT_VARS = ["volume"]
Expand Down Expand Up @@ -43,19 +44,19 @@ function mapQuoteObj(quoteObj) {
return returnVar
}

function mapSeriesObj(seriesObj) {
function mapSeriesObj(seriesObj, timeseriesType, timezone = "US/Eastern") {
var returnVar = {}
Object.keys(seriesObj).forEach((key) => {

const keyDate = new Date(key)
const year = String(keyDate.getFullYear())
const month = String(keyDate.getMonth()+1).padStart(2,0)
const day = String(keyDate.getDate()).padStart(2,0)
const hours = String(keyDate.getHours()).padStart(2,0)
const mins = String(keyDate.getMinutes()).padStart(2,0)
const seconds = String(keyDate.getSeconds()).padStart(2,0)
// we have to do this because package `alphavantage` returns the wrong date. 8pm Eastern will be provided as 7pm UTC, so we have to correct
var timestamp = DateTime.fromFormat(key.replace(/T|Z|.000/g," ").trim(), "yyyy-MM-dd HH:mm:ss", { zone: timezone }).plus({hours:1})

var format = "yyyy-MM-dd"

const seriesKey = `${year}-${month}-${day} ${hours}:${mins}:${seconds}`
if (timeseriesType === "Timestamp")
format = "yyyy-MM-dd HH:mm:ss"

const seriesKey = timestamp.toFormat(format)
returnVar[seriesKey] = seriesObj[key]

Object.keys(seriesObj[key]).forEach((dataPointKey) => {
Expand All @@ -66,12 +67,15 @@ function mapSeriesObj(seriesObj) {
returnVar[seriesKey][dataPointKey] = parseInt(seriesObj[key][dataPointKey], 10)
}
})

if (timeseriesType === "Timestamp")
returnVar[seriesKey].timestamp = timestamp.toISO()
})

return returnVar
}

function mapSeriesArray(seriesObj) {
function mapSeriesArray(seriesObj, timeseriesType, timezone = "US/Eastern") {
const returnVar = []
Object.keys(seriesObj).forEach((key) => {

Expand All @@ -86,7 +90,17 @@ function mapSeriesArray(seriesObj) {
}
})

seriesItem.timestamp = key
// we have to do this because package `alphavantage` returns the wrong date. 8pm Eastern will be provided as 7pm UTC, so we have to correct
var timestamp = DateTime.fromFormat(key.replace(/T|Z|.000/g," ").trim(), "yyyy-MM-dd HH:mm:ss", { zone: timezone }).plus({hours:1})
timestamp = timestamp.setZone(timezone, { keepLocalTime: false })

if (timeseriesType === "Timestamp") {
seriesItem.timestamp = timestamp.toISO()
seriesItem.datetime = timestamp.toFormat("yyyy-MM-dd HH:mm:ss")
} else if (timeseriesType === "Date") {
seriesItem.date = timestamp.toFormat("yyyy-MM-dd")
}

returnVar.push(seriesItem)
})

Expand All @@ -105,12 +119,22 @@ function processAVError(error) {
}
}

function createEnum(values) {
const enumObject = {}
for (const val of values) {
enumObject[val] = val
}
return Object.freeze(enumObject)
}

const timeseriesType = createEnum(["Date", "Timestamp"])

module.exports = {
setClient,
mapData,
mapQuoteObj,
mapSeriesObj,
timeseriesType,
mapSeriesArray,
processAVError
}
10 changes: 5 additions & 5 deletions test/alphavantage-core-stock-daily_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ describe("Node: alphavantage-core-stock-daily", function () {

try {
msg.payload.should.have.propertyByPath("data", "output_size").eql("Compact")
msg.payload.should.have.property("series").should.not.have.keys("2022-07-12 00:00:00")
msg.payload.series.should.not.have.keys("2022-07-13")
msg.payload.should.have.property("seriesArray").length(3)

done()
Expand Down Expand Up @@ -548,7 +548,7 @@ describe("Node: alphavantage-core-stock-daily", function () {

try {
msg.payload.should.have.propertyByPath("data", "output_size").eql("Compact")
msg.payload.series.should.not.have.keys("2022-07-13 01:00:00")
msg.payload.series.should.not.have.keys("2022-07-13")
msg.payload.should.have.property("seriesArray").length(3)

done()
Expand Down Expand Up @@ -589,7 +589,7 @@ describe("Node: alphavantage-core-stock-daily", function () {

try {
msg.payload.should.have.propertyByPath("data", "output_size").eql("Compact")
msg.payload.series.should.not.have.keys("2022-07-13 01:00:00")
msg.payload.series.should.not.have.keys("2022-07-13")
msg.payload.should.have.property("seriesArray").length(3)

done()
Expand Down Expand Up @@ -637,7 +637,7 @@ describe("Node: alphavantage-core-stock-daily", function () {

try {
msg.payload.should.have.propertyByPath("data", "output_size").eql("Full size")
msg.payload.series.should.have.keys("2022-07-13 01:00:00")
msg.payload.series.should.have.keys("2022-07-13")
msg.payload.should.have.property("seriesArray").length(4)

done()
Expand Down Expand Up @@ -684,7 +684,7 @@ describe("Node: alphavantage-core-stock-daily", function () {

try {
msg.payload.should.have.propertyByPath("data", "output_size").eql("Full size")
msg.payload.series.should.have.keys("2022-07-13 01:00:00")
msg.payload.series.should.have.keys("2022-07-13")
msg.payload.should.have.property("seriesArray").length(4)

done()
Expand Down
44 changes: 24 additions & 20 deletions test/alphavantage-core-stock-quote_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,16 +195,18 @@ describe("Node: alphavantage-core-stock-quote", function () {

try {

msg.payload.should.have.property("symbol", "MSFT")
msg.payload.should.have.property("open", 259.75)
msg.payload.should.have.property("high", 260.84)
msg.payload.should.have.property("low", 253.3)
msg.payload.should.have.property("price", 254.25)
msg.payload.should.have.property("volume", 20957772)
msg.payload.should.have.property("latest_trading_day", "2022-07-18")
msg.payload.should.have.property("prev_close", 256.72)
msg.payload.should.have.property("change", -2.47)
msg.payload.should.have.property("change_percent", -0.009621)
msg.should.have.property("payload", {
"symbol": "MSFT",
"open": 259.75,
"high": 260.84,
"low": 253.3,
"price": 254.25,
"volume": 20957772,
"latest_trading_day": "2022-07-18",
"prev_close": 256.72,
"change": -2.47,
"change_percent": -0.009621
})

done()
} catch(err) {
Expand Down Expand Up @@ -241,16 +243,18 @@ describe("Node: alphavantage-core-stock-quote", function () {

try {

msg.payload.should.have.property("symbol", "MSFT")
msg.payload.should.have.property("open", 259.75)
msg.payload.should.have.property("high", 260.84)
msg.payload.should.have.property("low", 253.3)
msg.payload.should.have.property("price", 254.25)
msg.payload.should.have.property("volume", 20957772)
msg.payload.should.have.property("latest_trading_day", "2022-07-18")
msg.payload.should.have.property("prev_close", 256.72)
msg.payload.should.have.property("change", -2.47)
msg.payload.should.have.property("change_percent", -0.009621)
msg.should.have.property("payload", {
"symbol": "MSFT",
"open": 259.75,
"high": 260.84,
"low": 253.3,
"price": 254.25,
"volume": 20957772,
"latest_trading_day": "2022-07-18",
"prev_close": 256.72,
"change": -2.47,
"change_percent": -0.009621
})

done()
} catch(err) {
Expand Down

0 comments on commit 9d96dd8

Please sign in to comment.