-
-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Dmitriy Yurov
committed
Mar 9, 2024
1 parent
7e0d031
commit f964654
Showing
5 changed files
with
270 additions
and
3 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
import { SMA } from './sma'; | ||
import { MaxProvider } from './providers/max-value'; | ||
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. | ||
*/ | ||
export class StochasticRSI { | ||
private max: MaxProvider; | ||
private min: MinProvider; | ||
private rsi: RSI; | ||
private sma1: SMA; | ||
private sma2: SMA; | ||
|
||
constructor(rsiPeriod = 14, kPeriod = 3, dPeriod = 3, stochPeriod = 14) { | ||
this.rsi = new RSI(rsiPeriod); | ||
this.sma1 = new SMA(kPeriod); | ||
this.sma2 = new SMA(dPeriod); | ||
this.max = new MaxProvider(stochPeriod); | ||
this.min = new MinProvider(stochPeriod); | ||
} | ||
|
||
/** | ||
* Get next value for closed candle | ||
* affect all next calculations | ||
*/ | ||
nextValue(close: number): { k: number, d: number, stochRsi: number } { | ||
const rsi = this.rsi.nextValue(close); | ||
|
||
if (rsi === undefined) { | ||
return; | ||
} | ||
|
||
const max = this.max.nextValue(rsi); | ||
const min = this.min.nextValue(rsi); | ||
|
||
if (!this.max.filled()) { | ||
return; | ||
} | ||
|
||
const stochRsi = ((rsi - min) / (max - min)) * 100; | ||
const k = this.sma1.nextValue(stochRsi); | ||
|
||
if (k === undefined) { | ||
return; | ||
} | ||
|
||
const d = this.sma2.nextValue(k); | ||
|
||
return { k, d, stochRsi }; | ||
} | ||
|
||
/** | ||
* Get next value for non closed (tick) candle hlc | ||
* does not affect any next calculations | ||
*/ | ||
momentValue(close: number): { k: number, d: number, stochRsi: number} { | ||
if (!this.max.filled()) { | ||
return; | ||
} | ||
|
||
const rsi = this.rsi.momentValue(close); | ||
const max = this.max.momentValue(rsi); | ||
const min = this.min.momentValue(rsi); | ||
|
||
const stochRsi = ((rsi - min) / (max - min)) * 100; | ||
const k = this.sma1.momentValue(stochRsi); | ||
const d = this.sma2.momentValue(k); | ||
|
||
return { k, d, stochRsi }; | ||
} | ||
} |
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,165 @@ | ||
export const ohlc = [ | ||
{ o: 1173.0, h: 1189.34998, l: 1162.0, c: 1181.75 }, | ||
{ o: 1187.05005, h: 1192.55005, l: 1148.09998, c: 1154.59998 }, | ||
{ o: 1156.0, h: 1168.75, l: 1128.44995, c: 1133.19995 }, | ||
{ o: 1136.40002, h: 1149.59998, l: 1126.05005, c: 1132.15002 }, | ||
{ o: 1136.0, h: 1172.90002, l: 1136.0, c: 1167.40002 }, | ||
{ o: 1199.0, h: 1219.80005, l: 1109.0, c: 1122.90002 }, | ||
{ o: 1107.44995, h: 1111.0, l: 1085.19995, c: 1099.40002 }, | ||
{ o: 1091.44995, h: 1115.55005, l: 1087.19995, c: 1097.59998 }, | ||
{ o: 1099.90002, h: 1104.34998, l: 1089.09998, c: 1097.34998 }, | ||
{ o: 1099.0, h: 1101.40002, l: 1090.0, c: 1094.90002 }, | ||
{ o: 1102.0, h: 1116.0, l: 1100.5, c: 1111.94995 }, | ||
{ o: 1113.0, h: 1130.0, l: 1110.59998, c: 1125.94995 }, | ||
{ o: 1125.0, h: 1146.84998, l: 1125.0, c: 1138.40002 }, | ||
{ o: 1138.40002, h: 1138.40002, l: 1138.40002, c: 1138.40002 }, | ||
{ o: 1141.80005, h: 1153.0, l: 1125.09998, c: 1149.90002 }, | ||
{ o: 1154.0, h: 1158.5, l: 1143.15002, c: 1152.15002 }, | ||
{ o: 1150.0, h: 1155.0, l: 1144.09998, c: 1149.40002 }, | ||
{ o: 1144.5, h: 1158.0, l: 1139.0, c: 1153.19995 }, | ||
{ o: 1153.09998, h: 1155.90002, l: 1136.05005, c: 1145.05005 }, | ||
{ o: 1145.0, h: 1145.0, l: 1130.0, c: 1135.44995 }, | ||
{ o: 1130.0, h: 1135.80005, l: 1114.09998, c: 1131.19995 }, | ||
{ o: 1133.40002, h: 1150.44995, l: 1133.40002, c: 1145.5 }, | ||
{ o: 1150.09998, h: 1157.59998, l: 1132.30005, c: 1136.80005 }, | ||
{ o: 1142.94995, h: 1145.0, l: 1119.40002, c: 1122.90002 }, | ||
{ o: 1123.0, h: 1143.90002, l: 1122.90002, c: 1138.30005 }, | ||
{ o: 1120.0, h: 1140.0, l: 1115.19995, c: 1134.59998 }, | ||
{ o: 1127.5, h: 1127.5, l: 1100.09998, c: 1103.84998 }, | ||
{ o: 1103.84998, h: 1103.84998, l: 1103.84998, c: 1103.84998 }, | ||
{ o: 1103.84998, h: 1103.84998, l: 1103.84998, c: 1103.84998 }, | ||
{ o: 1099.94995, h: 1106.0, l: 1090.0, c: 1100.80005 }, | ||
{ o: 1083.65002, h: 1094.0, l: 1067.19995, c: 1080.19995 }, | ||
{ o: 1080.0, h: 1082.90002, l: 1052.0, c: 1061.5 }, | ||
{ o: 1041.0, h: 1045.15002, l: 1011.25, c: 1020.0 }, | ||
{ o: 1030.25, h: 1052.0, l: 1023.79999, c: 1047.80005 }, | ||
{ o: 1048.0, h: 1063.19995, l: 1042.05005, c: 1052.40002 }, | ||
{ o: 1050.0, h: 1062.40002, l: 1038.0, c: 1053.69995 }, | ||
{ o: 1050.0, h: 1050.80005, l: 1037.0, c: 1041.15002 }, | ||
{ o: 1041.15002, h: 1041.15002, l: 1041.15002, c: 1041.15002 }, | ||
{ o: 1040.94995, h: 1059.5, l: 1040.05005, c: 1052.40002 }, | ||
{ o: 1058.0, h: 1070.0, l: 1045.0, c: 1066.34998 }, | ||
{ o: 1070.0, h: 1098.30005, l: 1056.19995, c: 1087.90002 }, | ||
{ o: 1088.0, h: 1095.0, l: 1072.94995, c: 1079.0 }, | ||
{ o: 1079.94995, h: 1079.94995, l: 1059.0, c: 1060.69995 }, | ||
{ o: 1061.0, h: 1064.80005, l: 1049.05005, c: 1057.75 }, | ||
{ o: 1049.0, h: 1064.90002, l: 1040.09998, c: 1049.05005 }, | ||
{ o: 1055.30005, h: 1059.0, l: 1040.0, c: 1046.25 }, | ||
{ o: 1045.05005, h: 1062.75, l: 1039.30005, c: 1044.40002 }, | ||
{ o: 1043.0, h: 1046.94995, l: 1022.54999, c: 1028.19995 }, | ||
{ o: 1036.59998, h: 1051.59998, l: 1030.30005, c: 1047.34998 }, | ||
{ o: 1054.0, h: 1061.90002, l: 1045.90002, c: 1052.80005 }, | ||
{ o: 1049.5, h: 1073.15002, l: 1048.05005, c: 1069.5 }, | ||
{ o: 1073.25, h: 1079.09998, l: 1058.80005, c: 1077.55005 }, | ||
{ o: 1083.40002, h: 1098.0, l: 1083.40002, c: 1095.84998 }, | ||
{ o: 1100.0, h: 1109.80005, l: 1088.0, c: 1107.09998 }, | ||
{ o: 1103.40002, h: 1103.40002, l: 1079.44995, c: 1083.15002 }, | ||
{ o: 1077.0, h: 1107.40002, l: 1065.94995, c: 1103.44995 }, | ||
{ o: 1097.44995, h: 1097.44995, l: 1080.09998, c: 1083.75 }, | ||
{ o: 1095.05005, h: 1102.5, l: 1087.05005, c: 1100.84998 }, | ||
{ o: 1102.05005, h: 1104.44995, l: 1090.09998, c: 1096.34998 }, | ||
{ o: 1096.34998, h: 1096.34998, l: 1096.34998, c: 1096.34998 }, | ||
{ o: 1090.0, h: 1110.0, l: 1090.0, c: 1104.75 }, | ||
{ o: 1101.25, h: 1110.0, l: 1097.30005, c: 1104.69995 }, | ||
{ o: 1101.09998, h: 1106.59998, l: 1083.0, c: 1086.30005 }, | ||
{ o: 1090.15002, h: 1109.94995, l: 1087.0, c: 1105.40002 }, | ||
{ o: 1100.0, h: 1108.94995, l: 1093.19995, c: 1105.25 }, | ||
{ o: 1099.94995, h: 1102.44995, l: 1076.05005, c: 1078.90002 }, | ||
{ o: 1085.5, h: 1085.5, l: 1062.25, c: 1074.05005 }, | ||
{ o: 1074.65002, h: 1074.65002, l: 1058.90002, c: 1069.34998 }, | ||
{ o: 1060.05005, h: 1067.90002, l: 1047.90002, c: 1050.80005 }, | ||
{ o: 1061.5, h: 1067.40002, l: 1055.5, c: 1063.30005 }, | ||
{ o: 1056.30005, h: 1069.94995, l: 1052.09998, c: 1055.69995 }, | ||
{ o: 1062.0, h: 1062.94995, l: 1030.84998, c: 1049.94995 }, | ||
{ o: 1057.0, h: 1091.0, l: 1048.09998, c: 1083.40002 }, | ||
{ o: 1066.0, h: 1155.0, l: 1054.34998, c: 1133.0 }, | ||
{ o: 1148.0, h: 1164.0, l: 1137.55005, c: 1139.90002 }, | ||
{ o: 1139.90002, h: 1162.09998, l: 1128.34998, c: 1131.90002 }, | ||
{ o: 1135.0, h: 1158.94995, l: 1128.55005, c: 1139.65002 }, | ||
{ o: 1134.0, h: 1160.0, l: 1117.0, c: 1121.25 }, | ||
{ o: 1135.0, h: 1142.5, l: 1122.0, c: 1137.05005 }, | ||
{ o: 1148.09998, h: 1152.5, l: 1131.0, c: 1136.25 }, | ||
]; | ||
|
||
export const rsiValues = [ | ||
undefined, | ||
undefined, | ||
undefined, | ||
undefined, | ||
undefined, | ||
undefined, | ||
undefined, | ||
undefined, | ||
undefined, | ||
undefined, | ||
undefined, | ||
undefined, | ||
undefined, | ||
undefined, | ||
42.50059, | ||
43.1493, | ||
42.51792, | ||
43.74289, | ||
41.69081, | ||
39.34911, | ||
38.32288, | ||
43.64827, | ||
41.31126, | ||
37.82651, | ||
43.51179, | ||
42.50609, | ||
35.22029, | ||
35.22029, | ||
35.22029, | ||
34.48798, | ||
29.95727, | ||
26.54783, | ||
20.87089, | ||
31.44632, | ||
33.04097, | ||
33.51166, | ||
31.22928, | ||
31.22928, | ||
35.7767, | ||
40.98758, | ||
48.00588, | ||
45.59417, | ||
41.02984, | ||
40.32898, | ||
38.25363, | ||
37.58328, | ||
37.12044, | ||
33.25797, | ||
41.06462, | ||
43.1043, | ||
48.93605, | ||
51.51585, | ||
56.85244, | ||
59.78307, | ||
51.72803, | ||
57.01472, | ||
51.15917, | ||
55.43742, | ||
54.09454, | ||
54.09454, | ||
56.38192, | ||
56.3639, | ||
50.0326, | ||
55.60712, | ||
55.55469, | ||
47.14692, | ||
45.77376, | ||
44.42346, | ||
39.47411, | ||
44.00166, | ||
41.94711, | ||
40.40977, | ||
51.53707, | ||
62.66867, | ||
63.91056, | ||
61.36179, | ||
62.90515, | ||
57.076, | ||
60.46395, | ||
60.20482, | ||
]; |
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,25 @@ | ||
import { ohlc } from './excel-data'; | ||
import { StochasticRSI } from '../../src/stochastic-rsi'; | ||
import { StochasticRSI as StochasticRSITI } from 'technicalindicators'; | ||
|
||
describe('StochRSI', () => { | ||
it('Cross sdk validate', () => { | ||
const configTI = { stochasticPeriod: 14, rsiPeriod: 14, kPeriod: 3, dPeriod: 3, values: [] as number[] }; | ||
const stochRsi = new StochasticRSI(); | ||
const stochRsi2 = new StochasticRSITI(configTI); | ||
|
||
ohlc.forEach((tick) => { | ||
configTI.values.push(tick.c); | ||
const local = stochRsi.nextValue(tick.c); | ||
//@ts-expect-error incorrect typings | ||
const cross = stochRsi2.nextValue(tick.c); | ||
|
||
if (local?.k && cross?.k) { | ||
//precision issues with technicalindicators setConfig('precision') is not work as expected | ||
expect(Math.abs(local.k - cross.k)).toBeLessThan(0.05); | ||
expect(Math.abs(local.d - cross.d)).toBeLessThan(0.05); | ||
expect(Math.abs(local.stochRsi - cross.stochRSI)).toBeLessThan(0.05); | ||
} | ||
}); | ||
}); | ||
}); |