Skip to content
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

Ichimoku indicator error #261

Open
werlang opened this issue Nov 3, 2022 · 2 comments
Open

Ichimoku indicator error #261

werlang opened this issue Nov 3, 2022 · 2 comments

Comments

@werlang
Copy link

werlang commented Nov 3, 2022

It seems that the Ichimoku indicator spanA and spanB lines are calculated wrong.
They should be plotted displacement periods in the future, but they are not.

Here is a reference for the calculation:
https://www.investopedia.com/terms/i/ichimoku-cloud.asp

I created a chart using TradingvVew lightweight charts, and plotted the ichimoku values as lines. To compare, I picked the same chart on TradingView with the ichimoku indicator enabled. It seems clear to me that the conversion and base lines are plotted right, but spanA and spanB are not plotted in the future, as they should be.

image

@werlang
Copy link
Author

werlang commented Nov 3, 2022

I believe the error is here. The commented part is responsible for the displacement.

// if(spanCounter < params.displacement) {
// spanCounter++
// } else {
// spanA = spanAs.shift()
// spanB = spanBs.shift()
// }

@werlang
Copy link
Author

werlang commented Nov 3, 2022

I corrected this error. Tried to follow the instructions to create a pull request, but got a bunch of errors.
This should fix the error:

class IchimokuCloud extends Indicator {
    constructor(input) {
        super(input);
        this.result = [];
        var defaults = {
            conversionPeriod: 9,
            basePeriod: 26,
            spanPeriod: 52,
            displacement: 26
        };
        var params = Object.assign({}, defaults, input);
        var currentConversionData = new FixedSizeLinkedList(params.conversionPeriod * 2, true, true, false);
        var currentBaseData = new FixedSizeLinkedList(params.basePeriod * 2, true, true, false);
        var currenSpanData = new FixedSizeLinkedList(params.spanPeriod * 2, true, true, false);
        let spanHistory = [];
        this.generator = (function* () {
            let result;
            let tick;
            let period = Math.max(params.conversionPeriod, params.basePeriod, params.spanPeriod, params.displacement);
            let periodCounter = 1;
            tick = yield;
            while (true) {
                // Keep a list of lows/highs for the max period
                currentConversionData.push(tick.high);
                currentConversionData.push(tick.low);
                currentBaseData.push(tick.high);
                currentBaseData.push(tick.low);
                currenSpanData.push(tick.high);
                currenSpanData.push(tick.low);
                if (periodCounter < period) {
                    periodCounter++;
                }
                else {
                    // Tenkan-sen (ConversionLine): (9-period high + 9-period low)/2))
                    let conversionLine = (currentConversionData.periodHigh + currentConversionData.periodLow) / 2;
                    // Kijun-sen (Base Line): (26-period high + 26-period low)/2))
                    let baseLine = (currentBaseData.periodHigh + currentBaseData.periodLow) / 2;
                    // Senkou Span A (Leading Span A): (Conversion Line + Base Line)/2))
                    let spanA = (conversionLine + baseLine) / 2;
                    // Senkou Span B (Leading Span B): (52-period high + 52-period low)/2))
                    let spanB = (currenSpanData.periodHigh + currenSpanData.periodLow) / 2;
                    // Senkou Span A / Senkou Span B offset by 26 periods
                    spanHistory.push([ spanA, spanB ]);

                    result = {
                        conversion: conversionLine,
                        base: baseLine,
                    };

                    if(spanHistory.length == params.displacement) {
                        [ spanA, spanB ] = spanHistory.shift();
                        result.spanA = spanA;
                        result.spanB = spanB;
                    }
                }
                tick = yield result;
            }
        })();
        this.generator.next();
        input.low.forEach((tick, index) => {
            var result = this.generator.next({
                high: input.high[index],
                low: input.low[index],
            });
            if (result.value) {
                this.result.push(result.value);
            }
        });
    }
    nextValue(price) {
        return this.generator.next(price).value;
    }
}

@werlang werlang closed this as completed Nov 3, 2022
@werlang werlang reopened this Nov 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant