I have a custom indicator that uses some values like the standard deviation of close and other calculated values.
I have a version of this that loads in a new window which doesn’t use graphics module and outputs fine. When you change time frames (1D/5m/etc) for that one, you get expected results, where values like standard deviation and others update as expected.
However on a more complicated version of it that uses the graphics module and outputs the values on the last bar, it does not update when you change time frames. So if you go from the daily bar to a 5 minute bar, the values will still reflect those of the daily bar, where the less complicated one will have the correct values corresponding to the current time frame.
Currently the only way to get it to update after changing times seems to be to re-save the indicator code or remove and re-add the indicator through the UI.
Uploading examples of daily and hourly time frame with both indicators shown. Source code below.
Daily chart, both indicators (one in new area, one as overlay) match:
If you change to the hourly, the values above and their plots still correspond to the daily bar, even though the chart has changed to hourly:
- Is there something I am missing to force it to update when the time frame is changed?
Here is the source of the overlay/graphics module version, which has the issue:
const predef = require("./tools/predef");
const meta = require("./tools/meta");
const MovingHigh = require("./tools/MovingHigh");
const MovingLow = require("./tools/MovingLow");
const MMA = require("./tools/MMA");
const StdDev = require("./tools/StdDev");
const trueRange = require("./tools/trueRange");
const g = require("./tools/graphics");
const du = g.du;
const op = g.op;
const px = g.px;
const barScapeLines = function (openValue, description, value, color, textSize, decimals) {
const startPosition = 40;
const length = 20;
const padding = 10;
return {
tag: 'Container',
key: description+'Container',
children: [
{
tag: 'LineSegments',
key: 'lines',
lines: [
{
tag: 'Line',
a: {
x: op(du(0), '+', px(startPosition)),
y: du(openValue+value),
},
b: {
x: op(du(0), '+', px(startPosition+length)),
y: du(openValue+value)
},
infiniteStart: false,
infiniteEnd: false,
},
{
tag: 'Line',
a: {
x: op(du(0), '+', px(startPosition)),
y: du(openValue-value),
},
b: {
x: op(du(0), '+', px(startPosition+length)),
y: du(openValue-value)
},
infiniteStart: false,
infiniteEnd: false,
}
],
lineStyle: {
lineWidth: 2,
color: color
}
},
{
tag: "Text",
key: description+"H",
text: `${description} ${value.toFixed(decimals)}`,
point: {
x: op(du(0), '+', px(startPosition+length+padding)),
y: op(du(openValue+value), '+', px(0))
},
style: { fontSize: textSize, fontWeight: "bold", fill: color},
textAlignment: "rightMiddle"
},
{
tag: "Text",
key: description+"L",
text: `${description} ${value.toFixed(decimals)}`,
point: {
x: op(du(0), '+', px(startPosition+length+padding)),
y: op(du(openValue-value), '+', px(0))
},
style: { fontSize: textSize, fontWeight: "bold", fill: color},
textAlignment: "rightMiddle"
},
]
}
};
class BarScape {
init() {
this.pullbackAverage = MMA(this.props.barScapePeriod);
this.pullbackHigh = MovingHigh(this.props.barScapePeriod);
this.bodyAverage = MMA(this.props.barScapePeriod);
this.bodyHigh = MovingHigh(this.props.barScapePeriod);
this.stdDev = StdDev(this.props.barScapePeriod);
}
map(d, i, history) {
const open = d.open();
const close = d.close();
const high = d.high();
const low = d.low();
const up = close > open ? true : false;
const down = close < open ? true : false;
const top = close > open ? close : open;
const bottom = close > open ? open : close;
const body = top-bottom;
const pullback = up ? bottom-low : high-top;
const averageBody = this.bodyAverage(body);
const highBody = this.bodyHigh(body);
const averagePullback = this.pullbackAverage(pullback);
const highPullback = this.pullbackHigh(pullback);
const standardDev = this.stdDev(close);
// display settings
const decimals = this.props.decimals;
const textSize = this.props.textSize;
const highPullbackColor = this.props.highPullbackColor;
const avgPullbackColor = this.props.avgPullbackColor;
const highBodyColor = this.props.highBodyColor;
const avgBodyColor = this.props.avgBodyColor;
const stdDevColor = this.props.stdDevColor;
return {
graphics: d.isLast() && {
items: [
barScapeLines (open, "OPEN", 0, "#BBBBBB", textSize, decimals),
barScapeLines (open, "STDEV", standardDev, stdDevColor, textSize, decimals),
barScapeLines (open, "PB_AVG", averagePullback, avgPullbackColor, textSize, decimals),
barScapeLines (open, "PB_HIGH", highPullback, highPullbackColor, textSize, decimals),
barScapeLines (open, "B_AVG", averageBody, avgBodyColor, textSize, decimals),
barScapeLines (open, "B_HIGH", highBody, highBodyColor, textSize, decimals),
]
}
};
}
filter(d,i) {
return i > this.props.barScapePeriod;
}
}
module.exports = {
name: "BarScape",
title: "BarScape",
description: "BarScape",
calculator: BarScape,
params: {
barScapePeriod: predef.paramSpecs.period(20),
decimals: predef.paramSpecs.number(7),
textSize: predef.paramSpecs.number(11),
stdDevColor: predef.paramSpecs.color("#fc03df"),
avgBodyColor: predef.paramSpecs.color("gray"),
highBodyColor: predef.paramSpecs.color("green"),
avgPullbackColor: predef.paramSpecs.color("orange"),
highPullbackColor: predef.paramSpecs.color("red")
},
inputType: meta.InputType.BARS,
plots: {
},
plotter: [
],
schemeStyles: {
},
tags: ["Brian"],
};
One update:
It seems the horizontal placement of this doesn’t really work right either. In the code editor view that I have set up using du(0) places it at the last bar more or less (with the padding), but if I use that code in the normal chart view it places it somewhere far off to the left on the chart. However, if I change that to pass i
in from the map function, and then use du(i)
instead, then the horizontal placement has strange behavior for any time frame but the first one pretty much. Changing from daily to 5m for example kicks it far off to the right off the screen.
I am evidently missing something here, or just doing it wrong.