anandanand84 / technicalindicators

A javascript technical indicators written in typescript with pattern recognition right in the browser
MIT License
2.14k stars 557 forks source link

Invalid Twizzer implementations #187

Open vitaly-t opened 5 years ago

vitaly-t commented 5 years ago

https://github.com/anandanand84/technicalindicators/blob/d8fe190212f5011a6057beaeaea0c11e763a4bcb/src/candlestick/TweezerTop.ts#L14

Your Twizzer Top + Bottom calculations look bad. You should not do exact match comparisons like data.high[3] == data.high[4].

The match must include a minor deviation, which may be invisible to the eye, but still forming the correct pattern, like 0.001% of the price. Otherwise, you are excluding a lot of valid matches. In fact, most of near-perfect matches will not be detected by your algorithm because of that.

UPDATE

I noticed this method you have that you use in some other patterns:

https://github.com/anandanand84/technicalindicators/blob/066f35bcffbf9f923f45ec28525d1f2a5d063a76/src/candlestick/CandlestickFinder.ts#L10

But that method doesn't look well either. For example, when trading Bitcoin, it tells me that approximateEqual(9840, 9849) is true. That's a whole $9 difference - too much to be considered the same. In this case I would expect a marginal error of about $1, not $10.

Here's implementation that I implemented within my own library:

/**
 * Calculates value-comparison error margin for the candles range.
 */
export function calcMargin(candles: Candle[]): number {
    let min = candles[0].low;
    let max = candles[0].high;
    candles.forEach(c => {
        min = Math.min(min, c.low);
        max = Math.max(max, c.high);
    });
    const minMargin = 0.0000001; // minimum possible margin
    const ave = (max + min) / 2;
    return Math.max(ave / 10000, minMargin);
}

I give it a range of candles, and it calculates the size of the error margin for that price range.

Then inside any candle pattern that I implement, if it uses a marginal error, I define it right there:

const approxEqual = (a, b) => Math.abs(a - b) <= margin;