tradovate-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseTradovate Patterns
Tradovate 开发模式
Lightweight scaffold for Tradovate JavaScript indicator development.
用于Tradovate JavaScript指标开发的轻量级脚手架。
File Conventions
文件命名规范
- File naming: or
*LB.js*ProLB.js - Tags: Must include "Luther Barnum"
- 文件命名:或
*LB.js*ProLB.js - 标签:必须包含 "Luther Barnum"
Dependencies
依赖项
javascript
const predef = require("./tools/predef");
const meta = require("./tools/meta");
const { ParamType } = meta;javascript
const predef = require("./tools/predef");
const meta = require("./tools/meta");
const { ParamType } = meta;Class Structure
类结构
javascript
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;
}
}javascript
class IndicatorName {
init() {
// 一次性初始化
this.cumulativeValue = 0;
}
map(d, i, history) {
// d = 当前K线 { open, high, low, close, volume, timestamp }
// i = K线索引
// history = 历史数据访问接口
const result = {};
result.plotName = calculatedValue;
return result;
}
filter() {
// 可选的验证逻辑
return true;
}
}Export Pattern
导出模式
javascript
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" })
}
}
};javascript
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- - Reset per trading day
"chart" - - Reset at specific time
"session" - - Reset per N-bar window
"rolling"
通过 访问:
this.props.type- - 每个交易日重置
"chart" - - 在特定时间重置
"session" - - 每N根K线窗口重置
"rolling"
History Access
历史数据访问
javascript
// Previous bar
const prevBar = history.prior();
// Specific historical bar
const bar = history.get(i - 5);
// Direct array access
const data = history.data[i];javascript
// 上一根K线
const prevBar = history.prior();
// 指定的历史K线
const bar = history.get(i - 5);
// 直接数组访问
const data = history.data[i];Session Detection
会话检测
javascript
map(d, i, history) {
const tradeDate = d.tradeDate();
if (tradeDate !== this.lastTradeDate) {
// New session - reset values
this.cumulativeValue = 0;
this.lastTradeDate = tradeDate;
}
}javascript
map(d, i, history) {
const tradeDate = d.tradeDate();
if (tradeDate !== this.lastTradeDate) {
// 新会话 - 重置数值
this.cumulativeValue = 0;
this.lastTradeDate = tradeDate;
}
}Helper Functions
辅助函数
javascript
function number(defValue, step, min, max) {
return { type: ParamType.NUMBER, def: defValue, step, min, max };
}javascript
function number(defValue, step, min, max) {
return { type: ParamType.NUMBER, def: defValue, step, min, max };
}Complete Example
完整示例
Reference:
/Users/lgbarn/Personal/Indicators/Tradovate/LRBMACD.jsjavascript
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 })
}
}
};参考:
/Users/lgbarn/Personal/Indicators/Tradovate/LRBMACD.jsjavascript
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
VWAP 计算模式
javascript
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
};
}
}javascript
class SessionVWAP {
init() {
this.cumVolume = 0;
this.cumVwap = 0;
this.cumVwap2 = 0;
this.lastTradeDate = null;
}
map(d, i, history) {
const currentDate = d.tradeDate();
// 新会话时重置
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
验证函数
javascript
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");
}
}javascript
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()中检查历史数据
javascript
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 };
}
}javascript
map(d, i, history) {
// 历史数据不足
if (i < this.props.period - 1) {
return { value: undefined };
}
// 检查上一根K线是否存在
const prev = history.prior();
if (!prev) {
return { value: undefined };
}
}Safe division
安全除法
javascript
const divisor = d.high() - d.low();
const result = divisor === 0 ? 0 : (d.close() - d.low()) / divisor;javascript
const divisor = d.high() - d.low();
const result = divisor === 0 ? 0 : (d.close() - d.low()) / divisor;Filter invalid data
过滤无效数据
javascript
filter(d) {
return predef.filters.isNumber(d.value);
}
// Or multiple checks
filter(d) {
return predef.filters.isNumber(d.value) &&
predef.filters.isNumber(d.signal);
}javascript
filter(d) {
return predef.filters.isNumber(d.value);
}
// 或者多条件检查
filter(d) {
return predef.filters.isNumber(d.value) &&
predef.filters.isNumber(d.signal);
}Undefined checks
未定义值检查
javascript
map(d, i, history) {
const prev = history.prior();
const prevClose = prev ? prev.close() : d.close();
}javascript
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/
- 关注品种:/ES、/NQ 期货
- 时间周期:5分钟
- 核心概念:VWAP、会话检测、累计计算
- 文件位置:
/Users/lgbarn/Personal/Indicators/Tradovate/
Documentation Sources
文档来源
Use WebSearch to find Tradovate indicator documentation:
- Tradovate Community Forum (community.tradovate.com)
- Tradovate Indicator API examples
使用网络搜索查找Tradovate指标相关文档:
- Tradovate 社区论坛 (community.tradovate.com)
- Tradovate 指标API示例