tradovate-patterns

Lightweight scaffold for Tradovate JavaScript indicator development.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "tradovate-patterns" with this command: npx skills add lgbarn/trading-indicator-plugins/lgbarn-trading-indicator-plugins-tradovate-patterns

Tradovate Patterns

Lightweight scaffold for Tradovate JavaScript indicator development.

File Conventions

  • File naming: *LB.js or *ProLB.js

  • Tags: Must include "Luther Barnum"

Dependencies

const predef = require("./tools/predef"); const meta = require("./tools/meta"); const { ParamType } = meta;

Class Structure

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;
}

}

Export Pattern

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" }) } } };

Session Types

Access via this.props.type :

  • "chart"

  • Reset per trading day

  • "session"

  • Reset at specific time

  • "rolling"

  • Reset per N-bar window

History Access

// Previous bar const prevBar = history.prior();

// Specific historical bar const bar = history.get(i - 5);

// Direct array access const data = history.data[i];

Session Detection

map(d, i, history) { const tradeDate = d.tradeDate();

if (tradeDate !== this.lastTradeDate) {
    // New session - reset values
    this.cumulativeValue = 0;
    this.lastTradeDate = tradeDate;
}

}

Helper Functions

function number(defValue, step, min, max) { return { type: ParamType.NUMBER, def: defValue, step, min, max }; }

Complete Example

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 }) } } };

VWAP Calculation Pattern

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
    };
}

}

Error Handling Patterns

Validation function

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"); } }

Check history in map()

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 };
}

}

Safe division

const divisor = d.high() - d.low(); const result = divisor === 0 ? 0 : (d.close() - d.low()) / divisor;

Filter invalid data

filter(d) { return predef.filters.isNumber(d.value); }

// Or multiple checks filter(d) { return predef.filters.isNumber(d.value) && predef.filters.isNumber(d.signal); }

Undefined checks

map(d, i, history) { const prev = history.prior(); const prevClose = prev ? prev.close() : d.close(); }

Trading Context

  • Focus: /ES, /NQ futures

  • Timeframe: 5-minute

  • Key concepts: VWAP, Session detection, Cumulative calculations

  • Location: /Users/lgbarn/Personal/Indicators/Tradovate/

Documentation Sources

Use WebSearch to find Tradovate indicator documentation:

  • Tradovate Community Forum (community.tradovate.com)

  • Tradovate Indicator API examples

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

pine-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

ninja-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

terraform-plan-review

No summary provided by upstream source.

Repository SourceNeeds Review