Skip to content

Commit

Permalink
Triple Exponential Average (TRIX) is added. (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
cinar authored Jan 23, 2022
1 parent 5d4bf02 commit c9aa59c
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 47 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ The following list of indicators are currently supported by this package:
- [Random Index (KDJ)](src/indicator/trend/index.md#random-index-kdj)
- [Simple Moving Average (SMA)](src/indicator/trend/index.md#simple-moving-average-sma)
- [Since Change](src/indicator/trend/index.md#since-change)
- [Triangular Moving Average (TRIMA)](src/indicator/trend/index.md#triangular-moving-average-trima)
- [Triple Exponential Moving Average (TEMA)](src/indicator/trend/index.md#triple-exponential-moving-average-tema)
- [Triangular Moving Average (TRIMA)](src/indicator/trend/index.md#triangular-moving-average-trima)
- [Triple Exponential Average (TRIX)](#triple-exponential-average-trix)
- [Typical Price](src/indicator/trend/index.md#typical-price)
- [Vortex Indicator](src/indicator/trend/index.md#vortex-indicator)

Expand Down
9 changes: 9 additions & 0 deletions src/helper/numArray.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,15 @@ describe('Number Array', () => {
deepStrictEqual(actual, expected);
});

it('should be able to shift and fill values', () => {
const values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const expected = [1, 1, 1, 2, 3, 4, 5, 6, 7, 8];
const n = 2;

const actual = NumArray.shiftRightAndFillBy(n, values[0], values);
deepStrictEqual(actual, expected);
});

it('should be able to shift values', () => {
const values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const expected = [0, 0, 1, 2, 3, 4, 5, 6, 7, 8];
Expand Down
23 changes: 19 additions & 4 deletions src/helper/numArray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,17 +163,22 @@ export function substractBy(n: number, values: number[]): number[] {
}

/**
* Shifts values right by given amount.
* Shift values right by given amount and fill with value.
* @param n shift amount.
* @param fill fill value.
* @param values values array.
* @return shifted values.
* @returns shifted and filled values.
*/
export function shiftRightBy(n: number, values: number[]): number[] {
export function shiftRightAndFillBy(
n: number,
fill: number,
values: number[]
): number[] {
const result = new Array<number>(values.length);

for (let i = 0; i < result.length; i++) {
if (i < n) {
result[i] = 0;
result[i] = fill;
} else {
result[i] = values[i - n];
}
Expand All @@ -182,6 +187,16 @@ export function shiftRightBy(n: number, values: number[]): number[] {
return result;
}

/**
* Shifts values right by given amount.
* @param n shift amount.
* @param values values array.
* @return shifted values.
*/
export function shiftRightBy(n: number, values: number[]): number[] {
return shiftRightAndFillBy(n, 0, values);
}

/**
* Change between the current value and the value n before.
* @param n shift amount.
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export * from './indicator/trend/since';
export * from './indicator/trend/sma';
export * from './indicator/trend/tema';
export * from './indicator/trend/trima';
export * from './indicator/trend/trix';
export * from './indicator/trend/typicalPrice';
export * from './indicator/trend/vortex';
export * from './indicator/volatility/accelerationBands';
Expand Down
69 changes: 31 additions & 38 deletions src/indicator/trend/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ Trend indicators measure the direction and strength of a trend.
- [Aroon Indicator](#aroon-indicator)
- [Balance of Power (BOP)](trend_indicators.md#balance-of-power-bop)
- [Chande Forecast Oscillator (CFO)](#chande-forecast-oscillator-cfo)
- [Community Channel Index (CMI)](#community-channel-index-cmi)
- [Double Exponential Moving Average (DEMA)](#double-exponential-moving-average-dema)
- [Exponential Moving Average (EMA)](#exponential-moving-average-ema)
- [Moving Average Convergence Divergence (MACD)](#moving-average-convergence-divergence-macd)
Expand All @@ -18,8 +17,9 @@ Trend indicators measure the direction and strength of a trend.
- [Random Index (KDJ)](#random-index-kdj)
- [Simple Moving Average (SMA)](#simple-moving-average-sma)
- [Since Change](#since-change)
- [Triangular Moving Average (TRIMA)](#triangular-moving-average-trima)
- [Triple Exponential Moving Average (TEMA)](#triple-exponential-moving-average-tema)
- [Triangular Moving Average (TRIMA)](#triangular-moving-average-trima)
- [Triple Exponential Average (TRIX)](#triple-exponential-average-trix)
- [Typical Price](#typical-price)
- [Vortex Indicator](#vortex-indicator)

Expand Down Expand Up @@ -88,30 +88,6 @@ import {chandeForecastOscillator} from 'indicatorts';
const cfo = chandeForecastOscillator(closings);
```

#### Community Channel Index (CMI)

The [communityChannelIndex](./communityChannelIndex.ts) is a momentum-based oscillator used to help determine when an investment vehicle is reaching a condition of being overbought or oversold.

```
Moving Average = Sma(Period, Typical Price)
Mean Deviation = Sma(Period, Abs(Typical Price - Moving Average))
CMI = (Typical Price - Moving Average) / (0.015 * Mean Deviation)
```

```TypeScript
import {communityChannelIndex} from 'indicatorts';

const result = communityChannelIndex(period, highs, lows, closings);
```

The [defaultCommunityChannelIndex](./communityChannelIndex.ts) calculates with the period of 20.

```TypeScript
import {defaultCommunityChannelIndex} from 'indicatorts';

const result = defaultCommunityChannelIndex(highs, lows, closings);
```

#### Double Exponential Moving Average (DEMA)

The [dema](./dema.ts) function calculates the Double Exponential Moving Average (DEMA) for a given period.
Expand Down Expand Up @@ -278,6 +254,27 @@ import {since} from 'indicatorts';
const result = since(values);
```

#### Triple Exponential Moving Average (TEMA)

The [tema](./tema.ts) function calculates the Triple Exponential Moving Average (TEMA) for a given period.

The triple exponential moving average (TEMA) was designed to smooth value fluctuations, thereby making it easier to identify trends without the lag associated with traditional moving averages. It does this by taking multiple exponential moving averages (EMA) of the original EMA and subtracting out some of the lag.

```
TEMA = (3 * EMA1) - (3 * EMA2) + EMA3
EMA1 = EMA(values)
EMA2 = EMA(EMA1)
EMA3 = EMA(EMA2)
```

```TypeScript
import {tema} from 'indicatorts';

const result = tema(period, values);
```

Based on [Triple Exponential Moving Average (TEMA)](https://www.investopedia.com/terms/t/triple-exponential-moving-average.asp).

#### Triangular Moving Average (TRIMA)

The [trima](./trima.ts) function calculates the Triangular Moving Average (TRIMA) for a given period.
Expand All @@ -299,27 +296,23 @@ const result = trima(period, values);

Based on [Triangular Moving Average](https://tulipindicators.org/trima).

#### Triple Exponential Moving Average (TEMA)

The [tema](./tema.ts) function calculates the Triple Exponential Moving Average (TEMA) for a given period.
#### Triple Exponential Average (TRIX)

The triple exponential moving average (TEMA) was designed to smooth value fluctuations, thereby making it easier to identify trends without the lag associated with traditional moving averages. It does this by taking multiple exponential moving averages (EMA) of the original EMA and subtracting out some of the lag.
The [trix](./trix.ts) indicator is an oscillator used to identify oversold and overbought markets, and it can also be used as a momentum indicator. Like many oscillators, TRIX oscillates around a zero line.

```
TEMA = (3 * EMA1) - (3 * EMA2) + EMA3
EMA1 = EMA(values)
EMA2 = EMA(EMA1)
EMA3 = EMA(EMA2)
EMA1 = EMA(period, values)
EMA2 = EMA(period, EMA1)
EMA3 = EMA(period, EMA2)
TRIX = (EMA3 - Previous EMA3) / Previous EMA3
```

```TypeScript
import {tema} from 'indicatorts';
import {trix} from 'indicatorts';

const result = tema(period, values);
const result = trix(period, values);
```

Based on [Triple Exponential Moving Average (TEMA)](https://www.investopedia.com/terms/t/triple-exponential-moving-average.asp).

#### Typical Price

The [typicalPrice](./typicalPrice.ts) function calculates another approximation of average price for each period and can be used as a filter for moving average systems.
Expand Down
16 changes: 16 additions & 0 deletions src/indicator/trend/trix.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) 2022 Onur Cinar. All Rights Reserved.
// https://github.com/cinar/indicatorts

import { roundDigitsAll } from '../../helper/numArray';
import { trix } from './trix';

describe('Triple Exponential Average (TRIX)', () => {
it('should be able to compute TRIX', () => {
const values = [2, 4, 6, 8, 12, 14, 16, 18, 20];
const period = 4;
const expected = [0, 0.06, 0.17, 0.26, 0.33, 0.33, 0.3, 0.25, 0.21];

const actual = trix(period, values);
expect(roundDigitsAll(2, actual)).toStrictEqual(expected);
});
});
29 changes: 29 additions & 0 deletions src/indicator/trend/trix.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2022 Onur Cinar. All Rights Reserved.
// https://github.com/cinar/indicatorts

import { divide, shiftRightAndFillBy, substract } from '../../helper/numArray';
import { ema } from './ema';

/**
* Triple Exponential Average (TRIX) indicator is an oscillator used to
* identify oversold and overbought markets, and it can also be used
* as a momentum indicator. Like many oscillators, TRIX oscillates
* around a zero line.
*
* EMA1 = EMA(period, values)
* EMA2 = EMA(period, EMA1)
* EMA3 = EMA(period, EMA2)
* TRIX = (EMA3 - Previous EMA3) / Previous EMA3
*
* @param period window period.
* @param values values array.
* @returns trix values.
*/
export function trix(period: number, values: number[]): number[] {
const ema1 = ema(period, values);
const ema2 = ema(period, ema1);
const ema3 = ema(period, ema2);
const previous = shiftRightAndFillBy(1, ema3[0], ema3);
const trix = divide(substract(ema3, previous), previous);
return trix;
}
6 changes: 2 additions & 4 deletions src/indicator/volume/volumePriceTrend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import {
divide,
multiply,
shiftRightBy,
shiftRightAndFillBy,
substract,
} from '../../helper/numArray';
import { msum } from '../trend/msum';
Expand All @@ -23,9 +23,7 @@ export function volumePriceTrend(
closings: number[],
volumes: number[]
): number[] {
const previousClosings = shiftRightBy(1, closings);
// TODO: Consider changing shiftRightBy to fill with last value.
previousClosings[0] = closings[0];
const previousClosings = shiftRightAndFillBy(1, closings[0], closings);
const vpt = multiply(
volumes,
divide(substract(closings, previousClosings), previousClosings)
Expand Down

0 comments on commit c9aa59c

Please sign in to comment.