remsed
Version:
A JavaScript cryptocurrency trading library with support for fairdesk.com
128 lines (123 loc) • 4.45 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var number = require('./number.js');
var errors = require('../errors.js');
// ----------------------------------------------------------------------------
//-------------------------------------------------------------------------
// converts timeframe to seconds
const parseTimeframe = (timeframe) => {
const amount = timeframe.slice(0, -1);
const unit = timeframe.slice(-1);
let scale = undefined;
if (unit === 'y') {
scale = 60 * 60 * 24 * 365;
}
else if (unit === 'M') {
scale = 60 * 60 * 24 * 30;
}
else if (unit === 'w') {
scale = 60 * 60 * 24 * 7;
}
else if (unit === 'd') {
scale = 60 * 60 * 24;
}
else if (unit === 'h') {
scale = 60 * 60;
}
else if (unit === 'm') {
scale = 60;
}
else if (unit === 's') {
scale = 1;
}
else {
throw new errors.NotSupported('timeframe unit ' + unit + ' is not supported');
}
return amount * scale;
};
const roundTimeframe = (timeframe, timestamp, direction = number.ROUND_DOWN) => {
const ms = parseTimeframe(timeframe) * 1000;
// Get offset based on timeframe in milliseconds
const offset = timestamp % ms;
return timestamp - offset + ((direction === number.ROUND_UP) ? ms : 0);
};
// given a sorted arrays of trades (recent last) and a timeframe builds an array of OHLCV candles
const buildOHLCVC = (trades, timeframe = '1m', since = -Infinity, limit = Infinity) => {
const ms = parseTimeframe(timeframe) * 1000;
const ohlcvs = [];
const [timestamp, /* open */ , high, low, close, volume, count] = [0, 1, 2, 3, 4, 5, 6];
const oldest = Math.min(trades.length - 1, limit);
for (let i = 0; i <= oldest; i++) {
const trade = trades[i];
if (trade.timestamp < since) {
continue;
}
const openingTime = Math.floor(trade.timestamp / ms) * ms; // shift to the edge of m/h/d (but not M)
const candle = ohlcvs.length - 1;
if (candle === -1 || openingTime >= ohlcvs[candle][timestamp] + ms) {
// moved to a new timeframe -> create a new candle from opening trade
ohlcvs.push([
openingTime,
trade.price,
trade.price,
trade.price,
trade.price,
trade.amount,
1, // count
]);
}
else {
// still processing the same timeframe -> update opening trade
ohlcvs[candle][high] = Math.max(ohlcvs[candle][high], trade.price);
ohlcvs[candle][low] = Math.min(ohlcvs[candle][low], trade.price);
ohlcvs[candle][close] = trade.price;
ohlcvs[candle][volume] += trade.amount;
ohlcvs[candle][count]++;
} // if
} // for
return ohlcvs;
};
const extractParams = (string) => {
const re = /{([\w-]+)}/g;
const matches = [];
let match = re.exec(string);
while (match) {
matches.push(match[1]);
match = re.exec(string);
}
return matches;
};
const implodeParams = (string, params) => {
if (!Array.isArray(params)) {
const keys = Object.keys(params);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (!Array.isArray(params[key])) {
string = string.replace('{' + key + '}', params[key]);
}
}
}
return string;
};
function vwap(baseVolume, quoteVolume) {
return ((baseVolume !== undefined) && (quoteVolume !== undefined) && (baseVolume > 0)) ? (quoteVolume / baseVolume) : undefined;
}
/* ------------------------------------------------------------------------ */
function aggregate(bidasks) {
const result = {};
for (let i = 0; i < bidasks.length; i++) {
const [price, volume] = bidasks[i];
if (volume > 0) {
result[price] = (result[price] || 0) + volume;
}
}
return Object.keys(result).map((price) => [parseFloat(price), parseFloat(result[price])]);
}
/* ------------------------------------------------------------------------ */
exports.aggregate = aggregate;
exports.buildOHLCVC = buildOHLCVC;
exports.extractParams = extractParams;
exports.implodeParams = implodeParams;
exports.parseTimeframe = parseTimeframe;
exports.roundTimeframe = roundTimeframe;
exports.vwap = vwap;