generated from bennycode/ts-node-starter
-
-
Notifications
You must be signed in to change notification settings - Fork 94
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(CCI,MAD): Add Commodity Channel Index (CCI) & Mean Absolute Devi…
…ation (MAD) (#355)
- Loading branch information
Showing
30 changed files
with
350 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import {CCI} from './CCI'; | ||
import {NotEnoughDataError} from '../error'; | ||
|
||
describe('CCI', () => { | ||
// Test data verified with: | ||
// https://tulipindicators.org/cci | ||
const candles = [ | ||
{close: 83.61, high: 83.85, low: 83.07}, | ||
{close: 83.15, high: 83.9, low: 83.11}, | ||
{close: 82.84, high: 83.33, low: 82.49}, | ||
{close: 83.99, high: 84.3, low: 82.3}, | ||
{close: 84.55, high: 84.84, low: 84.15}, | ||
{close: 84.36, high: 85.0, low: 84.11}, | ||
{close: 85.53, high: 85.9, low: 84.03}, | ||
{close: 86.54, high: 86.58, low: 85.39}, | ||
{close: 86.89, high: 86.98, low: 85.76}, | ||
{close: 87.77, high: 88.0, low: 87.17}, | ||
{close: 87.29, high: 87.87, low: 87.01}, | ||
]; | ||
let expectations: string[] = []; | ||
|
||
beforeEach(() => { | ||
expectations = ['166.67', '82.02', '95.50', '130.91', '99.16', '116.34', '71.93']; | ||
}); | ||
|
||
describe('getResult', () => { | ||
it('calculates the Commodity Channel Index (CCI)', () => { | ||
const cci = new CCI(5); | ||
for (const candle of candles) { | ||
cci.update(candle); | ||
if (cci.isStable) { | ||
const expected = expectations.shift(); | ||
expect(cci.getResult().toFixed(2)).toBe(expected!); | ||
} | ||
} | ||
const actual = cci.getResult().toFixed(2); | ||
expect(actual).toBe('71.93'); | ||
}); | ||
|
||
it('throws an error when there is not enough input data', () => { | ||
const cci = new CCI(5); | ||
try { | ||
cci.getResult(); | ||
fail('Expected error'); | ||
} catch (error) { | ||
expect(error).toBeInstanceOf(NotEnoughDataError); | ||
} | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import {BigIndicatorSeries} from '../Indicator'; | ||
import {Big, BigSource} from 'big.js'; | ||
import {HighLowClose} from '../util'; | ||
import {SMA} from '../SMA/SMA'; | ||
import {MAD} from '../MAD/MAD'; | ||
|
||
/** | ||
* Commodity Channel Index (CCI) | ||
* Type: Momentum | ||
* | ||
* The Commodity Channel Index (CCI), developed by Donald Lambert in 1980, compares the current mean price with the average mean price over a period of time. Approximately 70 to 80 percent of CCI values are between −100 and +100, which makes it an oscillator. Values above +100 imply an overbought condition, while values below −100 imply an oversold condition. | ||
* | ||
* According to [Investopia.com](https://www.investopedia.com/articles/active-trading/031914/how-traders-can-utilize-cci-commodity-channel-index-trade-stock-trends.asp#multiple-timeframe-cci-strategy), traders often buy when the CCI dips below -100 and then rallies back above -100 to sell the security when it moves above +100 and then drops back below +100. | ||
* | ||
* @see https://en.wikipedia.org/wiki/Commodity_channel_index | ||
*/ | ||
export class CCI extends BigIndicatorSeries { | ||
public readonly prices: BigSource[] = []; | ||
protected result?: Big; | ||
private readonly sma: SMA; | ||
private readonly typicalPrices: Big[] = []; | ||
|
||
constructor(public readonly interval: number) { | ||
super(); | ||
this.sma = new SMA(this.interval); | ||
} | ||
|
||
get isStable(): boolean { | ||
return this.result !== undefined; | ||
} | ||
|
||
update(candle: HighLowClose): void | Big { | ||
const typicalPrice = this.cacheTypicalPrice(candle); | ||
this.sma.update(typicalPrice); | ||
if (this.sma.isStable) { | ||
const mean = this.sma.getResult(); | ||
const meanDeviation = MAD.getResultFromBatch(this.typicalPrices, mean); | ||
const a = typicalPrice.minus(mean); | ||
const b = new Big(0.015).mul(meanDeviation); | ||
return this.setResult(a.div(b)); | ||
} | ||
} | ||
|
||
private cacheTypicalPrice({high, low, close}: HighLowClose): Big { | ||
const typicalPrice = new Big(high).plus(low).plus(close).div(3); | ||
this.typicalPrices.push(typicalPrice); | ||
if (this.typicalPrices.length > this.interval) { | ||
this.typicalPrices.shift(); | ||
} | ||
return typicalPrice; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.