├── .gitignore ├── .npmignore ├── LICENCE.md ├── core ├── _cvi.js ├── abands.js ├── ad.js ├── adosc.js ├── adx.js ├── adxr.js ├── alma.js ├── ao.js ├── apo.js ├── aroon.js ├── aroonosc.js ├── atr.js ├── avgprice.js ├── bbands.js ├── bop.js ├── cci.js ├── ce.js ├── cmf.js ├── cmo.js ├── copp.js ├── crossOverNumber.js ├── crossUnderNumber.js ├── crossany.js ├── crossover.js ├── cvi.js ├── dc.js ├── decay.js ├── dema.js ├── di.js ├── dm.js ├── dpo.js ├── dx.js ├── edecay.js ├── ema.js ├── emv.js ├── fi.js ├── fisher.js ├── fosc.js ├── hma.js ├── kama.js ├── kc.js ├── kst.js ├── kvo.js ├── lag.js ├── linreg.js ├── linregintercept.js ├── linregslope.js ├── macd.js ├── marketfi.js ├── mass.js ├── max.js ├── md.js ├── medprice.js ├── mfi.js ├── min.js ├── mom.js ├── msw.js ├── natr.js ├── normalize.js ├── normalize2.js ├── nvi.js ├── obv.js ├── pbands.js ├── pfe.js ├── posc.js ├── ppo.js ├── psar.js ├── pvi.js ├── qstick.js ├── rmi.js ├── rmta.js ├── roc.js ├── rocr.js ├── rsi.js ├── rvi.js ├── sma.js ├── smi.js ├── stddev.js ├── stderr.js ├── stoch.js ├── stochrsi.js ├── sum.js ├── tema.js ├── tr.js ├── trima.js ├── trix.js ├── tsf.js ├── tsi.js ├── typprice.js ├── ultosc.js ├── varf.js ├── vhf.js ├── vidya.js ├── volatility.js ├── vosc.js ├── vwap.js ├── vwma.js ├── wad.js ├── wcprice.js ├── wilders.js ├── willr.js ├── wma.js └── zlema.js ├── generate.js ├── index.js ├── package-lock.json ├── package.json ├── readme.md ├── rollup.config.js ├── todo.md ├── tsconfig.json └── types ├── core ├── _cvi.d.ts ├── abands.d.ts ├── ad.d.ts ├── adosc.d.ts ├── adx.d.ts ├── adxr.d.ts ├── alma.d.ts ├── ao.d.ts ├── apo.d.ts ├── aroon.d.ts ├── aroonosc.d.ts ├── atr.d.ts ├── avgprice.d.ts ├── bbands.d.ts ├── bop.d.ts ├── cci.d.ts ├── ce.d.ts ├── cmf.d.ts ├── cmo.d.ts ├── copp.d.ts ├── crossOverNumber.d.ts ├── crossUnderNumber.d.ts ├── crossany.d.ts ├── crossover.d.ts ├── cvi.d.ts ├── dc.d.ts ├── decay.d.ts ├── dema.d.ts ├── di.d.ts ├── dm.d.ts ├── dpo.d.ts ├── dx.d.ts ├── edecay.d.ts ├── ema.d.ts ├── emv.d.ts ├── fi.d.ts ├── fisher.d.ts ├── fosc.d.ts ├── hma.d.ts ├── kama.d.ts ├── kc.d.ts ├── kst.d.ts ├── kvo.d.ts ├── lag.d.ts ├── linreg.d.ts ├── linregintercept.d.ts ├── linregslope.d.ts ├── macd.d.ts ├── marketfi.d.ts ├── mass.d.ts ├── max.d.ts ├── md.d.ts ├── medprice.d.ts ├── mfi.d.ts ├── min.d.ts ├── mom.d.ts ├── msw.d.ts ├── natr.d.ts ├── normalize.d.ts ├── normalize2.d.ts ├── nvi.d.ts ├── obv.d.ts ├── pbands.d.ts ├── pfe.d.ts ├── posc.d.ts ├── ppo.d.ts ├── psar.d.ts ├── pvi.d.ts ├── qstick.d.ts ├── rmi.d.ts ├── rmta.d.ts ├── roc.d.ts ├── rocr.d.ts ├── rsi.d.ts ├── rvi.d.ts ├── sma.d.ts ├── smi.d.ts ├── stddev.d.ts ├── stderr.d.ts ├── stoch.d.ts ├── stochrsi.d.ts ├── sum.d.ts ├── tema.d.ts ├── tr.d.ts ├── trima.d.ts ├── trix.d.ts ├── tsf.d.ts ├── tsi.d.ts ├── typprice.d.ts ├── ultosc.d.ts ├── varf.d.ts ├── vhf.d.ts ├── vidya.d.ts ├── volatility.d.ts ├── vosc.d.ts ├── vwap.d.ts ├── vwma.d.ts ├── wad.d.ts ├── wcprice.d.ts ├── wilders.d.ts ├── willr.d.ts ├── wma.d.ts └── zlema.d.ts └── index.d.ts /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | generate.js 4 | core - promised 5 | rollup.config_old.js 6 | rollup.config_new.js -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | ./generate.js 3 | todo.md 4 | core - promised 5 | rollup.config_old.js 6 | rollup.config_new.js -------------------------------------------------------------------------------- /LICENCE.md: -------------------------------------------------------------------------------- 1 | Copyright 2024 IX JB 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /core/_cvi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function _cvi( 10 | high, low, 11 | period, size = high.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (period < 1) throw new Error("Invalid Options") 17 | // if (size <= period * 2 - 1) throw new Error("Out of range") 18 | 19 | const per = 2 / (period + 1) 20 | 21 | const lag = { 22 | size: period, 23 | index: 0, 24 | pushes: 0, 25 | vals: [] 26 | } 27 | 28 | let val = high[0] - low[0] 29 | 30 | for (let i = 1; i < period * 2 - 1; ++i) { 31 | val = ((high[i] - low[i]) - val) * per + val 32 | // Start ti_buffer_qpush 33 | // BUFFER = lag 34 | // VAL = val 35 | lag.vals[lag.index] = val 36 | lag.index = lag.index + 1 37 | if (lag.index >= lag.size) lag.index = 0 38 | // End ti_buffer_qpush 39 | } 40 | 41 | for (let i = period * 2 - 1; i < size; ++i) { 42 | val = ((high[i] - low[i]) - val) * per + val 43 | 44 | const old = lag.vals[lag.index] 45 | 46 | output.push(100.0 * (val - old) / old) 47 | // Start ti_buffer_qpush 48 | // BUFFER = lag 49 | // VAL = val 50 | lag.vals[lag.index] = val 51 | lag.index = lag.index + 1 52 | if (lag.index >= lag.size) lag.index = 0 53 | // End ti_buffer_qpush 54 | 55 | } 56 | 57 | return output 58 | } 59 | 60 | module.exports = _cvi -------------------------------------------------------------------------------- /core/abands.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} high 3 | * @param {number[]} low 4 | * @param {number[]} close 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns [upper_band, lower_band, middle_point] 8 | */ 9 | function abands( 10 | high, low, 11 | close, period, 12 | size = high.length 13 | ) { 14 | 15 | const upper_band = [] 16 | const lower_band = [] 17 | const middle_point = [] 18 | 19 | // if (period < 1) throw new Error("Invalid Options") 20 | // if (size <= period - 1) throw new Error("Out of range") 21 | 22 | const per = 1. / period 23 | 24 | const buffer_high = { 25 | size: period, 26 | index: 0, 27 | pushes: 0, 28 | sum: 0, 29 | vals: [] 30 | } 31 | const buffer_low = { 32 | size: period, 33 | index: 0, 34 | pushes: 0, 35 | sum: 0, 36 | vals: [] 37 | } 38 | 39 | let close_sum = 0 40 | 41 | for (let i = 0; i < period; ++i) { 42 | // Start MULT 43 | // MULT(i) (4. * (high[i] - low[i]) / (high[i] + low[i])) 44 | const mult = (4. * (high[i] - low[i]) / (high[i] + low[i])) 45 | // End MULT 46 | 47 | const high_val = (1. + mult) * high[i] 48 | 49 | // Start ti_buffer_push 50 | // BUFFER = buffer_high 51 | // VAL = high_val 52 | // ti_buffer_push(buffer_high, high_val) 53 | if (buffer_high.pushes >= buffer_high.size) { 54 | buffer_high.sum -= buffer_high.vals[buffer_high.index] 55 | } 56 | 57 | buffer_high.sum += high_val 58 | buffer_high.vals[buffer_high.index] = high_val 59 | buffer_high.pushes += 1 60 | buffer_high.index = (buffer_high.index + 1) 61 | if (buffer_high.index >= buffer_high.size) buffer_high.index = 0 62 | // End ti_buffer_push 63 | 64 | const low_val = (1. - mult) * low[i] 65 | 66 | // Start ti_buffer_push 67 | // BUFFER = buffer_low 68 | // VAL = low_val 69 | // ti_buffer_push(buffer_low, low_val) 70 | if (buffer_low.pushes >= buffer_low.size) { 71 | buffer_low.sum -= buffer_low.vals[buffer_low.index] 72 | } 73 | 74 | buffer_low.sum += low_val 75 | buffer_low.vals[buffer_low.index] = low_val 76 | buffer_low.pushes += 1 77 | buffer_low.index = (buffer_low.index + 1) 78 | if (buffer_low.index >= buffer_low.size) buffer_low.index = 0 79 | // End ti_buffer_push 80 | 81 | close_sum += close[i] 82 | } 83 | 84 | upper_band.push(buffer_high.sum * per) 85 | lower_band.push(buffer_low.sum * per) 86 | middle_point.push(close_sum * per) 87 | 88 | for (let i = period; i < size; ++i) { 89 | // Start MULT 90 | const mult = (4. * (high[i] - low[i]) / (high[i] + low[i])) 91 | // End MULT 92 | 93 | const high_val = (1. + mult) * high[i] 94 | // Start ti_buffer_push 95 | // BUFFER = buffer_high 96 | // VAL = high_val 97 | // ti_buffer_push(buffer_high, high_val) 98 | if (buffer_high.pushes >= buffer_high.size) { 99 | buffer_high.sum -= buffer_high.vals[buffer_high.index] 100 | } 101 | 102 | buffer_high.sum += high_val 103 | buffer_high.vals[buffer_high.index] = high_val 104 | buffer_high.pushes += 1 105 | buffer_high.index = (buffer_high.index + 1) 106 | if (buffer_high.index >= buffer_high.size) buffer_high.index = 0 107 | // End ti_buffer_push 108 | 109 | const low_val = (1. - mult) * low[i] 110 | 111 | // Start ti_buffer_push 112 | // BUFFER = buffer_low 113 | // VAL = low_val 114 | // ti_buffer_push(buffer_low, low_val) 115 | if (buffer_low.pushes >= buffer_low.size) { 116 | buffer_low.sum -= buffer_low.vals[buffer_low.index] 117 | } 118 | 119 | buffer_low.sum += low_val 120 | buffer_low.vals[buffer_low.index] = low_val 121 | buffer_low.pushes += 1 122 | buffer_low.index = (buffer_low.index + 1) 123 | if (buffer_low.index >= buffer_low.size) buffer_low.index = 0 124 | // End ti_buffer_push 125 | 126 | close_sum += close[i] - close[i - period] 127 | 128 | upper_band.push(buffer_high.sum * per) 129 | lower_band.push(buffer_low.sum * per) 130 | middle_point.push(close_sum * per) 131 | } 132 | 133 | return [upper_band, lower_band, middle_point] 134 | } 135 | 136 | module.exports = abands -------------------------------------------------------------------------------- /core/ad.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number[]} volume 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | function ad( 11 | high, low, 12 | close, volume, 13 | size = close.length 14 | ) { 15 | 16 | const output = [] 17 | 18 | let sum = 0 19 | 20 | for (let index = 0; index < size; ++index) { 21 | const hl = (high[index] - low[index]) 22 | if (hl != 0.0) { 23 | sum += (close[index] - low[index] - high[index] + close[index]) / hl * volume[index] 24 | } 25 | output[index] = sum 26 | } 27 | 28 | return output 29 | } 30 | 31 | module.exports = ad -------------------------------------------------------------------------------- /core/adosc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} high 3 | * @param {number[]} low 4 | * @param {number[]} close 5 | * @param {number[]} volume 6 | * @param {number} short_period 7 | * @param {number} long_period 8 | * @param {number} [size] 9 | * @returns 10 | */ 11 | function adosc( 12 | high, low, 13 | close, volume, 14 | short_period, long_period, 15 | size = close.length 16 | ) { 17 | 18 | const start = long_period - 1 19 | 20 | // if (short_period < 1) throw new Error("Invalid Options") 21 | // if (long_period < short_period) throw new Error("Invalid Options") 22 | // if (size <= long_period - 1) throw new Error("Out of range") 23 | 24 | const short_per = 2 / (short_period + 1) 25 | const long_per = 2 / (long_period + 1) 26 | 27 | const output = [] 28 | 29 | let sum = 0 30 | let short_ema = 0 31 | let long_ema = 0 32 | 33 | for (let index = 0; index < size; ++index) { 34 | 35 | const hl = (high[index] - low[index]) 36 | if (hl != 0.0) { 37 | sum += (close[index] - low[index] - high[index] + close[index]) / hl * volume[index] 38 | } 39 | 40 | if (index == 0) { 41 | short_ema = sum 42 | long_ema = sum 43 | } else { 44 | short_ema = (sum - short_ema) * short_per + short_ema 45 | long_ema = (sum - long_ema) * long_per + long_ema 46 | } 47 | 48 | if (index >= start) { 49 | // output[output.length] = short_ema - long_ema 50 | output.push(short_ema - long_ema) 51 | } 52 | } 53 | 54 | return output 55 | } 56 | 57 | module.exports = adosc -------------------------------------------------------------------------------- /core/adx.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} high 3 | * @param {number[]} low 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function adx( 9 | high, low, 10 | period, size = high.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 2) throw new Error("Invalid Options") 16 | // if (size <= (period - 1) * 2) throw new Error("Out of range") 17 | 18 | const per = ((period - 1)) / period 19 | const invper = 1.0 / (period) 20 | 21 | let dmup = 0 22 | let dmdown = 0 23 | 24 | for (let index = 1; index < period; ++index) { 25 | 26 | let dp = high[index] - high[index - 1] 27 | let dm = low[index - 1] - low[index] 28 | 29 | if (dp < 0) { 30 | dp = 0 31 | } else if (dp > dm) { 32 | dm = 0 33 | } 34 | 35 | if (dm < 0) { 36 | dm = 0 37 | } else if (dm > dp) { 38 | dp = 0 39 | } 40 | 41 | 42 | dmup += dp 43 | dmdown += dm 44 | } 45 | 46 | let adx = 0.0 47 | 48 | let di_up = dmup; 49 | let di_down = dmdown; 50 | let dm_diff = Math.abs(di_up - di_down); 51 | let dm_sum = di_up + di_down; 52 | let dx = dm_diff / dm_sum * 100; 53 | 54 | adx += dx; 55 | 56 | for (let index = period; index < size; ++index) { 57 | 58 | let dp = high[index] - high[index - 1] 59 | let dm = low[index - 1] - low[index] 60 | 61 | if (dp < 0) { 62 | dp = 0 63 | } else if (dp > dm) { 64 | dm = 0 65 | } 66 | 67 | if (dm < 0) { 68 | dm = 0 69 | } else if (dm > dp) { 70 | dp = 0 71 | } 72 | 73 | 74 | dmup = dmup * per + dp 75 | dmdown = dmdown * per + dm 76 | 77 | di_up = dmup 78 | di_down = dmdown 79 | dm_diff = Math.abs(di_up - di_down) 80 | dm_sum = di_up + di_down 81 | dx = dm_diff / dm_sum * 100 82 | 83 | if (index - period < period - 2) { 84 | adx += dx 85 | } else if (index - period == period - 2) { 86 | adx += dx 87 | // output[output.length] = adx * invper 88 | output.push(adx * invper) 89 | } else { 90 | adx = adx * per + dx 91 | // output[output.length] = adx * invper 92 | output.push(adx * invper) 93 | } 94 | } 95 | 96 | return output 97 | } 98 | 99 | module.exports = adx -------------------------------------------------------------------------------- /core/adxr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function adxr( 10 | high, low, 11 | period, size = high.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (period < 2) throw new Error("Invalid Options") 17 | // if (size <= (period-1) * 3) throw new Error("Out of Range") 18 | 19 | const per = (period - 1) / (period) 20 | const invper = 1.0 / (period) 21 | 22 | let dmup = 0 23 | let dmdown = 0 24 | 25 | for (let i = 1; i < period; ++i) { 26 | 27 | // Start CALC_DIRECTION 28 | let dp = high[i] - high[i - 1] 29 | let dm = low[i - 1] - low[i] 30 | 31 | if (dp < 0) { 32 | dp = 0 33 | } else if (dp > dm) { 34 | dm = 0 35 | } 36 | 37 | if (dm < 0) { 38 | dm = 0 39 | } else if (dm > dp) { 40 | dp = 0 41 | } 42 | // End CALC_DIRECTION 43 | 44 | dmup += dp 45 | dmdown += dm 46 | } 47 | 48 | let adx = 0.0 49 | 50 | let di_up = dmup 51 | let di_down = dmdown 52 | let dm_diff = Math.abs(di_up - di_down) 53 | let dm_sum = di_up + di_down 54 | let dx = dm_diff / dm_sum * 100 55 | 56 | adx += dx 57 | 58 | // Start ti_buffer_new 59 | const adxr = { 60 | size: period - 1, 61 | pushes: 0, 62 | index: 0, 63 | vals: [], 64 | } 65 | // End ti_buffer_new 66 | 67 | const first_adxr = (period - 1) * 3 68 | 69 | for (let i = period; i < size; ++i) { 70 | 71 | // Start CALC_DIRECTION 72 | let dp = high[i] - high[i - 1] 73 | let dm = low[i - 1] - low[i] 74 | 75 | if (dp < 0) { 76 | dp = 0 77 | } else if (dp > dm) { 78 | dm = 0 79 | } 80 | 81 | if (dm < 0) { 82 | dm = 0 83 | } else if (dm > dp) { 84 | dp = 0 85 | } 86 | // End CALC_DIRECTION 87 | 88 | dmup = dmup * per + dp 89 | dmdown = dmdown * per + dm 90 | 91 | di_up = dmup 92 | di_down = dmdown 93 | dm_diff = Math.abs(di_up - di_down) 94 | dm_sum = di_up + di_down 95 | dx = dm_diff / dm_sum * 100 96 | 97 | if (i - period < period - 2) { 98 | adx += dx 99 | } else if (i - period == period - 2) { 100 | adx += dx 101 | // ## Start ti_buffer_qpush 102 | // BUFFER = adxr 103 | // VAL = adx * invper 104 | adxr.vals[adxr.index] = adx * invper 105 | adxr.index = adxr.index + 1 106 | if (adxr.index >= adxr.size) adxr.index = 0 107 | // ## End ti_buffer_qpush 108 | } else { 109 | adx = adx * per + dx 110 | 111 | if (i >= first_adxr) { 112 | // ## Start ti_buffer_get 113 | // BUFFER = adxr 114 | // VAL = 1 115 | // ((BUFFER)->vals[((BUFFER)->index + (BUFFER)->size - 1 + (VAL)) % (BUFFER)->size]) 116 | const a = adxr.vals[adxr.index] 117 | const b = (adxr.size - 1) + 1 // + 1 = VAL 118 | const c = adxr.size 119 | const buffer_get = a + b % c 120 | // ## End ti_buffer_get 121 | output.push((0.5 * (adx * invper + buffer_get))) 122 | } 123 | 124 | // ## Start ti_buffer_qpush 125 | adxr.vals[adxr.index] = adx * invper 126 | adxr.index = adxr.index + 1 127 | if (adxr.index >= adxr.size) adxr.index = 0 128 | // ## End ti_buffer_qpush 129 | } 130 | } 131 | 132 | return output 133 | } 134 | 135 | module.exports = adxr -------------------------------------------------------------------------------- /core/alma.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} offset 6 | * @param {number} sigma 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | function alma( 11 | source, period, 12 | offset, sigma, 13 | size = source.length 14 | ) { 15 | 16 | const output = [] 17 | 18 | // validate options 19 | // if (period < 1) throw new Error("Invalid Options") 20 | // if (sigma <= 0) throw new Error("Invalid Options") 21 | // if ((offset < 0) || (offset > 1)) throw new Error("Invalid Options") 22 | // if (size <= period - 1) throw new Error("Out of range") 23 | 24 | const weights = [] 25 | 26 | const m = Math.floor(offset * (period - 1)) 27 | const s = period / sigma 28 | 29 | let norm = 0 30 | 31 | for (let i = 0; i < period; i++) { 32 | weights[i] = Math.exp(-1 * Math.pow(i - m, 2) / (2 * Math.pow(s, 2))) 33 | norm += weights[i] 34 | } 35 | 36 | for (let i = 0; i < period; i++) { 37 | weights[i] /= norm 38 | } 39 | 40 | for (let i = period - 1; i < size; i++) { 41 | let sum = 0 42 | for (let j = 0; j < period; j++) { 43 | sum += source[i - period + j + 1] * weights[j] 44 | } 45 | output.push(sum) 46 | } 47 | 48 | return output 49 | } 50 | 51 | module.exports = alma -------------------------------------------------------------------------------- /core/ao.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function ao( 9 | high, low, 10 | size = high.length 11 | ) { 12 | 13 | const period = 34; 14 | 15 | const output = [] 16 | 17 | // if (size <= 33) throw new Error("Out of range") 18 | 19 | let sum34 = 0 20 | let sum5 = 0 21 | const per34 = 1.0 / 34.0 22 | const per5 = 1.0 / 5.0 23 | 24 | for (let index = 0; index < 34; ++index) { 25 | const hl = 0.5 * (high[index] + low[index]) 26 | 27 | sum34 += hl 28 | 29 | if (index >= 29) { 30 | sum5 += hl 31 | } 32 | } 33 | 34 | output.push(per5 * sum5 - per34 * sum34) 35 | 36 | for (let index = period; index < size; ++index) { 37 | const hl = 0.5 * (high[index] + low[index]) 38 | 39 | sum34 += hl 40 | sum5 += hl 41 | 42 | sum34 -= 0.5 * (high[index - 34] + low[index - 34]) 43 | sum5 -= 0.5 * (high[index - 5] + low[index - 5]) 44 | 45 | // output[output.length] = per5 * sum5 - per34 * sum34 46 | output.push(per5 * sum5 - per34 * sum34) 47 | } 48 | 49 | return output 50 | } 51 | 52 | module.exports = ao -------------------------------------------------------------------------------- /core/apo.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} short_period 6 | * @param {number} long_period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | function apo( 11 | source, short_period, long_period, 12 | size = source.length 13 | ) { 14 | 15 | const output = [] 16 | 17 | // if (short_period < 1) throw new Error("Invalid Options") 18 | // if (long_period < 2) throw new Error("Invalid Options") 19 | // if (long_period < short_period) throw new Error("Invalid Options") 20 | // if (size <= 1) throw new Error("Out of range") 21 | 22 | const short_per = 2 / (short_period + 1) 23 | const long_per = 2 / (long_period + 1) 24 | 25 | let short_ema = source[0] 26 | let long_ema = source[0] 27 | 28 | for (let index = 1; index < size; ++index) { 29 | 30 | short_ema = (source[index] - short_ema) * short_per + short_ema 31 | long_ema = (source[index] - long_ema) * long_per + long_ema 32 | 33 | const out = short_ema - long_ema 34 | 35 | // output[output.length] = out 36 | output.push(out) 37 | } 38 | 39 | return output 40 | } 41 | 42 | module.exports = apo -------------------------------------------------------------------------------- /core/aroon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns First output = Aroon Down, Second output = Aroon Up 8 | */ 9 | function aroon( 10 | high, low, 11 | period, size = high.length 12 | ) { 13 | 14 | const adown = [] 15 | const aup = [] 16 | 17 | // if (period < 1) throw new Error("Invalid Options") 18 | // if (size <= period) throw new Error("Out of range") 19 | 20 | const scale = 100.0 / period 21 | let trail = 0 22 | let maxi = -1 23 | let mini = -1 24 | let max = high[0] 25 | let min = low[0] 26 | let bar 27 | 28 | let j 29 | for (let index = period; index < size; ++index, ++trail) { 30 | 31 | // Maintain highest 32 | bar = high[index] 33 | 34 | if (maxi < trail) { 35 | maxi = trail 36 | max = high[maxi] 37 | j = trail 38 | 39 | while (++j <= index) { 40 | bar = high[j] 41 | 42 | if (bar >= max) { 43 | max = bar 44 | maxi = j 45 | } 46 | } 47 | 48 | } else if (bar >= max) { 49 | maxi = index 50 | max = bar 51 | } 52 | 53 | // Maintain lowest 54 | bar = low[index] 55 | if (mini < trail) { 56 | mini = trail 57 | min = low[mini] 58 | j = trail 59 | while (++j <= index) { 60 | bar = low[j] 61 | if (bar <= min) { 62 | min = bar 63 | mini = j 64 | } 65 | } 66 | 67 | } else if (bar <= min) { 68 | mini = index 69 | min = bar 70 | } 71 | 72 | adown[adown.length] = (period - (index - mini)) * scale 73 | aup[aup.length] = (period - (index - maxi)) * scale 74 | } 75 | 76 | return [adown, aup] 77 | } 78 | 79 | module.exports = aroon -------------------------------------------------------------------------------- /core/aroonosc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function aroonosc( 10 | high, low, 11 | period, size = high.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (period < 1) throw new Error("Invalid Options") 17 | // if (size <= period) throw new Error("Out of range") 18 | 19 | const scale = 100.0 / period 20 | 21 | let trail = 0 22 | let maxi = -1 23 | let mini = -1 24 | let max = high[0] 25 | let min = low[0] 26 | 27 | let j 28 | for (let index = period; index < size; ++index, ++trail) { 29 | 30 | // Maintain highest 31 | let bar = high[index] 32 | if (maxi < trail) { 33 | maxi = trail 34 | max = high[maxi] 35 | j = trail 36 | while (++j <= index) { 37 | bar = high[j]; 38 | if (bar >= max) { 39 | max = bar 40 | maxi = j 41 | } 42 | } 43 | 44 | } else if (bar >= max) { 45 | maxi = index 46 | max = bar 47 | } 48 | 49 | 50 | // Maintain lowest 51 | bar = low[index] 52 | if (mini < trail) { 53 | mini = trail 54 | min = low[mini] 55 | j = trail 56 | while (++j <= index) { 57 | bar = low[j] 58 | if (bar <= min) { 59 | min = bar 60 | mini = j 61 | } 62 | } 63 | 64 | } else if (bar <= min) { 65 | mini = index 66 | min = bar 67 | } 68 | 69 | // output[output.length] = (maxi - mini) * scale 70 | output.push((maxi - mini) * scale) 71 | } 72 | 73 | return output 74 | } 75 | 76 | module.exports = aroonosc -------------------------------------------------------------------------------- /core/atr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} high 3 | * @param {number[]} low 4 | * @param {number[]} close 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function atr( 10 | high, low, close, 11 | period, size = high.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (period < 1) throw new Error("Invalid options") 17 | // if (size <= period - 1) throw new Error("Out of range") 18 | 19 | const per = 1.0 / period 20 | 21 | let sum = 0 22 | let truerange 23 | 24 | sum += high[0] - low[0] 25 | 26 | for (let i = 1; i < period; ++i) { 27 | 28 | // Start CALC_TRUERANGE() 29 | const l = low[i] 30 | const h = high[i] 31 | const c = close[i - 1] 32 | 33 | const ych = Math.abs(h - c) 34 | const ycl = Math.abs(l - c) 35 | 36 | let v = h - l 37 | 38 | if (ych > v) v = ych 39 | if (ycl > v) v = ycl 40 | truerange = v 41 | // End CALC_TRUERANGE() 42 | 43 | sum += truerange 44 | } 45 | 46 | let val = sum / period 47 | 48 | // output[output.length] = val 49 | output.push(val) 50 | 51 | for (let index = period; index < size; ++index) { 52 | // CALC TRUE RANGE 53 | const l = low[index] 54 | const h = high[index] 55 | const c = close[index - 1] 56 | 57 | const ych = Math.abs(h - c) 58 | const ycl = Math.abs(l - c) 59 | 60 | let v = h - l 61 | 62 | if (ych > v) v = ych 63 | if (ycl > v) v = ycl 64 | truerange = v 65 | // CALC TRUE RANGE 66 | 67 | val = (truerange - val) * per + val 68 | 69 | // output[output.length] = val 70 | output.push(val) 71 | } 72 | 73 | return output 74 | } 75 | 76 | module.exports = atr -------------------------------------------------------------------------------- /core/avgprice.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} open 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function avgprice( 10 | open, high, 11 | low, close, 12 | size = open.length 13 | ) { 14 | 15 | const output = [] 16 | 17 | for (let index = 0; index < size; ++index) { 18 | output.push((open[index] + high[index] + low[index] + close[index]) * 0.25) 19 | } 20 | 21 | return output 22 | } 23 | 24 | module.exports = avgprice -------------------------------------------------------------------------------- /core/bbands.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} stddev 6 | * @param {number} [size] 7 | * @returns [Lower, Middle, Upper] 8 | */ 9 | function bbands( 10 | source, period, stddev, 11 | size = source.length 12 | ) { 13 | 14 | const lower = [] 15 | const middle = [] 16 | const upper = [] 17 | 18 | const scale = 1.0 / period 19 | 20 | // if (period < 1) throw new Error("Invalid Options") 21 | // if (size <= period - 1) throw new Error("Out of range") 22 | 23 | let sum = 0 24 | let sum2 = 0 25 | 26 | for (let i = 0; i < period; ++i) { 27 | sum += source[i] 28 | sum2 += source[i] * source[i] 29 | } 30 | 31 | let sd = Math.sqrt(sum2 * scale - (sum * scale) * (sum * scale)) 32 | 33 | const calc_middle = sum * scale 34 | lower.push(calc_middle - stddev * sd) 35 | upper.push(calc_middle + stddev * sd) 36 | middle.push(calc_middle) 37 | 38 | for (let i = period; i < size; ++i) { 39 | sum += source[i] 40 | sum2 += source[i] * source[i] 41 | 42 | sum -= source[i - period] 43 | sum2 -= source[i - period] * source[i - period] 44 | 45 | sd = Math.sqrt(sum2 * scale - (sum * scale) * (sum * scale)) 46 | 47 | const calc_middle = sum * scale 48 | upper.push(calc_middle + stddev * sd) 49 | lower.push(calc_middle - stddev * sd) 50 | middle.push(calc_middle) 51 | } 52 | 53 | return [lower, middle, upper] 54 | } 55 | 56 | module.exports = bbands -------------------------------------------------------------------------------- /core/bop.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} open 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | function bop( 11 | open, high, 12 | low, close, 13 | size = open.length 14 | ) { 15 | 16 | const output = [] 17 | 18 | for (let index = 0; index < size; ++index) { 19 | const hl = high[index] - low[index] 20 | 21 | if (hl <= 0.0) { 22 | output[index] = 0 23 | } else { 24 | output[index] = (close[index] - open[index]) / hl 25 | } 26 | } 27 | 28 | return output 29 | } 30 | 31 | module.exports = bop -------------------------------------------------------------------------------- /core/cci.js: -------------------------------------------------------------------------------- 1 | class ti_buffer { 2 | 3 | size; 4 | pushes; 5 | index; 6 | sum; 7 | vals; 8 | 9 | constructor(size) { 10 | this.size = size; 11 | this.pushes = 0; 12 | this.index = 0; 13 | this.sum = 0; 14 | this.vals = [] 15 | } 16 | 17 | static new(size) { 18 | return new ti_buffer(size); 19 | } 20 | 21 | push(val) { 22 | if (this.pushes >= this.size) { 23 | this.sum -= this.vals[this.index]; 24 | } 25 | 26 | this.sum += val; 27 | this.vals[this.index] = val; 28 | this.pushes += 1; 29 | this.index = (this.index + 1) % this.size; 30 | } 31 | 32 | qpush(val) { 33 | this.vals[this.index] = val; 34 | this.index = (this.index + 1) % this.size; 35 | } 36 | 37 | get(val) { 38 | return this.vals[(this.index + this.size - 1 + val) % this.size]; 39 | } 40 | } 41 | 42 | /** 43 | * 44 | * @param {number[]} high 45 | * @param {number[]} low 46 | * @param {number[]} close 47 | * @param {number} period 48 | * @param {number} [size] 49 | * @returns 50 | */ 51 | function cci( 52 | high, low, 53 | close, period, 54 | size = high.length 55 | ) { 56 | 57 | const scale = 1.0 / period 58 | 59 | // if (period < 1) throw new Error("Invalid Options") 60 | // if (size <= (period-1) * 2) throw new Error("Out of range") 61 | 62 | const output = [] 63 | 64 | const sum = new ti_buffer(period) 65 | 66 | let i, j 67 | for (i = 0; i < size; ++i) { 68 | 69 | // Start TYPEPRICE 70 | // ((high[(INDEX)] + low[(INDEX)] + close[(INDEX)]) * (1.0/3.0)) 71 | const today = ((high[(i)] + low[(i)] + close[(i)]) * (1.0 / 3.0)) 72 | // End TYPEPRICE 73 | 74 | sum.push(today) 75 | const avg = sum.sum * scale 76 | 77 | if (i >= period * 2 - 2) { 78 | let acc = 0 79 | for (j = 0; j < period; ++j) { 80 | acc += Math.abs(avg - sum.vals[j]) 81 | } 82 | 83 | let cci = acc * scale 84 | cci *= .015 85 | cci = (today - avg) / cci 86 | output.push(cci) 87 | } 88 | } 89 | 90 | return output 91 | } 92 | 93 | module.exports = cci -------------------------------------------------------------------------------- /core/ce.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} period 7 | * @param {number} coef 8 | * @param {number} [size] 9 | * @returns [ce_high, ce_low] 10 | */ 11 | function ce( 12 | high, low, 13 | close, period, coef, 14 | size = high.length 15 | ) { 16 | 17 | const ce_high = [] 18 | const ce_low = [] 19 | 20 | // if (period < 1) throw new Error("Invalid Options") 21 | // if (size <= period - 1) throw new Error("Out of range") 22 | 23 | let atr = high[0] - low[0] 24 | 25 | let truerange 26 | let val 27 | 28 | let HP = high[0] 29 | let HP_idx = 0 30 | let LP = low[0] 31 | let LP_idx = 0 32 | 33 | for (let i = 1; i < period; ++i) { 34 | // Start CALC_TRUERANGE() 35 | const l = low[i] 36 | const h = high[i] 37 | const c = close[i - 1] 38 | 39 | const ych = Math.abs(h - c) 40 | const ycl = Math.abs(l - c) 41 | 42 | let v = h - l 43 | 44 | if (ych > v) v = ych 45 | if (ycl > v) v = ycl 46 | truerange = v 47 | // End CALC_TRUERANGE() 48 | 49 | atr += truerange 50 | 51 | if (HP <= (val = high[i])) { 52 | HP = val; 53 | HP_idx = i; 54 | } 55 | if (LP >= (val = low[i])) { 56 | LP = val; 57 | LP_idx = i; 58 | } 59 | } 60 | 61 | atr /= period 62 | 63 | const smth = (period - 1) / period 64 | const per = 1 / period 65 | 66 | ce_high.push(HP - coef * atr) 67 | ce_low.push(LP + coef * atr) 68 | 69 | for (let i = period; i < size; ++i) { 70 | // Start CALC_TRUERANGE() 71 | const l = low[i] 72 | const h = high[i] 73 | const c = close[i - 1] 74 | 75 | const ych = Math.abs(h - c) 76 | const ycl = Math.abs(l - c) 77 | 78 | let v = h - l 79 | 80 | if (ych > v) v = ych 81 | if (ycl > v) v = ycl 82 | truerange = v 83 | // End CALC_TRUERANGE() 84 | atr = atr * smth + truerange * per 85 | 86 | if (HP <= (val = high[i])) { 87 | HP = val 88 | HP_idx = i 89 | } else if (HP_idx == i - period) { 90 | HP = high[i - period + 1] 91 | HP_idx = i - period + 1 92 | 93 | for (let j = i - period + 2; j <= i; ++j) { 94 | if (HP <= (val = high[j])) { 95 | HP = val 96 | HP_idx = j 97 | } 98 | } 99 | } 100 | 101 | if (LP >= (val = low[i])) { 102 | LP = val 103 | LP_idx = i 104 | } else if (LP_idx == i - period) { 105 | LP = low[i - period + 1] 106 | LP_idx = i - period + 1 107 | 108 | for (let j = i - period + 2; j <= i; ++j) { 109 | if (LP >= (val = low[j])) { 110 | LP = val 111 | LP_idx = j 112 | } 113 | } 114 | } 115 | 116 | ce_high.push(HP - coef * atr) 117 | ce_low.push(LP + coef * atr) 118 | } 119 | 120 | return [ce_high, ce_low] 121 | } 122 | 123 | module.exports = ce -------------------------------------------------------------------------------- /core/cmf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number[]} volume 7 | * @param {number} period 8 | * @param {number} [size] 9 | * @returns 10 | */ 11 | function cmf( 12 | high, low, 13 | close, volume, 14 | period, size = high.length 15 | ) { 16 | 17 | const output = [] 18 | 19 | // if (period < 1) throw new Error("Invalid Options") 20 | // if (size <= period - 1) throw new Error("Out of range") 21 | 22 | let period_volume = 0 23 | let period_ad_sum = 0 24 | 25 | for (let i = 0; i < period - 1; ++i) { 26 | // Start CHAIKIN_AD 27 | period_ad_sum += (high[i] - low[i] ? volume[i] * ((close[i] - low[i]) - (high[i] - close[i])) / (high[i] - low[i]) : 0.) 28 | // End CHAIKIN_AD 29 | 30 | period_volume += volume[i] 31 | } 32 | 33 | for (let i = period - 1; i < size; ++i) { 34 | // Start CHAIKIN_AD 35 | period_ad_sum += (high[i] - low[i] ? volume[i] * ((close[i] - low[i]) - (high[i] - close[i])) / (high[i] - low[i]) : 0.) 36 | // End CHAIKIN_AD 37 | period_volume += volume[i] 38 | 39 | output.push(period_ad_sum / period_volume) 40 | 41 | // Start CHAIKIN_AD 42 | // i = i-period+1 43 | period_ad_sum -= (high[i - period + 1] - low[i - period + 1] ? volume[i - period + 1] * ((close[i - period + 1] - low[i - period + 1]) - (high[i - period + 1] - close[i - period + 1])) / (high[i - period + 1] - low[i - period + 1]) : 0.) 44 | // End CHAIKIN_AD 45 | period_volume -= volume[i - period + 1] 46 | } 47 | 48 | return output 49 | } 50 | 51 | module.exports = cmf -------------------------------------------------------------------------------- /core/cmo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function cmo( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid options") 16 | // if (size <= period) throw new Error("Out of range") 17 | 18 | let up_sum = 0 19 | let down_sum = 0 20 | 21 | for (let i = 1; i <= period; ++i) { 22 | // Start UPWARD 23 | // up_sum += UPWARD(i) 24 | up_sum += (source[(i)] > source[(i) - 1] ? source[(i)] - source[(i) - 1] : 0) 25 | // End UPWARD 26 | 27 | // Start DOWNWARD 28 | // down_sum += DOWNWARD(i) 29 | down_sum += (source[(i)] < source[(i) - 1] ? source[(i) - 1] - source[(i)] : 0) 30 | // End DOWNWARD 31 | } 32 | 33 | output.push(100 * (up_sum - down_sum) / (up_sum + down_sum)) 34 | 35 | for (let i = period + 1; i < size; ++i) { 36 | // i - period 37 | up_sum -= (source[(i - period)] > source[(i - period) - 1] ? source[(i - period)] - source[(i - period) - 1] : 0) 38 | down_sum -= (source[(i - period)] < source[(i - period) - 1] ? source[(i - period) - 1] - source[(i - period)] : 0) 39 | 40 | // i 41 | up_sum += (source[(i)] > source[(i) - 1] ? source[(i)] - source[(i) - 1] : 0) 42 | down_sum += (source[(i)] < source[(i) - 1] ? source[(i) - 1] - source[(i)] : 0) 43 | 44 | output.push(100 * (up_sum - down_sum) / (up_sum + down_sum)) 45 | } 46 | 47 | return output 48 | } 49 | 50 | module.exports = cmo -------------------------------------------------------------------------------- /core/copp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} data 3 | * @param {number} period1 4 | * @param {number} period2 5 | * @returns 6 | */ 7 | function copp(data, period1, period2) { 8 | 9 | const roc1 = new Array(data.length); 10 | const roc2 = new Array(data.length); 11 | const coppock = new Array(data.length); 12 | 13 | for (let i = 0; i < data.length; i++) { 14 | if (i < period1 - 1) { 15 | roc1[i] = null; 16 | } else { 17 | roc1[i] = (data[i] - data[i - period1]) / data[i - period1] * 100; 18 | } 19 | if (i < period2 - 1) { 20 | roc2[i] = null; 21 | } else { 22 | roc2[i] = (data[i] - data[i - period2]) / data[i - period2] * 100; 23 | } 24 | coppock[i] = (roc1[i] + roc2[i]) * 10; 25 | } 26 | 27 | return coppock; 28 | } 29 | 30 | module.exports = copp -------------------------------------------------------------------------------- /core/crossOverNumber.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} seriesA 4 | * @param {number} number 5 | * @returns 6 | */ 7 | function crossOverNumber(seriesA, number) { 8 | 9 | const output = [] 10 | 11 | for (let index = 0; index < seriesA.length; index++) { 12 | const current = seriesA[index] 13 | const pre = seriesA[index - 1] 14 | 15 | if ( 16 | current > number && 17 | pre <= number 18 | ) { 19 | output.push(true) 20 | } else { 21 | output.push(false) 22 | } 23 | } 24 | 25 | return output 26 | } 27 | 28 | module.exports = crossOverNumber -------------------------------------------------------------------------------- /core/crossUnderNumber.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} seriesA 4 | * @param {number} number 5 | * @returns 6 | */ 7 | function crossUnderNumber(seriesA, number) { 8 | 9 | const output = [] 10 | 11 | for (let index = 0; index < seriesA.length; index++) { 12 | const current = seriesA[index] 13 | const pre = seriesA[index - 1] 14 | 15 | if ( 16 | current < number && 17 | pre >= number 18 | ) { 19 | output.push(true) 20 | } else { 21 | output.push(false) 22 | } 23 | } 24 | 25 | return output 26 | } 27 | 28 | module.exports = crossUnderNumber -------------------------------------------------------------------------------- /core/crossany.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} a 3 | * @param {number[]} b 4 | * @param {number} [size] 5 | * @returns 6 | */ 7 | function crossany(a, b, size = a.length) { 8 | const output = [] 9 | 10 | for (let i = 0; i < size; ++i) { 11 | output.push((a[i] > b[i] && a[i - 1] <= b[i - 1]) 12 | || (a[i] < b[i] && a[i - 1] >= b[i - 1]) 13 | ) 14 | } 15 | 16 | return output 17 | } 18 | 19 | module.exports = crossany -------------------------------------------------------------------------------- /core/crossover.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} a 3 | * @param {number[]} b 4 | * @param {number} [size] 5 | * @returns 6 | */ 7 | function crossover(a, b, size = a.length) { 8 | 9 | const output = [] 10 | 11 | for (let i = 0; i < size; ++i) { 12 | output.push(a[i] > b[i] && a[i - 1] <= b[i - 1]) 13 | } 14 | 15 | return output 16 | } 17 | 18 | module.exports = crossover -------------------------------------------------------------------------------- /core/cvi.js: -------------------------------------------------------------------------------- 1 | class ti_buffer { 2 | 3 | size; 4 | pushes; 5 | index; 6 | sum; 7 | vals; 8 | 9 | constructor(size) { 10 | this.size = size; 11 | this.pushes = 0; 12 | this.index = 0; 13 | this.sum = 0; 14 | this.vals = [] 15 | } 16 | 17 | static new(size) { 18 | return new ti_buffer(size); 19 | } 20 | 21 | push(val) { 22 | if (this.pushes >= this.size) { 23 | this.sum -= this.vals[this.index]; 24 | } 25 | 26 | this.sum += val; 27 | this.vals[this.index] = val; 28 | this.pushes += 1; 29 | this.index = (this.index + 1) % this.size; 30 | } 31 | 32 | qpush(val) { 33 | this.vals[this.index] = val; 34 | this.index = (this.index + 1) % this.size; 35 | } 36 | 37 | get(val) { 38 | return this.vals[(this.index + this.size - 1 + val) % this.size]; 39 | } 40 | } 41 | 42 | /** 43 | * 44 | * @param {number[]} high 45 | * @param {number[]} low 46 | * @param {number} period 47 | * @param {number} [size] 48 | * @returns 49 | */ 50 | function cvi( 51 | high, low, 52 | period, size = high.length 53 | ) { 54 | 55 | const output = [] 56 | 57 | const per = 2 / (period + 1) 58 | 59 | const lag = new ti_buffer(period) 60 | 61 | let val = high[0] - low[0] 62 | 63 | let i 64 | for (i = 1; i < period * 2 - 1; ++i) { 65 | val = ((high[i] - low[i]) - val) * per + val 66 | 67 | lag.qpush(val) 68 | } 69 | 70 | for (i = period * 2 - 1; i < size; ++i) { 71 | val = ((high[i] - low[i]) - val) * per + val 72 | 73 | const old = lag.vals[lag.index] 74 | 75 | output.push(100.0 * (val - old) / old) 76 | 77 | lag.qpush(val) 78 | } 79 | 80 | return output 81 | } 82 | 83 | module.exports = cvi -------------------------------------------------------------------------------- /core/dc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} highs 4 | * @param {number[]} lows 5 | * @param {number} period 6 | * @returns [upper, middle, lower] 7 | */ 8 | function dc(highs, lows, period) { 9 | 10 | const upper = [] 11 | const lower = [] 12 | const middle = [] 13 | 14 | for (let i = period - 1; i < highs.length; i++) { 15 | upper.push(Math.max(...highs.slice(i - period + 1, i + 1))) 16 | lower.push(Math.min(...lows.slice(i - period + 1, i + 1))) 17 | middle.push((upper[upper.length - 1] + lower[lower.length - 1]) / 2) 18 | } 19 | 20 | return [upper, middle, lower] 21 | } 22 | 23 | module.exports = dc -------------------------------------------------------------------------------- /core/decay.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} source 3 | * @param {number} period 4 | * @param {number} [size] 5 | * @returns 6 | */ 7 | function decay( 8 | source, period, 9 | size = source.length 10 | ) { 11 | 12 | const output = [] 13 | 14 | const scale = 1.0 / period 15 | 16 | output.push(source[0]) 17 | 18 | for (let i = 1; i < size; ++i) { 19 | const d = output[output.length - 1] - scale 20 | output.push(source[i] > d ? source[i] : d) 21 | } 22 | 23 | return output 24 | } 25 | 26 | module.exports = decay -------------------------------------------------------------------------------- /core/dema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} source 3 | * @param {number} period 4 | * @param {number} [size] 5 | * @returns 6 | */ 7 | function dema( 8 | source, period, 9 | size = source.length 10 | ) { 11 | 12 | const output = [] 13 | 14 | // if (period < 1) throw new Error("Invalid Options") 15 | // if (size <= (period-1) * 2) throw new Error("Out of range") 16 | 17 | const per = 2 / (period + 1) 18 | const per1 = 1.0 - per 19 | 20 | /*Calculate EMA(input)*/ 21 | let ema = source[0] 22 | 23 | /*Calculate EMA(EMA(input))*/ 24 | let ema2 = ema 25 | 26 | for (let i = 0; i < size; ++i) { 27 | ema = ema * per1 + source[i] * per 28 | 29 | if (i == period - 1) { 30 | ema2 = ema 31 | } 32 | 33 | if (i >= period - 1) { 34 | ema2 = ema2 * per1 + ema * per 35 | 36 | if (i >= (period - 1) * 2) { 37 | output.push(ema * 2 - ema2) 38 | } 39 | } 40 | } 41 | 42 | return output 43 | } 44 | 45 | module.exports = dema -------------------------------------------------------------------------------- /core/di.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns [Plus DI, Minus DI] 9 | */ 10 | function di( 11 | high, low, close, 12 | period, size = high.length 13 | ) { 14 | 15 | const plus_di = [] 16 | const minus_di = [] 17 | 18 | // if (period < 1) throw new Error("Invalid Options") 19 | // if (size <= period - 1) throw new Error("Out of range") 20 | 21 | const per = (period - 1) / (period) 22 | 23 | let atr = 0 24 | let dmup = 0 25 | let dmdown = 0 26 | 27 | for (let i = 1; i < period; ++i) { 28 | 29 | // let truerange 30 | // Start CALC_TRUERANGE() 31 | const l = low[i] 32 | const h = high[i] 33 | const c = close[i - 1] 34 | const ych = Math.abs(h - c) 35 | const ycl = Math.abs(l - c) 36 | let v = h - l 37 | if (ych > v) v = ych 38 | if (ycl > v) v = ycl 39 | const truerange = v 40 | // End CALC_TRUERANGE() 41 | atr += truerange 42 | 43 | // Start CALC_DIRECTION 44 | let dp = high[i] - high[i - 1] 45 | let dm = low[i - 1] - low[i] 46 | 47 | if (dp < 0) { 48 | dp = 0 49 | } else if (dp > dm) { 50 | dm = 0 51 | } 52 | 53 | if (dm < 0) { 54 | dm = 0 55 | } else if (dm > dp) { 56 | dp = 0 57 | } 58 | // END CALC_DIRECTION 59 | 60 | dmup += dp; 61 | dmdown += dm; 62 | } 63 | 64 | 65 | plus_di.push(100.0 * dmup / atr) 66 | minus_di.push(100.0 * dmdown / atr) 67 | 68 | for (let i = period; i < size; ++i) { 69 | // let truerange 70 | // Start CALC_TRUERANGE() 71 | const l = low[i] 72 | const h = high[i] 73 | const c = close[i - 1] 74 | const ych = Math.abs(h - c) 75 | const ycl = Math.abs(l - c) 76 | let v = h - l 77 | if (ych > v) v = ych 78 | if (ycl > v) v = ycl 79 | const truerange = v 80 | // End CALC_TRUERANGE() 81 | atr = atr * per + truerange 82 | 83 | // Start CALC_DIRECTION 84 | let dp = high[i] - high[i - 1] 85 | let dm = low[i - 1] - low[i] 86 | 87 | if (dp < 0) { 88 | dp = 0 89 | } else if (dp > dm) { 90 | dm = 0 91 | } 92 | 93 | if (dm < 0) { 94 | dm = 0 95 | } else if (dm > dp) { 96 | dp = 0 97 | } 98 | // END CALC_DIRECTION 99 | 100 | 101 | dmup = dmup * per + dp; 102 | dmdown = dmdown * per + dm; 103 | 104 | plus_di.push(100.0 * dmup / atr) 105 | minus_di.push(100.0 * dmdown / atr) 106 | } 107 | 108 | return [plus_di, minus_di] 109 | } 110 | 111 | module.exports = di -------------------------------------------------------------------------------- /core/dm.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns [Plus DM, Minus DM] 8 | */ 9 | function dm( 10 | high, low, 11 | period, size = high.length 12 | ) { 13 | 14 | const plus_dm = [] 15 | const minus_dm = [] 16 | 17 | // if (period < 1) throw new Error("Invalid Options") 18 | // if (size <= period - 1) throw new Error("Out of range") 19 | 20 | const per = (period - 1) / (period) 21 | 22 | let dmup = 0 23 | let dmdown = 0 24 | 25 | for (let i = 1; i < period; ++i) { 26 | // Start CALC_DIRECTION 27 | let dp = high[i] - high[i - 1] 28 | let dm = low[i - 1] - low[i] 29 | 30 | if (dp < 0) { 31 | dp = 0 32 | } else if (dp > dm) { 33 | dm = 0 34 | } 35 | 36 | if (dm < 0) { 37 | dm = 0 38 | } else if (dm > dp) { 39 | dp = 0 40 | } 41 | // END CALC_DIRECTION 42 | 43 | dmup += dp 44 | dmdown += dm 45 | } 46 | 47 | 48 | plus_dm.push(dmup) 49 | minus_dm.push(dmdown) 50 | 51 | for (let i = period; i < size; ++i) { 52 | // Start CALC_DIRECTION 53 | let dp = high[i] - high[i - 1] 54 | let dm = low[i - 1] - low[i] 55 | 56 | if (dp < 0) { 57 | dp = 0 58 | } else if (dp > dm) { 59 | dm = 0 60 | } 61 | 62 | if (dm < 0) { 63 | dm = 0 64 | } else if (dm > dp) { 65 | dp = 0 66 | } 67 | // END CALC_DIRECTION 68 | 69 | dmup = dmup * per + dp 70 | dmdown = dmdown * per + dm 71 | 72 | plus_dm.push(dmup) 73 | minus_dm.push(dmdown) 74 | } 75 | 76 | return [plus_dm, minus_dm] 77 | } 78 | 79 | module.exports = dm -------------------------------------------------------------------------------- /core/dpo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function dpo( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const back = period / 2 + 1 14 | 15 | const output = [] 16 | 17 | const scale = 1.0 / period 18 | 19 | // if (period < 1) throw new Error("Invalid Options") 20 | // if (size <= period - 1) throw new Error("Out of range") 21 | 22 | let sum = 0 23 | 24 | for (let i = 0; i < period; ++i) { 25 | sum += source[i] 26 | } 27 | 28 | output.push(source[period - 1 - back] - (sum * scale)) 29 | 30 | for (let i = period; i < size; ++i) { 31 | sum += source[i] 32 | sum -= source[i - period] 33 | output.push(source[i - back] - (sum * scale)) 34 | } 35 | 36 | return output 37 | } 38 | 39 | module.exports = dpo -------------------------------------------------------------------------------- /core/dx.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function dx( 10 | high, low, 11 | period, size = high.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (period < 1) throw new Error("Invalid Options") 17 | // if (size <= period - 1) throw new Error("Out of range") 18 | 19 | const per = (period - 1) / (period) 20 | 21 | let dmup = 0 22 | let dmdown = 0 23 | 24 | for (let i = 1; i < period; ++i) { 25 | 26 | // Start CALC_DIRECTION 27 | let dp = high[i] - high[i - 1] 28 | let dm = low[i - 1] - low[i] 29 | 30 | if (dp < 0) { 31 | dp = 0 32 | } else if (dp > dm) { 33 | dm = 0 34 | } 35 | 36 | if (dm < 0) { 37 | dm = 0 38 | } else if (dm > dp) { 39 | dp = 0 40 | } 41 | // End CALC_DIRECTION 42 | 43 | dmup += dp 44 | dmdown += dm 45 | } 46 | 47 | let di_up = dmup 48 | let di_down = dmdown 49 | let dm_diff = Math.abs(di_up - di_down) 50 | let dm_sum = di_up + di_down 51 | let _dx = dm_diff / dm_sum * 100 52 | 53 | output.push(_dx) 54 | 55 | for (let i = period; i < size; ++i) { 56 | 57 | // Start CALC_DIRECTION 58 | let dp = high[i] - high[i - 1] 59 | let dm = low[i - 1] - low[i] 60 | 61 | if (dp < 0) { 62 | dp = 0 63 | } else if (dp > dm) { 64 | dm = 0 65 | } 66 | 67 | if (dm < 0) { 68 | dm = 0 69 | } else if (dm > dp) { 70 | dp = 0 71 | } 72 | // End CALC_DIRECTION 73 | 74 | 75 | dmup = dmup * per + dp; 76 | dmdown = dmdown * per + dm; 77 | 78 | 79 | di_up = dmup 80 | di_down = dmdown 81 | dm_diff = Math.abs(di_up - di_down) 82 | dm_sum = di_up + di_down 83 | _dx = dm_diff / dm_sum * 100 84 | 85 | output.push(_dx) 86 | } 87 | 88 | return output 89 | } 90 | 91 | module.exports = dx -------------------------------------------------------------------------------- /core/edecay.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function edecay( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | const scale = 1.0 - 1.0 / period 16 | 17 | output.push(source[0]) 18 | 19 | for (let i = 1; i < size; ++i) { 20 | const d = output[output.length - 1] * scale 21 | output.push(source[i] > d ? source[i] : d) 22 | } 23 | 24 | return output 25 | } 26 | 27 | module.exports = edecay -------------------------------------------------------------------------------- /core/ema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function ema( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= 0) throw new Error("Out of range") 17 | 18 | const per = 2 / (period + 1) 19 | 20 | let val = source[0] 21 | output.push(val) 22 | 23 | for (let i = 1; i < size; ++i) { 24 | val = (source[i] - val) * per + val 25 | output.push(val) 26 | } 27 | 28 | return output 29 | } 30 | 31 | module.exports = ema -------------------------------------------------------------------------------- /core/emv.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} volume 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function emv( 10 | high, low, volume, 11 | size = high.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (size <= 1) throw new Error("Out of range") 17 | 18 | let last = (high[0] + low[0]) * 0.5 19 | 20 | for (let i = 1; i < size; ++i) { 21 | const hl = (high[i] + low[i]) * 0.5 22 | const br = volume[i] / 10000.0 / (high[i] - low[i]) 23 | 24 | output.push((hl - last) / br) 25 | last = hl 26 | } 27 | 28 | return output 29 | } 30 | 31 | module.exports = emv -------------------------------------------------------------------------------- /core/fi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} close 4 | * @param {number[]} volume 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function fi( 10 | close, volume, 11 | period, size = close.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (period < 1) throw new Error("Invalid Options") 17 | // if (size <= 1) throw new Error("Out of range") 18 | 19 | const per = 2. / (period + 1.) 20 | 21 | let ema = volume[1] * (close[1] - close[0]) 22 | 23 | for (let i = 1; i < size; ++i) { 24 | ema = (volume[i] * (close[i] - close[i - 1]) - ema) * per + ema 25 | output.push(ema) 26 | } 27 | 28 | return output 29 | } 30 | 31 | module.exports = fi -------------------------------------------------------------------------------- /core/fisher.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns [fisher, signal] 8 | */ 9 | function fisher( 10 | high, low, 11 | period, size = high.length 12 | ) { 13 | 14 | const fisher = [] 15 | const signal = [] 16 | 17 | // if (period < 1) throw new Error("Invalid Options") 18 | // if (size <= period - 1) throw new Error("Out of range") 19 | 20 | let trail = 0 21 | let maxi = -1 22 | let mini = -1 23 | 24 | let max = (0.5 * (high[(0)] + low[(0)])) 25 | let min = (0.5 * (high[(0)] + low[(0)])) 26 | let val1 = 0.0 27 | let bar 28 | let fish = 0.0 29 | 30 | let j 31 | for (let i = period - 1; i < size; ++i, ++trail) { 32 | /* Maintain highest. */ 33 | bar = (0.5 * (high[(i)] + low[(i)])) 34 | if (maxi < trail) { 35 | maxi = trail 36 | max = (0.5 * (high[(maxi)] + low[(maxi)])) 37 | j = trail 38 | 39 | while (++j <= i) { 40 | bar = (0.5 * (high[(j)] + low[(j)])) 41 | if (bar >= max) { 42 | max = bar 43 | maxi = j 44 | } 45 | } 46 | 47 | } else if (bar >= max) { 48 | maxi = i 49 | max = bar 50 | } 51 | 52 | 53 | /* Maintain lowest. */ 54 | bar = (0.5 * (high[(i)] + low[(i)])) 55 | if (mini < trail) { 56 | mini = trail 57 | min = (0.5 * (high[(mini)] + low[(mini)])) 58 | j = trail 59 | 60 | while (++j <= i) { 61 | bar = (0.5 * (high[(j)] + low[(j)])) 62 | if (bar <= min) { 63 | min = bar 64 | mini = j 65 | } 66 | } 67 | 68 | } else if (bar <= min) { 69 | mini = i 70 | min = bar 71 | } 72 | 73 | let mm = max - min 74 | if (mm == 0.0) mm = 0.001 75 | val1 = 0.33 * 2.0 * (((0.5 * (high[(i)] + low[(i)])) - min) / (mm) - 0.5) + 0.67 * val1 76 | if (val1 > 0.99) val1 = .999 77 | if (val1 < -0.99) val1 = -.999 78 | 79 | signal.push(fish) 80 | fish = 0.5 * Math.log((1.0 + val1) / (1.0 - val1)) + 0.5 * fish 81 | fisher.push(fish) 82 | } 83 | 84 | return [fisher, signal] 85 | } 86 | 87 | module.exports = fisher -------------------------------------------------------------------------------- /core/fosc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function fosc( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= period) throw new Error("Out of range") 17 | 18 | // LINEAR_REGRESSION(size, input, period, output, period+1) 19 | // Start LINEAR_REGRESSION 20 | let x = 0 21 | let x2 = 0 22 | 23 | let y = 0 24 | let xy = 0 25 | 26 | // Start INIT() 27 | const p = (1.0 / (period)) 28 | let tsf = 0 29 | // End INIT() 30 | 31 | for (let i = 0; i < (period) - 1; ++i) { 32 | x += i + 1 33 | x2 += (i + 1) * (i + 1) 34 | xy += (source)[i] * (i + 1) 35 | y += (source)[i] 36 | } 37 | 38 | x += (period) 39 | x2 += (period) * (period) 40 | 41 | const bd = 1.0 / ((period) * x2 - x * x) 42 | 43 | for (let i = (period) - 1; i < (size); ++i) { 44 | xy += (source)[i] * (period) 45 | y += (source)[i] 46 | 47 | const b = ((period) * xy - x * y) * bd 48 | // Start FINAL() 49 | // ## forecast = period + 1 50 | const a = (y - b * x) * p 51 | if (i >= (period)) { 52 | output.push(100 * (source[i] - tsf) / source[i]) 53 | } 54 | tsf = (a + b * (period + 1)) 55 | // Start FINAL() 56 | 57 | xy -= y 58 | y -= (source)[i - (period) + 1] 59 | } 60 | // End LINEAR_REGRESSION 61 | 62 | return output 63 | } 64 | 65 | module.exports = fosc -------------------------------------------------------------------------------- /core/hma.js: -------------------------------------------------------------------------------- 1 | class ti_buffer { 2 | 3 | size; 4 | pushes; 5 | index; 6 | sum; 7 | vals; 8 | 9 | constructor(size) { 10 | this.size = size; 11 | this.pushes = 0; 12 | this.index = 0; 13 | this.sum = 0; 14 | this.vals = [] 15 | } 16 | 17 | static new(size) { 18 | return new ti_buffer(size); 19 | } 20 | 21 | push(val) { 22 | if (this.pushes >= this.size) { 23 | this.sum -= this.vals[this.index]; 24 | } 25 | 26 | this.sum += val; 27 | this.vals[this.index] = val; 28 | this.pushes += 1; 29 | this.index = (this.index + 1) % this.size; 30 | } 31 | 32 | qpush(val) { 33 | this.vals[this.index] = val; 34 | this.index = (this.index + 1) % this.size; 35 | } 36 | 37 | get(val) { 38 | return this.vals[(this.index + this.size - 1 + val) % this.size]; 39 | } 40 | } 41 | 42 | /** 43 | * 44 | * @param {number[]} input 45 | * @param {number} period 46 | * @param {number} [size] 47 | * @returns 48 | */ 49 | function hma(input, period, size = input.length) { 50 | 51 | const output = [] 52 | 53 | const period2 = Math.floor(period / 2) 54 | const periodsqrt = Math.floor(Math.sqrt(period)) 55 | 56 | const weights = period * (period + 1) / 2; 57 | const weights2 = period2 * (period2 + 1) / 2; 58 | const weightssqrt = periodsqrt * (periodsqrt + 1) / 2; 59 | 60 | let sum = 0; /* Flat sum of previous numbers. */ 61 | let weight_sum = 0; /* Weighted sum of previous numbers. */ 62 | 63 | let sum2 = 0; 64 | let weight_sum2 = 0; 65 | 66 | let sumsqrt = 0; 67 | let weight_sumsqrt = 0; 68 | 69 | /* Setup up the WMA(period) and WMA(period/2) on the input. */ 70 | let i; 71 | for (i = 0; i < period - 1; ++i) { 72 | weight_sum += input[i] * (i + 1); 73 | sum += input[i]; 74 | 75 | if (i >= period - period2) { 76 | weight_sum2 += input[i] * (i + 1 - (period - period2)); 77 | sum2 += input[i]; 78 | } 79 | } 80 | 81 | const buff = new ti_buffer(periodsqrt) 82 | 83 | for (i = period - 1; i < size; ++i) { 84 | weight_sum += input[i] * period; 85 | sum += input[i]; 86 | 87 | weight_sum2 += input[i] * period2; 88 | sum2 += input[i]; 89 | 90 | const wma = weight_sum / weights; 91 | const wma2 = weight_sum2 / weights2; 92 | const diff = 2 * wma2 - wma; 93 | 94 | weight_sumsqrt += diff * periodsqrt; 95 | sumsqrt += diff; 96 | 97 | buff.qpush(diff) 98 | 99 | if (i >= (period - 1) + (periodsqrt - 1)) { 100 | output.push(weight_sumsqrt / weightssqrt) 101 | 102 | weight_sumsqrt -= sumsqrt; 103 | // sumsqrt -= ti_buffer_get(buff, 1) 104 | sumsqrt -= buff.get(1) 105 | } else { 106 | weight_sumsqrt -= sumsqrt 107 | } 108 | 109 | 110 | weight_sum -= sum; 111 | sum -= input[i - period + 1]; 112 | 113 | weight_sum2 -= sum2; 114 | sum2 -= input[i - period2 + 1]; 115 | } 116 | 117 | return output 118 | } 119 | 120 | module.exports = hma -------------------------------------------------------------------------------- /core/kama.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} source 3 | * @param {number} period 4 | * @param {number} [size] 5 | * @returns 6 | */ 7 | function kama( 8 | source, period, 9 | size = source.length 10 | ) { 11 | 12 | const output = [] 13 | 14 | // if (period < 1) throw new Error("Invalid Options") 15 | // if (size <= period - 1) throw new Error("Out of range") 16 | 17 | const short_per = 2 / (2.0 + 1) 18 | const long_per = 2 / (30.0 + 1) 19 | 20 | let sum = 0 21 | 22 | for (let i = 1; i < period; ++i) { 23 | sum += Math.abs(source[i] - source[i - 1]) 24 | } 25 | 26 | let kama = source[period - 1] 27 | output.push(kama) 28 | let er 29 | let sc 30 | 31 | for (let i = period; i < size; ++i) { 32 | sum += Math.abs(source[i] - source[i - 1]) 33 | 34 | if (i > period) { 35 | sum -= Math.abs(source[i - period] - source[i - period - 1]) 36 | } 37 | 38 | if (sum != 0.0) { 39 | er = Math.abs(source[i] - source[i - period]) / sum 40 | } else { 41 | er = 1.0 42 | } 43 | sc = Math.pow(er * (short_per - long_per) + long_per, 2) 44 | 45 | kama = kama + sc * (source[i] - kama) 46 | output.push(kama) 47 | } 48 | 49 | return output 50 | } 51 | 52 | module.exports = kama -------------------------------------------------------------------------------- /core/kc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} period 7 | * @param {number} multiple 8 | * @param {number} [size] 9 | * @returns [kc_lower, kc_middle, kc_upper] 10 | */ 11 | function kc( 12 | high, low, 13 | close, period, 14 | multiple, size = high.length 15 | ) { 16 | 17 | const kc_lower = [] 18 | const kc_middle = [] 19 | const kc_upper = [] 20 | 21 | // if (period < 1) throw new Error("Invalid Options") 22 | 23 | const per = 2 / (period + 1) 24 | 25 | let price_ema = close[0] 26 | let tr_ema = high[0] - low[0] 27 | 28 | kc_lower.push(price_ema - multiple * tr_ema) 29 | kc_middle.push(price_ema) 30 | kc_upper.push(price_ema + multiple * tr_ema) 31 | 32 | let truerange = 0 33 | for (let i = 1; i < size; ++i) { 34 | price_ema = (close[i] - price_ema) * per + price_ema 35 | 36 | // Start CALC_TRUERANGE 37 | const l = low[i] 38 | const h = high[i] 39 | const c = close[i - 1] 40 | 41 | const ych = Math.abs(h - c) 42 | const ycl = Math.abs(l - c) 43 | 44 | let v = h - l 45 | 46 | if (ych > v) v = ych 47 | if (ycl > v) v = ycl 48 | truerange = v 49 | // End CALC_TRUERANGE 50 | 51 | tr_ema = (truerange - tr_ema) * per + tr_ema 52 | 53 | kc_lower.push(price_ema - multiple * tr_ema) 54 | kc_middle.push(price_ema) 55 | kc_upper.push(price_ema + multiple * tr_ema) 56 | } 57 | 58 | return [kc_lower, kc_middle, kc_upper] 59 | } 60 | 61 | module.exports = kc -------------------------------------------------------------------------------- /core/kst.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} roc1 5 | * @param {number} roc2 6 | * @param {number} roc3 7 | * @param {number} roc4 8 | * @param {number} ma1 9 | * @param {number} ma2 10 | * @param {number} ma3 11 | * @param {number} ma4 12 | * @param {number} [size] 13 | * @returns 14 | */ 15 | function kst( 16 | source, 17 | roc1, roc2, roc3, roc4, 18 | ma1, ma2, ma3, ma4, 19 | size = source.length 20 | ) { 21 | 22 | const kst = [] 23 | const kst_signal = [] 24 | 25 | // if(!(roc1 < roc2 && roc2 < roc3 && roc3 < roc4)) throw new Error("Invalid Options") 26 | 27 | // if (roc1 < 1 || roc2 < 1 || roc3 < 1 || roc4 < 1 || ma1 < 1 || ma2 < 1 || ma3 < 1 || ma4 < 1) { 28 | // return "Invalid Options" 29 | // } 30 | 31 | // Start MAX4 32 | // MAX4(max_ma, ma1, ma2, ma3, ma4) 33 | let max_ma = ma1 34 | if (max_ma < ma2) max_ma = ma2 35 | if (max_ma < ma3) max_ma = ma3 36 | if (max_ma < ma4) max_ma = ma4 37 | // End MAX4 38 | 39 | const per1 = 2 / (ma1 + 1) 40 | const per2 = 2 / (ma2 + 1) 41 | const per3 = 2 / (ma3 + 1) 42 | const per4 = 2 / (ma4 + 1) 43 | const per_signal = 2 / (9 + 1) 44 | 45 | /** 46 | * 47 | * @param {number} idx 48 | * @param {number} period 49 | * @returns 50 | */ 51 | function ROC(idx, period) { 52 | return ((source[idx] - source[idx - period]) / source[idx - period]) 53 | } 54 | 55 | let _1 = ROC(roc1, roc1) 56 | let _2 = ROC(roc2, roc2) 57 | let _3 = ROC(roc3, roc3) 58 | let _4 = ROC(roc4, roc4) 59 | 60 | for (let i = roc1 + 1; i < roc4 + 1 && i < size; ++i) { 61 | _1 = (ROC(i, roc1) - _1) * per1 + _1 62 | } 63 | for (let i = roc2 + 1; i < roc4 + 1 && i < size; ++i) { 64 | _2 = (ROC(i, roc2) - _2) * per2 + _2 65 | } 66 | for (let i = roc3 + 1; i < roc4 + 1 && i < size; ++i) { 67 | _3 = (ROC(i, roc3) - _3) * per3 + _3 68 | } 69 | for (let i = roc4 + 1; i < roc4 + 1 && i < size; ++i) { 70 | _4 = (ROC(i, roc4) - _4) * per4 + _4 71 | } 72 | 73 | let val = (_1 * 1 + _2 * 2 + _3 * 3 + _4 * 4) / 10 74 | kst_signal.push(val) 75 | 76 | let _signal = val 77 | kst.push(_signal) 78 | 79 | for (let i = roc4 + 1; i < size; ++i) { 80 | _1 = (ROC(i, roc1) - _1) * per1 + _1 81 | _2 = (ROC(i, roc2) - _2) * per2 + _2 82 | _3 = (ROC(i, roc3) - _3) * per3 + _3 83 | _4 = (ROC(i, roc4) - _4) * per4 + _4 84 | 85 | val = (_1 * 1 + _2 * 2 + _3 * 3 + _4 * 4) / 10 86 | kst.push(val) 87 | 88 | _signal = (val - _signal) * per_signal + _signal 89 | kst_signal.push(_signal) 90 | } 91 | 92 | return [kst, kst_signal] 93 | } 94 | 95 | module.exports = kst -------------------------------------------------------------------------------- /core/kvo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number[]} volume 7 | * @param {number} short_period 8 | * @param {number} long_period 9 | * @param {number} [size] 10 | * @returns 11 | */ 12 | function kvo( 13 | high, low, 14 | close, volume, 15 | short_period, long_period, 16 | size = high.length 17 | ) { 18 | 19 | // if (short_period < 1) throw new Error("Invalid Options") 20 | // if (long_period < short_period) throw new Error("Invalid Options") 21 | // if (size <= 1) throw new Error("Out of range") 22 | 23 | const short_per = 2 / (short_period + 1) 24 | const long_per = 2 / (long_period + 1) 25 | 26 | const output = [] 27 | let cm = 0 28 | let prev_hlc = high[0] + low[0] + close[0] 29 | let trend = -1 30 | 31 | let short_ema = 0 32 | let long_ema = 0 33 | 34 | for (let i = 1; i < size; ++i) { 35 | const hlc = high[i] + low[i] + close[i] 36 | const dm = high[i] - low[i] 37 | 38 | if (hlc > prev_hlc && trend != 1) { 39 | trend = 1 40 | cm = high[i - 1] - low[i - 1] 41 | } else if (hlc < prev_hlc && trend != 0) { 42 | trend = 0 43 | cm = high[i - 1] - low[i - 1] 44 | } 45 | 46 | cm += dm 47 | 48 | const vf = volume[i] * Math.abs(dm / cm * 2 - 1) * 100 * (trend ? 1.0 : -1.0) 49 | 50 | if (i == 1) { 51 | short_ema = vf 52 | long_ema = vf 53 | } else { 54 | short_ema = (vf - short_ema) * short_per + short_ema 55 | long_ema = (vf - long_ema) * long_per + long_ema 56 | } 57 | 58 | output.push(short_ema - long_ema) 59 | 60 | prev_hlc = hlc 61 | } 62 | 63 | return output 64 | } 65 | 66 | module.exports = kvo -------------------------------------------------------------------------------- /core/lag.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function lag( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 0) throw new Error("Invalid Options") 16 | // if (size <= period) throw new Error("Out of range") 17 | 18 | for (let i = period; i < size; ++i) { 19 | output.push(source[i - period]) 20 | } 21 | 22 | return output 23 | } 24 | 25 | module.exports = lag -------------------------------------------------------------------------------- /core/linreg.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function linreg( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= period - 1) throw new Error("Out of range") 17 | 18 | // Start LINEAR_REGRESSION 19 | // LINEAR_REGRESSION(size, input, period, output, period) 20 | let x = 0 21 | let x2 = 0 22 | 23 | let y = 0 24 | let xy = 0 25 | // Start INIT() 26 | const p = (1.0 / (period)) 27 | // End INIT() 28 | for (let i = 0; i < (period) - 1; ++i) { 29 | x += i + 1 30 | x2 += (i + 1) * (i + 1) 31 | xy += (source)[i] * (i + 1) 32 | y += (source)[i] 33 | } 34 | 35 | x += (period) 36 | x2 += (period) * (period) 37 | 38 | const bd = 1.0 / ((period) * x2 - x * x) 39 | 40 | for (let i = (period) - 1; i < (size); ++i) { 41 | xy += (source)[i] * (period) 42 | y += (source)[i] 43 | 44 | const b = ((period) * xy - x * y) * bd 45 | // Start FINAL 46 | // ## forecast = period 47 | const a = (y - b * x) * p 48 | output.push(a + b * (period)) 49 | // Start FINAL 50 | 51 | xy -= y 52 | y -= (source)[i - (period) + 1] 53 | } 54 | // End LINEAR_REGRESSION 55 | 56 | return output 57 | } 58 | 59 | module.exports = linreg -------------------------------------------------------------------------------- /core/linregintercept.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function linregintercept( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= period - 1) throw new Error("Out of range") 17 | 18 | // Start LINEAR_REGRESSION 19 | // LINEAR_REGRESSION(size, input, period, output, 1) 20 | let x = 0 21 | let x2 = 0 22 | 23 | let y = 0 24 | let xy = 0 25 | // Start INIT() 26 | const p = (1.0 / (period)) 27 | // End INIT() 28 | for (let i = 0; i < (period) - 1; ++i) { 29 | x += i + 1 30 | x2 += (i + 1) * (i + 1) 31 | xy += (source)[i] * (i + 1) 32 | y += (source)[i] 33 | } 34 | 35 | x += (period) 36 | x2 += (period) * (period) 37 | 38 | const bd = 1.0 / ((period) * x2 - x * x) 39 | 40 | for (let i = (period) - 1; i < (size); ++i) { 41 | xy += (source)[i] * (period) 42 | y += (source)[i] 43 | 44 | const b = ((period) * xy - x * y) * bd 45 | // Start FINAL 46 | // ## forecast = 1 47 | const a = (y - b * x) * p 48 | output.push(a + b * (1)) 49 | // Start FINAL 50 | 51 | xy -= y 52 | y -= (source)[i - (period) + 1] 53 | } 54 | // End LINEAR_REGRESSION 55 | 56 | return output 57 | } 58 | 59 | module.exports = linregintercept -------------------------------------------------------------------------------- /core/linregslope.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function linregslope( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= period - 1) throw new Error("Out of range") 17 | 18 | // Start LINEAR_REGRESSION 19 | // LINEAR_REGRESSION(size, input, period, output, period) 20 | let x = 0 21 | let x2 = 0 22 | 23 | let y = 0 24 | let xy = 0 25 | for (let i = 0; i < (period) - 1; ++i) { 26 | x += i + 1 27 | x2 += (i + 1) * (i + 1) 28 | xy += (source)[i] * (i + 1) 29 | y += (source)[i] 30 | } 31 | 32 | x += (period) 33 | x2 += (period) * (period) 34 | 35 | const bd = 1.0 / ((period) * x2 - x * x) 36 | 37 | for (let i = (period) - 1; i < (size); ++i) { 38 | xy += (source)[i] * (period) 39 | y += (source)[i] 40 | 41 | const b = ((period) * xy - x * y) * bd 42 | // Start FINAL 43 | // ## forecast = 1 44 | output.push(b) 45 | // Start FINAL 46 | 47 | xy -= y 48 | y -= (source)[i - (period) + 1] 49 | } 50 | // End LINEAR_REGRESSION 51 | 52 | return output 53 | } 54 | 55 | module.exports = linregslope -------------------------------------------------------------------------------- /core/macd.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} short_period 5 | * @param {number} long_period 6 | * @param {number} signal_period 7 | * @param {number} [size] 8 | * @returns [macd, signal, hist] 9 | */ 10 | function macd( 11 | source, short_period, 12 | long_period, signal_period, 13 | size = source.length 14 | ) { 15 | 16 | const macd = [] 17 | const signal = [] 18 | const hist = [] 19 | 20 | // if (short_period < 1) throw new Error("Invalid Options") 21 | // if (long_period < 2) throw new Error("Invalid Options") 22 | // if (long_period < short_period) throw new Error("Invalid Options") 23 | // if (signal_period < 1) throw new Error("Invalid Options") 24 | // if (size <= long_period - 1) throw new Error("Out of range") 25 | 26 | const short_per = 2 / (short_period + 1) 27 | const long_per = 2 / (long_period + 1) 28 | const signal_per = 2 / (signal_period + 1) 29 | 30 | // if (short_period == 12 && long_period == 26) { 31 | // short_per = 0.15 32 | // long_per = 0.075 33 | // } 34 | 35 | let short_ema = source[0] 36 | let long_ema = source[0] 37 | let signal_ema = 0 38 | 39 | for (let i = 1; i < size; ++i) { 40 | short_ema = (source[i] - short_ema) * short_per + short_ema 41 | long_ema = (source[i] - long_ema) * long_per + long_ema 42 | const out = short_ema - long_ema 43 | 44 | if (i == long_period - 1) { 45 | signal_ema = out 46 | } 47 | if (i >= long_period - 1) { 48 | signal_ema = (out - signal_ema) * signal_per + signal_ema 49 | 50 | macd.push(out) 51 | signal.push(signal_ema) 52 | hist.push(out - signal_ema) 53 | } 54 | } 55 | 56 | return [macd, signal, hist] 57 | } 58 | 59 | module.exports = macd -------------------------------------------------------------------------------- /core/marketfi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} volume 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function marketfi( 10 | high, low, 11 | volume, size = high.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (size <= 0) throw new Error("Out of range") 17 | 18 | for (let i = 0; i < size; ++i) { 19 | output.push((high[i] - low[i]) / volume[i]) 20 | } 21 | 22 | return output 23 | } 24 | 25 | module.exports = marketfi -------------------------------------------------------------------------------- /core/mass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function mass( 10 | high, low, 11 | period, size = high.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (period < 1) throw new Error("Invalid Options") 17 | // if (size <= 16 + sum_p) throw new Error("Out of range") 18 | 19 | const per = 2 / (9.0 + 1) 20 | const per1 = 1.0 - per 21 | 22 | let ema = high[0] - low[0] 23 | 24 | let ema2 = ema 25 | 26 | const sum = { 27 | index: 0, 28 | pushes: 0, 29 | size: period, 30 | sum: 0, 31 | vals: [] 32 | } 33 | 34 | for (let i = 0; i < size; ++i) { 35 | const hl = high[i] - low[i] 36 | 37 | ema = ema * per1 + hl * per 38 | 39 | if (i == 8) { 40 | ema2 = ema 41 | } 42 | 43 | if (i >= 8) { 44 | ema2 = ema2 * per1 + ema * per 45 | 46 | if (i >= 16) { 47 | // Start ti_buffer_push 48 | // BUFFER = sum 49 | // VAL = ema/ema2 50 | if (sum.pushes >= sum.size) { 51 | sum.sum -= sum.vals[sum.index] 52 | } 53 | 54 | sum.sum += ema / ema2 55 | sum.vals[sum.index] = ema / ema2 56 | sum.pushes += 1 57 | sum.index = (sum.index + 1) 58 | if (sum.index >= sum.size) sum.index = 0 59 | // End ti_buffer_push 60 | 61 | if (i >= 16 + period - 1) { 62 | output.push(sum.sum) 63 | } 64 | } 65 | } 66 | } 67 | 68 | return output 69 | } 70 | 71 | module.exports = mass -------------------------------------------------------------------------------- /core/max.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function max( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= period - 1) throw new Error("Out of range") 17 | 18 | let trail = 0 19 | let maxi = -1 20 | let max = source[0] 21 | 22 | let j 23 | for (let i = period - 1; i < size; ++i, ++trail) { 24 | let bar = source[i] 25 | 26 | if (maxi < trail) { 27 | maxi = trail 28 | max = source[maxi] 29 | j = trail 30 | 31 | while (++j <= i) { 32 | bar = source[j] 33 | 34 | if (bar >= max) { 35 | max = bar 36 | maxi = j 37 | } 38 | } 39 | 40 | } else if (bar >= max) { 41 | maxi = i 42 | max = bar 43 | } 44 | 45 | output.push(max) 46 | } 47 | 48 | return output 49 | } 50 | 51 | module.exports = max -------------------------------------------------------------------------------- /core/md.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function md( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | const scale = 1.0 / period 16 | 17 | // if (period < 1) throw new Error("Invalid Options") 18 | // if (size <= period - 1) throw new Error("Out of range") 19 | 20 | let sum = 0 21 | 22 | let j 23 | for (let i = 0; i < size; ++i) { 24 | const today = source[i] 25 | sum += today 26 | if (i >= period) sum -= source[i - period] 27 | 28 | const avg = sum * scale 29 | 30 | if (i >= period - 1) { 31 | let acc = 0 32 | for (j = 0; j < period; ++j) { 33 | acc += Math.abs(avg - source[i - j]) 34 | } 35 | 36 | output.push(acc * scale) 37 | } 38 | } 39 | 40 | return output 41 | } 42 | 43 | module.exports = md -------------------------------------------------------------------------------- /core/medprice.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function medprice( 9 | high, low, 10 | size = high.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | for (let i = 0; i < size; ++i) { 16 | output.push((high[i] + low[i]) * 0.5) 17 | } 18 | 19 | return output 20 | } 21 | 22 | module.exports = medprice -------------------------------------------------------------------------------- /core/mfi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number[]} volume 7 | * @param {number} period 8 | * @param {number} [size] 9 | * @returns 10 | */ 11 | function mfi( 12 | high, low, 13 | close, volume, 14 | period, size = high.length 15 | ) { 16 | 17 | // if (period < 1) throw new Error("Invalid Options") 18 | // if (size <= period) throw new Error("Out of range") 19 | 20 | const output = [] 21 | 22 | // Start TYPPRICE() 23 | let ytyp = ((high[(0)] + low[(0)] + close[(0)]) * (1.0 / 3.0)) 24 | // End TYPPRICE() 25 | 26 | const up = { 27 | size: period, 28 | index: 0, 29 | pushes: 0, 30 | sum: 0, 31 | vals: [] 32 | } 33 | 34 | const down = { 35 | size: period, 36 | index: 0, 37 | pushes: 0, 38 | sum: 0, 39 | vals: [] 40 | } 41 | 42 | for (let i = 1; i < size; ++i) { 43 | 44 | // Start TYPPRICE() 45 | const typ = ((high[(i)] + low[(i)] + close[(i)]) * (1.0 / 3.0)) 46 | // End TYPPRICE() 47 | 48 | const bar = typ * volume[i] 49 | 50 | if (typ > ytyp) { 51 | // Start ti_buffer_push 52 | // BUFFER = up 53 | // VAL = bar 54 | // ti_buffer_push(up, bar) 55 | if (up.pushes >= up.size) { 56 | up.sum -= up.vals[up.index] 57 | } 58 | 59 | up.sum += bar 60 | up.vals[up.index] = bar 61 | up.pushes += 1 62 | up.index = (up.index + 1) 63 | if (up.index >= up.size) up.index = 0 64 | // End ti_buffer_push 65 | 66 | // Start ti_buffer_push 67 | // BUFFER = down 68 | // VAL = 0.0 69 | // ti_buffer_push(down, 0.0) 70 | if (down.pushes >= down.size) { 71 | down.sum -= down.vals[down.index] 72 | } 73 | 74 | down.sum += 0.0 75 | down.vals[down.index] = 0.0 76 | down.pushes += 1 77 | down.index = (down.index + 1) 78 | if (down.index >= down.size) down.index = 0 79 | // End ti_buffer_push 80 | } else if (typ < ytyp) { 81 | // Start ti_buffer_push 82 | // BUFFER = down 83 | // VAL = bar 84 | // ti_buffer_push(down, bar) 85 | if (down.pushes >= down.size) { 86 | down.sum -= down.vals[down.index] 87 | } 88 | 89 | down.sum += bar 90 | down.vals[down.index] = bar 91 | down.pushes += 1 92 | down.index = (down.index + 1) 93 | if (down.index >= down.size) down.index = 0 94 | // End ti_buffer_push 95 | 96 | // Start ti_buffer_push 97 | // BUFFER = up 98 | // VAL = 0.0 99 | // ti_buffer_push(up, 0.0) 100 | if (up.pushes >= up.size) { 101 | up.sum -= up.vals[up.index] 102 | } 103 | 104 | up.sum += 0.0 105 | up.vals[up.index] = 0.0 106 | up.pushes += 1 107 | up.index = (up.index + 1) 108 | if (up.index >= up.size) up.index = 0 109 | // End ti_buffer_push 110 | } else { 111 | // Start ti_buffer_push 112 | // BUFFER = up 113 | // VAL = 0.0 114 | // ti_buffer_push(up, 0.0) 115 | if (up.pushes >= up.size) { 116 | up.sum -= up.vals[up.index] 117 | } 118 | 119 | up.sum += 0.0 120 | up.vals[up.index] = 0.0 121 | up.pushes += 1 122 | up.index = (up.index + 1) 123 | if (up.index >= up.size) up.index = 0 124 | // End ti_buffer_push 125 | 126 | // Start ti_buffer_push 127 | // BUFFER = down 128 | // VAL = 0.0 129 | // ti_buffer_push(down, 0.0) 130 | if (down.pushes >= down.size) { 131 | down.sum -= down.vals[down.index] 132 | } 133 | 134 | down.sum += 0.0 135 | down.vals[down.index] = 0.0 136 | down.pushes += 1 137 | down.index = (down.index + 1) 138 | if (down.index >= down.size) down.index = 0 139 | // End ti_buffer_push 140 | } 141 | 142 | ytyp = typ; 143 | 144 | if (i >= period) { 145 | output.push((up.sum / (up.sum + down.sum) * 100.0)) 146 | } 147 | } 148 | 149 | return output 150 | } 151 | 152 | module.exports = mfi -------------------------------------------------------------------------------- /core/min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function min( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= period - 1) throw new Error("Out of range") 17 | 18 | let trail = 0 19 | let mini = -1 20 | let min = source[0] 21 | 22 | let j 23 | for (let i = period - 1; i < size; ++i, ++trail) { 24 | let bar = source[i] 25 | 26 | if (mini < trail) { 27 | mini = trail 28 | min = source[mini] 29 | j = trail 30 | 31 | while (++j <= i) { 32 | bar = source[j] 33 | 34 | if (bar <= min) { 35 | min = bar 36 | mini = j 37 | } 38 | } 39 | 40 | } else if (bar <= min) { 41 | mini = i 42 | min = bar 43 | } 44 | 45 | output.push(min) 46 | } 47 | 48 | return output 49 | } 50 | 51 | module.exports = min -------------------------------------------------------------------------------- /core/mom.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function mom( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= period) throw new Error("Out of range") 17 | 18 | for (let i = period; i < size; ++i) { 19 | output.push(source[i] - source[i - period]) 20 | } 21 | 22 | return output 23 | } 24 | 25 | module.exports = mom -------------------------------------------------------------------------------- /core/msw.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function msw( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const sine = [] 14 | const lead = [] 15 | 16 | // if (period < 1) throw new Error("Invalid Options") 17 | // if (size <= period) throw new Error("Out of range") 18 | 19 | const pi = 3.1415926 20 | const tpi = 2 * pi 21 | 22 | let weight = 0 23 | let phase 24 | let rp 25 | let ip 26 | 27 | let j 28 | for (let i = period; i < size; ++i) { 29 | rp = 0 30 | ip = 0 31 | 32 | for (j = 0; j < period; ++j) { 33 | weight = source[i - j] 34 | rp = rp + Math.cos(tpi * j / period) * weight 35 | ip = ip + Math.sin(tpi * j / period) * weight 36 | } 37 | 38 | if (Math.abs(rp) > .001) { 39 | phase = Math.atan(ip / rp) 40 | } else { 41 | phase = tpi / 2.0 * (ip < 0 ? -1.0 : 1.0) 42 | } 43 | 44 | if (rp < 0.0) phase += pi 45 | phase += pi / 2.0 46 | 47 | if (phase < 0.0) phase += tpi 48 | if (phase > tpi) phase -= tpi 49 | 50 | sine.push(Math.sin(phase)) 51 | lead.push(Math.sin(phase + pi / 4.0)) 52 | } 53 | 54 | return [sine, lead] 55 | } 56 | 57 | module.exports = msw -------------------------------------------------------------------------------- /core/natr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | function natr( 11 | high, low, 12 | close, period, 13 | size = high.length 14 | ) { 15 | 16 | const output = [] 17 | 18 | // if (period < 1) throw new Error("Invalid Options") 19 | // if (size <= period - 1) throw new Error("Out of range") 20 | 21 | const per = 1.0 / (period) 22 | 23 | let sum = 0 24 | let truerange 25 | 26 | sum += high[0] - low[0] 27 | 28 | for (let i = 1; i < period; ++i) { 29 | // Start CALC_TRUERANGE() 30 | const l = low[i] 31 | const h = high[i] 32 | const c = close[i - 1] 33 | 34 | const ych = Math.abs(h - c) 35 | const ycl = Math.abs(l - c) 36 | 37 | let v = h - l 38 | 39 | if (ych > v) v = ych 40 | if (ycl > v) v = ycl 41 | truerange = v 42 | // End CALC_TRUERANGE() 43 | 44 | sum += truerange 45 | } 46 | 47 | 48 | let val = sum / period 49 | output.push(100 * (val) / close[period - 1]) 50 | 51 | for (let i = period; i < size; ++i) { 52 | // Start CALC_TRUERANGE() 53 | const l = low[i] 54 | const h = high[i] 55 | const c = close[i - 1] 56 | 57 | const ych = Math.abs(h - c) 58 | const ycl = Math.abs(l - c) 59 | 60 | let v = h - l 61 | 62 | if (ych > v) v = ych 63 | if (ycl > v) v = ycl 64 | truerange = v 65 | // End CALC_TRUERANGE() 66 | val = (truerange - val) * per + val 67 | output.push(100 * (val) / close[i]) 68 | } 69 | 70 | return output 71 | } 72 | 73 | module.exports = natr -------------------------------------------------------------------------------- /core/normalize.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number} originalLength - example 100 4 | * @param {number[]} source - example ema | sma | rsi | etc. 5 | * @param {*} empty - example NaN | Null | 0 | false | etc. 6 | * @returns 7 | */ 8 | function normalize(originalLength, source, empty = NaN) { 9 | const diff = originalLength - source.length 10 | 11 | const emptyList = [] 12 | for (let index = 0; index < diff; ++index) { 13 | emptyList.push(empty) 14 | } 15 | 16 | const result = [...emptyList, ...source] 17 | 18 | return result 19 | } 20 | 21 | module.exports = normalize -------------------------------------------------------------------------------- /core/normalize2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * More efficient 3 | * @param {number[]} source example: sma | rsi | cci | etc. 4 | * @param {number} length main source length, example: close.length 5 | * @returns 6 | */ 7 | function normalize2(source, length) { 8 | const temp = [] 9 | const diff = length - source.length 10 | temp[diff - 1] = NaN 11 | return [...temp, ...source] 12 | } 13 | 14 | module.exports = normalize2 -------------------------------------------------------------------------------- /core/nvi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} close 4 | * @param {number[]} volume 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function nvi( 9 | close, volume, 10 | size = close.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (size <= 0) throw new Error("Out of range") 16 | 17 | let nvi = 1000 18 | 19 | output.push(nvi) 20 | 21 | for (let i = 1; i < size; ++i) { 22 | 23 | if (volume[i] < volume[i - 1]) { 24 | nvi += ((close[i] - close[i - 1]) / close[i - 1]) * nvi 25 | } 26 | output.push(nvi) 27 | } 28 | 29 | return output 30 | } 31 | 32 | module.exports = nvi -------------------------------------------------------------------------------- /core/obv.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} close 4 | * @param {number[]} volume 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function obv( 9 | close, volume, 10 | size = close.length 11 | ) { 12 | 13 | const output = [] 14 | let sum = 0 15 | output.push(sum) 16 | 17 | let prev = close[0] 18 | 19 | for (let i = 1; i < size; ++i) { 20 | if (close[i] > prev) { 21 | sum += volume[i] 22 | } else if (close[i] < prev) { 23 | sum -= volume[i] 24 | } else { 25 | // No change. 26 | } 27 | 28 | prev = close[i] 29 | output.push(sum) 30 | } 31 | 32 | return output 33 | } 34 | 35 | module.exports = obv -------------------------------------------------------------------------------- /core/pbands.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} period 8 | * @param {number} [size] 9 | * @returns [pbands_lower, pbands_upper] 10 | */ 11 | function pbands( 12 | high, low, 13 | close, period, 14 | size = high.length 15 | ) { 16 | 17 | const pbands_lower = [] 18 | const pbands_upper = [] 19 | 20 | // if (period < 1) throw new Error("Invalid Options") 21 | // if (size <= period - 1) throw new Error("Out of range") 22 | 23 | let y_sum = 0. 24 | let xy_sum = 0. 25 | 26 | const x_sum = period * (period + 1) / 2. 27 | const xsq_sum = period * (period + 1) * (2 * period + 1) / 6. 28 | 29 | let i 30 | for (i = 0; i < period; ++i) { 31 | xy_sum += close[i] * (i + 1) 32 | y_sum += close[i] 33 | } 34 | 35 | --i 36 | 37 | const b = (xy_sum / period - x_sum / period * y_sum / period) / (xsq_sum / period - (x_sum / period) * (x_sum / period)) 38 | 39 | let the_max = high[i] 40 | 41 | for (let j = 1; j < period; ++j) { 42 | if (the_max < high[i - j] + j * b) { 43 | the_max = high[i - j] + j * b 44 | } 45 | } 46 | 47 | let the_min = low[i] 48 | for (let j = 1; j < period; ++j) { 49 | if (the_min > low[i - j] + j * b) { 50 | the_min = low[i - j] + j * b 51 | } 52 | } 53 | 54 | pbands_upper.push(the_max) 55 | pbands_lower.push(the_min) 56 | 57 | ++i 58 | 59 | for (; i < size; ++i) { 60 | xy_sum += -y_sum + close[i] * period; 61 | y_sum += -close[i - period] + close[i] 62 | 63 | const b = (xy_sum / period - x_sum / period * y_sum / period) / (xsq_sum / period - (x_sum / period) * (x_sum / period)); 64 | 65 | let the_max = high[i] 66 | for (let j = 1; j < period; ++j) { 67 | if (the_max < high[i - j] + j * b) { 68 | the_max = high[i - j] + j * b 69 | } 70 | } 71 | 72 | let the_min = low[i] 73 | for (let j = 1; j < period; ++j) { 74 | if (the_min > low[i - j] + j * b) { 75 | the_min = low[i - j] + j * b 76 | } 77 | } 78 | 79 | pbands_lower.push(the_min) 80 | pbands_upper.push(the_max) 81 | } 82 | 83 | return [pbands_lower, pbands_upper] 84 | } 85 | 86 | module.exports = pbands -------------------------------------------------------------------------------- /core/pfe.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} ema_period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function pfe( 10 | source, period, 11 | ema_period, size = source.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (period < 1) throw new Error("Invalid Options") 17 | // if (size <= period) throw new Error("Out of range") 18 | 19 | const per = 2 / (ema_period + 1) 20 | 21 | const denom = { 22 | size: period, 23 | index: 0, 24 | pushes: 0, 25 | sum: 0, 26 | vals: [] 27 | } 28 | 29 | let i 30 | for (i = 1; i < period; ++i) { 31 | // Start ti_buffer_push 32 | // BUFFER = denom 33 | // VAL = Math.sqrt(Math.pow(source[i] - source[i-1], 2) + 1.) 34 | // ti_buffer_push(denom, sqrt(pow(real[i] - real[i-1], 2) + 1.)) 35 | if (denom.pushes >= denom.size) { 36 | denom.sum -= denom.vals[denom.index] 37 | } 38 | 39 | denom.sum += Math.sqrt(Math.pow(source[i] - source[i - 1], 2) + 1) 40 | denom.vals[denom.index] = Math.sqrt(Math.pow(source[i] - source[i - 1], 2) + 1) 41 | denom.pushes += 1 42 | denom.index = (denom.index + 1) 43 | if (denom.index >= denom.size) denom.index = 0 44 | // End ti_buffer_push 45 | } 46 | 47 | // Start ti_buffer_push 48 | // BUFFER = denom 49 | // VAL = Math.sqrt(Math.pow(source[i] - source[i-1], 2) + 1.) 50 | // ti_buffer_push(denom, sqrt(pow(real[i] - real[i-1], 2) + 1.)) 51 | if (denom.pushes >= denom.size) { 52 | denom.sum -= denom.vals[denom.index] 53 | } 54 | 55 | denom.sum += Math.sqrt(Math.pow(source[i] - source[i - 1], 2) + 1) 56 | denom.vals[denom.index] = Math.sqrt(Math.pow(source[i] - source[i - 1], 2) + 1) 57 | denom.pushes += 1 58 | denom.index = (denom.index + 1) 59 | if (denom.index >= denom.size) denom.index = 0 60 | // End ti_buffer_push 61 | 62 | // Start SIGN 63 | // let numer = SIGN(source[i] - source[i-period]) * 100. * Math.sqrt(Math.pow(source[i] - source[i-period], 2) + 100.) 64 | const numer = ((source[i] - source[i - period]) > 0 ? 1 : -1) * 100 * Math.sqrt(Math.pow(source[i] - source[i - period], 2) + 100) 65 | // End SIGN 66 | 67 | let ema = numer / denom.sum 68 | output.push(ema) 69 | 70 | for (i = period + 1; i < size; ++i) { 71 | // Start ti_buffer_push 72 | // BUFFER = denom 73 | // VAL = Math.sqrt(Math.pow(source[i] - source[i-1], 2) + 1.) 74 | // ti_buffer_push(denom, sqrt(pow(real[i] - real[i-1], 2) + 1.)) 75 | if (denom.pushes >= denom.size) { 76 | denom.sum -= denom.vals[denom.index] 77 | } 78 | 79 | denom.sum += Math.sqrt(Math.pow(source[i] - source[i - 1], 2) + 1) 80 | denom.vals[denom.index] = Math.sqrt(Math.pow(source[i] - source[i - 1], 2) + 1) 81 | denom.pushes += 1 82 | denom.index = (denom.index + 1) 83 | if (denom.index >= denom.size) denom.index = 0 84 | // End ti_buffer_push 85 | 86 | // Start SIGN 87 | // let numer2 = SIGN(real[i] - real[i-(int)period]) * 100. * sqrt(pow(real[i] - real[i-(int)period], 2) + 100.) 88 | const numer2 = ((source[i] - source[i - period]) > 0 ? 1 : -1) * 100 * Math.sqrt(Math.pow(source[i] - source[i - period], 2) + 100) 89 | // End SIGN 90 | 91 | // Start EMA_NEXT 92 | // ema = EMA_NEXT(numer2 / denom->sum) 93 | ema = (((numer2 / denom.sum) - ema) * per + ema) 94 | // End EMA_NEXT 95 | 96 | output.push(ema) 97 | } 98 | 99 | return output 100 | } 101 | 102 | module.exports = pfe -------------------------------------------------------------------------------- /core/posc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} period 7 | * @param {number} ema_period 8 | * @param {number} [size] 9 | * @returns 10 | */ 11 | function posc( 12 | high, low, 13 | close, period, 14 | ema_period, size = high.length 15 | ) { 16 | 17 | const output = [] 18 | 19 | // if (period < 1) throw new Error("Invalid Options") 20 | // if (ema_period < 1) throw new Error("Invalid Options") 21 | // if (size <= period - 1) throw new Error("Out of range") 22 | 23 | let y_sum = 0 24 | let xy_sum = 0 25 | let ema 26 | 27 | const x_sum = period * (period + 1) / 2 28 | const xsq_sum = period * (period + 1) * (2 * period + 1) / 6 29 | 30 | let i 31 | for (i = 0; i < period; ++i) { 32 | xy_sum += close[i] * (i + 1) 33 | y_sum += close[i] 34 | } 35 | 36 | --i 37 | 38 | const b = (xy_sum / period - x_sum / period * y_sum / period) / (xsq_sum / period - (x_sum / period) * (x_sum / period)) 39 | 40 | let the_max = high[i] 41 | for (let j = 1; j < period; ++j) { 42 | if (the_max < high[i - j] + j * b) { 43 | the_max = high[i - j] + j * b 44 | } 45 | } 46 | let the_min = low[i] 47 | for (let j = 1; j < period; ++j) { 48 | if (the_min > low[i - j] + j * b) { 49 | the_min = low[i - j] + j * b 50 | } 51 | } 52 | 53 | ema = (close[i] - the_min) / (the_max - the_min) * 100 54 | output.push(ema) 55 | 56 | ++i 57 | 58 | for (; i < size; ++i) { 59 | xy_sum += -y_sum + close[i] * period 60 | y_sum += -close[i - period] + close[i] 61 | 62 | const b = (xy_sum / period - x_sum / period * y_sum / period) / (xsq_sum / period - (x_sum / period) * (x_sum / period)) 63 | 64 | let the_max = high[i] 65 | for (let j = 1; j < period; ++j) { 66 | if (the_max < high[i - j] + j * b) { 67 | the_max = high[i - j] + j * b 68 | } 69 | } 70 | 71 | let the_min = low[i] 72 | for (let j = 1; j < period; ++j) { 73 | if (the_min > low[i - j] + j * b) { 74 | the_min = low[i - j] + j * b 75 | } 76 | } 77 | 78 | const osc = (close[i] - the_min) / (the_max - the_min) * 100 79 | ema = (osc - ema) * 2. / (1 + ema_period) + ema 80 | output.push(ema) 81 | } 82 | 83 | return output 84 | } 85 | 86 | module.exports = posc -------------------------------------------------------------------------------- /core/ppo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} short_period 5 | * @param {number} long_period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function ppo( 10 | source, short_period, 11 | long_period, size = source.length 12 | ) { 13 | 14 | const ppo = [] 15 | 16 | // if (short_period < 1) throw new Error("Invalid Options") 17 | // if (long_period < 2) throw new Error("Invalid Options") 18 | // if (long_period < short_period) throw new Error("Invalid Options") 19 | // if (size <= 1) throw new Error("Out of range") 20 | 21 | const short_per = 2 / (short_period + 1) 22 | const long_per = 2 / (long_period + 1) 23 | 24 | let short_ema = source[0] 25 | let long_ema = source[0] 26 | 27 | for (let i = 1; i < size; ++i) { 28 | short_ema = (source[i] - short_ema) * short_per + short_ema 29 | long_ema = (source[i] - long_ema) * long_per + long_ema 30 | const out = 100.0 * (short_ema - long_ema) / long_ema 31 | 32 | ppo.push(out) 33 | } 34 | 35 | return ppo 36 | } 37 | 38 | module.exports = ppo -------------------------------------------------------------------------------- /core/psar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number} accel_step 6 | * @param {number} accel_max 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | function psar( 11 | high, low, 12 | accel_step, accel_max, 13 | size = high.length 14 | ) { 15 | 16 | const output = [] 17 | 18 | // if (accel_step <= 0) throw new Error("Invalid Options") 19 | // if (accel_max <= accel_step) throw new Error("Invalid Options") 20 | // if (size < 2) throw new Error("Out of range") 21 | 22 | let lng 23 | if (high[0] + low[0] <= high[1] + low[1]) { 24 | lng = 1 25 | } else { 26 | lng = 0 27 | } 28 | 29 | let sar 30 | let extreme 31 | 32 | if (lng) { 33 | extreme = high[0] 34 | sar = low[0] 35 | } else { 36 | extreme = low[0] 37 | sar = high[0] 38 | } 39 | 40 | let accel = accel_step 41 | 42 | for (let i = 1; i < size; ++i) { 43 | 44 | sar = (extreme - sar) * accel + sar 45 | 46 | if (lng) { 47 | 48 | if (i >= 2 && (sar > low[i - 2])) sar = low[i - 2] 49 | 50 | if ((sar > low[i - 1])) sar = low[i - 1] 51 | 52 | if (accel < accel_max && high[i] > extreme) { 53 | accel += accel_step 54 | if (accel > accel_max) accel = accel_max 55 | } 56 | 57 | if (high[i] > extreme) extreme = high[i] 58 | 59 | } else { 60 | 61 | if (i >= 2 && (sar < high[i - 2])) sar = high[i - 2] 62 | 63 | if ((sar < high[i - 1])) sar = high[i - 1] 64 | 65 | if (accel < accel_max && low[i] < extreme) { 66 | accel += accel_step 67 | if (accel > accel_max) accel = accel_max 68 | } 69 | 70 | if (low[i] < extreme) extreme = low[i] 71 | } 72 | 73 | if ((lng && low[i] < sar) || (!lng && high[i] > sar)) { 74 | accel = accel_step 75 | sar = extreme 76 | 77 | lng = !lng 78 | 79 | if (!lng) { 80 | extreme = low[i] 81 | } else { 82 | extreme = high[i] 83 | } 84 | } 85 | 86 | output.push(sar) 87 | } 88 | 89 | return output 90 | } 91 | 92 | module.exports = psar -------------------------------------------------------------------------------- /core/pvi.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * @param {number[]} close 5 | * @param {number[]} volume 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function pvi( 10 | close, volume, 11 | size = close.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (size <= 0) throw new Error("Out of range") 17 | 18 | let pvi = 1000 19 | output.push(pvi) 20 | 21 | for (let i = 1; i < size; ++i) { 22 | 23 | if (volume[i] > volume[i - 1]) { 24 | pvi += ((close[i] - close[i - 1]) / close[i - 1]) * pvi; 25 | } 26 | output.push(pvi) 27 | } 28 | 29 | return output 30 | } 31 | 32 | module.exports = pvi -------------------------------------------------------------------------------- /core/qstick.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} open 4 | * @param {number[]} close 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function qstick( 10 | open, 11 | close, 12 | period, 13 | size = close.length 14 | ) { 15 | 16 | const output = [] 17 | const scale = 1.0 / period 18 | 19 | let sum = 0 20 | 21 | let i; 22 | for (i = 0; i < period; ++i) { 23 | sum += close[i] - open[i] 24 | } 25 | 26 | output.push(sum * scale) 27 | 28 | for (i = period; i < size; ++i) { 29 | sum += close[i] - open[i] 30 | sum -= close[i - period] - open[i - period] 31 | output.push(sum * scale) 32 | } 33 | 34 | return output 35 | } 36 | 37 | module.exports = qstick -------------------------------------------------------------------------------- /core/rmi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} lookback_period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function rmi( 10 | source, period, 11 | lookback_period, size = source.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (period < 1) throw new Error("Invalid Options") 17 | // if (lookback_period < 1) throw new Error("Invalid Options") 18 | // if (size <= lookback_period) throw new Error("Out of range") 19 | 20 | let gains_ema 21 | let losses_ema 22 | 23 | let i = lookback_period 24 | gains_ema = ((0) > (source[i] - source[i - lookback_period]) ? (0) : (source[i] - source[i - lookback_period])) 25 | losses_ema = ((0) > (source[i - lookback_period] - source[i]) ? (0) : (source[i - lookback_period] - source[i])) 26 | ++i 27 | 28 | output.push(gains_ema / (gains_ema + losses_ema) * 100) 29 | 30 | for (; i < size; ++i) { 31 | gains_ema = ((0) > (source[i] - source[i - lookback_period]) ? (0) : (source[i] - source[i - lookback_period]) - gains_ema) * 2. / (1 + period) + gains_ema 32 | losses_ema = ((0) > (source[i - lookback_period] - source[i]) ? (0) : (source[i - lookback_period] - source[i]) - losses_ema) * 2. / (1 + period) + losses_ema 33 | output.push(gains_ema / (gains_ema + losses_ema) * 100) 34 | } 35 | 36 | return output 37 | } 38 | 39 | module.exports = rmi -------------------------------------------------------------------------------- /core/rmta.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} beta 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function rmta( 10 | source, period, 11 | beta, size = source.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (period < 1) throw new Error("Invalid Options") 17 | // if (size <= period - 1) throw new Error("Out of range") 18 | 19 | const alpha = 1 - beta 20 | let b = (1 - alpha) * source[0] + source[0] 21 | let rmta = (1 - alpha) * source[0] + alpha * (source[0] + b) 22 | 23 | for (let i = 1; i < period - 1; ++i) { 24 | const next_b = (1 - alpha) * b + source[i] 25 | rmta = (1 - alpha) * rmta + alpha * (source[i] + next_b - b) 26 | b = next_b 27 | } 28 | 29 | for (let i = period - 1; i < size; ++i) { 30 | const next_b = (1. - alpha) * b + source[i] 31 | rmta = (1 - alpha) * rmta + alpha * (source[i] + next_b - b) 32 | b = next_b 33 | output.push(rmta) 34 | } 35 | 36 | return output 37 | } 38 | 39 | module.exports = rmta -------------------------------------------------------------------------------- /core/roc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function roc( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= period) throw new Error("Out of range") 17 | 18 | for (let i = period; i < size; ++i) { 19 | output.push((source[i] - source[i - period]) / source[i - period]) 20 | } 21 | 22 | return output 23 | } 24 | 25 | module.exports = roc -------------------------------------------------------------------------------- /core/rocr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function rocr( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= period) throw new Error("Out of range") 17 | 18 | for (let i = period; i < size; ++i) { 19 | output.push(source[i] / source[i - period]) 20 | } 21 | 22 | return output 23 | } 24 | 25 | module.exports = rocr -------------------------------------------------------------------------------- /core/rsi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function rsi( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | const per = 1.0 / (period) 16 | 17 | // if (period < 1) throw new Error("Invalid Options") 18 | // if (size <= period) throw new Error("Out of range") 19 | 20 | let smooth_up = 0 21 | let smooth_down = 0 22 | 23 | for (let i = 1; i <= period; ++i) { 24 | const upward = source[i] > source[i - 1] ? source[i] - source[i - 1] : 0 25 | const downward = source[i] < source[i - 1] ? source[i - 1] - source[i] : 0 26 | smooth_up += upward 27 | smooth_down += downward 28 | } 29 | 30 | smooth_up /= period 31 | smooth_down /= period 32 | output.push(100.0 * (smooth_up / (smooth_up + smooth_down))) 33 | 34 | for (let i = period + 1; i < size; ++i) { 35 | const upward = (source[i] > source[i - 1] ? source[i] - source[i - 1] : 0) 36 | const downward = (source[i] < source[i - 1] ? source[i - 1] - source[i] : 0) 37 | 38 | smooth_up = (upward - smooth_up) * per + smooth_up 39 | smooth_down = (downward - smooth_down) * per + smooth_down 40 | 41 | output.push(100.0 * (smooth_up / (smooth_up + smooth_down))) 42 | } 43 | 44 | return output 45 | } 46 | 47 | module.exports = rsi -------------------------------------------------------------------------------- /core/rvi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} sma_period 5 | * @param {number} stddev_period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function rvi( 10 | source, sma_period, 11 | stddev_period, size = source.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (sma_period < 1) throw new Error("Invalid Options") 17 | // if (stddev_period < 1) throw new Error("Invalid Options") 18 | // if (size <= stddev_period-1) throw new Error("Out of range") 19 | 20 | let y_sum = 0 21 | let xy_sum = 0 22 | 23 | const x_sum = stddev_period * (stddev_period + 1) / 2 24 | const xsq_sum = stddev_period * (stddev_period + 1) * (2 * stddev_period + 1) / 6 25 | 26 | let gains_ema = 0 27 | let losses_ema = 0 28 | 29 | let i = 0 30 | for (; i < stddev_period; ++i) { 31 | xy_sum += source[i] * (i + 1) 32 | y_sum += source[i] 33 | } 34 | 35 | --i; 36 | const b = (xy_sum / stddev_period - x_sum / stddev_period * y_sum / stddev_period) / (xsq_sum / stddev_period - (x_sum / stddev_period) * (x_sum / stddev_period)) 37 | const a = y_sum / stddev_period - b * x_sum / stddev_period 38 | 39 | const higher = source[i] - (a + b * stddev_period) 40 | if (higher > 0) { 41 | gains_ema = higher * higher / stddev_period 42 | } else { 43 | losses_ema = higher * higher / stddev_period 44 | } 45 | 46 | if (gains_ema + losses_ema == 0) { 47 | output.push(50) 48 | } else { 49 | output.push(gains_ema / (gains_ema + losses_ema) * 100) 50 | } 51 | ++i 52 | 53 | for (; i < size; ++i) { 54 | xy_sum += -y_sum + source[i] * stddev_period 55 | y_sum += -source[i - stddev_period] + source[i] 56 | 57 | const b = (xy_sum / stddev_period - x_sum / stddev_period * y_sum / stddev_period) / (xsq_sum / stddev_period - (x_sum / stddev_period) * (x_sum / stddev_period)) 58 | const a = y_sum / stddev_period - b * x_sum / stddev_period 59 | 60 | const higher = source[i] - (a + b * stddev_period) 61 | 62 | if (higher > 0) { 63 | gains_ema = (higher * higher / stddev_period - gains_ema) * 2. / (sma_period + 1) + gains_ema 64 | } else { 65 | losses_ema = (higher * higher / stddev_period - losses_ema) * 2. / (sma_period + 1) + losses_ema 66 | } 67 | 68 | if (gains_ema + losses_ema == 0) { 69 | output.push(50) 70 | } else { 71 | output.push(gains_ema / (gains_ema + losses_ema) * 100) 72 | } 73 | } 74 | 75 | return output 76 | } 77 | 78 | module.exports = rvi -------------------------------------------------------------------------------- /core/sma.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function sma( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | const scale = 1.0 / period 16 | 17 | // if (period < 1) throw new Error("Invalid Options") 18 | // if (size <= period - 1) throw new Error("Out of range") 19 | 20 | let sum = 0 21 | 22 | for (let i = 0; i < period; ++i) { 23 | sum += source[i] 24 | } 25 | 26 | output.push(sum * scale) 27 | 28 | for (let i = period; i < size; ++i) { 29 | sum += source[i] 30 | sum -= source[i - period] 31 | output.push(sum * scale) 32 | } 33 | 34 | return output 35 | } 36 | 37 | module.exports = sma -------------------------------------------------------------------------------- /core/smi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} q_period 7 | * @param {number} r_period 8 | * @param {number} s_period 9 | * @param {number} [size] 10 | * @returns 11 | */ 12 | function smi( 13 | high, low, 14 | close, q_period, 15 | r_period, s_period, 16 | size = high.length 17 | ) { 18 | 19 | const output = [] 20 | 21 | // if (q_period < 1 || r_period < 1 || s_period < 1) { 22 | // throw new Error("Invalid Options" 23 | // } 24 | 25 | let progress = -q_period + 1 26 | 27 | let ema_r_num = NaN 28 | let ema_s_num = NaN 29 | let ema_r_den = NaN 30 | let ema_s_den = NaN 31 | let ll = 0 32 | let hh = 0 33 | let hh_idx = 0 34 | let ll_idx = 0 35 | 36 | let var1 = 0 37 | 38 | let i = 0 39 | for (; i < size && progress == -q_period + 1; ++i, ++progress) { 40 | hh = high[i] 41 | hh_idx = progress 42 | ll = low[i] 43 | ll_idx = progress 44 | } 45 | 46 | for (; i < size && progress < 0; ++i, ++progress) { 47 | if (hh <= high[i]) { 48 | hh = high[i] 49 | hh_idx = progress 50 | } 51 | 52 | if (ll >= low[i]) { 53 | ll = low[i] 54 | ll_idx = progress 55 | } 56 | } 57 | 58 | for (; i < size && progress == 0; ++i, ++progress) { 59 | if (hh <= high[i]) { 60 | hh = high[i] 61 | hh_idx = progress 62 | } 63 | 64 | if (ll >= low[i]) { 65 | ll = low[i] 66 | ll_idx = progress 67 | } 68 | 69 | ema_r_num = ema_s_num = close[i] - 0.5 * (hh + ll) 70 | ema_r_den = ema_s_den = hh - ll 71 | 72 | output.push(100 * ema_s_num / (0.5 * ema_s_den)) 73 | } 74 | 75 | for (; i < size; ++i, ++progress) { 76 | if (hh_idx == progress - q_period) { 77 | hh = high[i] 78 | hh_idx = progress 79 | for (let j = 1; j < q_period; ++j) { 80 | var1 = high[i - j] 81 | if (var1 > hh) { 82 | hh = var1 83 | hh_idx = progress - j; 84 | } 85 | } 86 | 87 | } else if (hh <= high[i]) { 88 | hh = high[i] 89 | hh_idx = progress 90 | } 91 | 92 | if (ll_idx == progress - q_period) { 93 | ll = low[i] 94 | ll_idx = progress 95 | for (let j = 1; j < q_period; ++j) { 96 | var1 = low[i - j] 97 | if (var1 < ll) { 98 | ll = var1 99 | ll_idx = progress - j 100 | } 101 | } 102 | 103 | } else if (ll >= low[i]) { 104 | ll = low[i] 105 | ll_idx = progress 106 | } 107 | 108 | ema_r_num = ((close[i] - 0.5 * (hh + ll)) - ema_r_num) * (2 / (1 + r_period)) + ema_r_num 109 | ema_s_num = (ema_r_num - ema_s_num) * (2 / (1 + s_period)) + ema_s_num 110 | 111 | ema_r_den = ((hh - ll) - ema_r_den) * (2 / (1 + r_period)) + ema_r_den 112 | ema_s_den = (ema_r_den - ema_s_den) * (2 / (1 + s_period)) + ema_s_den 113 | 114 | output.push(100 * ema_s_num / (0.5 * ema_s_den)) 115 | } 116 | 117 | return output 118 | } 119 | 120 | module.exports = smi -------------------------------------------------------------------------------- /core/stddev.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function stddev( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | const scale = 1.0 / period 16 | 17 | // if (period < 1) throw new Error("Invalid Options") 18 | // if (size <= period - 1) throw new Error("Out of range") 19 | 20 | let sum = 0 21 | let sum2 = 0 22 | 23 | for (let i = 0; i < period; ++i) { 24 | sum += source[i] 25 | sum2 += source[i] * source[i] 26 | } 27 | 28 | let s2s2 = (sum2 * scale - (sum * scale) * (sum * scale)) 29 | if (s2s2 > 0.0) s2s2 = Math.sqrt(s2s2) 30 | output.push(s2s2) 31 | 32 | for (let i = period; i < size; ++i) { 33 | sum += source[i] 34 | sum2 += source[i] * source[i] 35 | 36 | sum -= source[i - period] 37 | sum2 -= source[i - period] * source[i - period] 38 | 39 | let s2s2 = (sum2 * scale - (sum * scale) * (sum * scale)) 40 | if (s2s2 > 0.0) s2s2 = Math.sqrt(s2s2) 41 | output.push(s2s2) 42 | } 43 | 44 | return output 45 | } 46 | 47 | module.exports = stddev -------------------------------------------------------------------------------- /core/stderr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function stderr( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | const scale = 1.0 / period 16 | 17 | // if (period < 1) throw new Error("Invalid Options") 18 | // if (size <= period - 1) throw new Error("Out of range") 19 | 20 | let sum = 0 21 | let sum2 = 0 22 | 23 | const mul = 1.0 / Math.sqrt(period) 24 | 25 | for (let i = 0; i < period; ++i) { 26 | sum += source[i] 27 | sum2 += source[i] * source[i] 28 | } 29 | 30 | let s2s2 = (sum2 * scale - (sum * scale) * (sum * scale)) 31 | if (s2s2 > 0.0) s2s2 = Math.sqrt(s2s2) 32 | output.push(mul * s2s2) 33 | 34 | for (let i = period; i < size; ++i) { 35 | sum += source[i] 36 | sum2 += source[i] * source[i] 37 | 38 | sum -= source[i - period] 39 | sum2 -= source[i - period] * source[i - period] 40 | 41 | let s2s2 = (sum2 * scale - (sum * scale) * (sum * scale)) 42 | if (s2s2 > 0.0) s2s2 = Math.sqrt(s2s2) 43 | output.push(mul * s2s2) 44 | } 45 | 46 | return output 47 | } 48 | 49 | module.exports = stderr -------------------------------------------------------------------------------- /core/stoch.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} kperiod 7 | * @param {number} kslow 8 | * @param {number} dperiod 9 | * @param {number} [size] 10 | * @returns [stoch, stoch_ma] 11 | */ 12 | function stoch( 13 | high, low, 14 | close, 15 | kperiod, kslow, dperiod, 16 | size = high.length 17 | ) { 18 | 19 | const kper = 1.0 / kslow 20 | const dper = 1.0 / dperiod 21 | 22 | const stoch = [] 23 | const stoch_ma = [] 24 | 25 | // if (kperiod < 1) throw new Error("Invalid Options") 26 | // if (kslow < 1) throw new Error("Invalid Options") 27 | // if (dperiod < 1) throw new Error("Invalid Options") 28 | // if (size <= (kperiod + kslow + dperiod - 3)) throw new Error("Out of range") 29 | 30 | let trail = 0 31 | let maxi = -1 32 | let mini = -1 33 | let max = high[0] 34 | let min = low[0] 35 | let bar 36 | 37 | const k_sum = { 38 | size: kslow, 39 | index: 0, 40 | pushes: 0, 41 | sum: 0, 42 | vals: [] 43 | } 44 | 45 | const d_sum = { 46 | size: dperiod, 47 | index: 0, 48 | pushes: 0, 49 | sum: 0, 50 | vals: [] 51 | } 52 | 53 | let j 54 | for (let i = 0; i < size; ++i) { 55 | 56 | if (i >= kperiod) ++trail 57 | 58 | // Maintain highest 59 | bar = high[i] 60 | if (maxi < trail) { 61 | maxi = trail 62 | max = high[maxi] 63 | j = trail 64 | 65 | while (++j <= i) { 66 | bar = high[j] 67 | if (bar >= max) { 68 | max = bar 69 | maxi = j 70 | } 71 | } 72 | 73 | } else if (bar >= max) { 74 | maxi = i 75 | max = bar 76 | } 77 | 78 | // Maintain lowest 79 | bar = low[i] 80 | if (mini < trail) { 81 | mini = trail 82 | min = low[mini] 83 | j = trail 84 | 85 | while (++j <= i) { 86 | bar = low[j] 87 | if (bar <= min) { 88 | min = bar 89 | mini = j 90 | } 91 | } 92 | 93 | } else if (bar <= min) { 94 | mini = i 95 | min = bar 96 | } 97 | 98 | // Calculate it 99 | const kdiff = (max - min) 100 | const kfast = kdiff == 0.0 ? 0.0 : 100 * ((close[i] - min) / kdiff) 101 | 102 | // Start ti_buffer_push 103 | // BUFFER = k_sum 104 | // VAL = kfast 105 | // ti_buffer_push(k_sum, kfast) 106 | if (k_sum.pushes >= k_sum.size) { 107 | k_sum.sum -= k_sum.vals[k_sum.index] 108 | } 109 | 110 | k_sum.sum += kfast 111 | k_sum.vals[k_sum.index] = kfast 112 | k_sum.pushes += 1 113 | k_sum.index = (k_sum.index + 1) 114 | if (k_sum.index >= k_sum.size) k_sum.index = 0 115 | // End ti_buffer_push 116 | 117 | 118 | if (i >= kperiod - 1 + kslow - 1) { 119 | const k = k_sum.sum * kper 120 | // Start ti_buffer_push 121 | // BUFFER = d_sum 122 | // VAL = k 123 | // ti_buffer_push(d_sum, k) 124 | if (d_sum.pushes >= d_sum.size) { 125 | d_sum.sum -= d_sum.vals[d_sum.index] 126 | } 127 | 128 | d_sum.sum += k 129 | d_sum.vals[d_sum.index] = k 130 | d_sum.pushes += 1 131 | d_sum.index = (d_sum.index + 1) 132 | if (d_sum.index >= d_sum.size) d_sum.index = 0 133 | // End ti_buffer_push 134 | 135 | if (i >= kperiod - 1 + kslow - 1 + dperiod - 1) { 136 | stoch.push(k) 137 | stoch_ma.push(d_sum.sum * dper) 138 | } 139 | } 140 | } 141 | 142 | return [stoch, stoch_ma] 143 | } 144 | 145 | module.exports = stoch -------------------------------------------------------------------------------- /core/stochrsi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function stochrsi( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | const per = 1.0 / (period) 16 | 17 | // if (period < 2) throw new Error("Invalid Options") 18 | // if (size <= (period) * 2 - 1) throw new Error("Out of range") 19 | 20 | const rsi = { 21 | size: period, 22 | index: 0, 23 | pushes: 0, 24 | sum: 0, 25 | vals: [] 26 | } 27 | 28 | let smooth_up = 0 29 | let smooth_down = 0 30 | 31 | for (let i = 1; i <= period; ++i) { 32 | const upward = source[i] > source[i - 1] ? source[i] - source[i - 1] : 0 33 | const downward = source[i] < source[i - 1] ? source[i - 1] - source[i] : 0 34 | smooth_up += upward 35 | smooth_down += downward 36 | } 37 | 38 | smooth_up /= period 39 | smooth_down /= period 40 | let r = 100.0 * (smooth_up / (smooth_up + smooth_down)) 41 | 42 | // Start ti_buffer_push 43 | // BUFFER = rsi 44 | // VAL = r 45 | // ti_buffer_push(rsi, r) 46 | if (rsi.pushes >= rsi.size) { 47 | rsi.sum -= rsi.vals[rsi.index] 48 | } 49 | 50 | rsi.sum += r 51 | rsi.vals[rsi.index] = r 52 | rsi.pushes += 1 53 | rsi.index = (rsi.index + 1) 54 | if (rsi.index >= rsi.size) rsi.index = 0 55 | // End ti_buffer_push 56 | 57 | let min = r 58 | let max = r 59 | let mini = 0 60 | let maxi = 0 61 | 62 | for (let i = period + 1; i < size; ++i) { 63 | const upward = source[i] > source[i - 1] ? source[i] - source[i - 1] : 0 64 | const downward = source[i] < source[i - 1] ? source[i - 1] - source[i] : 0 65 | 66 | smooth_up = (upward - smooth_up) * per + smooth_up 67 | smooth_down = (downward - smooth_down) * per + smooth_down 68 | 69 | r = 100.0 * (smooth_up / (smooth_up + smooth_down)) 70 | 71 | if (r > max) { 72 | max = r; 73 | maxi = rsi.index 74 | } else if (maxi == rsi.index) { 75 | max = r 76 | for (let j = 0; j < rsi.size; ++j) { 77 | if (j == rsi.index) continue 78 | 79 | if (rsi.vals[j] > max) { 80 | max = rsi.vals[j] 81 | maxi = j 82 | } 83 | } 84 | } 85 | 86 | if (r < min) { 87 | min = r 88 | mini = rsi.index 89 | } else if (mini == rsi.index) { 90 | min = r 91 | for (let j = 0; j < rsi.size; ++j) { 92 | if (j == rsi.index) continue 93 | if (rsi.vals[j] < min) { 94 | min = rsi.vals[j] 95 | mini = j 96 | } 97 | } 98 | } 99 | 100 | // Start ti_buffer_qpush 101 | // BUFFER = rsi 102 | // VAL = r 103 | // ti_buffer_qpush(rsi, r) 104 | rsi.vals[rsi.index] = r 105 | rsi.index = rsi.index + 1 106 | if (rsi.index >= rsi.size) rsi.index = 0 107 | // End ti_buffer_qpush 108 | 109 | if (i > period * 2 - 2) { 110 | const diff = max - min 111 | if (diff == 0.0) { 112 | output.push(0.0) 113 | } else { 114 | output.push((r - min) / (diff)) 115 | } 116 | } 117 | } 118 | 119 | return output 120 | } 121 | 122 | module.exports = stochrsi -------------------------------------------------------------------------------- /core/sum.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function sum( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= period - 1) throw new Error("Out of range") 17 | 18 | let sum = 0 19 | 20 | for (let i = 0; i < period; ++i) { 21 | sum += source[i] 22 | } 23 | 24 | output.push(sum) 25 | 26 | for (let i = period; i < size; ++i) { 27 | sum += source[i] 28 | sum -= source[i - period] 29 | output.push(sum) 30 | } 31 | 32 | return output 33 | } 34 | 35 | module.exports = sum -------------------------------------------------------------------------------- /core/tema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function tema( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= (period - 1) * 3) throw new Error("Out of range") 17 | 18 | const per = 2 / (period + 1) 19 | const per1 = 1.0 - per 20 | 21 | let ema = source[0] 22 | let ema2 = 0 23 | let ema3 = 0 24 | 25 | for (let i = 0; i < size; ++i) { 26 | ema = ema * per1 + source[i] * per 27 | if (i == period - 1) { 28 | ema2 = ema 29 | } 30 | 31 | if (i >= period - 1) { 32 | ema2 = ema2 * per1 + ema * per 33 | if (i == (period - 1) * 2) { 34 | ema3 = ema2 35 | } 36 | 37 | if (i >= (period - 1) * 2) { 38 | ema3 = ema3 * per1 + ema2 * per 39 | 40 | if (i >= (period - 1) * 3) { 41 | output.push(3 * ema - 3 * ema2 + ema3) 42 | } 43 | } 44 | } 45 | } 46 | 47 | return output 48 | } 49 | 50 | module.exports = tema -------------------------------------------------------------------------------- /core/tr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function tr( 10 | high, low, 11 | close, size = high.length 12 | ) { 13 | 14 | const output = [] 15 | let truerange 16 | 17 | output[0] = high[0] - low[0] 18 | 19 | for (let i = 1; i < size; ++i) { 20 | // Start CALC_TRUERANGE 21 | const l = low[i] 22 | const h = high[i] 23 | const c = close[i - 1] 24 | 25 | const ych = Math.abs(h - c) 26 | const ycl = Math.abs(l - c) 27 | 28 | let v = h - l 29 | 30 | if (ych > v) v = ych 31 | if (ycl > v) v = ycl 32 | truerange = v 33 | // End CALC_TRUERANGE 34 | output.push(truerange) 35 | } 36 | 37 | return output 38 | } 39 | 40 | module.exports = tr -------------------------------------------------------------------------------- /core/trima.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function trima( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= period - 1) throw new Error("Out of range") 17 | 18 | const weights = 1 / ((period % 2) ? 19 | ((period / 2 + 1) * (period / 2 + 1)) : 20 | ((period / 2 + 1) * (period / 2))) 21 | 22 | let weight_sum = 0 23 | let lead_sum = 0 24 | let trail_sum = 0 25 | 26 | const lead_period = period % 2 ? period / 2 : period / 2 - 1 27 | const trail_period = lead_period + 1 28 | 29 | let w = 1 30 | 31 | for (let i = 0; i < period - 1; ++i) { 32 | weight_sum += source[i] * w 33 | 34 | if (i + 1 > period - lead_period) lead_sum += source[i] 35 | if (i + 1 <= trail_period) trail_sum += source[i] 36 | 37 | if (i + 1 < trail_period) ++w 38 | if (i + 1 >= period - lead_period) --w 39 | } 40 | 41 | 42 | let lsi = (period - 1) - lead_period + 1 43 | let tsi1 = (period - 1) - period + 1 + trail_period 44 | let tsi2 = (period - 1) - period + 1 45 | 46 | for (let i = period - 1; i < size; ++i) { 47 | weight_sum += source[i] 48 | output.push(weight_sum * weights) 49 | 50 | lead_sum += source[i] 51 | 52 | weight_sum += lead_sum; 53 | weight_sum -= trail_sum; 54 | 55 | lead_sum -= source[lsi++] 56 | trail_sum += source[tsi1++] 57 | trail_sum -= source[tsi2++] 58 | } 59 | 60 | return output 61 | } 62 | 63 | module.exports = trima -------------------------------------------------------------------------------- /core/trix.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function trix( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= ((period-1)*3)+1) throw new Error("Out of range") 17 | 18 | const start = (period * 3) - 2 19 | const per = 2 / (period + 1) 20 | 21 | let ema1 = source[0] 22 | let ema2 = 0 23 | let ema3 = 0 24 | 25 | for (let i = 1; i < start; ++i) { 26 | ema1 = (source[i] - ema1) * per + ema1 27 | 28 | if (i == period - 1) { 29 | ema2 = ema1 30 | } else if (i > period - 1) { 31 | ema2 = (ema1 - ema2) * per + ema2 32 | 33 | if (i == period * 2 - 2) { 34 | ema3 = ema2 35 | } else if (i > period * 2 - 2) { 36 | ema3 = (ema2 - ema3) * per + ema3 37 | } 38 | } 39 | } 40 | 41 | for (let i = start; i < size; ++i) { 42 | ema1 = (source[i] - ema1) * per + ema1 43 | ema2 = (ema1 - ema2) * per + ema2 44 | const last = ema3 45 | ema3 = (ema2 - ema3) * per + ema3 46 | output.push((ema3 - last) / ema3 * 100.0) 47 | } 48 | 49 | return output 50 | } 51 | 52 | module.exports = trix -------------------------------------------------------------------------------- /core/tsf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function tsf( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= period - 1) throw new Error("Out of range") 17 | 18 | // Start LINEAR_REGRESSION 19 | // LINEAR_REGRESSION(size, input, period, output, period + 1) 20 | let x = 0 21 | let x2 = 0 22 | 23 | let y = 0 24 | let xy = 0 25 | // Start INIT() 26 | const p = (1.0 / (period)) 27 | // End INIT() 28 | for (let i = 0; i < (period) - 1; ++i) { 29 | x += i + 1 30 | x2 += (i + 1) * (i + 1) 31 | xy += (source)[i] * (i + 1) 32 | y += (source)[i] 33 | } 34 | 35 | x += (period) 36 | x2 += (period) * (period) 37 | 38 | const bd = 1.0 / ((period) * x2 - x * x) 39 | 40 | for (let i = (period) - 1; i < (size); ++i) { 41 | xy += (source)[i] * (period) 42 | y += (source)[i] 43 | 44 | const b = ((period) * xy - x * y) * bd 45 | // Start FINAL 46 | // ## forecast = period + 1 47 | const a = (y - b * x) * p 48 | output.push(a + b * (period + 1)) 49 | // Start FINAL 50 | 51 | xy -= y 52 | y -= (source)[i - (period) + 1] 53 | } 54 | // End LINEAR_REGRESSION 55 | 56 | return output 57 | } 58 | 59 | module.exports = tsf -------------------------------------------------------------------------------- /core/tsi.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} y_period 5 | * @param {number} z_period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function tsi( 10 | source, y_period, 11 | z_period, size = source.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (y_period < 1 || z_period < 1) { 17 | // throw new Error("Invalid Options") 18 | // } 19 | 20 | let progress = -1 21 | 22 | let price = 0 23 | let y_ema_num = 0 24 | let z_ema_num = 0 25 | let y_ema_den = 0 26 | let z_ema_den = 0 27 | 28 | let i = 0 29 | for (; i < size && progress == -1; ++i, ++progress) { 30 | price = source[i] 31 | } 32 | 33 | for (; i < size && progress == 0; ++i, ++progress) { 34 | z_ema_num = y_ema_num = source[i] - price 35 | z_ema_den = y_ema_den = Math.abs(source[i] - price) 36 | 37 | output.push(100 * (z_ema_den ? z_ema_num / z_ema_den : 0)) 38 | 39 | price = source[i] 40 | } 41 | 42 | for (; i < size; ++i, ++progress) { 43 | y_ema_num = ((source[i] - price) - y_ema_num) * 2 / (1 + y_period) + y_ema_num 44 | y_ema_den = ((Math.abs(source[i] - price)) - y_ema_den) * 2 / (1 + y_period) + y_ema_den 45 | 46 | z_ema_num = (y_ema_num - z_ema_num) * 2 / (1 + z_period) + z_ema_num 47 | z_ema_den = (y_ema_den - z_ema_den) * 2 / (1 + z_period) + z_ema_den 48 | 49 | 50 | output.push(100 * (z_ema_den ? z_ema_num / z_ema_den : 0)) 51 | 52 | price = source[i] 53 | } 54 | 55 | return output 56 | } 57 | 58 | module.exports = tsi -------------------------------------------------------------------------------- /core/typprice.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function typprice( 10 | high, low, 11 | close, size = high.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | for (let i = 0; i < size; ++i) { 17 | output.push((high[i] + low[i] + close[i]) * (1.0 / 3.0)) 18 | } 19 | 20 | return output 21 | } 22 | 23 | module.exports = typprice -------------------------------------------------------------------------------- /core/ultosc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} short_period 7 | * @param {number} medium_period 8 | * @param {number} long_period 9 | * @param {number} [size] 10 | * @returns 11 | */ 12 | function ultosc( 13 | high, low, 14 | close, short_period, 15 | medium_period, long_period, 16 | size = high.length 17 | ) { 18 | 19 | const output = [] 20 | 21 | // if (short_period < 1) throw new Error("Invalid Options") 22 | // if (medium_period < short_period) throw new Error("Invalid Options") 23 | // if (long_period < medium_period) throw new Error("Invalid Options") 24 | // if (size <= medium_period) throw new Error("Out of range") 25 | 26 | 27 | const bp_buf = { 28 | size: long_period, 29 | index: 0, 30 | pushes: 0, 31 | sum: 0, 32 | vals: [] 33 | } 34 | 35 | const r_buf = { 36 | size: long_period, 37 | index: 0, 38 | pushes: 0, 39 | sum: 0, 40 | vals: [] 41 | } 42 | 43 | let bp_short_sum = 0 44 | let bp_medium_sum = 0 45 | let r_short_sum = 0 46 | let r_medium_sum = 0 47 | 48 | for (let i = 1; i < size; ++i) { 49 | 50 | // Start MIN 51 | // MIN(a,b) ((a)<(b)?(a):(b)) 52 | const true_low = ((low[i]) < (close[i - 1]) ? (low[i]) : (close[i - 1])) 53 | // End MIN 54 | 55 | // Start MAX 56 | // MAX(a,b) ((a)>(b)?(a):(b)) 57 | const true_high = ((high[i]) > (close[i - 1]) ? (high[i]) : (close[i - 1])) 58 | // End MAX 59 | 60 | const bp = close[i] - true_low 61 | const r = true_high - true_low 62 | 63 | bp_short_sum += bp 64 | bp_medium_sum += bp 65 | r_short_sum += r 66 | r_medium_sum += r 67 | 68 | // Start ti_buffer_push 69 | // BUFFER = bp_buf 70 | // VAL = bp 71 | // ti_buffer_push(bp_buf, bp) 72 | if (bp_buf.pushes >= bp_buf.size) { 73 | bp_buf.sum -= bp_buf.vals[bp_buf.index] 74 | } 75 | 76 | bp_buf.sum += bp 77 | bp_buf.vals[bp_buf.index] = bp 78 | bp_buf.pushes += 1 79 | bp_buf.index = (bp_buf.index + 1) 80 | if (bp_buf.index >= bp_buf.size) bp_buf.index = 0 81 | // End ti_buffer_push 82 | 83 | // Start ti_buffer_push 84 | // BUFFER = r_buf 85 | // VAL = r 86 | // ti_buffer_push(r_buf, r) 87 | if (r_buf.pushes >= r_buf.size) { 88 | r_buf.sum -= r_buf.vals[r_buf.index] 89 | } 90 | 91 | r_buf.sum += r 92 | r_buf.vals[r_buf.index] = r 93 | r_buf.pushes += 1 94 | r_buf.index = (r_buf.index + 1) 95 | if (r_buf.index >= r_buf.size) r_buf.index = 0 96 | // End ti_buffer_push 97 | 98 | if (i > short_period) { 99 | let short_index = bp_buf.index - short_period - 1 100 | if (short_index < 0) short_index += long_period 101 | 102 | bp_short_sum -= bp_buf.vals[short_index] 103 | r_short_sum -= r_buf.vals[short_index] 104 | 105 | if (i > medium_period) { 106 | let medium_index = bp_buf.index - medium_period - 1 107 | if (medium_index < 0) medium_index += long_period 108 | bp_medium_sum -= bp_buf.vals[medium_index] 109 | r_medium_sum -= r_buf.vals[medium_index] 110 | } 111 | } 112 | 113 | if (i >= long_period) { 114 | const first = 4 * bp_short_sum / r_short_sum 115 | const second = 2 * bp_medium_sum / r_medium_sum 116 | const third = 1 * bp_buf.sum / r_buf.sum 117 | const ult = (first + second + third) * 100.0 / 7.0 118 | output.push(ult) 119 | } 120 | } 121 | 122 | return output 123 | } 124 | 125 | module.exports = ultosc -------------------------------------------------------------------------------- /core/varf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function varf( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | const scale = 1.0 / period 16 | 17 | // if (period < 1) throw new Error("Invalid Options") 18 | // if (size <= period - 1) throw new Error("Out of range") 19 | 20 | let sum = 0 21 | let sum2 = 0 22 | 23 | for (let i = 0; i < period; ++i) { 24 | sum += source[i] 25 | sum2 += source[i] * source[i] 26 | } 27 | 28 | output.push(sum2 * scale - (sum * scale) * (sum * scale)) 29 | 30 | for (let i = period; i < size; ++i) { 31 | sum += source[i] 32 | sum2 += source[i] * source[i] 33 | 34 | sum -= source[i - period] 35 | sum2 -= source[i - period] * source[i - period] 36 | 37 | output.push(sum2 * scale - (sum * scale) * (sum * scale)) 38 | } 39 | 40 | return output 41 | } 42 | 43 | module.exports = varf -------------------------------------------------------------------------------- /core/vhf.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function vhf( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= period) throw new Error("Out of range") 17 | 18 | let trail = 1 19 | let maxi = -1 20 | let mini = -1 21 | 22 | let max = source[0] 23 | let min = source[0] 24 | let bar 25 | 26 | let sum = 0 27 | 28 | let yc = source[0] 29 | let c 30 | 31 | let j 32 | for (let i = 1; i < period; ++i) { 33 | c = source[i] 34 | sum += Math.abs(c - yc) 35 | yc = c 36 | } 37 | 38 | for (let i = period; i < size; ++i, ++trail) { 39 | c = source[i] 40 | sum += Math.abs(c - yc) 41 | yc = c 42 | 43 | if (i > period) { 44 | sum -= Math.abs(source[i - period] - source[i - period - 1]) 45 | } 46 | 47 | // Maintain highest 48 | bar = c 49 | if (maxi < trail) { 50 | maxi = trail 51 | max = source[maxi] 52 | j = trail 53 | 54 | while (++j <= i) { 55 | bar = source[j] 56 | if (bar >= max) { 57 | max = bar 58 | maxi = j 59 | } 60 | } 61 | 62 | } else if (bar >= max) { 63 | maxi = i 64 | max = bar 65 | } 66 | 67 | // Maintain lowest 68 | bar = c 69 | if (mini < trail) { 70 | mini = trail 71 | min = source[mini] 72 | j = trail 73 | 74 | while (++j <= i) { 75 | bar = source[j] 76 | if (bar <= min) { 77 | min = bar 78 | mini = j 79 | } 80 | } 81 | 82 | } else if (bar <= min) { 83 | mini = i 84 | min = bar 85 | } 86 | 87 | output.push(Math.abs(max - min) / sum) 88 | } 89 | 90 | return output 91 | } 92 | 93 | module.exports = vhf -------------------------------------------------------------------------------- /core/vidya.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} short_period 5 | * @param {number} long_period 6 | * @param {number} alpha 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | function vidya( 11 | source, short_period, 12 | long_period, alpha, 13 | size = source.length 14 | ) { 15 | 16 | const output = [] 17 | 18 | const short_div = 1.0 / short_period 19 | const long_div = 1.0 / long_period 20 | 21 | // if (short_period < 1) throw new Error("Invalid Options") 22 | // if (long_period < short_period) throw new Error("Invalid Options") 23 | // if (long_period < 2) throw new Error("Invalid Options") 24 | // if (alpha < 0.0 || alpha > 1.0) throw new Error("Invalid Options") 25 | // if (size <= long_period - 2) throw new Error("Out of range") 26 | 27 | let short_sum = 0 28 | let short_sum2 = 0 29 | 30 | let long_sum = 0 31 | let long_sum2 = 0 32 | 33 | for (let i = 0; i < long_period; ++i) { 34 | long_sum += source[i] 35 | long_sum2 += source[i] * source[i] 36 | 37 | if (i >= long_period - short_period) { 38 | short_sum += source[i] 39 | short_sum2 += source[i] * source[i] 40 | } 41 | } 42 | 43 | let val = source[long_period - 2] 44 | output.push(val) 45 | 46 | if (long_period - 1 < size) { 47 | const short_stddev = Math.sqrt(short_sum2 * short_div - (short_sum * short_div) * (short_sum * short_div)) 48 | const long_stddev = Math.sqrt(long_sum2 * long_div - (long_sum * long_div) * (long_sum * long_div)) 49 | let k = short_stddev / long_stddev 50 | if (k != k) k = 0; /* In some conditions it works out that we take the sqrt(-0.0), which gives NaN. 51 | That implies that k should be zero. */ 52 | k *= alpha 53 | val = (source[long_period - 1] - val) * k + val 54 | output.push(val) 55 | } 56 | 57 | for (let i = long_period; i < size; ++i) { 58 | long_sum += source[i] 59 | long_sum2 += source[i] * source[i] 60 | 61 | short_sum += source[i] 62 | short_sum2 += source[i] * source[i] 63 | 64 | long_sum -= source[i - long_period] 65 | long_sum2 -= source[i - long_period] * source[i - long_period] 66 | 67 | short_sum -= source[i - short_period] 68 | short_sum2 -= source[i - short_period] * source[i - short_period] 69 | 70 | const short_stddev = Math.sqrt(short_sum2 * short_div - (short_sum * short_div) * (short_sum * short_div)) 71 | const long_stddev = Math.sqrt(long_sum2 * long_div - (long_sum * long_div) * (long_sum * long_div)) 72 | let k = short_stddev / long_stddev 73 | if (k != k) k = 0 74 | k *= alpha 75 | val = (source[i] - val) * k + val 76 | 77 | output.push(val) 78 | } 79 | 80 | return output 81 | } 82 | 83 | module.exports = vidya -------------------------------------------------------------------------------- /core/volatility.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function volatility( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | const scale = 1.0 / period 16 | const annual = Math.sqrt(252) /* Multiplier, number of trading days in year. */ 17 | 18 | // if (period < 1) throw new Error("Invalid Options") 19 | // if (size <= period) throw new Error("Out of range") 20 | 21 | let sum = 0 22 | let sum2 = 0 23 | 24 | for (let i = 1; i <= period; ++i) { 25 | // Start Change() 26 | const c = (source[i] / source[i - 1] - 1.0) 27 | // End Change() 28 | sum += c 29 | sum2 += c * c 30 | } 31 | 32 | output.push(Math.sqrt(sum2 * scale - (sum * scale) * (sum * scale)) * annual) 33 | 34 | for (let i = period + 1; i < size; ++i) { 35 | // Start Change() 36 | const c = (source[i] / source[i - 1] - 1.0) 37 | // End Change() 38 | sum += c 39 | sum2 += c * c 40 | 41 | // Start Change() 42 | const cp = (source[i - period] / source[i - period - 1] - 1.0) 43 | // Start Change() 44 | sum -= cp 45 | sum2 -= cp * cp 46 | 47 | output.push(Math.sqrt(sum2 * scale - (sum * scale) * (sum * scale)) * annual) 48 | } 49 | 50 | return output 51 | } 52 | 53 | module.exports = volatility -------------------------------------------------------------------------------- /core/vosc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} short_period 5 | * @param {number} long_period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function vosc( 10 | source, short_period, 11 | long_period, size = source.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | const short_div = 1.0 / short_period 17 | const long_div = 1.0 / long_period 18 | 19 | // if (short_period < 1) throw new Error("Invalid Options") 20 | // if (long_period < short_period) throw new Error("Invalid Options") 21 | // if (size <= long_period - 1) throw new Error("Out of range") 22 | 23 | let short_sum = 0 24 | let long_sum = 0 25 | 26 | for (let i = 0; i < long_period; ++i) { 27 | if (i >= (long_period - short_period)) { 28 | short_sum += source[i] 29 | } 30 | long_sum += source[i] 31 | } 32 | 33 | const savg = short_sum * short_div 34 | const lavg = long_sum * long_div 35 | output.push(100.0 * (savg - lavg) / lavg) 36 | 37 | for (let i = long_period; i < size; ++i) { 38 | short_sum += source[i] 39 | short_sum -= source[i - short_period] 40 | 41 | long_sum += source[i] 42 | long_sum -= source[i - long_period] 43 | 44 | const savg = short_sum * short_div 45 | const lavg = long_sum * long_div 46 | output.push(100.0 * (savg - lavg) / lavg) 47 | } 48 | 49 | return output 50 | } 51 | 52 | module.exports = vosc -------------------------------------------------------------------------------- /core/vwap.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number[]} volume 7 | * @param {number} period 8 | * @param {number} [size] 9 | * @returns 10 | */ 11 | function vwap( 12 | high, low, 13 | close, volume, 14 | period, size = high.length 15 | ) { 16 | 17 | const output = [] 18 | 19 | // if (period < 1) throw new Error("Invalid Options") 20 | 21 | let progress = -period + 1 22 | 23 | let num = 0 24 | let den = 0 25 | 26 | let i = 0 27 | for (; i < size && progress < 1; ++i, ++progress) { 28 | num += (high[i] + low[i] + close[i]) / 3 * volume[i] 29 | den += volume[i] 30 | } 31 | 32 | if (i > 0 && progress == 1) { 33 | output.push(num / den) 34 | } 35 | 36 | for (; i < size; ++i, ++progress) { 37 | num += (high[i] + low[i] + close[i]) / 3 * volume[i] 38 | - (high[i - period] + low[i - period] + close[i - period]) / 3 * volume[i - period] 39 | den += volume[i] - volume[i - period] 40 | 41 | output.push(num / den) 42 | } 43 | 44 | return output 45 | } 46 | 47 | module.exports = vwap -------------------------------------------------------------------------------- /core/vwma.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number[]} volume 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function vwma( 10 | source, volume, 11 | period, size = source.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | // if (period < 1) throw new Error("Invalid Options") 17 | // if (size <= period - 1) throw new Error("Out of range") 18 | 19 | let sum = 0 20 | let vsum = 0 21 | 22 | for (let i = 0; i < period; ++i) { 23 | sum += source[i] * volume[i] 24 | vsum += volume[i] 25 | } 26 | 27 | output.push(sum / vsum) 28 | 29 | for (let i = period; i < size; ++i) { 30 | sum += source[i] * volume[i] 31 | sum -= source[i - period] * volume[i - period] 32 | vsum += volume[i] 33 | vsum -= volume[i - period] 34 | 35 | output.push(sum / vsum) 36 | } 37 | 38 | return output 39 | } 40 | 41 | module.exports = vwma -------------------------------------------------------------------------------- /core/wad.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function wad( 10 | high, low, 11 | close, size = high.length 12 | ) { 13 | 14 | // if (size <= 1) throw new Error("Out of range") 15 | 16 | const output = [] 17 | let sum = 0 18 | let yc = close[0] 19 | 20 | for (let i = 1; i < size; ++i) { 21 | const c = close[i] 22 | 23 | if (c > yc) { 24 | // Start MIN 25 | // MIN(a,b) ((a)<(b)?(a):(b)) 26 | sum += c - ((yc) < (low[i]) ? (yc) : (low[i])) 27 | // End MIN() 28 | } else if (c < yc) { 29 | // Start MAX 30 | // MAX(a,b) ((a)>(b)?(a):(b)) 31 | sum += c - ((yc) > (high[i]) ? (yc) : (high[i])) 32 | // End MAX 33 | } else { 34 | /* No change */ 35 | } 36 | 37 | output.push(sum) 38 | 39 | yc = close[i] 40 | } 41 | 42 | return output 43 | } 44 | 45 | module.exports = wad -------------------------------------------------------------------------------- /core/wcprice.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | function wcprice( 10 | high, low, 11 | close, size = high.length 12 | ) { 13 | 14 | const output = [] 15 | 16 | for (let i = 0; i < size; ++i) { 17 | output.push((high[i] + low[i] + close[i] + close[i]) * 0.25) 18 | } 19 | 20 | return output 21 | } 22 | 23 | module.exports = wcprice -------------------------------------------------------------------------------- /core/wilders.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function wilders( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= period - 1) throw new Error("Out of range") 17 | 18 | const per = 1.0 / (period) 19 | 20 | let sum = 0 21 | 22 | for (let i = 0; i < period; ++i) { 23 | sum += source[i] 24 | } 25 | 26 | 27 | let val = sum / period 28 | output.push(val) 29 | 30 | for (let i = period; i < size; ++i) { 31 | val = (source[i] - val) * per + val 32 | output.push(val) 33 | } 34 | 35 | return output 36 | } 37 | 38 | module.exports = wilders -------------------------------------------------------------------------------- /core/willr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | function willr( 11 | high, low, 12 | close, period, 13 | size = high.length 14 | ) { 15 | 16 | const output = [] 17 | 18 | // if (period < 1) throw new Error("Invalid Options") 19 | // if (size <= period - 1) throw new Error("Out of range") 20 | 21 | let trail = 0 22 | let maxi = -1 23 | let mini = -1 24 | let max = high[0] 25 | let min = low[0] 26 | let bar 27 | 28 | let j 29 | for (let i = period - 1; i < size; ++i, ++trail) { 30 | 31 | // Maintain highest 32 | bar = high[i] 33 | if (maxi < trail) { 34 | maxi = trail 35 | max = high[maxi] 36 | j = trail 37 | 38 | while (++j <= i) { 39 | bar = high[j]; 40 | if (bar >= max) { 41 | max = bar 42 | maxi = j 43 | } 44 | } 45 | 46 | } else if (bar >= max) { 47 | maxi = i 48 | max = bar 49 | } 50 | 51 | 52 | // Maintain lowest 53 | bar = low[i] 54 | if (mini < trail) { 55 | mini = trail 56 | min = low[mini] 57 | j = trail 58 | 59 | while (++j <= i) { 60 | bar = low[j]; 61 | if (bar <= min) { 62 | min = bar 63 | mini = j 64 | } 65 | } 66 | 67 | } else if (bar <= min) { 68 | mini = i 69 | min = bar 70 | } 71 | 72 | 73 | const highlow = (max - min) 74 | const r = highlow == 0.0 ? 0.0 : -100 * ((max - close[i]) / highlow) 75 | output.push(r) 76 | } 77 | 78 | return output 79 | } 80 | 81 | module.exports = willr -------------------------------------------------------------------------------- /core/wma.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function wma( 9 | source, period, 10 | size = source.length 11 | ) { 12 | 13 | const output = [] 14 | 15 | // if (period < 1) throw new Error("Invalid Options") 16 | // if (size <= period - 1) throw new Error("Out of range") 17 | 18 | const weights = period * (period + 1) / 2 19 | 20 | let sum = 0 21 | let weight_sum = 0 22 | 23 | for (let i = 0; i < period - 1; ++i) { 24 | weight_sum += source[i] * (i + 1) 25 | sum += source[i] 26 | } 27 | 28 | for (let i = period - 1; i < size; ++i) { 29 | weight_sum += source[i] * period 30 | sum += source[i] 31 | 32 | output.push(weight_sum / weights) 33 | 34 | weight_sum -= sum 35 | sum -= source[i - period + 1] 36 | } 37 | 38 | return output 39 | } 40 | 41 | module.exports = wma -------------------------------------------------------------------------------- /core/zlema.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @param {number[]} input 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | function zlema(input, period, size = input.length) { 9 | 10 | const lag = Math.floor((period - 1) / 2) 11 | 12 | const output = [] 13 | 14 | const per = 2 / (period + 1) 15 | 16 | let val = input[lag - 1] 17 | output.push(val) 18 | 19 | let i; 20 | for (i = lag; i < size; ++i) { 21 | const c = input[i]; 22 | const l = input[i - lag]; 23 | 24 | val = ((c + (c - l)) - val) * per + val; 25 | output.push(val) 26 | } 27 | 28 | return output 29 | } 30 | 31 | module.exports = zlema -------------------------------------------------------------------------------- /generate.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | const dirPath = './core'; 5 | 6 | const files = fs.readdirSync(dirPath) 7 | .filter(file => file.endsWith('.js')) 8 | .map(file => path.basename(file, '.js')); 9 | 10 | let output = ''; 11 | files.forEach(file => { 12 | output += `const ${file} = require("${dirPath}/${file}");\n`; 13 | }); 14 | 15 | output += '\nmodule.exports = {\n'; 16 | files.forEach(file => { 17 | output += ` ${file},\n`; 18 | }); 19 | output += '};\n'; 20 | 21 | fs.writeFileSync('index_.js', output); -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const _cvi = require("./core/_cvi"); 2 | const abands = require("./core/abands"); 3 | const ad = require("./core/ad"); 4 | const adosc = require("./core/adosc"); 5 | const adx = require("./core/adx"); 6 | const adxr = require("./core/adxr"); 7 | const alma = require("./core/alma"); 8 | const ao = require("./core/ao"); 9 | const apo = require("./core/apo"); 10 | const aroon = require("./core/aroon"); 11 | const aroonosc = require("./core/aroonosc"); 12 | const atr = require("./core/atr"); 13 | const avgprice = require("./core/avgprice"); 14 | const bbands = require("./core/bbands"); 15 | const bop = require("./core/bop"); 16 | const cci = require("./core/cci"); 17 | const ce = require("./core/ce"); 18 | const cmf = require("./core/cmf"); 19 | const cmo = require("./core/cmo"); 20 | const copp = require("./core/copp"); 21 | const crossany = require("./core/crossany"); 22 | const crossover = require("./core/crossover"); 23 | const crossOverNumber = require("./core/crossOverNumber"); 24 | const crossUnderNumber = require("./core/crossUnderNumber"); 25 | const cvi = require("./core/cvi"); 26 | const dc = require("./core/dc"); 27 | const decay = require("./core/decay"); 28 | const dema = require("./core/dema"); 29 | const di = require("./core/di"); 30 | const dm = require("./core/dm"); 31 | const dpo = require("./core/dpo"); 32 | const dx = require("./core/dx"); 33 | const edecay = require("./core/edecay"); 34 | const ema = require("./core/ema"); 35 | const emv = require("./core/emv"); 36 | const fi = require("./core/fi"); 37 | const fisher = require("./core/fisher"); 38 | const fosc = require("./core/fosc"); 39 | const hma = require("./core/hma"); 40 | const kama = require("./core/kama"); 41 | const kc = require("./core/kc"); 42 | const kst = require("./core/kst"); 43 | const kvo = require("./core/kvo"); 44 | const lag = require("./core/lag"); 45 | const linreg = require("./core/linreg"); 46 | const linregintercept = require("./core/linregintercept"); 47 | const linregslope = require("./core/linregslope"); 48 | const macd = require("./core/macd"); 49 | const marketfi = require("./core/marketfi"); 50 | const mass = require("./core/mass"); 51 | const max = require("./core/max"); 52 | const md = require("./core/md"); 53 | const medprice = require("./core/medprice"); 54 | const mfi = require("./core/mfi"); 55 | const min = require("./core/min"); 56 | const mom = require("./core/mom"); 57 | const msw = require("./core/msw"); 58 | const natr = require("./core/natr"); 59 | const normalize = require("./core/normalize"); 60 | const normalize2 = require("./core/normalize2"); 61 | const nvi = require("./core/nvi"); 62 | const obv = require("./core/obv"); 63 | const pbands = require("./core/pbands"); 64 | const pfe = require("./core/pfe"); 65 | const posc = require("./core/posc"); 66 | const ppo = require("./core/ppo"); 67 | const psar = require("./core/psar"); 68 | const pvi = require("./core/pvi"); 69 | const qstick = require("./core/qstick"); 70 | const rmi = require("./core/rmi"); 71 | const rmta = require("./core/rmta"); 72 | const roc = require("./core/roc"); 73 | const rocr = require("./core/rocr"); 74 | const rsi = require("./core/rsi"); 75 | const rvi = require("./core/rvi"); 76 | const sma = require("./core/sma"); 77 | const smi = require("./core/smi"); 78 | const stddev = require("./core/stddev"); 79 | const stderr = require("./core/stderr"); 80 | const stoch = require("./core/stoch"); 81 | const stochrsi = require("./core/stochrsi"); 82 | const sum = require("./core/sum"); 83 | const tema = require("./core/tema"); 84 | const tr = require("./core/tr"); 85 | const trima = require("./core/trima"); 86 | const trix = require("./core/trix"); 87 | const tsf = require("./core/tsf"); 88 | const tsi = require("./core/tsi"); 89 | const typprice = require("./core/typprice"); 90 | const ultosc = require("./core/ultosc"); 91 | const varf = require("./core/varf"); 92 | const vhf = require("./core/vhf"); 93 | const vidya = require("./core/vidya"); 94 | const volatility = require("./core/volatility"); 95 | const vosc = require("./core/vosc"); 96 | const vwap = require("./core/vwap"); 97 | const vwma = require("./core/vwma"); 98 | const wad = require("./core/wad"); 99 | const wcprice = require("./core/wcprice"); 100 | const wilders = require("./core/wilders"); 101 | const willr = require("./core/willr"); 102 | const wma = require("./core/wma"); 103 | const zlema = require("./core/zlema"); 104 | 105 | module.exports = { 106 | _cvi, 107 | abands, 108 | ad, 109 | adosc, 110 | adx, 111 | adxr, 112 | alma, 113 | ao, 114 | apo, 115 | aroon, 116 | aroonosc, 117 | atr, 118 | avgprice, 119 | bbands, 120 | bop, 121 | cci, 122 | ce, 123 | cmf, 124 | cmo, 125 | copp, 126 | crossany, 127 | crossover, 128 | crossOverNumber, 129 | crossUnderNumber, 130 | cvi, 131 | dc, 132 | decay, 133 | dema, 134 | di, 135 | dm, 136 | dpo, 137 | dx, 138 | edecay, 139 | ema, 140 | emv, 141 | fi, 142 | fisher, 143 | fosc, 144 | hma, 145 | kama, 146 | kc, 147 | kst, 148 | kvo, 149 | lag, 150 | linreg, 151 | linregintercept, 152 | linregslope, 153 | macd, 154 | marketfi, 155 | mass, 156 | max, 157 | md, 158 | medprice, 159 | mfi, 160 | min, 161 | mom, 162 | msw, 163 | natr, 164 | normalize, 165 | normalize2, 166 | nvi, 167 | obv, 168 | pbands, 169 | pfe, 170 | posc, 171 | ppo, 172 | psar, 173 | pvi, 174 | qstick, 175 | rmi, 176 | rmta, 177 | roc, 178 | rocr, 179 | rsi, 180 | rvi, 181 | sma, 182 | smi, 183 | stddev, 184 | stderr, 185 | stoch, 186 | stochrsi, 187 | sum, 188 | tema, 189 | tr, 190 | trima, 191 | trix, 192 | tsf, 193 | tsi, 194 | typprice, 195 | ultosc, 196 | varf, 197 | vhf, 198 | vidya, 199 | volatility, 200 | vosc, 201 | vwap, 202 | vwma, 203 | wad, 204 | wcprice, 205 | wilders, 206 | willr, 207 | wma, 208 | zlema, 209 | }; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ixjb94/indicators-js", 3 | "version": "1.0.0", 4 | "description": "Fastest Technical Indicators written in javascript. More than +100 indicators(SMA, EMA, RSI, MACD, ...)", 5 | "main": "index.js", 6 | "types": "types/index.d.ts", 7 | "scripts": { 8 | "test": "jest", 9 | "build": "rollup -c --bundleConfigAsCjs", 10 | "public": "npm publish --access=public", 11 | "tsc": "npx tsc", 12 | "pub": "npm version patch && npm publish" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/ixjb94/indicators-js.git" 17 | }, 18 | "keywords": [ 19 | "indicators", 20 | "ema", 21 | "sma", 22 | "rsi", 23 | "cci", 24 | "technical indicators", 25 | "chart", 26 | "trade" 27 | ], 28 | "author": "IX JB", 29 | "license": "MIT", 30 | "devDependencies": { 31 | "@rollup/plugin-terser": "^0.4.4", 32 | "rollup": "^4.21.3", 33 | "rollup-plugin-commonjs": "^10.1.0", 34 | "rollup-plugin-node-resolve": "^5.2.0", 35 | "typescript": "^5.6.2" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import resolve from 'rollup-plugin-node-resolve'; 2 | import commonjs from 'rollup-plugin-commonjs'; 3 | import terser from "@rollup/plugin-terser"; 4 | 5 | export default { 6 | input: 'index.js', 7 | output: { 8 | file: 'dist/index.umd.js', 9 | format: 'umd', 10 | name: 'indicators', 11 | exports: 'named', 12 | }, 13 | plugins: [resolve(), commonjs(), terser()], 14 | }; -------------------------------------------------------------------------------- /todo.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ixjb94/indicators-js/d0bd29565247b6a646f7a0d64823541d47166d55/todo.md -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES6", 4 | "module": "commonjs", 5 | "declaration": true, 6 | "emitDeclarationOnly": true, 7 | "outDir": "types", 8 | "allowJs": true, 9 | "checkJs": true 10 | }, 11 | "include": [ 12 | "core/**/*.js", 13 | "index.js" 14 | ] 15 | } -------------------------------------------------------------------------------- /types/core/_cvi.d.ts: -------------------------------------------------------------------------------- 1 | export = _cvi; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function _cvi(high: number[], low: number[], period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/abands.d.ts: -------------------------------------------------------------------------------- 1 | export = abands; 2 | /** 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns [upper_band, lower_band, middle_point] 9 | */ 10 | declare function abands(high: number[], low: number[], close: number[], period: number, size?: number): number[][]; 11 | -------------------------------------------------------------------------------- /types/core/ad.d.ts: -------------------------------------------------------------------------------- 1 | export = ad; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number[]} volume 8 | * @param {number} [size] 9 | * @returns 10 | */ 11 | declare function ad(high: number[], low: number[], close: number[], volume: number[], size?: number): number[]; 12 | -------------------------------------------------------------------------------- /types/core/adosc.d.ts: -------------------------------------------------------------------------------- 1 | export = adosc; 2 | /** 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number[]} volume 7 | * @param {number} short_period 8 | * @param {number} long_period 9 | * @param {number} [size] 10 | * @returns 11 | */ 12 | declare function adosc(high: number[], low: number[], close: number[], volume: number[], short_period: number, long_period: number, size?: number): number[]; 13 | -------------------------------------------------------------------------------- /types/core/adx.d.ts: -------------------------------------------------------------------------------- 1 | export = adx; 2 | /** 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function adx(high: number[], low: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/adxr.d.ts: -------------------------------------------------------------------------------- 1 | export = adxr; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function adxr(high: number[], low: number[], period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/alma.d.ts: -------------------------------------------------------------------------------- 1 | export = alma; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} offset 7 | * @param {number} sigma 8 | * @param {number} [size] 9 | * @returns 10 | */ 11 | declare function alma(source: number[], period: number, offset: number, sigma: number, size?: number): number[]; 12 | -------------------------------------------------------------------------------- /types/core/ao.d.ts: -------------------------------------------------------------------------------- 1 | export = ao; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function ao(high: number[], low: number[], size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/apo.d.ts: -------------------------------------------------------------------------------- 1 | export = apo; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} short_period 6 | * @param {number} long_period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function apo(source: number[], short_period: number, long_period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/aroon.d.ts: -------------------------------------------------------------------------------- 1 | export = aroon; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns First output = Aroon Down, Second output = Aroon Up 9 | */ 10 | declare function aroon(high: number[], low: number[], period: number, size?: number): number[][]; 11 | -------------------------------------------------------------------------------- /types/core/aroonosc.d.ts: -------------------------------------------------------------------------------- 1 | export = aroonosc; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function aroonosc(high: number[], low: number[], period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/atr.d.ts: -------------------------------------------------------------------------------- 1 | export = atr; 2 | /** 3 | * @param {number[]} high 4 | * @param {number[]} low 5 | * @param {number[]} close 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function atr(high: number[], low: number[], close: number[], period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/avgprice.d.ts: -------------------------------------------------------------------------------- 1 | export = avgprice; 2 | /** 3 | * @param {number[]} open 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function avgprice(open: number[], high: number[], low: number[], close: number[], size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/bbands.d.ts: -------------------------------------------------------------------------------- 1 | export = bbands; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} stddev 7 | * @param {number} [size] 8 | * @returns [Lower, Middle, Upper] 9 | */ 10 | declare function bbands(source: number[], period: number, stddev: number, size?: number): number[][]; 11 | -------------------------------------------------------------------------------- /types/core/bop.d.ts: -------------------------------------------------------------------------------- 1 | export = bop; 2 | /** 3 | * 4 | * @param {number[]} open 5 | * @param {number[]} high 6 | * @param {number[]} low 7 | * @param {number[]} close 8 | * @param {number} [size] 9 | * @returns 10 | */ 11 | declare function bop(open: number[], high: number[], low: number[], close: number[], size?: number): number[]; 12 | -------------------------------------------------------------------------------- /types/core/cci.d.ts: -------------------------------------------------------------------------------- 1 | export = cci; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} period 8 | * @param {number} [size] 9 | * @returns 10 | */ 11 | declare function cci(high: number[], low: number[], close: number[], period: number, size?: number): number[]; 12 | -------------------------------------------------------------------------------- /types/core/ce.d.ts: -------------------------------------------------------------------------------- 1 | export = ce; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} period 8 | * @param {number} coef 9 | * @param {number} [size] 10 | * @returns [ce_high, ce_low] 11 | */ 12 | declare function ce(high: number[], low: number[], close: number[], period: number, coef: number, size?: number): number[][]; 13 | -------------------------------------------------------------------------------- /types/core/cmf.d.ts: -------------------------------------------------------------------------------- 1 | export = cmf; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number[]} volume 8 | * @param {number} period 9 | * @param {number} [size] 10 | * @returns 11 | */ 12 | declare function cmf(high: number[], low: number[], close: number[], volume: number[], period: number, size?: number): number[]; 13 | -------------------------------------------------------------------------------- /types/core/cmo.d.ts: -------------------------------------------------------------------------------- 1 | export = cmo; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function cmo(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/copp.d.ts: -------------------------------------------------------------------------------- 1 | export = copp; 2 | /** 3 | * @param {number[]} data 4 | * @param {number} period1 5 | * @param {number} period2 6 | * @returns 7 | */ 8 | declare function copp(data: number[], period1: number, period2: number): any[]; 9 | -------------------------------------------------------------------------------- /types/core/crossOverNumber.d.ts: -------------------------------------------------------------------------------- 1 | export = crossOverNumber; 2 | /** 3 | * 4 | * @param {number[]} seriesA 5 | * @param {number} number 6 | * @returns 7 | */ 8 | declare function crossOverNumber(seriesA: number[], number: number): boolean[]; 9 | -------------------------------------------------------------------------------- /types/core/crossUnderNumber.d.ts: -------------------------------------------------------------------------------- 1 | export = crossUnderNumber; 2 | /** 3 | * 4 | * @param {number[]} seriesA 5 | * @param {number} number 6 | * @returns 7 | */ 8 | declare function crossUnderNumber(seriesA: number[], number: number): boolean[]; 9 | -------------------------------------------------------------------------------- /types/core/crossany.d.ts: -------------------------------------------------------------------------------- 1 | export = crossany; 2 | /** 3 | * @param {number[]} a 4 | * @param {number[]} b 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | declare function crossany(a: number[], b: number[], size?: number): boolean[]; 9 | -------------------------------------------------------------------------------- /types/core/crossover.d.ts: -------------------------------------------------------------------------------- 1 | export = crossover; 2 | /** 3 | * @param {number[]} a 4 | * @param {number[]} b 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | declare function crossover(a: number[], b: number[], size?: number): boolean[]; 9 | -------------------------------------------------------------------------------- /types/core/cvi.d.ts: -------------------------------------------------------------------------------- 1 | export = cvi; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function cvi(high: number[], low: number[], period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/dc.d.ts: -------------------------------------------------------------------------------- 1 | export = dc; 2 | /** 3 | * 4 | * @param {number[]} highs 5 | * @param {number[]} lows 6 | * @param {number} period 7 | * @returns [upper, middle, lower] 8 | */ 9 | declare function dc(highs: number[], lows: number[], period: number): number[][]; 10 | -------------------------------------------------------------------------------- /types/core/decay.d.ts: -------------------------------------------------------------------------------- 1 | export = decay; 2 | /** 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | declare function decay(source: number[], period: number, size?: number): any[]; 9 | -------------------------------------------------------------------------------- /types/core/dema.d.ts: -------------------------------------------------------------------------------- 1 | export = dema; 2 | /** 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | declare function dema(source: number[], period: number, size?: number): number[]; 9 | -------------------------------------------------------------------------------- /types/core/di.d.ts: -------------------------------------------------------------------------------- 1 | export = di; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} period 8 | * @param {number} [size] 9 | * @returns [Plus DI, Minus DI] 10 | */ 11 | declare function di(high: number[], low: number[], close: number[], period: number, size?: number): number[][]; 12 | -------------------------------------------------------------------------------- /types/core/dm.d.ts: -------------------------------------------------------------------------------- 1 | export = dm; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns [Plus DM, Minus DM] 9 | */ 10 | declare function dm(high: number[], low: number[], period: number, size?: number): number[][]; 11 | -------------------------------------------------------------------------------- /types/core/dpo.d.ts: -------------------------------------------------------------------------------- 1 | export = dpo; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function dpo(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/dx.d.ts: -------------------------------------------------------------------------------- 1 | export = dx; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function dx(high: number[], low: number[], period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/edecay.d.ts: -------------------------------------------------------------------------------- 1 | export = edecay; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function edecay(source: number[], period: number, size?: number): any[]; 10 | -------------------------------------------------------------------------------- /types/core/ema.d.ts: -------------------------------------------------------------------------------- 1 | export = ema; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function ema(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/emv.d.ts: -------------------------------------------------------------------------------- 1 | export = emv; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} volume 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function emv(high: number[], low: number[], volume: number[], size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/fi.d.ts: -------------------------------------------------------------------------------- 1 | export = fi; 2 | /** 3 | * 4 | * @param {number[]} close 5 | * @param {number[]} volume 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function fi(close: number[], volume: number[], period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/fisher.d.ts: -------------------------------------------------------------------------------- 1 | export = fisher; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns [fisher, signal] 9 | */ 10 | declare function fisher(high: number[], low: number[], period: number, size?: number): number[][]; 11 | -------------------------------------------------------------------------------- /types/core/fosc.d.ts: -------------------------------------------------------------------------------- 1 | export = fosc; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function fosc(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/hma.d.ts: -------------------------------------------------------------------------------- 1 | export = hma; 2 | /** 3 | * 4 | * @param {number[]} input 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function hma(input: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/kama.d.ts: -------------------------------------------------------------------------------- 1 | export = kama; 2 | /** 3 | * @param {number[]} source 4 | * @param {number} period 5 | * @param {number} [size] 6 | * @returns 7 | */ 8 | declare function kama(source: number[], period: number, size?: number): number[]; 9 | -------------------------------------------------------------------------------- /types/core/kc.d.ts: -------------------------------------------------------------------------------- 1 | export = kc; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} period 8 | * @param {number} multiple 9 | * @param {number} [size] 10 | * @returns [kc_lower, kc_middle, kc_upper] 11 | */ 12 | declare function kc(high: number[], low: number[], close: number[], period: number, multiple: number, size?: number): number[][]; 13 | -------------------------------------------------------------------------------- /types/core/kst.d.ts: -------------------------------------------------------------------------------- 1 | export = kst; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} roc1 6 | * @param {number} roc2 7 | * @param {number} roc3 8 | * @param {number} roc4 9 | * @param {number} ma1 10 | * @param {number} ma2 11 | * @param {number} ma3 12 | * @param {number} ma4 13 | * @param {number} [size] 14 | * @returns 15 | */ 16 | declare function kst(source: number[], roc1: number, roc2: number, roc3: number, roc4: number, ma1: number, ma2: number, ma3: number, ma4: number, size?: number): number[][]; 17 | -------------------------------------------------------------------------------- /types/core/kvo.d.ts: -------------------------------------------------------------------------------- 1 | export = kvo; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number[]} volume 8 | * @param {number} short_period 9 | * @param {number} long_period 10 | * @param {number} [size] 11 | * @returns 12 | */ 13 | declare function kvo(high: number[], low: number[], close: number[], volume: number[], short_period: number, long_period: number, size?: number): number[]; 14 | -------------------------------------------------------------------------------- /types/core/lag.d.ts: -------------------------------------------------------------------------------- 1 | export = lag; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function lag(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/linreg.d.ts: -------------------------------------------------------------------------------- 1 | export = linreg; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function linreg(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/linregintercept.d.ts: -------------------------------------------------------------------------------- 1 | export = linregintercept; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function linregintercept(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/linregslope.d.ts: -------------------------------------------------------------------------------- 1 | export = linregslope; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function linregslope(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/macd.d.ts: -------------------------------------------------------------------------------- 1 | export = macd; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} short_period 6 | * @param {number} long_period 7 | * @param {number} signal_period 8 | * @param {number} [size] 9 | * @returns [macd, signal, hist] 10 | */ 11 | declare function macd(source: number[], short_period: number, long_period: number, signal_period: number, size?: number): number[][]; 12 | -------------------------------------------------------------------------------- /types/core/marketfi.d.ts: -------------------------------------------------------------------------------- 1 | export = marketfi; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} volume 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function marketfi(high: number[], low: number[], volume: number[], size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/mass.d.ts: -------------------------------------------------------------------------------- 1 | export = mass; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function mass(high: number[], low: number[], period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/max.d.ts: -------------------------------------------------------------------------------- 1 | export = max; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function max(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/md.d.ts: -------------------------------------------------------------------------------- 1 | export = md; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function md(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/medprice.d.ts: -------------------------------------------------------------------------------- 1 | export = medprice; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function medprice(high: number[], low: number[], size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/mfi.d.ts: -------------------------------------------------------------------------------- 1 | export = mfi; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number[]} volume 8 | * @param {number} period 9 | * @param {number} [size] 10 | * @returns 11 | */ 12 | declare function mfi(high: number[], low: number[], close: number[], volume: number[], period: number, size?: number): number[]; 13 | -------------------------------------------------------------------------------- /types/core/min.d.ts: -------------------------------------------------------------------------------- 1 | export = min; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function min(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/mom.d.ts: -------------------------------------------------------------------------------- 1 | export = mom; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function mom(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/msw.d.ts: -------------------------------------------------------------------------------- 1 | export = msw; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function msw(source: number[], period: number, size?: number): number[][]; 10 | -------------------------------------------------------------------------------- /types/core/natr.d.ts: -------------------------------------------------------------------------------- 1 | export = natr; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} period 8 | * @param {number} [size] 9 | * @returns 10 | */ 11 | declare function natr(high: number[], low: number[], close: number[], period: number, size?: number): number[]; 12 | -------------------------------------------------------------------------------- /types/core/normalize.d.ts: -------------------------------------------------------------------------------- 1 | export = normalize; 2 | /** 3 | * 4 | * @param {number} originalLength - example 100 5 | * @param {number[]} source - example ema | sma | rsi | etc. 6 | * @param {*} empty - example NaN | Null | 0 | false | etc. 7 | * @returns 8 | */ 9 | declare function normalize(originalLength: number, source: number[], empty?: any): any[]; 10 | -------------------------------------------------------------------------------- /types/core/normalize2.d.ts: -------------------------------------------------------------------------------- 1 | export = normalize2; 2 | /** 3 | * More efficient 4 | * @param {number[]} source example: sma | rsi | cci | etc. 5 | * @param {number} length main source length, example: close.length 6 | * @returns 7 | */ 8 | declare function normalize2(source: number[], length: number): number[]; 9 | -------------------------------------------------------------------------------- /types/core/nvi.d.ts: -------------------------------------------------------------------------------- 1 | export = nvi; 2 | /** 3 | * 4 | * @param {number[]} close 5 | * @param {number[]} volume 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function nvi(close: number[], volume: number[], size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/obv.d.ts: -------------------------------------------------------------------------------- 1 | export = obv; 2 | /** 3 | * 4 | * @param {number[]} close 5 | * @param {number[]} volume 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function obv(close: number[], volume: number[], size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/pbands.d.ts: -------------------------------------------------------------------------------- 1 | export = pbands; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} period 8 | * @param {number} [size] 9 | * @returns [pbands_lower, pbands_upper] 10 | */ 11 | declare function pbands(high: number[], low: number[], close: number[], period: number, size?: number): number[][]; 12 | -------------------------------------------------------------------------------- /types/core/pfe.d.ts: -------------------------------------------------------------------------------- 1 | export = pfe; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} ema_period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function pfe(source: number[], period: number, ema_period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/posc.d.ts: -------------------------------------------------------------------------------- 1 | export = posc; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} period 8 | * @param {number} ema_period 9 | * @param {number} [size] 10 | * @returns 11 | */ 12 | declare function posc(high: number[], low: number[], close: number[], period: number, ema_period: number, size?: number): number[]; 13 | -------------------------------------------------------------------------------- /types/core/ppo.d.ts: -------------------------------------------------------------------------------- 1 | export = ppo; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} short_period 6 | * @param {number} long_period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function ppo(source: number[], short_period: number, long_period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/psar.d.ts: -------------------------------------------------------------------------------- 1 | export = psar; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number} accel_step 7 | * @param {number} accel_max 8 | * @param {number} [size] 9 | * @returns 10 | */ 11 | declare function psar(high: number[], low: number[], accel_step: number, accel_max: number, size?: number): number[]; 12 | -------------------------------------------------------------------------------- /types/core/pvi.d.ts: -------------------------------------------------------------------------------- 1 | export = pvi; 2 | /** 3 | * 4 | * @param {number[]} close 5 | * @param {number[]} volume 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function pvi(close: number[], volume: number[], size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/qstick.d.ts: -------------------------------------------------------------------------------- 1 | export = qstick; 2 | /** 3 | * 4 | * @param {number[]} open 5 | * @param {number[]} close 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function qstick(open: number[], close: number[], period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/rmi.d.ts: -------------------------------------------------------------------------------- 1 | export = rmi; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} lookback_period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function rmi(source: number[], period: number, lookback_period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/rmta.d.ts: -------------------------------------------------------------------------------- 1 | export = rmta; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} beta 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function rmta(source: number[], period: number, beta: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/roc.d.ts: -------------------------------------------------------------------------------- 1 | export = roc; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function roc(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/rocr.d.ts: -------------------------------------------------------------------------------- 1 | export = rocr; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function rocr(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/rsi.d.ts: -------------------------------------------------------------------------------- 1 | export = rsi; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function rsi(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/rvi.d.ts: -------------------------------------------------------------------------------- 1 | export = rvi; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} sma_period 6 | * @param {number} stddev_period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function rvi(source: number[], sma_period: number, stddev_period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/sma.d.ts: -------------------------------------------------------------------------------- 1 | export = sma; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function sma(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/smi.d.ts: -------------------------------------------------------------------------------- 1 | export = smi; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} q_period 8 | * @param {number} r_period 9 | * @param {number} s_period 10 | * @param {number} [size] 11 | * @returns 12 | */ 13 | declare function smi(high: number[], low: number[], close: number[], q_period: number, r_period: number, s_period: number, size?: number): number[]; 14 | -------------------------------------------------------------------------------- /types/core/stddev.d.ts: -------------------------------------------------------------------------------- 1 | export = stddev; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function stddev(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/stderr.d.ts: -------------------------------------------------------------------------------- 1 | export = stderr; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function stderr(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/stoch.d.ts: -------------------------------------------------------------------------------- 1 | export = stoch; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} kperiod 8 | * @param {number} kslow 9 | * @param {number} dperiod 10 | * @param {number} [size] 11 | * @returns [stoch, stoch_ma] 12 | */ 13 | declare function stoch(high: number[], low: number[], close: number[], kperiod: number, kslow: number, dperiod: number, size?: number): number[][]; 14 | -------------------------------------------------------------------------------- /types/core/stochrsi.d.ts: -------------------------------------------------------------------------------- 1 | export = stochrsi; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function stochrsi(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/sum.d.ts: -------------------------------------------------------------------------------- 1 | export = sum; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function sum(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/tema.d.ts: -------------------------------------------------------------------------------- 1 | export = tema; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function tema(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/tr.d.ts: -------------------------------------------------------------------------------- 1 | export = tr; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function tr(high: number[], low: number[], close: number[], size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/trima.d.ts: -------------------------------------------------------------------------------- 1 | export = trima; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function trima(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/trix.d.ts: -------------------------------------------------------------------------------- 1 | export = trix; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function trix(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/tsf.d.ts: -------------------------------------------------------------------------------- 1 | export = tsf; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function tsf(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/tsi.d.ts: -------------------------------------------------------------------------------- 1 | export = tsi; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} y_period 6 | * @param {number} z_period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function tsi(source: number[], y_period: number, z_period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/typprice.d.ts: -------------------------------------------------------------------------------- 1 | export = typprice; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function typprice(high: number[], low: number[], close: number[], size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/ultosc.d.ts: -------------------------------------------------------------------------------- 1 | export = ultosc; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} short_period 8 | * @param {number} medium_period 9 | * @param {number} long_period 10 | * @param {number} [size] 11 | * @returns 12 | */ 13 | declare function ultosc(high: number[], low: number[], close: number[], short_period: number, medium_period: number, long_period: number, size?: number): number[]; 14 | -------------------------------------------------------------------------------- /types/core/varf.d.ts: -------------------------------------------------------------------------------- 1 | export = varf; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function varf(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/vhf.d.ts: -------------------------------------------------------------------------------- 1 | export = vhf; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function vhf(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/vidya.d.ts: -------------------------------------------------------------------------------- 1 | export = vidya; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} short_period 6 | * @param {number} long_period 7 | * @param {number} alpha 8 | * @param {number} [size] 9 | * @returns 10 | */ 11 | declare function vidya(source: number[], short_period: number, long_period: number, alpha: number, size?: number): number[]; 12 | -------------------------------------------------------------------------------- /types/core/volatility.d.ts: -------------------------------------------------------------------------------- 1 | export = volatility; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function volatility(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/vosc.d.ts: -------------------------------------------------------------------------------- 1 | export = vosc; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} short_period 6 | * @param {number} long_period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function vosc(source: number[], short_period: number, long_period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/vwap.d.ts: -------------------------------------------------------------------------------- 1 | export = vwap; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number[]} volume 8 | * @param {number} period 9 | * @param {number} [size] 10 | * @returns 11 | */ 12 | declare function vwap(high: number[], low: number[], close: number[], volume: number[], period: number, size?: number): number[]; 13 | -------------------------------------------------------------------------------- /types/core/vwma.d.ts: -------------------------------------------------------------------------------- 1 | export = vwma; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number[]} volume 6 | * @param {number} period 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function vwma(source: number[], volume: number[], period: number, size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/wad.d.ts: -------------------------------------------------------------------------------- 1 | export = wad; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function wad(high: number[], low: number[], close: number[], size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/wcprice.d.ts: -------------------------------------------------------------------------------- 1 | export = wcprice; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} [size] 8 | * @returns 9 | */ 10 | declare function wcprice(high: number[], low: number[], close: number[], size?: number): number[]; 11 | -------------------------------------------------------------------------------- /types/core/wilders.d.ts: -------------------------------------------------------------------------------- 1 | export = wilders; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function wilders(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/willr.d.ts: -------------------------------------------------------------------------------- 1 | export = willr; 2 | /** 3 | * 4 | * @param {number[]} high 5 | * @param {number[]} low 6 | * @param {number[]} close 7 | * @param {number} period 8 | * @param {number} [size] 9 | * @returns 10 | */ 11 | declare function willr(high: number[], low: number[], close: number[], period: number, size?: number): number[]; 12 | -------------------------------------------------------------------------------- /types/core/wma.d.ts: -------------------------------------------------------------------------------- 1 | export = wma; 2 | /** 3 | * 4 | * @param {number[]} source 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function wma(source: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/core/zlema.d.ts: -------------------------------------------------------------------------------- 1 | export = zlema; 2 | /** 3 | * 4 | * @param {number[]} input 5 | * @param {number} period 6 | * @param {number} [size] 7 | * @returns 8 | */ 9 | declare function zlema(input: number[], period: number, size?: number): number[]; 10 | -------------------------------------------------------------------------------- /types/index.d.ts: -------------------------------------------------------------------------------- 1 | import _cvi = require("./core/_cvi"); 2 | import abands = require("./core/abands"); 3 | import ad = require("./core/ad"); 4 | import adosc = require("./core/adosc"); 5 | import adx = require("./core/adx"); 6 | import adxr = require("./core/adxr"); 7 | import alma = require("./core/alma"); 8 | import ao = require("./core/ao"); 9 | import apo = require("./core/apo"); 10 | import aroon = require("./core/aroon"); 11 | import aroonosc = require("./core/aroonosc"); 12 | import atr = require("./core/atr"); 13 | import avgprice = require("./core/avgprice"); 14 | import bbands = require("./core/bbands"); 15 | import bop = require("./core/bop"); 16 | import cci = require("./core/cci"); 17 | import ce = require("./core/ce"); 18 | import cmf = require("./core/cmf"); 19 | import cmo = require("./core/cmo"); 20 | import copp = require("./core/copp"); 21 | import crossany = require("./core/crossany"); 22 | import crossover = require("./core/crossover"); 23 | import crossOverNumber = require("./core/crossOverNumber"); 24 | import crossUnderNumber = require("./core/crossUnderNumber"); 25 | import cvi = require("./core/cvi"); 26 | import dc = require("./core/dc"); 27 | import decay = require("./core/decay"); 28 | import dema = require("./core/dema"); 29 | import di = require("./core/di"); 30 | import dm = require("./core/dm"); 31 | import dpo = require("./core/dpo"); 32 | import dx = require("./core/dx"); 33 | import edecay = require("./core/edecay"); 34 | import ema = require("./core/ema"); 35 | import emv = require("./core/emv"); 36 | import fi = require("./core/fi"); 37 | import fisher = require("./core/fisher"); 38 | import fosc = require("./core/fosc"); 39 | import hma = require("./core/hma"); 40 | import kama = require("./core/kama"); 41 | import kc = require("./core/kc"); 42 | import kst = require("./core/kst"); 43 | import kvo = require("./core/kvo"); 44 | import lag = require("./core/lag"); 45 | import linreg = require("./core/linreg"); 46 | import linregintercept = require("./core/linregintercept"); 47 | import linregslope = require("./core/linregslope"); 48 | import macd = require("./core/macd"); 49 | import marketfi = require("./core/marketfi"); 50 | import mass = require("./core/mass"); 51 | import max = require("./core/max"); 52 | import md = require("./core/md"); 53 | import medprice = require("./core/medprice"); 54 | import mfi = require("./core/mfi"); 55 | import min = require("./core/min"); 56 | import mom = require("./core/mom"); 57 | import msw = require("./core/msw"); 58 | import natr = require("./core/natr"); 59 | import normalize = require("./core/normalize"); 60 | import normalize2 = require("./core/normalize2"); 61 | import nvi = require("./core/nvi"); 62 | import obv = require("./core/obv"); 63 | import pbands = require("./core/pbands"); 64 | import pfe = require("./core/pfe"); 65 | import posc = require("./core/posc"); 66 | import ppo = require("./core/ppo"); 67 | import psar = require("./core/psar"); 68 | import pvi = require("./core/pvi"); 69 | import qstick = require("./core/qstick"); 70 | import rmi = require("./core/rmi"); 71 | import rmta = require("./core/rmta"); 72 | import roc = require("./core/roc"); 73 | import rocr = require("./core/rocr"); 74 | import rsi = require("./core/rsi"); 75 | import rvi = require("./core/rvi"); 76 | import sma = require("./core/sma"); 77 | import smi = require("./core/smi"); 78 | import stddev = require("./core/stddev"); 79 | import stderr = require("./core/stderr"); 80 | import stoch = require("./core/stoch"); 81 | import stochrsi = require("./core/stochrsi"); 82 | import sum = require("./core/sum"); 83 | import tema = require("./core/tema"); 84 | import tr = require("./core/tr"); 85 | import trima = require("./core/trima"); 86 | import trix = require("./core/trix"); 87 | import tsf = require("./core/tsf"); 88 | import tsi = require("./core/tsi"); 89 | import typprice = require("./core/typprice"); 90 | import ultosc = require("./core/ultosc"); 91 | import varf = require("./core/varf"); 92 | import vhf = require("./core/vhf"); 93 | import vidya = require("./core/vidya"); 94 | import volatility = require("./core/volatility"); 95 | import vosc = require("./core/vosc"); 96 | import vwap = require("./core/vwap"); 97 | import vwma = require("./core/vwma"); 98 | import wad = require("./core/wad"); 99 | import wcprice = require("./core/wcprice"); 100 | import wilders = require("./core/wilders"); 101 | import willr = require("./core/willr"); 102 | import wma = require("./core/wma"); 103 | import zlema = require("./core/zlema"); 104 | export { _cvi, abands, ad, adosc, adx, adxr, alma, ao, apo, aroon, aroonosc, atr, avgprice, bbands, bop, cci, ce, cmf, cmo, copp, crossany, crossover, crossOverNumber, crossUnderNumber, cvi, dc, decay, dema, di, dm, dpo, dx, edecay, ema, emv, fi, fisher, fosc, hma, kama, kc, kst, kvo, lag, linreg, linregintercept, linregslope, macd, marketfi, mass, max, md, medprice, mfi, min, mom, msw, natr, normalize, normalize2, nvi, obv, pbands, pfe, posc, ppo, psar, pvi, qstick, rmi, rmta, roc, rocr, rsi, rvi, sma, smi, stddev, stderr, stoch, stochrsi, sum, tema, tr, trima, trix, tsf, tsi, typprice, ultosc, varf, vhf, vidya, volatility, vosc, vwap, vwma, wad, wcprice, wilders, willr, wma, zlema }; 105 | --------------------------------------------------------------------------------