Repository: cinar/indicatorts (ts)

Issue:
ATR is calculated wrongly
**Describe the bug**
ATR is calculated wrongly

`Function atr (average true range) returns the RMA of true range. True range is max(high - low, abs(high - close[1]), abs(low - close[1])).`

whereas this library is subtracting values from the same day

**Expected behavior**
The close prices should taken from close price from previous day. 


Pull request description:
Fix True Range calculation.
# Describe Request

Fixing the way True Range is getting calculated.

Fixed #422 

# Change Type

Bug Fix


Patch:
diff --git a/.prettierrc.json b/.prettierrc.json
index 544138b..c1a6f66 100644
--- a/.prettierrc.json
+++ b/.prettierrc.json
@@ -1,3 +1,4 @@
 {
-  "singleQuote": true
+  "singleQuote": true,
+  "trailingComma": "es5"
 }
diff --git a/src/indicator/momentum/index.md b/src/indicator/momentum/index.md
index 10542d0..0da909c 100644
--- a/src/indicator/momentum/index.md
+++ b/src/indicator/momentum/index.md
@@ -138,7 +138,7 @@ const result = defaultPercentageVolumeOscillator(volumes);
 
 #### Price Rate of Change (ROC)
 
-The [roc](./priceRateOfChange.ts) function calculates a unbounded momentum indicator for the closing prices. A rising ROC above zero typically indicates an uptrend whereas a falling ROC below zero indicates a downtrend. 
+The [roc](./priceRateOfChange.ts) function calculates a unbounded momentum indicator for the closing prices. A rising ROC above zero typically indicates an uptrend whereas a falling ROC below zero indicates a downtrend.
 
 ```
 ROC[i] = 0 when i < period
diff --git a/src/indicator/volatility/atr.ts b/src/indicator/volatility/atr.ts
index 4b54594..b902fe7 100644
--- a/src/indicator/volatility/atr.ts
+++ b/src/indicator/volatility/atr.ts
@@ -1,7 +1,7 @@
 // Copyright (c) 2022 Onur Cinar. All Rights Reserved.
 // https://github.com/cinar/indicatorts
 
-import { checkSameLength, max, subtract } from '../../helper/numArray';
+import { tr } from './tr';
 import { sma } from '../../indicator/trend/sma';
 
 /**
@@ -32,14 +32,7 @@ export function atr(
   lows: number[],
   closings: number[]
 ): AtrResult {
-  checkSameLength(highs, lows, closings);
-
-  const trLine = max(
-    subtract(highs, lows),
-    subtract(highs, closings),
-    subtract(closings, lows)
-  );
-
+  const trLine = tr(period, highs, lows, closings);
   const atrLine = sma(period, trLine);
 
   return {
diff --git a/src/indicator/volatility/tr.ts b/src/indicator/volatility/tr.ts
new file mode 100644
index 0000000..5507c92
--- /dev/null
+++ b/src/indicator/volatility/tr.ts
@@ -0,0 +1,40 @@
+// Copyright (c) 2022 Onur Cinar. All Rights Reserved.
+// https://github.com/cinar/indicatorts
+
+import {
+  abs,
+  checkSameLength,
+  max,
+  shiftRightAndFillBy,
+  subtract,
+} from '../../helper/numArray';
+
+/**
+ * True Range (TR).
+ *
+ * TR = Max((High - Low), Abs(High - Closing[-1]), Abs(Low - Closing[-1]))
+ *
+ * @param period window period.
+ * @param highs high values.
+ * @param lows low values.
+ * @param closings closing values.
+ * @return tr values.
+ */
+export function tr(
+  period: number,
+  highs: number[],
+  lows: number[],
+  closings: number[]
+): number[] {
+  checkSameLength(highs, lows, closings);
+
+  const previous = shiftRightAndFillBy(1, closings[0], closings);
+
+  const result = max(
+    subtract(highs, lows),
+    abs(subtract(highs, previous)),
+    abs(subtract(lows, previous))
+  );
+
+  return result;
+}


Test patch:
diff --git a/src/indicator/momentum/priceRateOfChange.test.ts b/src/indicator/momentum/priceRateOfChange.test.ts
index a7d5267..e8665ea 100644
--- a/src/indicator/momentum/priceRateOfChange.test.ts
+++ b/src/indicator/momentum/priceRateOfChange.test.ts
@@ -1,9 +1,9 @@
-import { deepStrictEqual } from "assert";
-import { roundDigitsAll } from "../../helper/numArray";
-import { roc } from "./priceRateOfChange";
+import { deepStrictEqual } from 'assert';
+import { roundDigitsAll } from '../../helper/numArray';
+import { roc } from './priceRateOfChange';
 
-describe("Price Rate of Change (ROC)", () => {
-  it("should be able to compute ROC", () => {
+describe('Price Rate of Change (ROC)', () => {
+  it('should be able to compute ROC', () => {
     const values = [1, 3, 5, 4, 2, 5, 3];
     const expected = [0, 0, 0, 300, -33.33, 0, -25];
     const period = 3;
diff --git a/src/indicator/volatility/keltnerChannel.test.ts b/src/indicator/volatility/keltnerChannel.test.ts
index be8efd4..bc9e4b6 100644
--- a/src/indicator/volatility/keltnerChannel.test.ts
+++ b/src/indicator/volatility/keltnerChannel.test.ts
@@ -10,8 +10,8 @@ describe('Keltner Channel', () => {
     const lows = [6, 7, 9, 12, 10];
     const closings = [9, 11, 7, 10, 8];
     const expectedMiddleLine = [9, 9.19, 8.98, 9.08, 8.98];
-    const expectedUpperBand = [17, 17.19, 17.65, 17.58, 17.38];
-    const expectedLowerBand = [1, 1.19, 0.32, 0.58, 0.58];
+    const expectedUpperBand = [17, 15.19, 14.98, 17.08, 16.18];
+    const expectedLowerBand = [1, 3.19, 2.98, 1.08, 1.78];
 
     const actual = defaultKeltnerChannel(highs, lows, closings);
     expect(roundDigitsAll(2, actual.middleLine)).toStrictEqual(