Skip to content

Commit

Permalink
MFI indicator implementation and unit tests for #46
Browse files Browse the repository at this point in the history
  • Loading branch information
BusinessDuck committed Sep 19, 2024
1 parent 58fcb58 commit 31245b5
Show file tree
Hide file tree
Showing 33 changed files with 24,512 additions and 24,212 deletions.
2 changes: 1 addition & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ export { CircularBuffer } from './src/providers/circular-buffer';
export { Sampler } from './src/providers/sampler';
export { VolumeProfile } from './src/volume-profile'; /** BETA UNSTABLE */
export { ChaikinOscillator } from './src/chaikin';
// export { OrderBlock } from './src/order-block';
// export { OrderBlock } from './src/order-block';
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"test": "jest",
"version": "npm run build",
"postversion": "git push && git push --tags",
"prettier": "prettier --config './.prettierrc' --write 'src/**/*.ts'"
"prettier": "prettier --config './.prettierrc' --write './**/*.ts'"
},
"bugs": {
"url": "https://github.com/debut-js/Indicators/issues"
Expand Down
54 changes: 54 additions & 0 deletions src/mfi.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { CircularBuffer } from './providers/circular-buffer';

/**
* Money Flow Index (MFI) is a movement indicator used in technical analysis that looks at time and price
* to measure the trading pressure — buying or selling. It is also called volume-weighted
* Relative Strength Index (RSI), as it includes volume, unlike RSI, which only incorporates price.
*/
export class MFI {
private positiveMoneyFlowSum = 0;
private negativeMoneyFlowSum = 0;
private pevTypicalPrice = 0;
private posCircular: CircularBuffer;
private negCircular: CircularBuffer;

constructor(period = 14) {
this.posCircular = new CircularBuffer(period);
this.negCircular = new CircularBuffer(period);
}

nextValue(high: number, low: number, close: number, volume: number) {
const typicalPrice = (high + low + close) / 3;
const moneyFlow = typicalPrice * volume;

if (!this.pevTypicalPrice) {
this.pevTypicalPrice = typicalPrice;
return;
}

const positiveMoneyFlow = typicalPrice > this.pevTypicalPrice ? moneyFlow : 0;
const negativeMoneyFlow = typicalPrice < this.pevTypicalPrice ? moneyFlow : 0;

this.pevTypicalPrice = typicalPrice;
this.negativeMoneyFlowSum += negativeMoneyFlow;
this.positiveMoneyFlowSum += positiveMoneyFlow;

const posRedunant = this.posCircular.push(positiveMoneyFlow);
const negRedunant = this.negCircular.push(negativeMoneyFlow);

if (!this.posCircular.filled) {
return;
}

this.negativeMoneyFlowSum -= negRedunant || 0;
this.positiveMoneyFlowSum -= posRedunant || 0;

const moneyFlowRatio = this.positiveMoneyFlowSum / this.negativeMoneyFlowSum;

return 100 - 100 / (1 + moneyFlowRatio);
}

momentValue(high: number, low: number, close: number, volume: number) {
return 0;
}
}
5 changes: 2 additions & 3 deletions src/providers/max-value.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ export class MaxProvider {

const rmMax = this.highest.push(high);

// Most perf degrade case
if (rmMax === this.max && high !== this.max) {
// Most perf degrade case
if (rmMax === this.max && high !== this.max) {
// console.count('degrade_max');

this.max = getMax(this.highest.toArray());
Expand All @@ -37,4 +37,3 @@ export class MaxProvider {
return this.max > high ? this.max : high;
}
}

14 changes: 7 additions & 7 deletions src/stochastic-rsi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { MinProvider } from './providers/min-value';
import { RSI } from './rsi';

/**
* Developed by Tushar Chande and Stanley Kroll, StochRSI is an oscillator that measures the level of RSI relative
* to its high-low range over a set time period. StochRSI applies the Stochastics formula to RSI values, rather
* than price values, making it an indicator of an indicator. The result is an oscillator that
* fluctuates between 0 and 1.
* Developed by Tushar Chande and Stanley Kroll, StochRSI is an oscillator that measures the level of RSI relative
* to its high-low range over a set time period. StochRSI applies the Stochastics formula to RSI values, rather
* than price values, making it an indicator of an indicator. The result is an oscillator that
* fluctuates between 0 and 1.
*/
export class StochasticRSI {
private max: MaxProvider;
Expand All @@ -28,7 +28,7 @@ export class StochasticRSI {
* Get next value for closed candle
* affect all next calculations
*/
nextValue(close: number): { k: number, d: number, stochRsi: number } {
nextValue(close: number): { k: number; d: number; stochRsi: number } {
const rsi = this.rsi.nextValue(close);

if (rsi === undefined) {
Expand All @@ -37,7 +37,7 @@ export class StochasticRSI {

const max = this.max.nextValue(rsi);
const min = this.min.nextValue(rsi);

if (!this.max.filled()) {
return;
}
Expand All @@ -58,7 +58,7 @@ export class StochasticRSI {
* Get next value for non closed (tick) candle hlc
* does not affect any next calculations
*/
momentValue(close: number): { k: number, d: number, stochRsi: number} {
momentValue(close: number): { k: number; d: number; stochRsi: number } {
if (!this.max.filled()) {
return;
}
Expand Down
1 change: 0 additions & 1 deletion src/stochastic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ export class Stochastic {
const max = this.max.momentValue(high);
const min = this.min.momentValue(low);


const k: number = ((close - min) / (max - min)) * 100;
const d: number = this.sma.momentValue(k);

Expand Down
116 changes: 10 additions & 106 deletions tests/ac/excel-data.ts
Original file line number Diff line number Diff line change
@@ -1,112 +1,16 @@
export const highs = [
7150,
7169,
7278.2,
7410,
7500,
7520,
7535,
7588,
7584.6,
7598,
7647,
7592,
7598,
7660.5,
7668.4,
7773.4,
7791.55,
7809.95,
7796.7,
7751.95,
7822,
7848.95,
7800,
7839.9,
7790.15,
7687.3,
7670.7,
7629.9,
7743.5,
7769,
7926.8,
7962,
7996.5,
8021.9,
7980,
7952,
8029,
8035.15,
8037,
7950,
7874.45,
7949.95,
7789,
7817.5,
7770.6,
7912.2,
7933.55,
7909.9,
7939.4,
7891.8,
7898.1,
7957.8,
7150, 7169, 7278.2, 7410, 7500, 7520, 7535, 7588, 7584.6, 7598, 7647, 7592, 7598, 7660.5, 7668.4, 7773.4, 7791.55,
7809.95, 7796.7, 7751.95, 7822, 7848.95, 7800, 7839.9, 7790.15, 7687.3, 7670.7, 7629.9, 7743.5, 7769, 7926.8, 7962,
7996.5, 8021.9, 7980, 7952, 8029, 8035.15, 8037, 7950, 7874.45, 7949.95, 7789, 7817.5, 7770.6, 7912.2, 7933.55,
7909.9, 7939.4, 7891.8, 7898.1, 7957.8,
];

export const lows = [
7060,
6884.85,
7092.25,
7344.15,
7407,
7443,
7457.3,
7451.75,
7491.6,
7508,
7584.65,
7532.15,
7492,
7545.1,
7587.8,
7672.15,
7714,
7738.8,
7686.4,
7676.65,
7726.8,
7783.3,
7733.7,
7767.15,
7645,
7639,
7590.1,
7584.8,
7566,
7717.15,
7818.7,
7885.3,
7930.15,
7924,
7922,
7867.6,
7871.1,
7991,
7884,
7831.1,
7805.1,
7770.1,
7725,
7733,
7700.95,
7775,
7867.15,
7798.2,
7860.4,
7787.3,
7780.1,
7896,
]
7060, 6884.85, 7092.25, 7344.15, 7407, 7443, 7457.3, 7451.75, 7491.6, 7508, 7584.65, 7532.15, 7492, 7545.1, 7587.8,
7672.15, 7714, 7738.8, 7686.4, 7676.65, 7726.8, 7783.3, 7733.7, 7767.15, 7645, 7639, 7590.1, 7584.8, 7566, 7717.15,
7818.7, 7885.3, 7930.15, 7924, 7922, 7867.6, 7871.1, 7991, 7884, 7831.1, 7805.1, 7770.1, 7725, 7733, 7700.95, 7775,
7867.15, 7798.2, 7860.4, 7787.3, 7780.1, 7896,
];

export const aoValues = [
undefined,
Expand Down Expand Up @@ -161,4 +65,4 @@ export const aoValues = [
28.34868,
16.81946,
8.91114,
]
];
116 changes: 10 additions & 106 deletions tests/ao/excel-data.ts
Original file line number Diff line number Diff line change
@@ -1,112 +1,16 @@
export const highs = [
7150,
7169,
7278.2,
7410,
7500,
7520,
7535,
7588,
7584.6,
7598,
7647,
7592,
7598,
7660.5,
7668.4,
7773.4,
7791.55,
7809.95,
7796.7,
7751.95,
7822,
7848.95,
7800,
7839.9,
7790.15,
7687.3,
7670.7,
7629.9,
7743.5,
7769,
7926.8,
7962,
7996.5,
8021.9,
7980,
7952,
8029,
8035.15,
8037,
7950,
7874.45,
7949.95,
7789,
7817.5,
7770.6,
7912.2,
7933.55,
7909.9,
7939.4,
7891.8,
7898.1,
7957.8,
7150, 7169, 7278.2, 7410, 7500, 7520, 7535, 7588, 7584.6, 7598, 7647, 7592, 7598, 7660.5, 7668.4, 7773.4, 7791.55,
7809.95, 7796.7, 7751.95, 7822, 7848.95, 7800, 7839.9, 7790.15, 7687.3, 7670.7, 7629.9, 7743.5, 7769, 7926.8, 7962,
7996.5, 8021.9, 7980, 7952, 8029, 8035.15, 8037, 7950, 7874.45, 7949.95, 7789, 7817.5, 7770.6, 7912.2, 7933.55,
7909.9, 7939.4, 7891.8, 7898.1, 7957.8,
];

export const lows = [
7060,
6884.85,
7092.25,
7344.15,
7407,
7443,
7457.3,
7451.75,
7491.6,
7508,
7584.65,
7532.15,
7492,
7545.1,
7587.8,
7672.15,
7714,
7738.8,
7686.4,
7676.65,
7726.8,
7783.3,
7733.7,
7767.15,
7645,
7639,
7590.1,
7584.8,
7566,
7717.15,
7818.7,
7885.3,
7930.15,
7924,
7922,
7867.6,
7871.1,
7991,
7884,
7831.1,
7805.1,
7770.1,
7725,
7733,
7700.95,
7775,
7867.15,
7798.2,
7860.4,
7787.3,
7780.1,
7896,
]
7060, 6884.85, 7092.25, 7344.15, 7407, 7443, 7457.3, 7451.75, 7491.6, 7508, 7584.65, 7532.15, 7492, 7545.1, 7587.8,
7672.15, 7714, 7738.8, 7686.4, 7676.65, 7726.8, 7783.3, 7733.7, 7767.15, 7645, 7639, 7590.1, 7584.8, 7566, 7717.15,
7818.7, 7885.3, 7930.15, 7924, 7922, 7867.6, 7871.1, 7991, 7884, 7831.1, 7805.1, 7770.1, 7725, 7733, 7700.95, 7775,
7867.15, 7798.2, 7860.4, 7787.3, 7780.1, 7896,
];

export const aoValues = [
undefined,
Expand Down Expand Up @@ -161,4 +65,4 @@ export const aoValues = [
47.6922,
44.2532,
45.0772,
]
];
Loading

0 comments on commit 31245b5

Please sign in to comment.