New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

binary-indicators

Package Overview
Dependencies
Maintainers
2
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

binary-indicators - npm Package Compare versions

Comparing version 1.4.1 to 1.5.0

lib/macd-data.js

38

lib/exponentialMovingAverage.js

@@ -8,21 +8,20 @@ 'use strict';

var _binaryUtils = require('binary-utils');
var _math = require('./math');
var ema = function ema(vals, periods) {
if (vals.length === 1) {
return vals[0];
}
var prev = ema(vals.slice(0, vals.length - 1), periods);
return (vals.slice(-1)[0] - prev) * (0, _math.weightingMultiplier)(periods) + prev;
};
var exponentialMovingAverage = function exponentialMovingAverage(data, config) {
var initVal = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
var periods = config.periods;
var field = config.field;
var _config$pipSize = config.pipSize;
var pipSize = _config$pipSize === undefined ? 2 : _config$pipSize;
var weightingMultiplier = 2 / (periods + 1);
var vals = (0, _math.takeField)(data, field);
if (initVal) {
return (vals[0] - initVal) * weightingMultiplier + initVal;
}
if (data.length < periods) {

@@ -32,5 +31,7 @@ throw new Error('Periods longer than data length');

var vals = (0, _math.takeLast)(data, periods, field);
var meanVal = (0, _math.mean)((0, _math.takeField)(data.slice(0, periods), field));
return ema(vals, periods);
return +vals.slice(periods).reduce(function (prev, e) {
return (e - prev) * weightingMultiplier + prev;
}, meanVal).toFixed(pipSize);
};

@@ -40,7 +41,8 @@

var periods = config.periods;
var _config$pipSize = config.pipSize;
var pipSize = _config$pipSize === undefined ? 2 : _config$pipSize;
return (0, _binaryUtils.sequence)(data.length - periods + 1).map(function (x, i) {
return +exponentialMovingAverage(data.slice(i, i + periods), config).toFixed(pipSize);
var initVal = exponentialMovingAverage(data.slice(0, periods), config);
return data.slice(periods - 1).map(function (x, i) {
return !i ? initVal : initVal = exponentialMovingAverage([x], config, initVal);
});

@@ -47,0 +49,0 @@ };

@@ -7,4 +7,47 @@ 'use strict';

exports.default = function (data, config) {
// TODO
};
var _math = require('./math');
var _simpleMovingAverage = require('./simpleMovingAverage');
var _exponentialMovingAverage = require('./exponentialMovingAverage');
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
var paddingLeft = function paddingLeft(data, length) {
var arr = [];
arr.length = length - data.length;
arr.fill(0);
return [].concat(arr, _toConsumableArray(data));
};
var macdArray = function macdArray(data, config) {
var field = config.field;
var _config$fastEmaPeriod = config.fastEmaPeriod;
var fastEmaPeriod = _config$fastEmaPeriod === undefined ? 12 : _config$fastEmaPeriod;
var _config$slowEmaPeriod = config.slowEmaPeriod;
var slowEmaPeriod = _config$slowEmaPeriod === undefined ? 26 : _config$slowEmaPeriod;
var _config$signalSmaPeri = config.signalSmaPeriod;
var signalSmaPeriod = _config$signalSmaPeri === undefined ? 9 : _config$signalSmaPeri;
var _config$pipSize = config.pipSize;
var pipSize = _config$pipSize === undefined ? 2 : _config$pipSize;
var vals = (0, _math.takeField)(data, field);
var length = vals.length;
var fastEmaArray = paddingLeft((0, _exponentialMovingAverage.exponentialMovingAverageArray)(vals, { periods: fastEmaPeriod, pipSize: pipSize, field: field }), length);
var slowEmaArray = paddingLeft((0, _exponentialMovingAverage.exponentialMovingAverageArray)(vals, { periods: slowEmaPeriod, pipSize: pipSize, field: field }), length);
var macdCalcArray = paddingLeft(slowEmaArray.map(function (x, i) {
return +(fastEmaArray[i] - x).toFixed(pipSize);
}), length);
var smaArray = paddingLeft((0, _simpleMovingAverage.simpleMovingAverageArray)(macdCalcArray.slice(slowEmaPeriod - 1), { periods: signalSmaPeriod, pipSize: pipSize }), length);
return macdCalcArray.map(function (x, i) {
return [+(x - smaArray[i]).toFixed(pipSize), x, smaArray[i]];
});
};
exports.default = macdArray;

@@ -22,6 +22,2 @@ "use strict";

var weightingMultiplier = exports.weightingMultiplier = function weightingMultiplier(periods) {
return 2 / (periods + 1);
};
var mean = exports.mean = function mean(data) {

@@ -28,0 +24,0 @@ return data.reduce(function (a, b) {

{
"name": "binary-indicators",
"version": "1.4.1",
"version": "1.5.0",
"description": "Binary.com Indicators",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -10,5 +10,4 @@ import exponentialMovingAverage, { exponentialMovingAverageArray } from '../exponentialMovingAverage';

it('whole data sample', () => {
const result = exponentialMovingAverage([1, 2, 3], { periods: 3 });
// const roundedResult = roundResult(result);
expect(result).toEqual(2.25);
const result = exponentialMovingAverage([1, 2, 3, 4, 5, 6], { periods: 3 });
expect(result).toEqual(5);
});

@@ -19,3 +18,3 @@

const result = exponentialMovingAverageArray(data, { periods: 3 });
expect(result).toEqual([2.25, 3.25, 4.25]);
expect(result).toEqual([2, 3, 4]);
});

@@ -27,5 +26,5 @@

23.87, 23.65, 23.19, 23.10, 23.33, 22.68, 23.10, 22.40, 22.17];
const ema10days = [22.25, 22.22, 22.24, 22.28, 22.34, 22.52, 22.81,
23.01, 23.13, 23.29, 23.33, 23.45, 23.53, 23.58, 23.61,
23.61, 23.52, 23.38, 23.34, 23.13, 22.98];
const ema10days = [22.22, 22.21, 22.24, 22.27, 22.33, 22.52, 22.79,
22.97, 23.13, 23.28, 23.34, 23.43, 23.51, 23.53, 23.47, 23.4,
23.39, 23.26, 23.23, 23.08, 22.91];
const result = exponentialMovingAverageArray(data, { periods: 10 });

@@ -32,0 +31,0 @@ const roundedResult = result.map(x => Math.round(x * 100) / 100);

@@ -1,31 +0,19 @@

import macd, { macdArray } from '../relativeStrengthIndex';
import macdArray from '../macd';
import { data, histogram, macd, signal } from '../macd-data';
describe('macd', () => {
it.skip('single value with periods of 1 equals the value', () => {
const result = macd([1], { periods: 1 });
expect(result).toEqual(1);
});
it('real world', () => {
const result = macdArray(data, { fastEmaPeriod: 12, slowEmaPeriod: 26, signalSmaPeriod: 9 }).slice(-100);
const expectedHistogram = histogram.slice(-100);
const expectedMacd = macd.slice(-100);
const expectedSignal = signal.slice(-100);
it.skip('whole data sample', () => {
const result = macd([1, 2, 3], { periods: 3 });
// const roundedResult = roundResult(result);
expect(result).toEqual(1);
});
const diff = result.reduce((p2, val, i) =>
p2 + Math.abs(val[0] - expectedHistogram[i]) +
Math.abs(val[1] - expectedMacd[i]) +
Math.abs(val[2] - expectedSignal[i])
, 0);
it.skip('wuut2', () => {
const data = [1, 2, 3, 4, 5];
const result = macd(data, { periods: 3 });
expect(result).toEqual([1, 1.5, 2.25, 3.125, 4.063]);
expect(parseInt((diff / (3 * 100)) * 10, 10)).toEqual(0); // expect diff to be less than 0.1 for each sample
});
it.skip('real world', () => {
const data = [22.27, 22.19, 22.08, 22.17, 22.18, 22.13, 22.23, 22.43, 22.24, 22.29,
22.15, 22.39, 22.38, 22.61, 23.36, 24.05, 23.75, 23.83, 23.95, 23.63, 23.82,
23.87, 23.65, 23.19, 23.10, 23.33, 22.68, 23.10, 22.40, 22.17];
const ema10days = [22.22, 22.21, 22.24, 22.27, 22.33, 22.52, 22.80, 22.97, 23.13,
23.28, 23.34, 23.43, 23.51, 23.54, 23.47, 23.40, 23.39, 23.26, 23.23, 23.08, 22.92];
const result = macdArray(data, { periods: 10 });
const roundedResult = result.map(x => Math.round(x * 100) / 100);
expect(roundedResult).toEqual(ema10days);
});
});

@@ -1,2 +0,2 @@

import { mean, stddev, sum, takeLast, weightingMultiplier } from '../math';
import { mean, stddev, sum, takeLast, takeField } from '../math';

@@ -32,6 +32,5 @@ describe('math', () => {

it('weightingMultiplier', () => {
expect(weightingMultiplier(10)).toBeCloseTo(0.1818);
expect(weightingMultiplier(20)).toBeCloseTo(0.0952);
it('takeField', () => {
expect(takeLast([{ close: 123 }, { close: 321 }], 2, 'close')).toEqual([123, 321]);
});
});

@@ -1,3 +0,2 @@

import { sequence } from 'binary-utils';
import { takeLast, weightingMultiplier } from './math';
import { takeField, mean } from './math';

@@ -12,14 +11,12 @@ type CandleField = 'open' | 'high' | 'low' | 'close';

const ema = (vals: [], periods: number) => {
if (vals.length === 1) {
return vals[0];
}
const exponentialMovingAverage = (data: Candle[], config: ExponentialMovingAverageConfig, initVal: number = 0): number => {
const { periods, field, pipSize = 2 } = config;
const prev = ema(vals.slice(0, vals.length - 1), periods);
const weightingMultiplier = (2 / (periods + 1));
return (vals.slice(-1)[0] - prev) * weightingMultiplier(periods) + prev;
};
const vals = takeField(data, field);
const exponentialMovingAverage = (data: Candle[], config: ExponentialMovingAverageConfig): number => {
const { periods, field } = config;
if (initVal) {
return ((vals[0] - initVal) * weightingMultiplier + initVal);
}

@@ -30,15 +27,19 @@ if (data.length < periods) {

const vals = takeLast(data, periods, field);
const meanVal = mean(takeField(data.slice(0, periods), field));
return ema(vals, periods);
return +(vals.slice(periods)
.reduce((prev, e) => (e - prev) * weightingMultiplier + prev, meanVal)).toFixed(pipSize);
};
export const exponentialMovingAverageArray = (data: Candle[], config: ExponentialMovingAverageConfig): number[] => {
const { periods, pipSize = 2 } = config;
return sequence(data.length - periods + 1)
.map((x, i) =>
+(exponentialMovingAverage(data.slice(i, i + periods), config).toFixed(pipSize))
);
const { periods } = config;
let initVal = exponentialMovingAverage(data.slice(0, periods), config);
return data.slice(periods - 1).map((x, i) =>
!i ? initVal :
(initVal = exponentialMovingAverage([x], config, initVal))
);
};
export default exponentialMovingAverage;

@@ -1,8 +0,42 @@

type MomentumConfig = {
periods: number,
field: 'open' | 'high' | 'low' | 'close',
import { takeField } from './math';
import { simpleMovingAverageArray } from './simpleMovingAverage';
import { exponentialMovingAverageArray } from './exponentialMovingAverage';
type CandleField = 'open' | 'high' | 'low' | 'close';
type MacdConfig = {
fastEmaPeriod: number,
slowEmaPeriod: number,
signalSmaPeriod: number,
field?: CandleField,
pipSize: number,
};
export default (data: Candle[], config: MomentumConfig) => {
// TODO
type MacdEntry = number[];
const paddingLeft = (data: any[], length: number): any[] => {
const arr = [];
arr.length = length - data.length;
arr.fill(0);
return [...arr, ...data];
};
const macdArray = (data: Candle[], config: MacdConfig): MacdEntry[] => {
const { field, fastEmaPeriod = 12, slowEmaPeriod = 26, signalSmaPeriod = 9, pipSize = 2 } = config;
const vals = takeField(data, field);
const length = vals.length;
const fastEmaArray = paddingLeft(exponentialMovingAverageArray(vals, { periods: fastEmaPeriod, pipSize, field }), length);
const slowEmaArray = paddingLeft(exponentialMovingAverageArray(vals, { periods: slowEmaPeriod, pipSize, field }), length);
const macdCalcArray = paddingLeft(slowEmaArray.map((x, i) => +(fastEmaArray[i] - x).toFixed(pipSize)), length);
const smaArray = paddingLeft(simpleMovingAverageArray(macdCalcArray.slice(slowEmaPeriod - 1), { periods: signalSmaPeriod, pipSize }), length);
return macdCalcArray.map((x, i) =>
[+(x - smaArray[i]).toFixed(pipSize), x, smaArray[i]]);
};
export default macdArray;

@@ -11,5 +11,2 @@ export const takeField = (arr: any[], field?: string): any[] =>

export const weightingMultiplier = (periods: number): number =>
(2 / (periods + 1));
export const mean = (data: number[]): number =>

@@ -16,0 +13,0 @@ data.reduce((a, b) => a + b) / data.length;

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc