all files / technicalindicators/lib/momentum/ WilliamsR.js

97.92% Statements 47/48
93.75% Branches 15/16
100% Functions 5/5
97.92% Lines 47/48
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86                                  120× 120× 120×   52×     68× 68× 68× 68×         90×         90× 51×                   30× 30× 17×    
/**
 * Created by AAravindan on 5/11/16.
 */
 
"use strict"
 
const LinkedList = require('../Utils/FixedSizeLinkedList');
const nf         = require('../Utils/NumberFormatter');
 
let WilliamsR;
 
module.exports = WilliamsR = function(input) {
 
  let lows = input.low;
  let highs = input.high;
  let closes = input.close;
  let period = input.period;
  let format = input.format || nf;
 
  if(I!((lows.length === highs.length) && (highs.length === closes.length) )){
    throw ('Inputs(low,high, close) not of equal size');
  }
  this.result = [];
 
  //%R = (Highest High - Close)/(Highest High - Lowest Low) * -100
  //Lowest Low = lowest low for the look-back period
  //Highest High = highest high for the look-back period
  //%R is multiplied by -100 correct the inversion and move the decimal.
  this.generator = (function* (){
    let index = 1;
    let pastHighPeriods = new LinkedList(period, true, false);
    let pastLowPeriods = new LinkedList(period, false, true);
    let periodLow;
    let periodHigh;
    var tick = yield;
    let williamsR;
    while (true) {
      pastHighPeriods.push(tick.high);
      pastLowPeriods.push(tick.low);
      if(index < period){
        index++;
        tick = yield;
        continue;
      }
      periodLow = pastLowPeriods.periodLow;
      periodHigh= pastHighPeriods.periodHigh;
      williamsR = format((periodHigh - tick.close) / (periodHigh- periodLow) * -100);
      tick = yield williamsR;
    }
  })();
 
  this.generator.next();
 
  lows.forEach((low, index) => {
    var result = this.generator.next({
      high : highs[index],
      low  : lows[index],
      close : closes[index]
    });
    if(result.value !== undefined){
      this.result.push(result.value);
    }
  });
};
 
 WilliamsR.calculate = function(input) {
  if(input.reversedInput) {
    input.high.reverse();
    input.low.reverse();
    input.close.reverse();
  }
  let result = (new WilliamsR(input)).result;
  input.reversedInput ? result.reverse():undefined;
  return result;
};
 
WilliamsR.prototype.getResult = function () {
  return this.result;
};
 
WilliamsR.prototype.nextValue = function (input) {
  let nextResult = this.generator.next(input);
  if(nextResult.value !== undefined)
    return nextResult.value;
};