-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IndicatorsNormalized returns not reusable data for other indicators #18
Comments
@iocron Hi 🤗, SolutionUse Indicators and NOT the Normalized version. /**
* @param {number[]} output
* @param {number} source_length
*/
function addEmpty(output, source_length) {
const temp = []
const diff = source_length - output.length
temp[diff - 1] = NaN
return [...temp, ...output]
} Full Exampleconst {
Indicators, IndicatorsNormalized,
} = require("@ixjb94/indicators")
const ta = new Indicators()
const tan = new IndicatorsNormalized() // <== don't use me
/**
* @param {number} min
* @param {number} max
*/
function Random(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
const close = []
for (let index = 0; index < 50; index++) {
const randomNumber = Random(10, 40)
close.push(randomNumber)
}
/**
* @param {number[]} output
* @param {number} source_length
*/
function addEmpty(output, source_length) {
const temp = []
const diff = source_length - output.length
temp[diff - 1] = NaN
return [...temp, ...output]
}
Run()
async function Run() {
const rsi = await ta.rsi(close, 7)
const rsi_ma = await ta.sma(rsi, 20)
const output = addEmpty(rsi_ma, close.length)
console.log(output)
} Output: (the output may be different than yours, because it's Generated) [
undefined, undefined, undefined,
undefined, undefined, undefined,
undefined, undefined, undefined,
undefined, undefined, undefined,
undefined, undefined, undefined,
undefined, undefined, undefined,
undefined, undefined, undefined,
undefined, undefined, undefined,
undefined, NaN, 48.409972870313666,
48.758523920696206, 48.50023087557265, 48.94769344216493,
48.43780346856899, 48.31505005147469, 49.19289826629342,
49.28825140608763, 49.129617185904095, 49.6415874878621,
49.69494592271763, 49.14570752567564, 49.149323617199656,
49.945004924935745, 49.56460975230834, 50.00279206973923,
49.69814879052427, 49.5256522683758, 49.11588410882351,
48.54057548642972, 48.78522623006723, 49.30666004481652,
49.10587194114991, 49.503918175336295
] |
@ixjb94 thanks for taking the time to explain it this thoroughly 👍 I partly agree on the performance perspective, but I disagree regarding the usability/data error-resilience. If I understand this correctly:
My question, why do the (normalized) indicators accept NaN/undefined if they can't process it properly / if it results in a misleading outcome? But also a regular indicator can rarely produce a result like [ NaN ], which can cause unexpected side effects for the user in their codebase (e.g. In my case, I actually need the normalized output for processing, not just for displaying / charting. I try to keep my data consistent all over the place and compare the lengths of the data everywhere I can. I believe data consistency and resilience are more important than performance for trading (most of the time), a single (wrong) data entry can sometimes mess up entire calculations/estimations. Maybe I am overlooking something, who knows 😅 |
@iocron, I should point it out that the solution that I've mentioned earlier is still valid. also there is a method named: normalize which is the equivalent of the About the performance, As you know when calculating a big real-time data every milliseconds counts. Use each class based on your needs: If at the end you needed a normalized data as well, you can use I hope it was helpful and answered you questions, if there is anything else please feel free to ask. 🤗 |
@ixjb94 Awesome thanks 👍 I have not noticed the normalize method in the Indicators class before, that makes it easier to work with without implementing a own helper function :) Does this not make the IndicatorsNormalized class possibly redundant (and partly confusing)? I still don't understand why performance of milliseconds should be important for charting, but thats likely off-topic. Btw., I've realised that some indicators seem not to be aligned and produce misleading data. For example the following SMA and EMA are not returning the same Array length when using the exact same period and data:
|
@iocron, About array length, the reason is due to calculations, // code...
let val = source[0]
output.push(val)
// other code... Example:
But SMA and others are not. Based on my own experience, if you are trying to use it for finances and trading strategies. you probably don't need the head and the tail would be sufficient. Example: rsi = ta.rsi(close, 14)
r1 = ta.sma(rsi, 10)
r2 = ta.ema(r1, 20)
// ... and all other nesting, etc.
// now normalizing the data would be optional, if you want to use the data for plotting, you can. I hope that helped. if you need more in-depth explanations feel free to ask. |
@ixjb94 That's simply wrong, all Moving Averages are by definition Lagging Indicators. Also, if I compare it to other libraries and the official TradingView SMA/EMA, then there is no such thing as you explained. They all return the same result length and starting point. Some of the ixjb94/indicators seem like very custom implementations and this makes the package a bit unpredictable to use. |
@iocron, About EMA, I tend to simply the term, that's why I put it on a quotations "Lagging", but it tends to reduce the lag (compared to SMA, etc.). Logically when you see that I/O of an indicator is not the same, you can say that it's lagging. Moving Averages are NOT having the same starting points (results of course). About the implementation, this algorithm is the fastest way of having the indicators, so implementing doesn't mean wrong. Example (ixjb94/indicators vs technicalindicators)const { IndicatorsSync } = require("@ixjb94/indicators")
const { SMA } = require("technicalindicators")
const close = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// @ixjb94/indicators
const ta = new IndicatorsSync()
const sma = ta.sma(close, 5)
console.log({
"ixjb94/indicators": sma.length,
})
// technicalindicators
const r1 = SMA.calculate({ period: 5, values: close })
console.log({
"technicalindicators": r1.length,
})
// output:
{ 'ixjb94/indicators': 6 }
{ technicalindicators: 6 } Exponential Moving Average (EMA)Question: How to have the same length when working with both EMA and SMA?
pseudo code
Data IntegrityYou can check my other repository in order to find Data Integrity (verifying it with TradingView Data) OR this issue: I hope it helped you. 🤗 |
If you have any other questions please open new issue. 🤗 |
While using IndicatorsNormalized and a indicator the returned data is not being processed correctly by other indicators, because the normalization returns a array with empty/undefined/NaN, which breaks the logic, see example below:
Instead the other indicators should skip empty/undefined/NaN values in the calculation.
The text was updated successfully, but these errors were encountered: