How to add custom indicator

Can not get it to go through have it on my code editor but can get it added to my entries. any help would be nice or if you can added it for me to community indictors this is my code just name it Jdog.

const predef = require("./tools/predef");

const EMA = require(“./tools/EMA”);

function rollingAvg(arr) {
if (!arr.length) return 0;
return arr.reduce((a, b) => a + b, 0) / arr.length;
}

class LiquidityVolumeTrend {
init() {
this.fastEMA = EMA(9);
this.slowEMA = EMA(21);
this.volEMA = EMA(20);
this.rangeHistory = ;
}

map(d) {
    const close = d.close();
    const volume = d.volume();
    if (close === undefined || volume === undefined) return {};

    const fast = this.fastEMA(close);
    const slow = this.slowEMA(close);
    const volAvg = this.volEMA(volume);
    if (!fast || !slow || !volAvg) return {};

    const volRatio = volAvg > 0 ? volume / volAvg : 1;
    const upTrend = fast > slow;
    const isSpike = volume > volAvg * 1.5;
    const buySignal = upTrend && isSpike ? 1 : 0;
    const sellSignal = !upTrend && isSpike ? 1 : 0;

    return { volRatio, buySignal, sellSignal };
}

filter(d) {
    return d.volume() !== undefined;
}

}

module.exports = {
name: “jdog”,
description: “Liquidity and Volume Trend”,
plots: {
volRatio: { title: “Vol Ratio” },
buySignal: { title: “Buy” },
sellSignal: { title: “Sell” }
},
schemeStyles: predef.styles.standard({
volRatio: { color: “#4fc3f7” },
buySignal: { color: “#00e676” },
sellSignal: { color: “#ff1744” }
}),
plotter: [
predef.plotters.histogram(“volRatio”)
],
calculator: LiquidityVolumeTrend
};

const predef = require("./tools/predef");
const EMA = require("./tools/EMA");

function rollingAvg(arr) {
    if (!arr.length) return 0;
    return arr.reduce((a, b) => a + b, 0) / arr.length;
}

class LiquidityVolumeTrend {
    init() {
        this.fastEMA = EMA(9);
        this.slowEMA = EMA(21);
        this.volEMA = EMA(20);
        this.rangeHistory = [];
    }

    map(d) {
        const close = d.close();
        const volume = d.volume();
        if (close === undefined || volume === undefined) return {};

        const fast = this.fastEMA(close);
        const slow = this.slowEMA(close);
        const volAvg = this.volEMA(volume);
        if (!fast || !slow || !volAvg) return {};

        const volRatio = volAvg > 0 ? volume / volAvg : 1;
        const upTrend = fast > slow;
        const isSpike = volume > volAvg * 1.5;
        const buySignal = upTrend && isSpike ? 1 : 0;
        const sellSignal = !upTrend && isSpike ? 1 : 0;

        return { volRatio, buySignal, sellSignal };
    }

    filter(d) {
        return d.volume() !== undefined;
    }
}

module.exports = {
    name: "jdog",
    description: "Liquidity and Volume Trend",
    plots: {
        volRatio: { title: "Vol Ratio" },
        buySignal: { title: "Buy" },
        sellSignal: { title: "Sell" }
    },
    schemeStyles: predef.styles.standard({
        volRatio: { color: "#4fc3f7" },
        buySignal: { color: "#00e676" },
        sellSignal: { color: "#ff1744" }
    }),
    plotter: [
        predef.plotters.histogram("volRatio")
    ],
    calculator: LiquidityVolumeTrend
};

Any help would be greatly appriated i have worked hours with AI trying to get it on there, this is my original code.

const predef = require(“./tools/predef”); const EMA = require(“./tools/EMA”); function rollingAvg(arr) { if (!arr.length) return 0; return arr.reduce((a, b) => a + b, 0) / arr.length; } class LiquidityVolumeTrend { init() { this.fastEMA = EMA(this.props.fastPeriod); this.slowEMA = EMA(this.props.slowPeriod); this.volEMA = EMA(this.props.volumePeriod); this.rangeHistory = []; this.rangeLookback = this.props.volumePeriod; } map(d) { const open = d.open(); const high = d.high(); const low = d.low(); const close = d.close(); const volume = d.volume(); if (!open || !high || !low || !close || !volume) return {}; const fast = this.fastEMA(close); const slow = this.slowEMA(close); const volAvg = this.volEMA(volume); if (!fast || !slow || !volAvg) return {}; const upTrend = fast > slow; const downTrend = fast < slow; const barRange = high - low; const closePos = barRange > 0 ? (close - low) / barRange : 0.5; this.rangeHistory.push(barRange); if (this.rangeHistory.length > this.rangeLookback) { this.rangeHistory.shift(); } const avgRange = rollingAvg(this.rangeHistory); const isSpike = volume > volAvg * this.props.spikeMultiplier; const isInstSize = volume > volAvg * this.props.instMultiplier; const tinyRange = avgRange > 0 && barRange < avgRange * this.props.absorptionRangeRatio; const isAbsorption = isInstSize && tinyRange; const isClimaxBuy = isInstSize && closePos >= 0.70; const isClimaxSell = isInstSize && closePos <= 0.30; const isWideBar = avgRange > 0 && barRange > avgRange * this.props.aggressiveRangeRatio; const isAggressiveBuy = isInstSize && isWideBar && closePos >= 0.65 && close > open; const isAggressiveSell = isInstSize && isWideBar && closePos <= 0.35 && close < open; const instBuy = (isAbsorption && upTrend) || isClimaxBuy || isAggressiveBuy; const instSell = (isAbsorption && downTrend) || isClimaxSell || isAggressiveSell; const buySignal = !instBuy && !instSell && upTrend && isSpike ? 1 : 0; const sellSignal = !instBuy && !instSell && downTrend && isSpike ? 1 : 0; const volRatio = volAvg > 0 ? volume / volAvg : 1; return { volRatio, buySignal, sellSignal, instBuy: instBuy ? 1 : 0, instSell: instSell ? 1 : 0 }; } filter(d) { return d.volume() !== undefined; } } module.exports = { name: “LiquidityVolumeTrend”, description: “Liquidity & Volume Trend + Institutional Order Flow”, params: { fastPeriod: predef.paramSpecs.period(9), slowPeriod: predef.paramSpecs.period(21), volumePeriod: predef.paramSpecs.period(20), spikeMultiplier: { type: “number”, def: 1.5, label: “Volume Spike Multiplier” }, instMultiplier: { type: “number”, def: 2.5, label: “Institutional Volume Multiplier” }, absorptionRangeRatio: { type: “number”, def: 0.4, label: “Absorption Range Ratio” }, aggressiveRangeRatio: { type: “number”, def: 1.8, label: “Aggressive Bar Range Ratio” } }, plots: { volRatio: { title: “Vol Ratio” }, buySignal: { title: “Buy” }, sellSignal: { title: “Sell” }, instBuy: { title: “Inst Buy” }, instSell: { title: “Inst Sell” } }, schemeStyles: predef.styles.standard({ volRatio: { color: “#4fc3f7” }, buySignal: { color: “#00e676” }, sellSignal: { color: “#ff1744” }, instBuy: { color: “#00ffaa” }, instSell: { color: “#ff4466” } }), plotter: [ predef.plotters.histogram(“volRatio”), predef.plotters.custom(function(canvas, item) { if (!item.buySignal) return; var rect = canvas.rect; canvas.text(“BUY”, rect.x, rect.y + rect.height - 6, { textAlign: “center”, fillStyle: “#00e676”, font: “bold 10px sans-serif” }); }), predef.plotters.custom(function(canvas, item) { if (!item.sellSignal) return; var rect = canvas.rect; canvas.text(“SELL”, rect.x, rect.y + 12, { textAlign: “center”, fillStyle: “#ff1744”, font: “bold 10px sans-serif” }); }), predef.plotters.custom(function(canvas, item) { if (!item.instBuy) return; var rect = canvas.rect; canvas.text(“INST BUY”, rect.x, rect.y + rect.height - 6, { textAlign: “center”, fillStyle: “#00ffaa”, font: “bold 11px sans-serif” }); }), predef.plotters.custom(function(canvas, item) { if (!item.instSell) return; var rect = canvas.rect; canvas.text(“INST SELL”, rect.x, rect.y + 12, { textAlign: “center”, fillStyle: “#ff4466”, font: “bold 11px sans-serif” }); }) ], calculator: LiquidityVolumeTrend };

Aloha @intercoastal7! Was curious to see what you were cooking up here so fixed it for you.

const predef = require('./tools/predef');
const meta = require('./tools/meta');
const EMA = require('./tools/EMA');
const { px, du, op } = require('./tools/graphics');

function rollingAvg(arr) {
    if (!arr.length) return 0;
    return arr.reduce((a, b) => a + b, 0) / arr.length;
}

class LiquidityVolumeTrend {
    init() {
        this.fastEMA = EMA(this.props.fastPeriod);
        this.slowEMA = EMA(this.props.slowPeriod);
        this.volEMA = EMA(this.props.volumePeriod);
        this.rangeHistory = [];
        this.rangeLookback = this.props.volumePeriod;
    }
    map(d) {
        const open = d.open();
        const high = d.high();
        const low = d.low();
        const close = d.close();
        const volume = d.volume();
        if (!open || !high || !low || !close || !volume) return {};
        const fast = this.fastEMA(close);
        const slow = this.slowEMA(close);
        const volAvg = this.volEMA(volume);
        if (!fast || !slow || !volAvg) return {};
        const upTrend = fast > slow;
        const downTrend = fast < slow;
        const barRange = high - low;
        const closePos = barRange > 0 ? (close - low) / barRange : 0.5;
        this.rangeHistory.push(barRange);
        if (this.rangeHistory.length > this.rangeLookback) {
            this.rangeHistory.shift();
        }
        const avgRange = rollingAvg(this.rangeHistory);
        const isSpike = volume > volAvg * this.props.spikeMultiplier;
        const isInstSize = volume > volAvg * this.props.instMultiplier;
        const tinyRange = avgRange > 0 && barRange < avgRange * this.props.absorptionRangeRatio;
        const isAbsorption = isInstSize && tinyRange;
        const isClimaxBuy = isInstSize && closePos >= 0.7;
        const isClimaxSell = isInstSize && closePos <= 0.3;
        const isWideBar = avgRange > 0 && barRange > avgRange * this.props.aggressiveRangeRatio;
        const isAggressiveBuy = isInstSize && isWideBar && closePos >= 0.65 && close > open;
        const isAggressiveSell = isInstSize && isWideBar && closePos <= 0.35 && close < open;
        const instBuy = (isAbsorption && upTrend) || isClimaxBuy || isAggressiveBuy;
        const instSell = (isAbsorption && downTrend) || isClimaxSell || isAggressiveSell;
        const buySignal = !instBuy && !instSell && upTrend && isSpike ? 1 : 0;
        const sellSignal = !instBuy && !instSell && downTrend && isSpike ? 1 : 0;
        const volRatio = volAvg > 0 ? volume / volAvg : 1;

        const graphicsItems = [];
        if (buySignal) {
            graphicsItems.push({
                tag: 'Text',
                key: 'buy_' + d.index(),
                point: {
                    x: du(d.index()),
                    y: op(du(volRatio), '+', px(12)),
                },
                text: 'BUY',
                style: {
                    fontSize: 10,
                    fontWeight: 'bold',
                    fill: '#00e676',
                },
                textAlignment: 'centerMiddle',
            });
        } else if (sellSignal) {
            graphicsItems.push({
                tag: 'Text',
                key: 'sell_' + d.index(),
                point: {
                    x: du(d.index()),
                    y: op(du(volRatio), '+', px(12)),
                },
                text: 'SELL',
                style: {
                    fontSize: 10,
                    fontWeight: 'bold',
                    fill: '#ff1744',
                },
                textAlignment: 'centerMiddle',
            });
        } else if (instBuy) {
            graphicsItems.push({
                tag: 'Text',
                key: 'ibuy_' + d.index(),
                point: {
                    x: du(d.index()),
                    y: op(du(volRatio), '+', px(12)),
                },
                text: 'INST BUY',
                style: {
                    fontSize: 11,
                    fontWeight: 'bold',
                    fill: '#00ffaa',
                },
                textAlignment: 'centerMiddle',
            });
        } else if (instSell) {
            graphicsItems.push({
                tag: 'Text',
                key: 'isell_' + d.index(),
                point: {
                    x: du(d.index()),
                    y: op(du(volRatio), '+', px(12)),
                },
                text: 'INST SELL',
                style: {
                    fontSize: 11,
                    fontWeight: 'bold',
                    fill: '#ff4466',
                },
                textAlignment: 'centerMiddle',
            });
        }

        return {
            volRatio,
            buySignal,
            sellSignal,
            instBuy: instBuy ? 1 : 0,
            instSell: instSell ? 1 : 0,
            graphics: graphicsItems.length > 0 ? { items: graphicsItems } : undefined,
        };
    }
    filter(d) {
        return predef.filters.isNumber(d.volRatio);
    }
}
module.exports = {
    name: 'LiquidityVolumeTrend',
    description: 'Liquidity & Volume Trend + Institutional Order Flow',
    calculator: LiquidityVolumeTrend,
    inputType: meta.InputType.BARS,
    areaChoice: meta.AreaChoice.NEW,
    params: {
        fastPeriod: predef.paramSpecs.period(9),
        slowPeriod: predef.paramSpecs.period(21),
        volumePeriod: predef.paramSpecs.period(20),
        spikeMultiplier: predef.paramSpecs.number(1.5, 0.1, 0),
        instMultiplier: predef.paramSpecs.number(2.5, 0.1, 0),
        absorptionRangeRatio: predef.paramSpecs.number(0.4, 0.05, 0),
        aggressiveRangeRatio: predef.paramSpecs.number(1.8, 0.1, 0),
    },
    plots: {
        volRatio: { title: 'Vol Ratio' },
        buySignal: { title: 'Buy', displayOnly: true },
        sellSignal: { title: 'Sell', displayOnly: true },
        instBuy: { title: 'Inst Buy', displayOnly: true },
        instSell: { title: 'Inst Sell', displayOnly: true },
    },
    tags: [predef.tags.Volumes, 'Tikitrade 🏝️ Try tikitrade.com'],
    schemeStyles: {
        dark: {
            volRatio: predef.styles.plot('#4fc3f7'),
            buySignal: predef.styles.plot('#00e676'),
            sellSignal: predef.styles.plot('#ff1744'),
            instBuy: predef.styles.plot('#00ffaa'),
            instSell: predef.styles.plot('#ff4466'),
        },
    },
    plotter: [
        predef.plotters.columns('volRatio'),
    ],
};


Awesome thank so very much. Are you able to help me with this i added some more to the last one.

const predef = require(“./tools/predef”);
const EMA = require(“./tools/EMA”);

function rollingAvg(arr) {
if (!arr.length) return 0;
return arr.reduce((a, b) => a + b, 0) / arr.length;
}

class Jdog {
init() {
this.fastEMA = EMA(9);
this.slowEMA = EMA(21);
this.volEMA = EMA(20);
this.rangeHistory = ;
}

map(d) {
const open = d.open();
const high = d.high();
const low = d.low();
const close = d.close();
const volume = d.volume();

if (open === undefined || high === undefined || low === undefined || close === undefined || volume === undefined) {
return {};
}

const fast = this.fastEMA(close);
const slow = this.slowEMA(close);
const volAvg = this.volEMA(volume);

if (!fast || !slow || !volAvg) {
return {};
}

const upTrend = fast > slow;
const downTrend = fast < slow;
const barRange = high - low;
const closePos = barRange > 0 ? (close - low) / barRange : 0.5;

this.rangeHistory.push(barRange);
if (this.rangeHistory.length > 20) {
this.rangeHistory.shift();
}
const avgRange = rollingAvg(this.rangeHistory);

const isSpike = volume > volAvg * 1.5;
const isInstSize = volume > volAvg * 2.5;
const tinyRange = avgRange > 0 && barRange < avgRange * 0.4;
const isAbsorption = isInstSize && tinyRange;
const isClimaxBuy = isInstSize && closePos >= 0.70;
const isClimaxSell = isInstSize && closePos <= 0.30;
const isWideBar = avgRange > 0 && barRange > avgRange * 1.8;
const isAggressiveBuy = isInstSize && isWideBar && closePos >= 0.65 && close > open;
const isAggressiveSell = isInstSize && isWideBar && closePos <= 0.35 && close < open;

const instBuy = (isAbsorption && upTrend) || isClimaxBuy || isAggressiveBuy;
const instSell = (isAbsorption && downTrend) || isClimaxSell || isAggressiveSell;
const buySignal = !instBuy && !instSell && upTrend && isSpike ? 1 : 0;
const sellSignal = !instBuy && !instSell && downTrend && isSpike ? 1 : 0;
const volRatio = volAvg > 0 ? volume / volAvg : 1;

const base = Math.round(close / 100) * 100;
const gamma0 = base - 200;
const gamma1 = base - 100;
const gamma2 = base - 50;
const gamma3 = base;
const gamma4 = base + 50;
const gamma5 = base + 100;
const gamma6 = base + 200;

return {
volRatio,
buySignal,
sellSignal,
instBuy: instBuy ? 1 : 0,
instSell: instSell ? 1 : 0,
gamma0,
gamma1,
gamma2,
gamma3,
gamma4,
gamma5,
gamma6
};
}

filter(d) {
return d.volume() !== undefined;
}
}

module.exports = {
name: “jdog”,
description: “jdog Liquidity Volume Trend with Institutional Flow and Gamma Levels”,
calculator: Jdog,
plots: {
volRatio: { title: “Vol Ratio” },
buySignal: { title: “Buy” },
sellSignal: { title: “Sell” },
instBuy: { title: “Inst Buy” },
instSell: { title: “Inst Sell” },
gamma0: { title: “Gamma -200” },
gamma1: { title: “Gamma -100” },
gamma2: { title: “Gamma -50” },
gamma3: { title: “Key Level” },
gamma4: { title: “Gamma +50” },
gamma5: { title: “Gamma +100” },
gamma6: { title: “Gamma +200” }
},
schemeStyles: predef.styles.standard({
volRatio: { color: “#4fc3f7” },
buySignal: { color: “#00e676” },
sellSignal: { color: “#ff1744” },
instBuy: { color: “#00ffaa” },
instSell: { color: “#ff4466” },
gamma0: { color: “#ff4466”, lineWidth: 1 },
gamma1: { color: “#ff4466”, lineWidth: 1 },
gamma2: { color: “#ffaa00”, lineWidth: 1 },
gamma3: { color: “#ffffff”, lineWidth: 2 },
gamma4: { color: “#ffaa00”, lineWidth: 1 },
gamma5: { color: “#00ffaa”, lineWidth: 1 },
gamma6: { color: “#00ffaa”, lineWidth: 1 }
}),
plotter: [
predef.plotters.histogram(“volRatio”),
predef.plotters.custom(function(canvas, item) {
if (!item.buySignal) return;
var x = canvas.rect.x;
var y = canvas.rect.y;
var h = canvas.rect.height;
canvas.text(“BUY”, x, y + h - 6, {
textAlign: “center”,
fillStyle: “#00e676”,
font: “bold 10px sans-serif”
});
}),
predef.plotters.custom(function(canvas, item) {
if (!item.sellSignal) return;
var x = canvas.rect.x;
var y = canvas.rect.y;
canvas.text(“SELL”, x, y + 12, {
textAlign: “center”,
fillStyle: “#ff1744”,
font: “bold 10px sans-serif”
});
}),
predef.plotters.custom(function(canvas, item) {
if (!item.instBuy) return;
var x = canvas.rect.x;
var y = canvas.rect.y;
var h = canvas.rect.height;
canvas.text(“INST BUY”, x, y + h - 6, {
textAlign: “center”,
fillStyle: “#00ffaa”,
font: “bold 11px sans-serif”
});
}),
predef.plotters.custom(function(canvas, item) {
if (!item.instSell) return;
var x = canvas.rect.x;
var y = canvas.rect.y;
canvas.text(“INST SELL”, x, y + 12, {
textAlign: “center”,
fillStyle: “#ff4466”,
font: “bold 11px sans-serif”
});
})
]
};

On the one you fixed for me i was able to find it but it only shows the volume in the blue with buy and sell trying to get something on the candles that have a buy and sell button. Thanks for the help. I truly appreciate it. JDog

Just checked out your website do you have a good indicator that you have built that would be good for ES trading in the even hours? This is where I seem to do the best. Let me know what plan I may need to get on. Thanks

Ah - you cannot draw on the candles when using the area charts (area = below the chart), best you can do is paint the candles a certain color, or you can use two indicators - one for the area and one for the price chart.

As for my premium set of indicators, not sure what you are looking for but our new Tiki Gamma indicator (pictured above) works well at any time. It shows dealer gamma levels from SPY/SPX option chains on your ES chart. It’s been pretty mind-blowing to be honest - sign up for a free trial at https://tikitrade.com and give it a try.

How does it work? if i pay will i have access on tradovate?

Yep just make sure to sign up with the same email associated with your Tradovate account to gain access automatically, and if you have any issues let me know!