Creating Custom Studies - kroim/charting-library-wiki GitHub Wiki
The instruction below explains how to display chart data as an indicator. Please follow these steps.
-
Come up with a new ticker name to display your data and set up your server to return valid SymbolInfo for this new ticker.
-
Also, set up the server to return valid historical data for this ticker.
-
Use the indicator template and complete the following fields: name, descriptions, and the ticker. Modify the default style of the indicator if required.
{ // Replace the <study name> with your study name // The name will be used internally by the Charting Library name: "<study name>", metainfo: { "_metainfoVersion": 40, "id": "<study name>@tv-basicstudies-1", "scriptIdPart": "", "name": "<study name>", // This description will be displayed in the Indicators window // It is also used as a "name" argument when calling the createStudy method "description": "<study description>", // This description will be displayed on the chart "shortDescription": "<short study description>", "is_hidden_study": true, "is_price_study": true, "isCustomIndicator": true, "plots": [{"id": "plot_0", "type": "line"}], "defaults": { "styles": { "plot_0": { "linestyle": 0, "visible": true, // Plot line width. "linewidth": 2, // Plot type: // 1 - Histogram // 2 - Line // 3 - Cross // 4 - Area // 5 - Columns // 6 - Circles // 7 - Line With Breaks // 8 - Area With Breaks "plottype": 2, // Show price line? "trackPrice": false, // Plot transparency, in percent. "transparency": 40, // Plot color in #RRGGBB format "color": "#0000FF" } }, // Precision of the study's output values // (quantity of digits after the decimal separator). "precision": 2, "inputs": {} }, "styles": { "plot_0": { // Output name will be displayed in the Style window "title": "-- output name --", "histogramBase": 0, } }, "inputs": [], }, constructor: function() { this.init = function(context, inputCallback) { this._context = context; this._input = inputCallback; // Define the symbol to be plotted. // Symbol should be a string. // You can use PineJS.Std.ticker(this._context) to get the selected symbol's ticker. // For example, // var symbol = "AAPL"; // var symbol = "#EQUITY"; // var symbol = PineJS.Std.ticker(this._context) + "#TEST"; var symbol = "<TICKER>"; this._context.new_sym(symbol, PineJS.Std.period(this._context), PineJS.Std.period(this._context)); }; this.main = function(context, inputCallback) { this._context = context; this._input = inputCallback; this._context.select_sym(1); // You can use following built-in functions in PineJS.Std object: // open, high, low, close // hl2, hlc3, ohlc4 var v = PineJS.Std.close(this._context); return [v]; } } }
-
Add custom_indicators_getter key to the widget constructor. Its value is a function that returns a Promise object with a list of custom indicators.
{ custom_indicators_getter: function(PineJS) { return Promise.resolve([ // *** your indicator object, created from the template *** ]); }, }
-
Update your widget's initialization code to create this indicator when the chart is ready.
-
Add the indicator to the Charting Library using custom_indicators_getter option.
-
Change your widget's initialization code. Here is an example.
widget = new TradingView.widget(/* ... */); widget.onChartReady(function() { widget.chart().createStudy('<indicator-name>', false, true); });
Let's assume that you wish to display the equity curve on the chart. You will have to do the following.
- Create a name for the new ticker, e.g.
#EQUITY
. You can use any name that you can think of. - Change your server's code to validate this symbol. The minimum amount of symbol information should be returned for this ticker.
- Make the server return valid historical data for this ticker just as you return the historical data for the generic symbols such as AAPL.
- Modify the indicator template mentioned above and create the indicators file (or add a new indicator to the existing indicators file). Here is an example:
{
name: "Equity",
metainfo: {
"_metainfoVersion": 40,
"id": "Equity@tv-basicstudies-1",
"scriptIdPart": "",
"name": "Equity",
"description": "Equity",
"shortDescription": "Equity",
"is_hidden_study": true,
"is_price_study": true,
"isCustomIndicator": true,
"plots": [{"id": "plot_0", "type": "line"}],
"defaults": {
"styles": {
"plot_0": {
"linestyle": 0,
"visible": true,
// Make the line thinner
"linewidth": 1,
// Plot type is Line
"plottype": 2,
// Show price line
"trackPrice": true,
"transparency": 40,
// Set the plotted line color to dark red
"color": "#880000"
}
},
// Precision is set to one digit, e.g. 777.7
"precision": 1,
"inputs": {}
},
"styles": {
"plot_0": {
// Output name will be displayed in the Style window
"title": "Equity value",
"histogramBase": 0,
}
},
"inputs": [],
},
constructor: function() {
this.init = function(context, inputCallback) {
this._context = context;
this._input = inputCallback;
var symbol = "#EQUITY";
this._context.new_sym(symbol, PineJS.Std.period(this._context), PineJS.Std.period(this._context));
};
this.main = function(context, inputCallback) {
this._context = context;
this._input = inputCallback;
this._context.select_sym(1);
var v = PineJS.Std.close(this._context);
return [v];
}
}
}
{
name: "Bar Colorer Demo",
metainfo: {
_metainfoVersion: 42,
id: "BarColoring@tv-basicstudies-1",
name: "BarColoring",
description: "Bar Colorer Demo",
shortDescription: "BarColoring",
scriptIdPart: "",
is_price_study: true,
is_hidden_study: false,
isCustomIndicator: true,
isTVScript: false,
isTVScriptStub: false,
defaults: {
precision: 4,
palettes: {
palette_0: {
// palette colors
// change it to the default colors that you prefer,
// but note that the user can change them in the Style tab
// of indicator properties
colors: [
{ color: "#FFFF00" },
{ color: "#0000FF" }
]
}
}
},
inputs: [],
plots: [{
id: "plot_0",
// plot type should be set to 'bar_colorer'
type: "bar_colorer",
// this is the name of the palette that is defined
// in 'palettes' and 'defaults.palettes' sections
palette: "palette_0"
}],
palettes: {
palette_0: {
colors: [
{ name: "Color 0" },
{ name: "Color 1" }
],
// the mapping between the values that
// are returned by the script and palette colors
valToIndex: {
100: 0,
200: 1
}
}
}
},
constructor: function() {
this.main = function(context, input) {
this._context = context;
this._input = input;
var valueForColor0 = 100;
var valueForColor1 = 200;
// perform your calculations here and return one of the constants
// that is specified as a key in 'valToIndex' mapping
var result =
Math.random() * 100 % 2 > 1 ? // we randomly select one of the color values
valueForColor0 : valueForColor1;
return [result];
}
}
}