Highcharts.setOptions({lang :{
rangeSelectorZoom : "",
/*rangeSelectorFrom : "",
rangeSelectorTo : "",*/
}});
$(document).ajaxStart(function() {
$(productChart.loadingContainer).show();
$(".control-container").addClass("disabled");
});
$(document).ajaxStop(function() {
$(productChart.loadingContainer).hide();
$(".control-container").removeClass("disabled");
});
$(window).on('resize.productChart', function(e) {
if (isMobileView){
productChart.resize(e);
}
});
var productChart = {
chart : null,
cur_chart : null,
data : null,
period: 5,
usedSlot : ["","","","",""],
usedMASlot : ["","","","",""],
//maColors : {10: "#F48B28", 20: "#FF68D3", 50: "#00DEBB", 100: "#9FA1F3",250:"#BC6BC6"},
maColors : ["#78c043","#865bbc","#da0c6f","#7a004c","#4c227c"],
maIndex : {10: 0, 20: 1, 50: 2, 100:3, 250:4},
maIndex2 : [10,20,50,100,250],
yAxisRange : [undefined,undefined],
colors : {wntLine : "#003868",underlyingLine : "#0072ce"},
navigatorUpdated : null,
toolTipMoved : null,
selectedRange : [-1,-1],
stockcode: "",
ucode:'',
comparecode : "",
backgroundColor: "",
selected_ts:0,
loadingContainer:null,
lastTooltipPoint:null,
charttype: "candlestick",
isMobile:false,
init : function(code, callback, navUpdated, ttMoved){
var self = this;
self.navigatorUpdated = (navUpdated!==undefined)?navUpdated:null;
self.toolTipMoved = (ttMoved!==undefined)?ttMoved:null;
self.isMobile = (isMobileView || $("body").attr("data-broswer-view") == "mobile")?true:false;
if (self.isMobile){
self.options.subChartHeight = 75;
self.options.chartHeight = 238;
}
$.getJSON('/'+lang+'/data/chart/productChart/code/'+code+'/period/'+self.period, function(_data) {
$(".chartContainer").show();
noChart = 0;
if (!_data.mainData.underlying || _data.mainData.underlying.length == 0){
$(".chartContainer").hide();
noChart = 1;
return;
}
self.data = self.decode(_data);
var htmlContainer = null;
if ($('#productChartContainer .highcharts-html-container').length>0){
htmlContainer = $('#productChartContainer .highcharts-html-container');
}
$(".chart-stime").html(_data.stime);
$('#productChartContainer').highcharts('StockChart',self.getJSON(self.data), function (chart){
if ($(chart.renderTo).attr("id")){
if (!$('#productChartContainer').hasClass("noSetting")){
if (htmlContainer){
$('#productChartContainer').append(htmlContainer);
}else{
$('#productChartContainer').append("
");
$('#productChartContainer .highcharts-html-container').append("");
self.loadingContainer = $('#productChartContainer .highcharts-html-container .highcharts-loading');
}
}
self.chart = chart;
self.cur_chart = chart;
self.stockcode = code;
self.drawBackground();
if (self.period == 0){
self.setPeriod(self.data.last[self.data.last.length-1][0]- (60*60*24*1000)*180,self.data.last[self.data.last.length-1][0]);
}else if(self.data.last[0]){
self.setPeriod(self.data.last[Math.max(self.data.last.length-71,0)][0],self.data.last[self.data.last.length-1][0]);
}
//self.setPeriod(self.data.last[self.data.last.length-1][0]- (60*60*24*1000)*365,self.data.last[self.data.last.length-1][0]);
self.changeChartType(self.charttype);
if (callback){
callback();
}
}else{
chart.reflow();
}
});
});
},
decode : function(_data){
this.ucode = _data.mainData.ucode;
var udata = _data.mainData.underlying;
var uohlc = [], uvolume = [], uturnover = [],ulast = [];
for (i = 0; i < udata.length; i++) {
uohlc.push({
x: udata[i].ts,
y: udata[i].last,
high: udata[i].high,
low: udata[i].low,
open: udata[i].open,
close: udata[i].last,
});
ulast.push([
udata[i].ts, // the date
udata[i].last // close
]);
uvolume.push([
udata[i].ts, // the date
udata[i].vol // the volume
]);
uturnover.push([
udata[i].ts, // the date
udata[i].turnover // the turnover
]);
}
var _max = 0;
var _min = 99999;
var data = _data.mainData.warrant;
var ohlc = [], volume = [], turnover = [],last = [], os=[];
for (i = 0; i < data.length; i++) {
// ohlc.push({
// x: data[i].ts,
// y: data[i].last,
// high: data[i].high,
// low: data[i].low,
// open: data[i].open,
// close: data[i].last,
// });
_max = Math.max(_max,data[i].last);
_min = Math.min(_min,data[i].last);
last.push([
data[i].ts, // the date
data[i].last // close
]);
volume.push([
data[i].ts, // the date
data[i].vol // the volume
]);
turnover.push([
data[i].ts, // the date
data[i].turnover // the turnover
]);
os.push([
data[i].ts, // the date
data[i].os // the turnover
]);
}
if (_max == _min){
this.yAxisRange[0] = _max-0.01;
this.yAxisRange[1] = _max+0.01;
}else if (_min<=0.012){
this.yAxisRange[0] = _min-0.001;
}
return {vol:volume, turnover: turnover, last:last, os:os, uohlc : uohlc, uvol:uvolume, uturnover: uturnover, ulast:ulast};
},
options : {
groupingUnits : [["minute",[5]],],//[['day',[1]],],
chartHeight : 400,
chartTitle : 45,
subChartHeight : 100,
subChartTitle : 23,
dateBarHeight : 25,
footerPadding : 5,
/*chartTitle : 23,*/
},
resize: function(e){
var self = this;
var chart = this.chart;
var count = 0;
//usedSlot
for(var i=0;i1000)?80:60,
marginRight: 50,
marginTop: this.options.chartTitle,
events: {
load: function(){
if (this == self.chart){
//self.refreshSeries();
}else{
//console.log("load: copy");
self.cur_chart = this;
//self.refreshSeries();
setTimeout(function(){ self.cur_chart = self.chart; }, 100);
}
},
redraw: function(event) {
if ((self.selectedRange[0]!=event.target.xAxis[0].min || self.selectedRange[1]!=event.target.xAxis[0].max) || (self.selectedRange[0]==-1 && self.selectedRange[1]==-1)){
//console.log("redraw",self.navigatorUpdated);
self.selectedRange[0] = event.target.xAxis[0].min;
self.selectedRange[1] = event.target.xAxis[0].max;
if (self.navigatorUpdated){
self.navigatorUpdated(event.target.xAxis[0].min,event.target.xAxis[0].max);
}
}
}
}
},
annotationsOptions: {
enabled: true,
noButtons: true,
/*buttonsElementId: "underlyingMasterTools",*/
},
exporting: {
enabled: false,
},
plotOptions: {
candlestick: {
oxymoronic: true,
color: '#d91e19',
lineColor: '#d91e19',
upColor: '#003868',
upLineColor: '#003868'
},
area: {
threshold: null,
},
series: {
//turboThreshold: 2000,
states:{
hover: {
enabled: false,
},
inactive:{
opacity:1,
}
}
}
},
tooltip: {
backgroundColor: "rgba(0,0,0,0)",
borderWidth: 0,
borderRadius: 0,
useHTML: true,
positioner: function(width, height, point){
var pos = this.getPosition(width, height, point);
if (self.lastTooltipPoint && self.lastTooltipPoint.series.type == "line"){
var _point = self.lastTooltipPoint.point;
pos.y = _point.plotY;
}
return pos;
},
formatter : function(){
self.drawToolTip(this);
return "";
},
shadow: false,
},
rangeSelector : {
enabled: false,
selected: 1
},
xAxis:{
type: 'datetime',
gridLineWidth: 0,
lineWidth: 0,
tickColor: '#00000000',
crosshair: {
width: 1,
color: "#000",
zIndex: 4,
dashStyle: "Dash",
},
tickPixelInterval:100,
labels: {
style:{"color": "#000"},
formatter: function () {
if (Highcharts.dateFormat('%H:%M', this.value) != "00:00"){
if (Highcharts.dateFormat('%H%M', this.value)*1 < 920){
return Highcharts.dateFormat('09:20', this.value);
}
return Highcharts.dateFormat('%H:%M', this.value);
}else{
return Highcharts.dateFormat('%d/%m', this.value);
}
}
},
opposite: true,
offset: this.options.chartHeight*-1-30,
},
yAxis: [{
labels:{
style:{"color": "#000"},
formatter: function () {
return formatPrice(this.value);
},
align:"right",
x: -3,
y: 4,
},
tickAmount : 7,
height: this.options.chartHeight,
top:this.options.chartTitle,
opposite: false,
showFirstLabel: false,
showLastLabel: true,
crosshair: {
width: 1,
color: "#000",
snap:true,
zIndex: 4,
dashStyle: "Dash",
label: {
/*shape: "rect",*/
backgroundColor: "#0072ce",
enabled: true,
format: '{value:.2f}',
style:{"color": "#fff"},
}
},
gridLineWidth: (self.toolTipMoved !=null)?0:1,
},
{
labels:{
style:{"color": "#000"},
formatter: function () {
return formatPrice(this.value);
},
align:'left',
x: 3,
y: 4,
},
min:this.yAxisRange[0],
max:this.yAxisRange[1],
tickAmount : 7,
height: this.options.chartHeight,
top:this.options.chartTitle,
opposite: true,
showFirstLabel: false,
showLastLabel: true,
crosshair: {
width: 1,
color: "#000",
snap:true,
zIndex: 4,
dashStyle: "Dash",
label: {
/*shape: "rect",*/
backgroundColor: "#003868",
enabled: true,
format: '{value:.3f}',
style:{"color": "#fff"},
}
},
},
{
top:-100,//this.options.chartHeight-43,
height: 90,
gridLineWidth: 0,
labels:{
enabled: false,
style:{"color": "#000"},
},
},
{
top:-100,height: this.options.subChartHeight,title: {text: null,},offset: 0,tickAmount : 5,opposite: false,showFirstLabel: false,showLastLabel: false,
labels:{formatter: this.subChartLabelFormatter,align:'right',x: -3,y: 4,style:{"color": "#000"}}, crosshair: {width: 0},
},{
top:-100,height: this.options.subChartHeight,title: {text: null,},offset: 0,tickAmount : 5,opposite: true,showFirstLabel: false,showLastLabel: false,
labels:{formatter: this.subChartLabelFormatter,align:'left',x: 3,y: 4,style:{"color": "#000"}}, crosshair: {width: 0},
},{
top:-100,height: this.options.subChartHeight,title: {text: null,},offset: 0,tickAmount : 5,opposite: true,showFirstLabel: false,showLastLabel: false,
labels:{formatter: this.subChartLabelFormatter,align:'left',x: 3,y: 4,style:{"color": "#000"}}, crosshair: {width: 0},
},{
top:-100,height: this.options.subChartHeight,title: {text: null,},offset: 0,tickAmount : 5,opposite: true,showFirstLabel: false,showLastLabel: false,
labels:{formatter: this.subChartLabelFormatter,align:'left',x: 3,y: 4,style:{"color": "#000"}}, crosshair: {width: 0},
},{
top:-100,height: this.options.subChartHeight,title: {text: null,},offset: 0,tickAmount : 5,opposite: true,showFirstLabel: false,showLastLabel: false,
labels:{formatter: this.subChartLabelFormatter,align:'left',x: 3,y: 4,style:{"color": "#000"}}, crosshair: {width: 0},
},{
top:-100,height: this.options.subChartHeight,title: {text: null,},offset: 0,tickAmount : 5,opposite: true,showFirstLabel: false,showLastLabel: false,
labels:{formatter: this.subChartLabelFormatter,align:'left',x: 3,y: 4,style:{"color": "#000"}}, crosshair: {width: 0},
}],
navigator : {
enabled : (this.isMobile || this.period != 0)?false:true,
height : 60,
baseSeries: 0,
outlineColor: '#00716C',
maskFill: 'rgba(36, 130, 125, 0.1)',
handles: {
backgroundColor: "#a8d0ce",
borderColor: "#00716C"
},
xAxis: {
gridLineWidth: 0,
labels:{
enabled: false
}
},
yAxis: {
gridLineWidth: 0,
labels:{
enabled: false
}
},
series: {
data: data.last,
type: 'area',
fillColor: 'rgba(237,237,237,1)',
lineColor: '#00000000'
}
},
scrollbar : {
enabled : false
},
series : [{
id : "vol",
type: 'column',
name: 'vol',
data: data.vol,
yAxis: 2,
color: "#cad3da",
dataGrouping: {
approximation: "sum",
units: self.options.groupingUnits,
groupPixelWidth: 1000
}
},{
name: 'primary',
type: 'candlestick',
id: 'primary',
data : data.uohlc,
yAxis: 0,
zIndex: 1,
dataGrouping: {
units: self.options.groupingUnits,
groupPixelWidth: 1000
}
},{
name: 'w_primary',
type: 'line',
id: 'w_primary',
data : data.last,
yAxis: 1,
zIndex: 1,
color: this.colors['wntLine'],
dataGrouping: {
units: self.options.groupingUnits,
//groupPixelWidth: 1000
}
}],
};
},
refreshSeries : function(){
var chart = this.cur_chart;
var _series = [];
for (var i=0;i0 && this.cur_chart!=this.chart){
for (var j=0;j0){
chart.tooltip.refresh(_series);
}
},
setPeriod : function(_from,_to){
if (this.data.last[0][0]){
this.chart.xAxis[0].setExtremes(Math.max(_from,this.data.last[0][0]), _to);
}
},
drawToolTip: function(obj){
//console.log("start drawToolTip");
//console.log(obj);
//var chart = this.chart;
var chart = this.cur_chart;
var fontstyle = {color: '#000', fontSize: '13px'};
var textattr = {zIndex: 7, class: "tooltipElement"};
var xoffset = 0;
//if ($(".tooltipElement.s"+obj.points[0].x).length>0){
if ($(".tooltipElement.s"+obj.points[0].x).length>0 && this.cur_chart == this.chart){
return;
}
if (this.cur_chart == this.chart){
$(".tooltipElement").remove();
}
if (this.toolTipMoved){
this.toolTipMoved(obj.points[0].x);
}
if (this.period!=0){
chart.renderer.text(Highcharts.dateFormat('%d/%m/%Y %H:%M',obj.points[0].x), 15, 18).css(fontstyle).attr(textattr).add();
xoffset = 50;
}else{
chart.renderer.text(Highcharts.dateFormat('%d/%m/%Y',obj.points[0].x), 15, 18).css(fontstyle).attr(textattr).add();
}
try {
var _points = [];
for(var j = 0; j b.series.name ? 1 : -1;
});
for(var j = 0; j<_points.length;j++){
/*if (this.points[j].series.name.startsWith(self.usedMASlot[i])){
_index = j;
break;
}*/
this.selected_ts = _points[0].x;
if (_points[j].series.name == "primary"){
}else if (_points[j].series.name == "vol"){
}else if (_points[j].series.name.indexOf("_sma")>0 || _points[j].series.name.indexOf("_ema")>0 ){
for(var i =0; i0){
chart.renderer.text("SMA("+days+"):"+formatPrice(_points[j].y), 145*_index+45+chart.margin[3]+xoffset, 18).css(fontstyle).attr(textattr).add();
}else{
chart.renderer.text("EMA("+days+"):"+formatPrice(_points[j].y), 145*_index+45+chart.margin[3]+xoffset, 18).css(fontstyle).attr(textattr).add();
}
}else if (_points[j].series.name.indexOf("_compare")>0){
}else if (_points[j].series.name.indexOf("_bol")>0 && _points[j].point.high){
var _label1 = this.labels()[lang].toolTip.MASlot[5][0]+": "; //"("+_points[j].series.userOptions.p1+","+_points[j].series.userOptions.p2+"): ";
var _label2 = this.labels()[lang].toolTip.MASlot[5][1]+": ";
var _label3 = this.labels()[lang].toolTip.MASlot[5][2]+": ";
_label1 += (_points[j-1].y).toFixed(2);
_label2 += (_points[j].point.high).toFixed(2);
_label3 += (_points[j].point.low).toFixed(2);
chart.renderer.text(_label1, 25+chart.margin[3]+xoffset, 18).css(fontstyle).attr(textattr).add();
chart.renderer.text(_label2, 185+chart.margin[3]+xoffset, 18).css(fontstyle).attr(textattr).add();
chart.renderer.text(_label3, 345+chart.margin[3]+xoffset, 18).css(fontstyle).attr(textattr).add();
}else if (_points[j].series.name.indexOf("_sar")>0){
}else{
var segment = _points[j].series.name.split("_");
var days = "";
if (segment.length==2){
textattr.class = "tooltipElement text_subchart";
var index = segment[0].replace("s","")*1;
var _top = (this.options.chartHeight+this.options.chartTitle)+((this.options.subChartHeight+this.options.subChartTitle)*index)+this.options.dateBarHeight;
for(var i =0; i=0;i--){
if (chart.series[i].name && (chart.series[i].name == this.usedMASlot[_id[j]] || chart.series[i].name.startsWith(this.usedMASlot[_id[j]]+"_"))){
chart.series[i].remove();
}
}
}
this.setUsedMASlot(_id[j], "");
}
},
addMAline: function(type, id){
var chart = this.chart;
var self = this;
//return;
if (type!=""){
var tempArr = type.split("-");
var _type = tempArr[0];
var _para = "?type="+_type;
for (var i=1; i0){
self.setUsedMASlot(_index, series[i].name);
}
}else{
series[i].name = "t"+id+"_"+type;
self.setUsedMASlot(id, "t"+id+"_"+type);
for (var j=1; j=0;i--){
if (chart.series[i].name && (chart.series[i].name == this.usedSlot[id] || chart.series[i].name.startsWith(this.usedSlot[id]+"_"))){
chart.series[i].remove();
chart.yAxis[yAxisID].userOptions.top = -100;
chart.yAxis[yAxisID].userOptions.min = null;
chart.yAxis[yAxisID].userOptions.max = null;
chart.yAxis[yAxisID].userOptions.togetherWith = null;
}
}
}
this.setUsedSlot(id, "");
},
addSeries: function(type, id){
var chart = this.chart;
var yAxisID = id + 4;
var self = this;
$(".tooltipElement").remove();
if (id>=0 && type!="" && !(type == "vol" || type == "turnover" || type == "os" || type == "turnovers")){
var tempArr = type.split("-");
var _type = tempArr[0];
var _para = "?type="+_type;
for (var i=1; i0){
return;
}
var chartWidth = $('#productChartContainer').width();
var sbox = ' ';
var cbox = ' ';
container.append(sbox+cbox);*/
},
updateSeriesPosition: function(){
var chart = this.chart;
var j=0;
for (var i=0;i=0 && id=0 && id0 || self.usedMASlot[0].indexOf("_ema")>0 ){
// command = (self.usedMASlot[0].split("_"))[1];
// for(var i=1;i0){
var _value = (self.usedMASlot[i].split("-"));
for(var j=1; j<_value.length;j++){
command += "-"+_value[j];
}
}else{
if(self.usedMASlot[i]!=""){
command += "-"+(self.usedMASlot[i].split("-"))[1];
// self.addMAline(command, i);
}
}
}
if (command){
self.addMAline(command, -1);
}
/*for(var i=0;i0){
$("#confirm_btn").trigger("click");
}else if (typeof updateChartLayout == "function"){
updateChartLayout();
}
},
getChartHeight : function(){
var height = this.options.chartHeight+this.options.chartTitle+this.options.dateBarHeight;
if (!(this.isMobile || this.period != 0)){
height += 90;
}
for(var i = 0; i < this.usedSlot.length; i++) {
if (this.usedSlot[i] != ""){
height += this.options.subChartHeight+this.options.subChartTitle;
}
}
/*this.chart.xAxis[0].userOptions.top = height-70;
this.chart.xAxis[0].update();*/
//return height-((this.isIntraday)?70:0);
return height+this.options.footerPadding;
},
labels : function (){
var _out = {
tc :{
ucurrency: uunit,
currency: "港元",
unit:{
K:"千",
M:"百萬",
B:"十億",
},
subTitle : {
macd : "相關資產平滑異同移動平均線",
rsi : "相關資產相對強弱指數",
turnover : "輪證成交額",
turnovers: "",
os : "輪證街貨量",
},
toolTip : {
open:"O:",
high:"H:",
low:"L:",
last : "輪證價格",
/*last:"C:",*/
volume:"成交量:",
uhigh: this.ucode + " 最高價",
ulow: this.ucode + " 最低價",
uopen: this.ucode + " 開市價",
ulast: "相關資產價格",
wlast: this.stockcode + " 價格",
MASlot: ["10天移動平均線","20天移動平均線","50天移動平均線","100天移動平均線","250天移動平均線",["保力加平均線","保力加下限線","保力加上限線"],adddigit(this.comparecode) + " 價格"],
TASlot: {
os : "",
turnover:"",
turnovers:["輪證成交額","相關資產成交額"],
rsi:"",
macd:["MACD","MACD-訊號","MACD-差異"],
},
},
calllv : "收回價",
maturity : "到期日",
strike : "行使價",
gearing : "有效槓桿",
egearing : "有效槓桿",
x: "倍",
call : "認購",
put : "認沽",
bull : "牛證",
bear : "熊證",
stime: "最後更新時間: "
},
sc :{
ucurrency: uunit,
currency: "港元",
unit:{
K:"千",
M:"百万",
B:"十亿",
},
subTitle : {
macd : "相关资产平滑异同移动平均线",
rsi : "相关资产相对强弱指数",
turnover : "轮证成交额",
turnovers: "",
os : "轮证街货量",
},
toolTip : {
open:"O:",
high:"H:",
low:"L:",
last : "轮证价格",
/*last:"C:",*/
volume:"成交量:",
uhigh: this.ucode + " 最高价",
ulow: this.ucode + " 最低价",
uopen: this.ucode + " 开市价",
ulast: "相关资产价格",
wlast: this.stockcode + " 价格",
MASlot: ["10天移动平均线","20天移动平均线","50天移动平均线","100天移动平均线","250天移动平均线",["保力加平均线","保力加下限线","保力加上限线"],adddigit(this.comparecode) + " 价格"],
TASlot: {
os : "",
turnover:"",
turnovers:["轮证成交额","相关资产成交额"],
rsi:"",
macd:["MACD","MACD-讯号","MACD-差异"],
},
},
calllv : "收回价",
maturity : "到期日",
strike : "行使价",
gearing : "有效杠杆",
egearing : "有效杠杆",
x: "倍",
call : "认购",
put : "认沽",
bull : "牛证",
bear : "熊证",
stime: "最後更新时间: "
},
en :{
ucurrency: uunit,
currency: "HKD",
unit:{
K:"K",
M:"M",
B:"B",
},
subTitle : {
macd : "MACD",
rsi : "RSI",
turnover : "Product turnover",
turnovers: "",
os : "Outstanding",
},
toolTip : {
open:"O:",
high:"H:",
low:"L:",
last : "Product last",
/*last:"C:",*/
volume:"Volume:",
uhigh: this.ucode + " high",
ulow: this.ucode + " low",
uopen: this.ucode + " open",
ulast: "Underlying last",
wlast: this.stockcode + " last",
MASlot: ["SMA-10","SMA-20","SMA-50","SMA-100","SMA-250",["Moving average","Bollinger lower bound","Bollinger upper bound"],adddigit(this.comparecode) + " last"],
TASlot: {
os : "",
turnover:"",
turnovers:["Product turnover","Underlying turnover"],
rsi:"RSI",
macd:["MACD","MACD-signal","MACD-diff"],
},
},
calllv : "Call level",
maturity : "Maturity",
strike : "Strike",
gearing : "Gearing",
egearing : "Eff.Gearing",
x: "X",
call : "Call",
put : "Put",
bull : "Bull",
bear : "Bear",
stime: "Last update: "
},
};
if (typeof ucurrency == "string"){
_out[lang].ucurrency = ucurrency;
}
return _out;
},
}