Tradovate JavaScript indicator scaffold and patterns. Provides class structure and export guidance. Use when developing Tradovate indicators.
/plugin marketplace add lgbarn/trading-indicator-plugins/plugin install lgbarn-trading-indicators-plugins-trading-indicators@lgbarn/trading-indicator-pluginsThis skill inherits all available tools. When active, it can use any tool Claude has access to.
Lightweight scaffold for Tradovate JavaScript indicator development.
*LB.js or *ProLB.jsconst predef = require("./tools/predef");
const meta = require("./tools/meta");
const { ParamType } = meta;
class IndicatorName {
init() {
// One-time initialization
this.cumulativeValue = 0;
}
map(d, i, history) {
// d = current bar { open, high, low, close, volume, timestamp }
// i = bar index
// history = historical data access
const result = {};
result.plotName = calculatedValue;
return result;
}
filter() {
// Optional validation
return true;
}
}
module.exports = {
name: "indicator-name",
description: "Description of indicator",
calculator: IndicatorName,
params: {
period: predef.paramSpecs.period(14),
multiplier: {
type: ParamType.NUMBER,
def: 1.0,
step: 0.1,
min: 0.1,
max: 10.0
}
},
plots: {
value: { title: "Value" },
upperBand: { title: "Upper Band" }
},
inputType: meta.InputType.BARS,
tags: ["Luther Barnum", "vwap", "trading"],
schemeStyles: {
dark: {
value: predef.styles.plot({ color: "#00FF00" })
}
}
};
Access via this.props.type:
"chart" - Reset per trading day"session" - Reset at specific time"rolling" - Reset per N-bar window// Previous bar
const prevBar = history.prior();
// Specific historical bar
const bar = history.get(i - 5);
// Direct array access
const data = history.data[i];
map(d, i, history) {
const tradeDate = d.tradeDate();
if (tradeDate !== this.lastTradeDate) {
// New session - reset values
this.cumulativeValue = 0;
this.lastTradeDate = tradeDate;
}
}
function number(defValue, step, min, max) {
return { type: ParamType.NUMBER, def: defValue, step, min, max };
}
Reference: /Users/lgbarn/Personal/Indicators/Tradovate/LRBMACD.js
const predef = require("./tools/predef");
const meta = require("./tools/meta");
const SMA = require("./tools/SMA");
class SimpleMACD {
init() {
this.fastSMA = SMA(this.props.fast);
this.slowSMA = SMA(this.props.slow);
this.signalSMA = SMA(this.props.signal);
}
map(d, i) {
const value = d.value();
const macd = this.fastSMA(value) - this.slowSMA(value);
let signal;
let histogram;
if (i >= this.props.slow - 1) {
signal = this.signalSMA(macd);
histogram = macd - signal;
}
return { macd, signal, histogram, zero: 0 };
}
filter(d) {
return predef.filters.isNumber(d.histogram);
}
}
module.exports = {
name: "simple-macd-lb",
description: "Simple MACD Indicator",
calculator: SimpleMACD,
params: {
fast: predef.paramSpecs.period(3),
slow: predef.paramSpecs.period(10),
signal: predef.paramSpecs.period(16)
},
validate(obj) {
if (obj.slow < obj.fast) {
return meta.error("slow", "Slow must be >= fast");
}
},
inputType: meta.InputType.BARS,
plots: {
macd: { title: "MACD" },
signal: { title: "Signal" },
histogram: { title: "Histogram" },
zero: { displayOnly: true }
},
tags: ["Luther Barnum", predef.tags.Oscillators],
schemeStyles: {
dark: {
macd: predef.styles.plot("#FFA500"),
signal: predef.styles.plot("#0000FF"),
histogram: predef.styles.plot("#FF3300"),
zero: predef.styles.plot({ color: "#B5BAC2", lineStyle: 3 })
}
}
};
class SessionVWAP {
init() {
this.cumVolume = 0;
this.cumVwap = 0;
this.cumVwap2 = 0;
this.lastTradeDate = null;
}
map(d, i, history) {
const currentDate = d.tradeDate();
// Reset on new session
if (currentDate !== this.lastTradeDate) {
this.cumVolume = 0;
this.cumVwap = 0;
this.cumVwap2 = 0;
this.lastTradeDate = currentDate;
}
const typicalPrice = (d.high() + d.low() + d.close()) / 3;
const volume = d.volume();
this.cumVolume += volume;
this.cumVwap += volume * typicalPrice;
this.cumVwap2 += volume * typicalPrice * typicalPrice;
if (this.cumVolume === 0) {
return { vwap: undefined, upper: undefined, lower: undefined };
}
const vwap = this.cumVwap / this.cumVolume;
const variance = (this.cumVwap2 / this.cumVolume) - (vwap * vwap);
const stdev = variance > 0 ? Math.sqrt(variance) : 0;
return {
vwap,
upper: vwap + stdev,
lower: vwap - stdev
};
}
}
validate(obj) {
if (obj.period < 1) {
return meta.error("period", "Period must be >= 1");
}
if (obj.slow <= obj.fast) {
return meta.error("slow", "Slow must be greater than fast");
}
}
map(d, i, history) {
// Not enough history
if (i < this.props.period - 1) {
return { value: undefined };
}
// Check previous bar exists
const prev = history.prior();
if (!prev) {
return { value: undefined };
}
}
const divisor = d.high() - d.low();
const result = divisor === 0 ? 0 : (d.close() - d.low()) / divisor;
filter(d) {
return predef.filters.isNumber(d.value);
}
// Or multiple checks
filter(d) {
return predef.filters.isNumber(d.value) &&
predef.filters.isNumber(d.signal);
}
map(d, i, history) {
const prev = history.prior();
const prevClose = prev ? prev.close() : d.close();
}
/Users/lgbarn/Personal/Indicators/Tradovate/Use WebSearch to find Tradovate indicator documentation:
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.