fme-free-barchart
Version:
API for fetching data from the Free Barchart API
182 lines (181 loc) • 8.09 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const fme_logger_1 = require("fme-logger");
var L = new fme_logger_1.Log("FreeBarchart");
const _m = require("moment-timezone");
const request = require("request-promise-native");
const fme_quotes_models_1 = require("fme-quotes-models");
function convert(x, type, interval) {
var obj = new fme_quotes_models_1.FmeQuote();
obj.symbol = x.symbol.toUpperCase();
obj.YYYYMMDD = _m(x.timestamp).format("YYYYMMDD");
obj.timeHHMM = _m(x.timestamp).format("HHmm");
obj.time = _m(x.timestamp).hours() * 60 + _m(x.timestamp).minutes();
obj.timestamp = x.timestamp;
obj.open = x.open;
obj.close = x.close;
obj.high = x.high;
obj.low = x.low;
obj.avg = (x.open + x.close + x.high + x.low) / 4;
obj.volume = x.volume;
obj.source = "barchart-free";
obj.decimalPoints = 2;
obj.interval = interval;
obj.type = type;
return obj;
}
class FreeBarchart {
//
// @KEY = FREE BARCHART KEY STRING
// @SYMBOL = BARCHART SYMBOL
// @FRAME = TIMEFRAME = "minute","day","week"
// @Interval = number (1,2,3) (combines with FRAME to complete the reqeust);
//
constructor(key, symbol, frame, interval, targetDate, startTime, endTime) {
this.key = key;
this.version = "1.0.0";
this.host = "marketdata.websol.barchart.com";
this.endpoint = "getHistory.json";
// symbol = "ES*1";
this.symbol = "SPY";
this.type = "minutes";
this.types = ["ticks", "minutes", "nearbyMinutes", "formTMinutes", "daily", "dailyNearest", "dailyContinue", "weekly", "weeklyNearest",
"weeklyContinue", "monthly", "monthlyNearest", "monthlyContinue", "quarterly", "quarterlyNearest", "quarterlyContinue", "yearly",
"yearlyNearest", "yearlyContinue"];
this.typesSingleDay = ["ticks", "minutes", "nearbyMinutes", "formTMinutes"];
this.interval = 1;
this.startTime = 9 * 60 + 30; // default startTime == 9:30;
this.endTime = 16 * 60 + 0; // default endTime = 4pm;
this.targetDate = new Date();
this.getDailyMinutes = () => __awaiter(this, void 0, void 0, function* () {
var type = this.type.trim().toLowerCase();
var symbol = this.symbol.trim().toLowerCase();
var startDate = _m(this.targetDate).format("YYYYMMDD");
var req = "/" + this.endpoint + "?key=" + this.key + "&symbol=" + this.symbol + "&type=" + type + "&startDate=" + startDate + "&interval=" + this.interval;
var fullUrl = "http://" + this.host + req;
L.info("requesting:", fullUrl);
try {
var results = yield request(fullUrl);
var rtn = JSON.parse(results).results;
if (!rtn) {
L.info("barchart did not return a value for date", startDate);
return null;
}
}
catch (err) {
L.error(err, results);
return;
}
L.info("Rtn is", rtn.length, rtn[rtn.length - 1]);
var filter = [];
if (this.typesSingleDay.indexOf(type) > -1) {
filter = rtn.filter((x) => { return _m(x.timestamp).format("YYYYMMDD") == startDate; }).map((a) => { return convert(a, type, this.interval); });
}
else {
filter = rtn.filter.map((a) => { return convert(a, type, this.interval); });
}
// L.info("filter length is",filter.length,filter[0],filter[filter.length-1]);
// return filter.filter((a) => {return a.time >= this.startTime && a.time <= this.endTime});
return filter.map((a) => { return convert(a, type, this.interval); });
});
this.symbol = symbol;
//
// => convert futures contract to dated contract based on target date
//
if (this.symbol.toLowerCase().indexOf("_f") > -1) {
var contract = new ContractConversion();
var expiry = 3;
if (symbol.toLowerCase().indexOf("cl") > -1)
expiry = 1;
this.symbol = this.symbol.toLowerCase().replace("_f", contract.findCode(targetDate, expiry));
}
this.type = frame.toLowerCase().trim();
if (startTime)
this.startTime == startTime;
if (endTime)
this.endTime == endTime;
this.targetDate = targetDate;
if (this.types.indexOf(this.type) == -1) {
L.error("Invalid type passed", this.types, "valid types are", JSON.stringify(this.types));
return;
}
if (!interval)
this.interval = 1;
else
this.interval = interval;
;
}
}
exports.FreeBarchart = FreeBarchart;
class Conversion {
constructor() {
this.inputSymbol = "SPY";
this.symbol = "spy";
this.exchange = "nyse";
this.timeAdjust = 0;
this.expiryLength = 3;
}
}
exports.Conversion = Conversion;
class ContractConversion {
constructor() {
this.codes = ["F", "G", "H", "J", "K", "M", "N", "Q", "U", "V", "X", "Z"];
this.rollOffset = 8; // number of days offset from expiration the roll is.
//
// => find codes
// Date: date to find code for
// Length: Number of Months between contract roll, only supports monthly (1) or quarterly(3);
//
this.findCode = (date, length) => {
if (length == 1) {
if (_m(date).date() > 20)
offset = 2;
else
offset = 2;
var month = _m(date).month() + offset;
return this.codes[month] + _m(date).format("YY");
}
if (length == 3) {
var quarter = _m(date).quarter();
; // quarter to find contract
L.info("We are in this quarter", quarter);
//
// add either 2 or 5 to this number to get the contract
// add 2 if the current date is before the expiration + rolloffset, else add 3.
//
var startOfMonth = _m(date).startOf("quarter").add(2, "months").clone();
var today = startOfMonth.day();
if (today == 6)
var inc = 3;
else
inc = 2;
var expiration = startOfMonth.day(5).add(inc, "weeks");
var rollover = expiration.clone().subtract(this.rollOffset, "days");
L.info("Date", _m(date).format("YYYYMMDD"), "rollover", rollover.format("YYYYMMDD"));
if (date >= rollover.toDate())
var offset = quarter * 3 + 2;
else
offset = quarter * 3 - 1;
//
// => take care of annual roll at the end of the year!
//
var annualOffset = 0;
if (offset > 11) {
offset = offset - 12;
annualOffset = 1;
}
L.info("expiration is", expiration.format("YYYYMMDD"), "roll over is", rollover.format("YYYYMMDD"), "offset is", offset);
return this.codes[offset] + _m(date).add(annualOffset, "years").format("YY");
}
};
}
}
exports.ContractConversion = ContractConversion;