TradingView 支持自定義指標,不過是把你要定義的指標寫成一個 JS 源文件(customIndex.js),放在圖表庫 static 文件夾下。自定義指標 JS 源代碼模板以下:ajax
1 __customIndicators = [ 2 { 3 name: 'ShuBenRSI', 4 metainfo: { 5 '_metainfoVersion': 40, 6 'id': 'ShuBenRSI@tv-basicstudies-1', 7 'scriptIdPart': '', 8 'name': 'ShuBenRSI', 9 'description': 'ShuBenRSI', 10 'shortDescription': 'ShuBenRSI', 11 'is_hidden_study': true, 12 'is_price_study': true, 13 'isCustomIndicator': true, 14 'plots': [{'id': 'plot_0', 'type': 'line'}], 15 'defaults': { 16 'styles': { 17 'plot_0': { 18 'linestyle': 0, 19 'visible': true, 20 'linewidth': 1, 21 'plottype': 2, // 繪製類型爲線形圖: 2 22 'trackPrice': true, 23 'transparency': 40, 24 'color': '#880000' 25 } 26 }, 27 'precision': 1, // 精度 eg:608.4 28 'inputs': {} 29 }, 30 'styles': { 31 'plot_0': { 32 'title': 'ShuBenRSI', 33 'histogrambase': 0, 34 } 35 }, 36 'inputs': [], 37 }, 38 constructor: function () { 39 this.init = function (context, inputCallback) { 40 this._context = context; 41 this._input = inputCallback; 42 //var symbol = 'p1905'; 43 var symbol = PineJS.Std.ticker(this._context); // 獲取所選商品代碼 44 this._context.new_sym(symbol, PineJS.Std.period(this._context), PineJS.Std.period(this._context)); 45 }; 46 this.main = function (context, inputCallback) { 47 this._context = context; 48 this._input = inputCallback; 49 this._context.select_sym(1); 50 if(this._context['symbol']['time'] != NaN){ 51 var c = PineJS.Std.close(this._context)-50; 52 var o = PineJS.Std.open(this._context)-50; 53 var l = PineJS.Std.low(this._context)-50; 54 var h = PineJS.Std.high(this._context)-50; 55 console.log('execute custom index!'); 56 console.log('symbol: ', this._context['symbol']['time']); 57 return [o, c]; 58 } 59 60 } 61 } 62 } 63 ];
其中 main 方法會根據數據量(getBar 中的後臺獲取的數據)的多少自動進行循環遍歷,在此能夠對數據進行修改,以建立本身的數據曲線(我的理解)async
即 new TradingView.widget() 中使用 indicators_file_name: 'customIndex.js' ide
onChartReady() 中將定義指標添加到頁面顯示中 widget.chart().createStudy('ShuBenRSI', false, false); // 自定義 RSI 曲線函數
自定義的曲線數據源來自 getBar 方法中回調函數中的 bar 數據,能夠在自定義模板中修改此數據。post
1 __customIndicators = [ 2 { 3 name: 'ShuBenRSI', 4 metainfo: { 5 '_metainfoVersion': 40, 6 'id': 'ShuBenRSI@tv-basicstudies-1', 7 'scriptIdPart': '', 8 'name': 'ShuBenRSI', 9 //當調用createStudy方法時,它也被用做「name」參數 10 'description': 'ShuBenRSI', 11 // 該描述將顯示在圖表上 12 'shortDescription': 'ShuBenRSI', 13 'is_hidden_study': true, 14 // 指標曲線是否在主數據列窗口中顯示 15 'is_price_study': true, 16 'isCustomIndicator': true, 17 'plots': [{'id': 'plot_0', 'type': 'line'}], 18 'defaults': { 19 'styles': { 20 'plot_0': { 21 'linestyle': 0, 22 'visible': true, 23 'linewidth': 1, 24 'plottype': 2, // 繪製類型爲線形圖: 2 25 'trackPrice': true, 26 'transparency': 40, 27 'color': '#880000' 28 } 29 }, 30 'precision': 3, // 精度 eg:608.4 31 'inputs': {} 32 }, 33 'styles': { 34 'plot_0': { 35 'title': 'ShuBenRSI', 36 'histogrambase': 0, 37 } 38 }, 39 'inputs': [], 40 }, 41 constructor: function () { 42 this.init = function (context, inputCallback) { 43 var host = window.location; 44 var host1 = host.href.split('static'); 45 var fakeDataRSI = []; 46 $.ajaxSetup({ async: false }); 47 $.post(host1[0] + 'cta_posPL_syetem/getChartData',{method:'getDataRSI'}, function (result) { 48 if(result.result_code == 'success'){ 49 fakeDataRSI = result.data; 50 } 51 52 }); 53 this.fakeData = fakeDataRSI; 54 this.count = 0; 55 this.time = 0; 56 this.rsi = 0; 57 this.infoList = []; 58 //console.log('init context: ', context); 59 //console.log(this.count); 60 this._context = context; 61 this._input = inputCallback; 62 //var symbol = 'p1905'; 63 var symbol = PineJS.Std.ticker(this._context); // 獲取所選商品代碼 64 this._context.new_sym(symbol, PineJS.Std.period(this._context), PineJS.Std.period(this._context)); 65 }; 66 this.main = function (context, inputCallback) { 67 //this.count += 1; 68 //console.log('count: ',this.count); 69 //if(this.count<5)console.log('main fakeData: ', this.fakeData[this.count]); 70 this._context = context; 71 this._input = inputCallback; 72 this._context.select_sym(1); 73 /* 74 // RSI 計算 75 if(this.count > 1 && this.time != this._context['symbol']['time']){ 76 //console.log(PineJS.Std.close(this._context)); 77 this.infoList.push(PineJS.Std.close(this._context)); 78 var upSum = 0;var downSum = 0; 79 if(this.count > 15){ 80 for(var i = 1; i <= 14; i++){ 81 var change = this.infoList[i] - this.infoList[i - 1]; 82 change > 0 ? upSum += change : downSum -= change; 83 } 84 var rs = Math.round(upSum / 14 *1000) / downSum; 85 this.rsi = Math.round(rs / (1 + rs) * 100 * 1000) / 1000; 86 //console.log('current: ', this._context['symbol']['time'], 'pretime: ',this.time); 87 //console.log('infoList: ',this.infoList); 88 this.infoList.splice(0, 1); 89 this.time = this._context['symbol']['time']; 90 //console.log('index close: --- >', PineJS.Std.close(this._context)); 91 return [this.rsi]; 92 } 93 } 94 return [this.rsi]; 95 */ 96 var c = this.fakeData[this.count++]['close']; 97 //console.log('rsi: ',this.rsi); 98 99 return [c]; 100 /* 101 var c = PineJS.Std.close(this._context)-50; 102 var o = PineJS.Std.open(this._context)-50; 103 var l = PineJS.Std.low(this._context)-50; 104 var h = PineJS.Std.high(this._context)-50; 105 //console.log('execute custom index!'); 106 console.log('symbol: ', this._context['symbol']['time']); 107 //return [o, c]; 108 */ 109 } 110 } 111 } 112 ];
若是你想要自定義的曲線數據並非 K 線數據,你能夠在自定義模板中,向後臺請求 用後臺返回的數據。eg: this
1 __customIndicators = [ 2 { 3 name: 'ShuBenRSI', 4 metainfo: { 5 '_metainfoVersion': 40, 6 'id': 'ShuBenRSI@tv-basicstudies-1', 7 'scriptIdPart': '', 8 'name': 'ShuBenRSI', 9 //當調用createStudy方法時,它也被用做「name」參數 10 'description': 'ShuBenRSI', 11 // 該描述將顯示在圖表上 12 'shortDescription': 'ShuBenRSI', 13 'is_hidden_study': true, 14 'is_price_study': false, 15 'isCustomIndicator': true, 16 'plots': [{'id': 'plot_0', 'type': 'line'}], 17 'defaults': { 18 'styles': { 19 'plot_0': { 20 'linestyle': 0, 21 'visible': true, 22 'linewidth': 1, 23 'plottype': 2, // 繪製類型爲線形圖: 2 24 'trackPrice': true, 25 'transparency': 40, 26 'color': '#880000' 27 } 28 }, 29 'precision': 3, // 精度 eg:608.4 30 'inputs': {} 31 }, 32 'styles': { 33 'plot_0': { 34 'title': 'ShuBenRSI', 35 'histogrambase': 0, 36 } 37 }, 38 'inputs': [], 39 }, 40 constructor: function () { 41 this.init = function (context, inputCallback) { 42 var host = window.location.href.split('static')[0]; 43 var fakeDataRSI = []; 44 $.ajaxSetup({ async: false }); 45 $.post(host + 'cta_posPL_syetem/getChartData',{method:'getDataRSI'}, function (result) { 46 if(result.result_code == 'success'){ 47 fakeDataRSI = result.data; 48 } 49 }); 50 this.fakeData = fakeDataRSI; 51 this.count = 0; 52 this.time = 0; 53 this.rsi = 0; 54 this.infoList = []; 55 this._context = context; 56 this._input = inputCallback; 57 var symbol = PineJS.Std.ticker(this._context); // 獲取所選商品代碼 58 this._context.new_sym(symbol, PineJS.Std.period(this._context), PineJS.Std.period(this._context)); 59 }; 60 this.main = function (context, inputCallback) { 61 this._context = context; 62 this._input = inputCallback; 63 this._context.select_sym(1); 64 var c = this.fakeData[this.count++]['close']; 65 return [c]; 66 } 67 } 68 } 69 ];