@millistream/millistream-widgets 1.0.38 → 1.0.40

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/millistream-widgets.js +203 -811
  2. package/package.json +2 -2
@@ -210,7 +210,6 @@ function Milli_Chart(settings) {
210
210
 
211
211
  function getScaledSetting(setting) {
212
212
  return parseInt(setting);
213
- // return parseInt(setting) * window.devicePixelRatio;
214
213
  }
215
214
  _this.get_lang_text = function(string) {
216
215
  return string;
@@ -250,7 +249,6 @@ function Milli_Chart(settings) {
250
249
  }
251
250
 
252
251
  function getFontSize(obj) {
253
- //return parseInt(obj.fontSize) * 1;
254
252
  return parseInt(obj.fontSize);
255
253
  }
256
254
 
@@ -348,37 +346,32 @@ function Milli_Chart(settings) {
348
346
  }
349
347
 
350
348
  function getTickNextTickValue(value) {
351
- return (value < 0.000001 ? 0.0000005 :
352
- (value < 0.0000015 ? 0.000001 :
353
- (value < 0.0000025 ? 0.000002 :
354
- (value < 0.000005 ? 0.0000025 :
355
- (value < 0.0000075 ? 0.000005 :
356
- (value < 0.00001 ? 0.000005 :
357
- (value < 0.000015 ? 0.00001 :
358
- (value < 0.000025 ? 0.00002 :
359
- (value < 0.00005 ? 0.000025 :
360
- (value < 0.000075 ? 0.00005 :
361
- (value < 0.0001 ? 0.00005 :
362
- (value < 0.00015 ? 0.0001 :
363
- (value < 0.00025 ? 0.0002 :
364
- (value < 0.0005 ? 0.00025 :
365
- (value < 0.00075 ? 0.0005 :
366
- (value < 0.001 ? 0.0005 :
367
- (value < 0.0015 ? 0.001 :
368
- (value < 0.0025 ? 0.002 :
369
- (value < 0.005 ? 0.0025 :
370
- (value < 0.0075 ? 0.005 :
371
- (value < 0.01 ? 0.005 :
372
- (value < 0.015 ? 0.01 :
373
- (value < 0.025 ? 0.02 :
374
- (value < 0.05 ? 0.025 :
375
- (value < 0.075 ? 0.05 :
376
- (value < 0.1 ? 0.05 :
377
- (value < 0.15 ? 0.1 :
378
- (value < 0.25 ? 0.20 :
379
- (value < 0.5 ? 0.25 :
380
- (value < 0.75 ? 0.5 :
381
- 1))))))))))))))))))))))))))))));
349
+ if (value < 0.000001) return 0.0000005;
350
+ if (value < 0.0000015) return 0.000001;
351
+ if (value < 0.0000025) return 0.000002;
352
+ if (value < 0.000005) return 0.0000025;
353
+ if (value < 0.00001) return 0.000005;
354
+ if (value < 0.000015) return 0.00001;
355
+ if (value < 0.000025) return 0.00002;
356
+ if (value < 0.00005) return 0.000025;
357
+ if (value < 0.0001) return 0.00005;
358
+ if (value < 0.00015) return 0.0001;
359
+ if (value < 0.00025) return 0.0002;
360
+ if (value < 0.0005) return 0.00025;
361
+ if (value < 0.001) return 0.0005;
362
+ if (value < 0.0015) return 0.001;
363
+ if (value < 0.0025) return 0.002;
364
+ if (value < 0.005) return 0.0025;
365
+ if (value < 0.01) return 0.005;
366
+ if (value < 0.015) return 0.01;
367
+ if (value < 0.025) return 0.02;
368
+ if (value < 0.05) return 0.025;
369
+ if (value < 0.1) return 0.05;
370
+ if (value < 0.15) return 0.1;
371
+ if (value < 0.25) return 0.2;
372
+ if (value < 0.5) return 0.25;
373
+ if (value < 0.75) return 0.5;
374
+ return 1;
382
375
  }
383
376
 
384
377
  function getTickValue(minValue, maxValue, num_labels) {
@@ -411,6 +404,11 @@ function Milli_Chart(settings) {
411
404
  m_ctx.stroke();
412
405
  m_ctx.closePath();
413
406
  var x = cs.left - 3;
407
+ if (m_yLegendCss.float == 'right') {
408
+ x = cs.right;
409
+ }
410
+
411
+
414
412
  var lineLength = cs.bottom - cs.top;
415
413
  var numticks = lineLength / (getFontSize(m_yLegendCss) * 2);
416
414
  if (numticks < 1) {
@@ -478,7 +476,16 @@ function Milli_Chart(settings) {
478
476
  if (m_yLegendCss.verticalAlign == 'top') {
479
477
  if (y - (getFontSize(m_yLegendCss)) > 0) // dont draw if cropped
480
478
  m_ctx.fillText(label, textpos, y - ((getFontSize(m_yLegendCss) + 2)));
481
- } else
479
+ } else if(m_yLegendCss.float == 'right') {
480
+ if (m_yLegendCss.textAlign == 'right') {
481
+ m_ctx.textAlign = 'left';
482
+ textpos = x + 5;
483
+ } else {
484
+ m_ctx.textAlign = 'right';
485
+ textpos = x - 5;
486
+ }
487
+ m_ctx.fillText(label, textpos, y - (getFontSize(m_yLegendCss) / 2));
488
+ } else
482
489
  m_ctx.fillText(label, textpos, y - (getFontSize(m_yLegendCss) / 2));
483
490
  }
484
491
  }
@@ -494,335 +501,7 @@ function Milli_Chart(settings) {
494
501
  return true;
495
502
  }
496
503
 
497
- /*function calcHighLow(scaleinfoY, scaleinfoY2) {
498
- scaleinfoY.lowValue = null;
499
- scaleinfoY.highValue = null;
500
- scaleinfoY2.lowValue = null;
501
- scaleinfoY2.highValue = null;
502
-
503
- _this.scaleinfoY.lowValue = null;
504
- _this.scaleinfoY.highValue = null;
505
- _this.scaleinfoY2.lowValue = null;
506
- _this.scaleinfoY2.highValue = null;
507
- _this.scaleinfoY.lowLowerChart = null;
508
- _this.scaleinfoY.highLowerChart = null;
509
-
510
- var data, i;
511
- var useCloseprice = false;
512
- var today = new Date().getTime();
513
- today -= today % 86400000;
514
- var lastTradeDate = new Date().getTime();
515
- var todaysOpenTime = new Date(new Date().toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z').getTime();
516
-
517
- if (typeof _this.instruments[0].trades !== 'undefined' && _this.instruments[0].trades.length > 0) {
518
- lastTradeDate = new Date(_this.instruments[0].trades[_this.instruments[0].trades.length - 1].timestamp).getTime();
519
- lastTradeDate -= lastTradeDate % 86400000;
520
- }
521
-
522
- var quote_timestamp = _this.instruments[0].quotedate + _this.instruments[0].quotetime;
523
- if ((_this.instruments[0].quotedate == today && quote_timestamp > todaysOpenTime) || _this.instruments[0].quotedate == lastTradeDate) useCloseprice = true;
524
-
525
- for (var s = 0; s < _this.instruments.length; s++) {
526
- if (_this.instruments[s].insref == 0) continue;
527
- _this.instruments[s].startValue = null;
528
- data = _this.instruments[s][chartType];
529
- if (chartType != 'history' && useCloseprice) {
530
- if ((_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && !m_zoom.mousedown.timestamp) {
531
- _this.instruments[s].startValue = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
532
- }
533
- }
534
- //var quantity = 0;
535
- let prevPrice = null;
536
- for (i = 0; i < data.length; i++) {
537
- // only calc on visible data
538
- var price = data[i].price * _this.instruments[s].factor;
539
- let highprice = data[i].highprice * _this.instruments[s].factor;
540
- let lowprice = data[i].lowprice * _this.instruments[s].factor;
541
-
542
- //quantity = 0;
543
- if (data[i].timestamp < _this.scaleinfoX.startTimeStamp) {
544
- if (chartType == 'history') {
545
- //_this.instruments[s].startValue = price; // skall inte sättas eftersom vi inte ritar den i history
546
- scaleinfoY2.lowValue = 0;
547
- scaleinfoY2.highValue = 0;
548
- }
549
- //else if (_this.settings.chartlen != '1d' && _this.settings.chartlen != '0d' && !m_zoom.mousedown.timestamp) {
550
- else if (useCloseprice == false || m_zoom.mousedown.timestamp) {
551
- _this.instruments[s].startValue = price;
552
- }
553
- continue;
554
- }
555
- if (data[i].timestamp > _this.scaleinfoX.endTimeStamp) {
556
- break;
557
- }
558
- _this.instruments[s].endValue = price;
559
-
560
- if (chartType != 'history' && (data[i].timestamp % 86400000 < _this.instruments[0].opentimestamp || data[i].timestamp % 86400000 > _this.instruments[0].closetimestamp)) {
561
- // stämmer detta kan det bli överlapp vid sommartid/vintertid?
562
- continue;
563
- }
564
-
565
- if (_this.instruments[s].startValue == null) { // no value before this date , use this date?
566
- if (chartType == 'history') {
567
- _this.instruments[s].startValue = price;
568
- } else {
569
- if (isToday(new Date(data[i].timestamp)) && !m_zoom.mousedown.timestamp) {
570
- _this.instruments[s].startValue = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
571
- } else {
572
- _this.instruments[s].startValue = price;
573
- }
574
- }
575
- }
576
- if(_this.settings.type == 'ohlc' || _this.settings.type == 'candlestick') {
577
- if (scaleinfoY.lowValue == null || scaleinfoY.lowValue > lowprice) scaleinfoY.lowValue = lowprice;
578
- if (scaleinfoY.highValue == null || scaleinfoY.highValue < highprice) scaleinfoY.highValue = highprice;
579
- }
580
- else {
581
- if (scaleinfoY.lowValue == null || scaleinfoY.lowValue > price) scaleinfoY.lowValue = price;
582
- if (scaleinfoY.highValue == null || scaleinfoY.highValue < price) scaleinfoY.highValue = price;
583
- }
584
- var diff = (price - _this.instruments[s].startValue);
585
- if (diff != 0) diff = diff / _this.instruments[s].startValue * 100;
586
- if (_this.instruments[s].startValue == null) diff = 0;
587
- data[i].diff = diff;
588
- if (scaleinfoY2.lowValue == null || scaleinfoY2.lowValue > diff) scaleinfoY2.lowValue = diff;
589
- if (scaleinfoY2.highValue == null || scaleinfoY2.highValue < diff) scaleinfoY2.highValue = diff;
590
- //if (scaleinfoY.lowLowerChart == null || scaleinfoY.lowLowerChart > quantity) scaleinfoY.lowLowerChart = quantity;
591
- //if (scaleinfoY.highLowerChart == null || scaleinfoY.highLowerChart < quantity) scaleinfoY.highLowerChart = quantity;
592
- }
593
- if ((_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && !m_zoom.mousedown.timestamp) { // if closeprice is used calch high/low on it
594
- var cp = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
595
- if (scaleinfoY.lowValue > cp) scaleinfoY.lowValue = cp;
596
- else
597
- if (scaleinfoY.highValue < cp) scaleinfoY.highValue = cp;
598
- }
599
- if (chartType != 'history') {
600
- if (scaleinfoY2.lowValue > 0) {
601
- scaleinfoY2.lowValue = 0;
602
- } else {
603
- if (scaleinfoY2.highValue < 0) scaleinfoY2.highValue = 0;
604
- }
605
- }
606
- if (_this.instruments[s].startValue) { // ta bort? fråga mats
607
- if (_this.instruments[s].startValue > scaleinfoY.highValue) scaleinfoY.highValue = _this.instruments[s].startValue;
608
- if (_this.instruments[s].startValue < scaleinfoY.lowValue) scaleinfoY.lowValue = _this.instruments[s].startValue;
609
- }
610
- }
611
- if (scaleinfoY.lowValue == null) {
612
- scaleinfoY.lowValue = 0;
613
- scaleinfoY.highValue = 100;
614
- scaleinfoY2.lowValue = 0;
615
- scaleinfoY2.highValue = 100;
616
- return;
617
- } else
618
- if (scaleinfoY.lowValue == scaleinfoY.highValue && scaleinfoY.lowValue == 0) {
619
- scaleinfoY.lowValue -= 1;
620
- scaleinfoY.highValue += 1;
621
- scaleinfoY.lowValue -= 1;
622
- scaleinfoY.highValue += 1;
623
- }
624
- // do we have any analyzis we need to take into account
625
- for (i = 0; i < _this.settings.indicators.length; i++) {
626
- if (_this.settings.indicators[i].method == 'rsi') continue;
627
- if (_this.settings.indicators[i].method == 'quantity') continue;
628
- if (_this.settings.indicators[i].method == 'news') continue;
629
- if (_this.settings.indicators[i].target == 'lower') continue;
630
- if (!_this.settings.indicators[i].timeseries || _this.settings.indicators[i].timeseries.length == 0) {
631
- continue;
632
- }
633
- data = _this.settings.indicators[i].timeseries;
634
- for (s = 0; s < data.length; s++) {
635
- if (data[s].timestamp < _this.scaleinfoX.startTimeStamp) {
636
- continue;
637
- }
638
- if (data[s].timestamp > _this.scaleinfoX.endTimeStamp) {
639
- break;
640
- }
641
- if (typeof data[s].datapoints !== 'undefined') {
642
- for (var x = 0; x < data[s].datapoints.length; x++) {
643
- if (data[s].datapoints[x] < scaleinfoY.lowValue) {
644
- scaleinfoY.lowValue = data[s].datapoints[x];
645
- scaleinfoY2.lowValue = data[s].datapoints[x] - _this.instruments[0].startValue; // lower min diff to get full legend from bottom
646
- } else {
647
- if (data[s].datapoints[x] > scaleinfoY.highValue) {
648
- scaleinfoY.highValue = data[s].datapoints[x];
649
- scaleinfoY2.highValue = data[s].datapoints[x] - _this.instruments[0].startValue; // lower min diff to get full legend from bottom
650
- }
651
- }
652
- }
653
- }
654
- }
655
- }
656
- scaleinfoY2.lowValue = (scaleinfoY.lowValue - _this.instruments[0].startValue) / _this.instruments[0].startValue * 100;
657
- scaleinfoY2.highValue = (scaleinfoY.highValue - _this.instruments[0].startValue) / _this.instruments[0].startValue * 100;
658
- return 1;
659
- }
660
- */
661
- /* function calcHighLow2(scale, cs, css, factorInfo) {
662
- scale.lowValue = null;
663
- scale.highValue = null;
664
-
665
- let data, i;
666
- let useCloseprice = false;
667
- let today = new Date().getTime();
668
- today -= today % 86400000;
669
- let lastTradeDate = new Date().getTime();
670
- let todaysOpenTime = new Date(new Date().toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z').getTime();
671
-
672
- if (typeof _this.instruments[0].trades !== 'undefined' && _this.instruments[0].trades.length > 0) {
673
- lastTradeDate = new Date(_this.instruments[0].trades[_this.instruments[0].trades.length - 1].timestamp).getTime();
674
- lastTradeDate -= lastTradeDate % 86400000;
675
- }
676
-
677
- var quote_timestamp = _this.instruments[0].quotedate + _this.instruments[0].quotetime;
678
- if ((_this.instruments[0].quotedate == today && quote_timestamp > todaysOpenTime) || _this.instruments[0].quotedate == lastTradeDate) useCloseprice = true;
679
-
680
- for (var s = 0; s < _this.instruments.length; s++) {
681
- if (_this.instruments[s].insref == 0) continue;
682
- _this.instruments[s].startValue = null;
683
- data = _this.instruments[s][chartType];
684
- if (chartType != 'history' && useCloseprice) {
685
- if ((_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && !m_zoom.mousedown.timestamp) {
686
- _this.instruments[s].startValue = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
687
- }
688
- }
689
- //var quantity = 0;
690
-
691
- for (i = 0; i < data.length; i++) {
692
- // only calc on visible data
693
- var price = data[i].price * _this.instruments[s].factor;
694
-
695
- if (data[i].timestamp < _this.scaleinfoX.startTimeStamp) {
696
- if (chartType == 'history') {
697
- _this.instruments[s].startValue = price;
698
- }
699
- //else if (_this.settings.chartlen != '1d' && _this.settings.chartlen != '0d' && !m_zoom.mousedown.timestamp) {
700
- else if (useCloseprice == false || m_zoom.mousedown.timestamp) {
701
- _this.instruments[s].startValue = price;
702
- }
703
- continue;
704
- }
705
- if (data[i].timestamp > _this.scaleinfoX.endTimeStamp) {
706
- break;
707
- }
708
-
709
- if (chartType != 'history' && (data[i].timestamp % 86400000 < _this.instruments[0].opentimestamp || data[i].timestamp % 86400000 > _this.instruments[0].closetimestamp)) { // summertime?
710
- continue;
711
- }
712
-
713
- if (_this.instruments[s].startValue == null) { // no value before this date , use this date?
714
- if (chartType == 'history') {
715
- _this.instruments[s].startValue = price;
716
- } else {
717
- if (isToday(new Date(data[i].timestamp)) && !m_zoom.mousedown.timestamp) {
718
- _this.instruments[s].startValue = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
719
- } else {
720
- _this.instruments[s].startValue = price;
721
- }
722
- }
723
- }
724
- if (typeof factorInfo === 'undefined') {
725
- if (scale.lowValue == null || scale.lowValue > price) scale.lowValue = price;
726
- if (scale.highValue == null || scale.highValue < price) scale.highValue = price;
727
- } else {
728
- let diff = (price - _this.instruments[s].startValue);
729
- if (diff != 0) diff = diff / _this.instruments[s].startValue * 100;
730
- if (_this.instruments[s].startValue == null) diff = 0;
731
- data[i][factorInfo.name] = diff;
732
- if (scale.lowValue == null || scale.lowValue > diff) scale.lowValue = diff;
733
- if (scale.highValue == null || scale.highValue < diff) scale.highValue = diff;
734
- }
735
- }
736
- // hur hantera om factorInfo
737
- if ((_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && !m_zoom.mousedown.timestamp) { // if closeprice is used calch high/low on it
738
- var cp = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
739
- if (scale.lowValue > cp) scale.lowValue = cp;
740
- else
741
- if (scale.highValue < cp) scale.highValue = cp;
742
- }
743
- if (chartType != 'history') {
744
- consolle
745
- if (scale.lowValue > 0) {
746
- scale.lowValue = 0;
747
- } else {
748
- if (scale.highValue < 0) scale.highValue = 0;
749
- }
750
- }
751
- if (typeof factorInfo === 'undefined') {
752
- if (_this.instruments[s].startValue) { // ta bort? fråga mats
753
- if (_this.instruments[s].startValue > scale.highValue) scale.highValue = _this.instruments[s].startValue;
754
- if (_this.instruments[s].startValue < scale.lowValue) scale.lowValue = _this.instruments[s].startValue;
755
- }
756
- }
757
- }
758
- if (scale.lowValue == null) {
759
- scale.lowValue = 0;
760
- scale.highValue = 100;
761
- } else
762
- if (scale.lowValue == scale.highValue && scale.lowValue == 0) {
763
- scale.lowValue -= 1;
764
- scale.highValue += 1;
765
- }
766
- // do we have any analyzis we need to take into account
767
- if (typeof factorInfo === 'undefined') {
768
- for (i = 0; i < _this.settings.indicators.length; i++) {
769
- if (_this.settings.indicators[i].method == 'rsi') continue;
770
- if (_this.settings.indicators[i].method == 'quantity') continue;
771
- if (!_this.settings.indicators[i].timeseries || _this.settings.indicators[i].timeseries.length == 0) continue;
772
- data = _this.settings.indicators[i].timeseries;
773
- for (s = 0; s < data.length; s++) {
774
- if (data[s].timestamp < _this.scaleinfoX.startTimeStamp) {
775
- continue;
776
- }
777
- if (data[s].timestamp > _this.scaleinfoX.endTimeStamp) {
778
- break;
779
- }
780
- if (typeof data[s].datapoints !== 'undefined') {
781
- for (var x = 0; x < data[i].datapoints.length; x++) {
782
- if (data[s].datapoints[x] < scale.lowValue) {
783
- scale.lowValue = data[s].datapoints[x];
784
- } else {
785
- if (data[s].datapoints[x] > scaleinfoY.highValue) {
786
- scale.highValue = data[s].datapoints[x];
787
- }
788
- }
789
- }
790
- }
791
- }
792
- }
793
- }
794
- m_ctx.font = css.fontWeight + ' ' + css.fontSize + ' ' + css.fontFamily; // set font so measure works
795
-
796
- let v = (scale.highValue - scale.lowValue) / scale.lineLength;
797
- scale.maxValue = scale.highValue + (v * parseInt(css.fontSize));
798
- scale.minValue = scale.lowValue - (v * parseInt(css.fontSize));
799
- scale.lineLength = cs.bottom - cs.top;
800
-
801
- let numticks = scale.lineLength / (getFontSize(css) * _this.settings.yAxisSpacing);
802
- if (numticks > 8) numticks = 8; // limit to 8 items on Y legend ( this is not an absolut count, since we calculate nice legend numbers
803
- scale.tickSize = getTickValue(scale.lowValue, scale.highValue, numticks);
804
- scale.decimals = scale.tickSize.countDecimals();
805
-
806
- if (typeof factorInfo === 'undefined') {
807
- if (scale.decimals > 4) scale.decimals = 4;
808
- else if (scale.decimals < 2) scale.decimals = 2;
809
- }
810
-
811
- let widestValue = (scale.lowValue < 0 ? '-' : '') + Math.max(Math.abs(scale.highValue), Math.abs(scale.lowValue));
812
- let label = formatNiceNumber(widestValue, _this.settings.thousandseparator, _this.settings.decimalseparator, scale.decimals);
813
- if (typeof factorInfo !== 'undefined' && typeof factorInfo.suffix !== 'undefined') label += factorInfo.suffix;
814
- if (css.float != 'right') {
815
- cs.left = 10 + Math.round(m_ctx.measureText(label).width); // + 'px'; // räkna fram hur hur mycket plats Y värdena tar och sätt margin till det, skall vi göra så?
816
- } else {
817
- if (css.textAlign == 'right') {
818
- cs.right = m_canvas.getWidth() - (10 + Math.round(m_ctx.measureText(label).width)); // + 'px'; // räkna fram hur hur mycket plats Y värdena tar och sätt margin till det, skall vi göra så?
819
- }
820
- }
821
- return true;
822
- }
823
- */
824
-
825
- function calcHighLow(scaleinfoY, scaleinfoY2) {
504
+ function calcHighLow(scaleinfoY, scaleinfoY2) {
826
505
  scaleinfoY.lowValue = null;
827
506
  scaleinfoY.highValue = null;
828
507
  scaleinfoY2.lowValue = null;
@@ -950,151 +629,13 @@ function Milli_Chart(settings) {
950
629
  // do we have any analyzis we need to take into account
951
630
  for (i = 0; i < _this.settings.indicators.length; i++) {
952
631
  if (_this.settings.indicators[i].method == 'rsi') continue;
953
- if (_this.settings.indicators[i].method == 'quantity') continue;
954
- if (_this.settings.indicators[i].method == 'news') continue;
955
- if (_this.settings.indicators[i].target == 'lower') continue;
956
- if (!_this.settings.indicators[i].timeseries || _this.settings.indicators[i].timeseries.length == 0) {
957
- continue;
958
- }
959
- data = _this.settings.indicators[i].timeseries;
960
- for (s = 0; s < data.length; s++) {
961
- if (data[s].timestamp < _this.scaleinfoX.startTimeStamp) {
962
- continue;
963
- }
964
- if (data[s].timestamp > _this.scaleinfoX.endTimeStamp) {
965
- break;
966
- }
967
- if (typeof data[s].datapoints !== 'undefined') {
968
- for (var x = 0; x < data[s].datapoints.length; x++) {
969
- if (data[s].datapoints[x] < scaleinfoY.lowValue) {
970
- scaleinfoY.lowValue = data[s].datapoints[x];
971
- scaleinfoY2.lowValue = data[s].datapoints[x] - _this.instruments[0].startValue; // lower min diff to get full legend from bottom
972
- } else {
973
- if (data[s].datapoints[x] > scaleinfoY.highValue) {
974
- scaleinfoY.highValue = data[s].datapoints[x];
975
- scaleinfoY2.highValue = data[s].datapoints[x] - _this.instruments[0].startValue; // lower min diff to get full legend from bottom
976
- }
977
- }
978
- }
979
- }
980
- }
981
- }
982
- scaleinfoY2.lowValue = (scaleinfoY.lowValue - _this.instruments[0].startValue) / _this.instruments[0].startValue * 100;
983
- scaleinfoY2.highValue = (scaleinfoY.highValue - _this.instruments[0].startValue) / _this.instruments[0].startValue * 100;
984
- return 1;
985
- }
986
- /*function calcHighLow() {
987
- scaleinfoY.lowValue = null;
988
- scaleinfoY.highValue = null;
989
- scaleinfoY2.lowValue = null;
990
- scaleinfoY2.highValue = null;
991
- scaleinfoY.lowLowerChart = null;
992
- scaleinfoY.highLowerChart = null;
993
- var data, i;
994
- var useCloseprice = false;
995
- var today = new Date().getTime();
996
- today -= today % 86400000;
997
- var lastTradeDate = new Date().getTime();
998
- var todaysOpenTime = new Date(new Date().toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z').getTime();
999
- if (typeof _this.instruments[0].trades !== 'undefined' && _this.instruments[0].trades.length > 0) {
1000
- lastTradeDate = new Date(_this.instruments[0].trades[_this.instruments[0].trades.length - 1].timestamp).getTime();
1001
- lastTradeDate -= lastTradeDate % 86400000;
1002
- }
1003
- var quote_timestamp = _this.instruments[0].quotedate + _this.instruments[0].quotetime;
1004
-
1005
- if ((_this.instruments[0].quotedate == today && quote_timestamp > todaysOpenTime) || _this.instruments[0].quotedate == lastTradeDate) useCloseprice = true;
1006
- for (var s = 0; s < _this.instruments.length; s++) {
1007
- if (_this.instruments[s].insref == 0) continue;
1008
- _this.instruments[s].startValue = null;
1009
- data = _this.instruments[s][chartType];
1010
- if (chartType != 'history' && useCloseprice) {
1011
- if ((_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && !m_zoom.mousedown.timestamp) {
1012
- _this.instruments[s].startValue = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
1013
- }
1014
- }
1015
- var quantity = 0;
1016
-
1017
- for (i = 0; i < data.length; i++) {
1018
- // only calc on visible data
1019
- var price = data[i].price * _this.instruments[s].factor;
1020
- quantity = 0;
1021
- if (data[i].quantity !== 'undefined') {
1022
- quantity = data[i].quantity;
1023
- }
1024
- if (data[i].timestamp < _this.scaleinfoX.startTimeStamp) {
1025
- if (chartType == 'history') _this.instruments[s].startValue = price;
1026
- //else if (_this.settings.chartlen != '1d' && _this.settings.chartlen != '0d' && !m_zoom.mousedown.timestamp) {
1027
- else if (useCloseprice == false || m_zoom.mousedown.timestamp) {
1028
- _this.instruments[s].startValue = price;
1029
- }
1030
- continue;
1031
- }
1032
- if (data[i].timestamp > _this.scaleinfoX.endTimeStamp) {
1033
- break;
1034
- }
1035
-
1036
- if (chartType != 'history' && (data[i].timestamp % 86400000 < _this.instruments[0].opentimestamp || data[i].timestamp % 86400000 > _this.instruments[0].closetimestamp)) {
1037
- // stämmer detta kan det bli överlapp vid sommartid/vintertid?
1038
- continue;
1039
- }
1040
-
1041
- if (_this.instruments[s].startValue == null) {
1042
- if (chartType == 'history') {
1043
- _this.instruments[s].startValue = price;
1044
- } else {
1045
- if (isToday(new Date(data[i].timestamp)) && !m_zoom.mousedown.timestamp) {
1046
- _this.instruments[s].startValue = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
1047
- } else {
1048
- _this.instruments[s].startValue = price;
1049
- }
1050
- }
1051
- }
1052
- if (scaleinfoY.lowValue == null || scaleinfoY.lowValue > price) scaleinfoY.lowValue = price;
1053
- if (scaleinfoY.highValue == null || scaleinfoY.highValue < price) scaleinfoY.highValue = price;
1054
- var diff = (price - _this.instruments[s].startValue);
1055
- if (diff != 0) diff = diff / _this.instruments[s].startValue * 100;
1056
- if (_this.instruments[s].startValue == null) diff = 0;
1057
- data[i].diff = diff;
1058
-
1059
- if (scaleinfoY2.lowValue == null || scaleinfoY2.lowValue > diff) scaleinfoY2.lowValue = diff;
1060
- if (scaleinfoY2.highValue == null || scaleinfoY2.highValue < diff) scaleinfoY2.highValue = diff;
1061
- if (scaleinfoY.lowLowerChart == null || scaleinfoY.lowLowerChart > quantity) scaleinfoY.lowLowerChart = quantity;
1062
- if (scaleinfoY.highLowerChart == null || scaleinfoY.highLowerChart < quantity) scaleinfoY.highLowerChart = quantity;
1063
- }
1064
- if ((_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && !m_zoom.mousedown.timestamp) { // if closeprice is used calch high/low on it
1065
- var cp = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
1066
- if (scaleinfoY.lowValue > cp) scaleinfoY.lowValue = cp;
1067
- else
1068
- if (scaleinfoY.highValue < cp) scaleinfoY.highValue = cp;
1069
- }
1070
- if (chartType != 'history') {
1071
- if (scaleinfoY2.lowValue > 0) {
1072
- scaleinfoY2.lowValue = 0;
1073
- } else {
1074
- if (scaleinfoY2.highValue < 0) scaleinfoY2.highValue = 0;
1075
- }
1076
- }
1077
- if (_this.instruments[s].startValue) {
1078
- if (_this.instruments[s].startValue > scaleinfoY.highValue) scaleinfoY.highValue = _this.instruments[s].startValue;
1079
- if (_this.instruments[s].startValue < scaleinfoY.lowValue) scaleinfoY.lowValue = _this.instruments[s].startValue;
1080
- }
1081
- }
1082
-
1083
- if (scaleinfoY.lowValue == null) {
1084
- scaleinfoY.lowValue = 0;
1085
- scaleinfoY.highValue = 100;
1086
- scaleinfoY2.lowValue = 0;
1087
- scaleinfoY2.highValue = 100;
1088
- } else
1089
- if (scaleinfoY.lowValue == scaleinfoY.highValue && scaleinfoY.lowValue == 0) {
1090
- scaleinfoY.lowValue -= 1;
1091
- scaleinfoY.highValue += 1;
1092
- }
1093
- console.log(_this.settings.indicators);
1094
- // do we have any analyzis we need to take into account
1095
- for (i = 0; i < _this.settings.indicators.length; i++) {
1096
- if (chartType == 'history') data = _this.settings.indicators[i].history;
1097
- else data = _this.settings.indicators[i].trades;
632
+ if (_this.settings.indicators[i].method == 'quantity') continue;
633
+ if (_this.settings.indicators[i].method == 'news') continue;
634
+ if (_this.settings.indicators[i].target == 'lower') continue;
635
+ if (!_this.settings.indicators[i].timeseries || _this.settings.indicators[i].timeseries.length == 0) {
636
+ continue;
637
+ }
638
+ data = _this.settings.indicators[i].timeseries;
1098
639
  for (s = 0; s < data.length; s++) {
1099
640
  if (data[s].timestamp < _this.scaleinfoX.startTimeStamp) {
1100
641
  continue;
@@ -1103,10 +644,16 @@ function Milli_Chart(settings) {
1103
644
  break;
1104
645
  }
1105
646
  if (typeof data[s].datapoints !== 'undefined') {
1106
- for (var x = 0; x < data[i].datapoints.length; x++) {
1107
- if (data[s].datapoints[x] < scaleinfoY.lowValue) scaleinfoY.lowValue = data[s].datapoints[x];
1108
- else
1109
- if (data[s].datapoints[x] > scaleinfoY.highValue) scaleinfoY.highValue = data[s].datapoints[x];
647
+ for (var x = 0; x < data[s].datapoints.length; x++) {
648
+ if (data[s].datapoints[x] < scaleinfoY.lowValue) {
649
+ scaleinfoY.lowValue = data[s].datapoints[x];
650
+ scaleinfoY2.lowValue = data[s].datapoints[x] - _this.instruments[0].startValue; // lower min diff to get full legend from bottom
651
+ } else {
652
+ if (data[s].datapoints[x] > scaleinfoY.highValue) {
653
+ scaleinfoY.highValue = data[s].datapoints[x];
654
+ scaleinfoY2.highValue = data[s].datapoints[x] - _this.instruments[0].startValue; // lower min diff to get full legend from bottom
655
+ }
656
+ }
1110
657
  }
1111
658
  }
1112
659
  }
@@ -1114,7 +661,7 @@ function Milli_Chart(settings) {
1114
661
  scaleinfoY2.lowValue = (scaleinfoY.lowValue - _this.instruments[0].startValue) / _this.instruments[0].startValue * 100;
1115
662
  scaleinfoY2.highValue = (scaleinfoY.highValue - _this.instruments[0].startValue) / _this.instruments[0].startValue * 100;
1116
663
  return 1;
1117
- }*/
664
+ }
1118
665
 
1119
666
  function drawY2Legend(scaleinfoY, scaleinfoY2, x) { // percent
1120
667
  if (_this.instruments[0].pricetype == 'yield') return;
@@ -1145,7 +692,6 @@ function Milli_Chart(settings) {
1145
692
  var count = 0;
1146
693
  for (;;) {
1147
694
  if (count++ > 10) {
1148
- console.log('break out');
1149
695
  break;
1150
696
  }
1151
697
  var v;
@@ -1206,7 +752,7 @@ function Milli_Chart(settings) {
1206
752
  si.valuePerPixel = (si.maxValue - si.minValue) / si.lineLength;
1207
753
 
1208
754
  if (isNaN(si.valuePerPixel) || !isFinite(si.valuePerPixel)) {
1209
- console.log('cant draw valuePerPixel', si.valuePerPixel, si.lineLength, si.maxValue, si.minValue);
755
+ console.log('cant draw valuePerPixel', si.valuePerPixel, si.lineLength, si.maxValue, si.minValue,si.highValue,si.lowValue,m_yLegendCss,v);
1210
756
  return false;
1211
757
  }
1212
758
  var textpos;
@@ -1367,75 +913,6 @@ function Milli_Chart(settings) {
1367
913
  return true;
1368
914
  }
1369
915
 
1370
- function drawYAxisNew(scale, cs, css, drawAxis, gridLines, factor) {
1371
- /*let scale = {};
1372
- if (false == calcHighLow2(scale, factor)) {
1373
- console.log('fail highlow');
1374
- return;
1375
- }*/
1376
- m_ctx.save();
1377
- m_ctx.strokeStyle = m_gridHorizontalCss.color;
1378
- m_ctx.font = css.fontWeight + ' ' + css.fontSize + ' ' + css.fontFamily;
1379
- m_ctx.fillStyle = css.color;
1380
- scale.lineLength = cs.bottom - cs.top;
1381
- /* let numticks = scale.lineLength / (getFontSize(css) * _this.settings.yAxisSpacing);
1382
- if (numticks > 8) numticks = 8; // limit to 8 items on Y legend ( this is not an absolut count, since we calculate nice legend numbers
1383
- scale.tickSize = getTickValue(scale.lowValue, scale.highValue, numticks);
1384
- scale.decimals = scale.tickSize.countDecimals();*/
1385
- //scale.decimals > 4 ? 4 : (scale.decimals < 2 ? 2 : scale.decimals);
1386
-
1387
-
1388
-
1389
-
1390
- /* let widestValue = (scale.lowValue < 0 ? '-' : '') + Math.max(Math.abs(scale.highValue), Math.abs(scale.lowValue));
1391
- let label = formatNiceNumber(widestValue, _this.settings.thousandseparator, _this.settings.decimalseparator, scale.decimals);
1392
- console.log('testw', label, )
1393
- if (drawAxis) {
1394
- if (css.float != 'right') {
1395
- cs.left = 10 + Math.round(m_ctx.measureText(label).width); // + 'px'; // räkna fram hur hur mycket plats Y värdena tar och sätt margin till det, skall vi göra så?
1396
- } else {
1397
- if (css.textAlign == 'right') {
1398
- cs.right = m_canvas.getWidth() - (10 + Math.round(m_ctx.measureText(label).width)); // + 'px'; // räkna fram hur hur mycket plats Y värdena tar och sätt margin till det, skall vi göra så?
1399
- }
1400
- }
1401
- }
1402
- */
1403
-
1404
-
1405
-
1406
-
1407
- if (css.float != 'right' && drawAxis) { // do we need to add space for half a date? ie prices are to tiny so date will be trunkated
1408
- m_ctx.save();
1409
- m_ctx.font = m_xLegendCss.fontWeight + ' ' + m_xLegendCss.fontSize + ' ' + m_xLegendCss.fontFamily;
1410
- if (getStringWidth(m_ctx, _this.settings.dateformat) / 2 + 5 > cs.left) {
1411
- cs.left = getStringWidth(m_ctx, _this.settings.dateformat) / 2 + 5;
1412
- }
1413
- m_ctx.restore();
1414
- }
1415
- // draw line
1416
- m_ctx.strokeStyle = m_gridVerticalCss.color;
1417
- m_ctx.beginPath();
1418
- m_ctx.moveTo(cs.left + 0.5, cs.top);
1419
- m_ctx.lineTo(cs.left + 0.5, cs.height - cs.marginBottom);
1420
- m_ctx.stroke();
1421
- m_ctx.closePath();
1422
- m_ctx.strokeStyle = m_gridHorizontalCss.color;
1423
- var x;
1424
- if (css.float == 'right')
1425
- x = cs.right;
1426
- else
1427
- x = cs.left;
1428
- if (css.textAlign == 'right') {
1429
- m_ctx.textAlign = 'left';
1430
- drawYLegendNew(scale, cs, x, css, drawAxis, gridLines, factor);
1431
- } else {
1432
- m_ctx.textAlign = 'right';
1433
- drawYLegendNew(scale, cs, x, css, drawAxis, gridLines), factor;
1434
- }
1435
- m_ctx.restore();
1436
- return scale;
1437
- }
1438
-
1439
916
  function drawYAxis(scaleinfoY, scaleinfoY2) {
1440
917
  m_ctx.save();
1441
918
  m_ctx.strokeStyle = m_gridHorizontalCss.color;
@@ -2412,6 +1889,11 @@ function Milli_Chart(settings) {
2412
1889
  _this.settings.indicators[x].toolTip.div.style.left = _this.settings.indicators[x].timeseries[xx].pos.x / 1 + (pointerWidth / 2) + 'px'; // this i modified in the data for the instruments, but not for indicators
2413
1890
  _this.settings.indicators[x].toolTip.div.style.top = _this.settings.indicators[x].timeseries[xx].pos.y / 1 + 'px'; // this i modified in the data for the instruments, but not for indicators
2414
1891
  _this.settings.indicators[x].toolTip.div.innerHTML = _this.settings.indicators[x].toolTip.formatter.call(_this.settings.indicators[x].timeseries[xx]);
1892
+
1893
+ if (y >= _this.settings.indicators[x].timeseries[xx].pos.y && y <= _this.settings.indicators[x].timeseries[xx].pos.y + width)
1894
+ m_canvas.style.cursor = "pointer";
1895
+ else
1896
+ m_canvas.style.cursor = "crosshair";
2415
1897
  remove = false;
2416
1898
  toolArray.push({ top: parseInt(_this.settings.indicators[x].toolTip.div.style.top), indicator: x });
2417
1899
  }
@@ -2421,6 +1903,7 @@ function Milli_Chart(settings) {
2421
1903
  if (_this.settings.indicators[x].toolTip.div && _this.settings.indicators[x].staticTooltip != true) {
2422
1904
  _this.settings.indicators[x].toolTip.div.parentNode.removeChild(_this.settings.indicators[x].toolTip.div);
2423
1905
  _this.settings.indicators[x].toolTip.div = undefined;
1906
+ m_canvas.style.cursor = "crosshair";
2424
1907
  }
2425
1908
 
2426
1909
  }
@@ -2582,7 +2065,7 @@ function Milli_Chart(settings) {
2582
2065
  _this.settings.indicators[i].timeseries = calculateBollingerBands(_this.instruments[0].trades, _this.settings.indicators[i].method_length, _this.settings.indicators[i].stddev | 2);
2583
2066
  break;
2584
2067
  case 'news':
2585
- _this.settings.indicators[i].timeseries = calculateNews(_this.settings.indicators[i].news, _this.settings.indicators[i].method_length, _this.settings.indicators[i].stddev | 2);
2068
+ _this.settings.indicators[i].timeseries = calculateNews(_this.settings.indicators[i].news);
2586
2069
  break;
2587
2070
  // future events osv?
2588
2071
  default:
@@ -2780,29 +2263,6 @@ function Milli_Chart(settings) {
2780
2263
  if (false == checkChartData(_this.instruments[0].history)) return;
2781
2264
  calculateIndicators();
2782
2265
 
2783
- /*let scaleY = {};
2784
- if (_this.settings.drawyaxis) {
2785
- if (false == calcHighLow2(scaleY, m_chartspaces.chart, m_yLegendCss)) {
2786
- console.log('fail highlow');
2787
- return;
2788
- }
2789
- }
2790
- let scaleY2 = {};
2791
- let factorInfo = {
2792
- name: 'diff',
2793
- actor: _this.instruments[0].startValue,
2794
- suffix: '%'
2795
- };
2796
- if (_this.settings.drawy2axis) {
2797
- if (false == calcHighLow2(scaleY2, m_chartspaces.chart, m_y2LegendCss, factorInfo)) {
2798
- console.log('fail highlow');
2799
- return;
2800
- }
2801
- }
2802
-
2803
- drawYAxisNew(scaleY, m_chartspaces.chart, m_yLegendCss, _this.settings.drawyaxis, _this.settings.gridHorizontalLines);
2804
- drawYAxisNew(scaleY2, m_chartspaces.chart, m_y2LegendCss, _this.settings.drawy2axis, false, factorInfo); *
2805
- */
2806
2266
  drawYAxis(scaleinfoY, scaleinfoY2);
2807
2267
  drawXAxisMonth(_this.scaleinfoX.startTimeStamp, _this.scaleinfoX.endTimeStamp);
2808
2268
 
@@ -2944,6 +2404,7 @@ function Milli_Chart(settings) {
2944
2404
  case 'rsi':
2945
2405
  if (chartType == 'history') _this.settings.indicators[i].timeseries = calculateRSI(_this.instruments[0].history, _this.settings.indicators[i].method_length);
2946
2406
  else _this.settings.indicators[i].timeseries = calculateRSI(_this.instruments[0].trades, _this.settings.indicators[i].method_length);
2407
+ console.log(_this.settings.indicators[i].timeseries);
2947
2408
  if (_this.settings.indicators[i].target == 'upper') {
2948
2409
  lowerScale = drawYAxisIndicator(_this.settings.indicators[i].timeseries, m_chartspaces.chart, false);
2949
2410
  plotIndicatorLine(_this.settings.indicators[i], lowerScale, m_chartspaces.chart);
@@ -3177,27 +2638,31 @@ function Milli_Chart(settings) {
3177
2638
  var startpoint = { x: 0, y: 0 };
3178
2639
  var endpoint = { x: 0, y: 0 };
3179
2640
  var startDate = _this.scaleinfoX.startTimeStamp;
3180
- var len = data.length;
3181
2641
  var lastdate = new Date(_this.scaleinfoX.startTimeStamp);
3182
2642
  var offset = 0;
3183
2643
  var maxy = 0;
3184
2644
  var ret = [];
3185
2645
  let num = 0;
3186
- for (var i = 0; i < len; i++) {
2646
+ for (var i = 0; i < data.length; i++) {
3187
2647
  var currentDate;
3188
2648
  var tmpx = startpoint.x;
3189
2649
  var tmp;
3190
- var timestamp = data[i].timestamp;
2650
+ var timestamp = typeof data[i].newstimestamp !== 'undefined' ? data[i].newstimestamp : data[i].timestamp;
3191
2651
  if (chartType == 'history') timestamp -= (timestamp % 86400000)
3192
2652
  if (timestamp < _this.scaleinfoX.startTimeStamp) {
3193
2653
  continue;
3194
2654
  }
3195
2655
  if (timestamp > _this.scaleinfoX.endTimeStamp) {
3196
- console.log('to big', data[i].timestamp, _this.scaleinfoX.endTimeStamp);
3197
- break;
2656
+ data.splice(i,1);
2657
+ i--;
2658
+ continue;
3198
2659
  }
3199
2660
 
3200
- if (chartType != 'history' && (data[i].timestamp % 86400000 < _this.instruments[0].opentimestamp || data[i].timestamp % 86400000 > _this.instruments[0].closetimestamp)) {
2661
+ //if (chartType != 'history' && (data[i].timestamp % 86400000 < _this.instruments[0].opentimestamp || data[i].timestamp % 86400000 > _this.instruments[0].closetimestamp)) {
2662
+ if (chartType != 'history' && (timestamp % 86400000 < _this.instruments[0].opentimestamp || timestamp % 86400000 > _this.instruments[0].closetimestamp)) {
2663
+ // data outside tradinghours, removed from data so we do not get data entries without pos
2664
+ data.splice(i,1);
2665
+ i--;
3201
2666
  continue;
3202
2667
  }
3203
2668
  var endtimeToday = new Date(timestamp);
@@ -3305,6 +2770,10 @@ function Milli_Chart(settings) {
3305
2770
  let data = method.timeseries;
3306
2771
  let num = calcAnalyzisLine(data, 0, undefined, cs, scale);
3307
2772
  if (num == 0) return;
2773
+ let start = data.length-1;
2774
+ while(start > 0 && typeof data[start].pos === 'undefined') start--;
2775
+ if(start < 0) return;
2776
+
3308
2777
  m_ctx.save();
3309
2778
  m_ctx.beginPath();
3310
2779
  m_ctx.closePath();
@@ -3312,10 +2781,13 @@ function Milli_Chart(settings) {
3312
2781
  m_ctx.strokeStyle = method.color;
3313
2782
  if (typeof method.lineStyle === 'string' && method.lineStyle == 'dash') m_ctx.setLineDash([3, 3]);
3314
2783
 
3315
- m_ctx.moveTo(data[data.length - 1].pos.x, data[data.length - 1].pos.y);
2784
+ m_ctx.moveTo(data[start].pos.x, data[start].pos.y);
3316
2785
  let lastPos = null;
3317
- for (var i = data.length - 2; i >= 0; i--) {
3318
- if (typeof data[i].pos === 'undefined') break;
2786
+ for (var i = start - 1; i >= 0; i--) {
2787
+ if (typeof data[i].pos === 'undefined') {
2788
+ console.log(i);
2789
+ break;
2790
+ }
3319
2791
  m_ctx.lineTo(data[i].pos.x, data[i].pos.y);
3320
2792
  lastPos = data[i].pos;
3321
2793
  }
@@ -3325,7 +2797,7 @@ function Milli_Chart(settings) {
3325
2797
  }
3326
2798
  if (typeof method.callback === 'function') method.callback.call({ x: data[data.length - 1].pos.x, y: data[data.length - 1].pos.y });
3327
2799
  m_ctx.stroke();
3328
- m_ctx.lineTo(data[data.length - 1].pos.x, cs.bottom);
2800
+ m_ctx.lineTo(data[start].pos.x, cs.bottom);
3329
2801
  m_ctx.restore();
3330
2802
  }
3331
2803
 
@@ -3371,11 +2843,11 @@ function Milli_Chart(settings) {
3371
2843
  if (fabs(lastPos.x - data[i].pos.x) > width || fabs(lastPos.y > data[i].pos.y) > width) {
3372
2844
  m_ctx.fillText(method.indicator, data[i].pos.x - (width / 2), data[i].pos.y);
3373
2845
  lastPos = { x: data[i].pos.x, y: data[i].y };
3374
- method.timeseries[i].hl = [{ timestamp: data[i].timestamp, headline: data[i].headline }];
2846
+ method.timeseries[i].hl = [{ timestamp: data[i].timestamp, headline: data[i].headline,newsid: data[i].newsid }];
3375
2847
  hlPos = i;
3376
2848
 
3377
2849
  } else {
3378
- method.timeseries[hlPos].hl.push({ timestamp: data[i].timestamp, headline: data[i].headline });
2850
+ method.timeseries[hlPos].hl.push({ timestamp: data[i].timestamp, headline: data[i].headline,newsid: data[i].newsid });
3379
2851
  }
3380
2852
  } else m_ctx.fillText(method.indicator, data[i].pos.x - (width / 2), data[i].pos.y);
3381
2853
 
@@ -3389,29 +2861,56 @@ function Milli_Chart(settings) {
3389
2861
  m_ctx.strokeStyle = method.color;
3390
2862
  m_ctx.lineWidth = method.lineWidth | 1;
3391
2863
  m_ctx.save();
2864
+
2865
+ // draw upper
3392
2866
  m_ctx.beginPath();
2867
+ m_ctx.closePath();
3393
2868
  let num = calcAnalyzisLine(data, 0, undefined, m_chartspaces.chart, scaleinfoY);
2869
+ m_ctx.moveTo(data[data.length - 1].pos.x, data[data.length - 1].pos.y);
3394
2870
  for (let i = data.length - 1; i >= data.length - num; i--) {
3395
2871
  m_ctx.lineTo(data[i].pos.x, data[i].pos.y);
3396
2872
  }
3397
- num = calcAnalyzisLine(data, 1, undefined, m_chartspaces.chart, scaleinfoY);
3398
- m_ctx.lineTo(data[data.length - num].pos.x, data[data.length - num].pos.y);
3399
- for (let i = data.length - num; i < data.length; i++) {
3400
- m_ctx.lineTo(data[i].pos.x, data[i].pos.y);
3401
- }
3402
- m_ctx.closePath();
2873
+ m_ctx.stroke();
2874
+
2875
+ // draw the fill area
3403
2876
  if (method.fill) {
2877
+ m_ctx.beginPath();
2878
+ m_ctx.moveTo(data[data.length - 1].pos.x, data[data.length - 1].pos.y);
2879
+ for (let i = data.length - 1; i >= data.length - num; i--) {
2880
+ m_ctx.lineTo(data[i].pos.x, data[i].pos.y);
2881
+ }
2882
+
2883
+ num = calcAnalyzisLine(data, 1, undefined, m_chartspaces.chart, scaleinfoY);
2884
+
2885
+ m_ctx.lineTo(data[data.length - num].pos.x, data[data.length - num].pos.y); // behöver döljas...
2886
+ for (let i = data.length - num +1; i < data.length; i++) {
2887
+ m_ctx.lineTo(data[i].pos.x, data[i].pos.y);
2888
+ }
2889
+
2890
+ m_ctx.closePath();
2891
+
3404
2892
  m_ctx.fillStyle = method.fill;
3405
2893
  m_ctx.fill();
3406
2894
  }
3407
- num = calcAnalyzisLine(data, 2, undefined, m_chartspaces.chart, scaleinfoY);
2895
+ // draw Lower
2896
+ m_ctx.beginPath();
2897
+ m_ctx.closePath();
2898
+ m_ctx.moveTo(data[data.length - num].pos.x, data[data.length - num].pos.y); // behöver döljas...
2899
+ for (let i = data.length - num; i < data.length; i++) {
2900
+ m_ctx.lineTo(data[i].pos.x, data[i].pos.y);
2901
+ }
2902
+ m_ctx.stroke();
2903
+
2904
+ // draw middle
3408
2905
  m_ctx.beginPath();
3409
- m_ctx.closePath(); // clear path
2906
+ m_ctx.closePath();
2907
+ num = calcAnalyzisLine(data, 2, undefined, m_chartspaces.chart, scaleinfoY);
3410
2908
  m_ctx.moveTo(data[data.length - num].x, data[data.length - num].y);
3411
2909
  for (let i = data.length - num; i < data.length; i++) {
3412
2910
  m_ctx.lineTo(data[i].pos.x, data[i].pos.y);
3413
2911
  }
3414
2912
  m_ctx.stroke();
2913
+
3415
2914
  m_ctx.restore();
3416
2915
  return;
3417
2916
  }
@@ -3482,8 +2981,6 @@ function Milli_Chart(settings) {
3482
2981
  var hCurveLastPoint = null;
3483
2982
  var quantity = 0;
3484
2983
  var nextDate;
3485
- var firstDataPoint = null;
3486
- var lastDataPoint = null;
3487
2984
 
3488
2985
  var today = new Date().getTime();
3489
2986
  today -= today % 86400000;
@@ -3757,30 +3254,40 @@ function Milli_Chart(settings) {
3757
3254
  let timeseries = [];
3758
3255
  for (let i = 0; i < data.length; i++) {
3759
3256
  let s = 0;
3760
- if (data[i].timestamp >= _this.scaleinfoX.startTimeStamp) {
3257
+ let newstimestamp = data[i].timestamp;
3258
+ if(data[i].timestamp < (data[i].timestamp - (data[i].timestamp % 86400000) + _this.instruments[0].opentimestamp)) {
3259
+ newstimestamp = data[i].timestamp - (data[i].timestamp % 86400000) + _this.instruments[0].opentimestamp;
3260
+ console.log('1', new Date(data[i].timestamp),new Date(newstimestamp));
3261
+ } else if(data[i].timestamp > (data[i].timestamp - (data[i].timestamp % 86400000) + _this.instruments[0].closetimestamp)) {
3262
+ newstimestamp = data[i].timestamp - (data[i].timestamp % 86400000) + _this.instruments[0].closetimestamp;
3263
+ console.log('2', new Date(data[i].timestamp),new Date(newstimestamp));
3264
+ }
3265
+ if (newstimestamp >= _this.scaleinfoX.startTimeStamp) {
3761
3266
  let item = null;
3762
3267
  for (s; s < _this.instruments[0][chartType].length; s++) {
3763
3268
  if (chartType == 'history') {
3764
3269
  if ((data[i].timestamp - (data[i].timestamp % 86400000)) < _this.instruments[0].history[s].timestamp) break;
3765
3270
  if ((data[i].timestamp - (data[i].timestamp % 86400000)) >= _this.instruments[0].history[s].timestamp) {
3766
3271
  item = data[i];
3272
+ item.newstimestamp = newstimestamp;
3767
3273
  item.datapoints = [_this.instruments[0].history[s].price];
3768
3274
  }
3769
3275
  } else {
3770
- if ((data[i].timestamp) < _this.instruments[0].trades[s].timestamp) break;
3771
- if ((data[i].timestamp) >= _this.instruments[0].trades[s].timestamp) {
3276
+ if (newstimestamp < _this.instruments[0].trades[s].timestamp) break;
3277
+ if (newstimestamp >= _this.instruments[0].trades[s].timestamp) {
3772
3278
  item = data[i];
3279
+ item.newstimestamp = newstimestamp;
3773
3280
  item.datapoints = [_this.instruments[0].trades[s].price];
3774
3281
  }
3775
3282
  }
3776
3283
  }
3777
- timeseries.push(item);
3284
+ if(item) timeseries.push(item);
3778
3285
  }
3779
3286
  }
3287
+ console.log(timeseries);
3780
3288
  return timeseries;
3781
3289
  }
3782
3290
 
3783
-
3784
3291
  function calculateBollingerBands(prices, window, stddev) {
3785
3292
  // borde returnera ett object med high/low också
3786
3293
 
@@ -3826,29 +3333,6 @@ function Milli_Chart(settings) {
3826
3333
  return simpleMovingAverages;
3827
3334
  }
3828
3335
 
3829
-
3830
- /*function simpleMovingAverage(prices, window, n = Infinity) {
3831
- // borde returnera ett object med high/low också
3832
- if (!prices || prices.length < window) {
3833
- return [];
3834
- }
3835
- let index = window - 1;
3836
- const length = prices.length + 1;
3837
- const simpleMovingAverages = [];
3838
- let numberOfSMAsCalculated = 0;
3839
- const today = new Date().getTime();
3840
- const startDate = _this.scaleinfoX.startTimeStamp - (window * 86400000);
3841
- while (++index < length && numberOfSMAsCalculated < n) {
3842
- const windowSlice = prices.slice(index - window, index);
3843
- if (windowSlice[window - 1].timestamp > startDate) {
3844
- const sum = windowSlice.reduce((prev, curr) => prev + curr.price, 0);
3845
- simpleMovingAverages.push({ timestamp: prices[index - 1].timestamp, datapoints: [sum / window] });
3846
- numberOfSMAsCalculated++;
3847
- }
3848
- if (typeof prices[index] == 'undefined' || prices[index].timestamp > today) break;
3849
- }
3850
- return simpleMovingAverages;
3851
- }*/
3852
3336
  function exponentialMovingAverage(prices, window) {
3853
3337
  if (!prices || prices.length < window) {
3854
3338
  return [];
@@ -3871,49 +3355,6 @@ function Milli_Chart(settings) {
3871
3355
  return exponentialMovingAverages;
3872
3356
  }
3873
3357
 
3874
- /*function exponentialMovingAverage(prices, window) {
3875
- if (!prices || prices.length < window) {
3876
- return [];
3877
- }
3878
- let index = window - 1;
3879
- let previousEmaIndex = 0;
3880
- const length = prices.length;
3881
- const smoothingFactor = 2 / (window + 1);
3882
- const exponentialMovingAverages = [];
3883
-
3884
- const [sma] = simpleMovingAverage(prices, window, 1);
3885
- exponentialMovingAverages.push(sma);
3886
-
3887
- while (++index < length) {
3888
- const value = prices[index].price;
3889
- const previousEma = [exponentialMovingAverages[previousEmaIndex++].datapoints[0]];
3890
- const currentEma = (value * smoothingFactor) + (previousEma * (1 - smoothingFactor));
3891
- exponentialMovingAverages.push({ timestamp: prices[index].timestamp, datapoints: [currentEma] });
3892
- }
3893
- return exponentialMovingAverages;
3894
- }*/
3895
-
3896
- function bollingerBands(prices, window, stddev) {
3897
- if (!prices || prices.length < window) {
3898
- return [];
3899
- }
3900
-
3901
- let index = window - 1;
3902
- const length = prices.length + 1;
3903
- const standardDeviations = [];
3904
- while (++index < length) {
3905
- const windowSlice = prices.slice(index - window, index);
3906
- const mean = windowSlice.reduce((prev, curr) => prev + curr.price, 0) / window;
3907
- const variance = Math.sqrt(windowSlice.reduce((a, b) => a + (b.price - mean) ** 2, 0) / window) * stddev;
3908
- const uppervariance = mean + variance;
3909
- const lowervariance = mean - variance;
3910
- standardDeviations.push({ timestamp: prices[index - 1].timestamp, datapoints: [uppervariance, lowervariance, mean] });
3911
- if (typeof prices[index] == 'undefined' || prices[index].timestamp > new Date().getTime()) break;
3912
- }
3913
- return standardDeviations;
3914
- }
3915
-
3916
-
3917
3358
  function calculateRSI(p, window) {
3918
3359
  // borde returnera ett object med high/low också
3919
3360
  let rsi = [];
@@ -3958,9 +3399,9 @@ function Milli_Chart(settings) {
3958
3399
  rsi.push({ timestamp: p[i].timestamp, datapoints: [100 - 100 / (1 + rs)] });
3959
3400
  }
3960
3401
  }
3961
- console.log('RSI',rsi[rsi.length-1]);
3962
3402
  return rsi;
3963
3403
  }
3404
+
3964
3405
  _this.removeAllIndicators = function(j) {
3965
3406
  _this.settings.indicators = [];
3966
3407
  _this.drawChart();
@@ -4041,95 +3482,6 @@ function Milli_Chart(settings) {
4041
3482
  _this.drawChart();
4042
3483
  };
4043
3484
 
4044
- /*_this.addIndicator = function(method) {
4045
- if (typeof method !== 'object' || method == null || typeof method.type == undefined) return;
4046
- if (indicatorAlreadyExists(method)) return;
4047
-
4048
- switch (method.method) {
4049
- case 'sma':
4050
- {
4051
- if (typeof method.method_length !== 'number') return;
4052
- method.history = simpleMovingAverage(_this.instruments[0].history, method.method_length);
4053
- method.trades = simpleMovingAverage(_this.instruments[0].trades, method.method_length);
4054
- }
4055
- break;
4056
- case 'ema':
4057
- {
4058
- if (typeof method.method_length !== 'number') return;
4059
- method.history = exponentialMovingAverage(_this.instruments[0].history, method.method_length);
4060
- method.trades = exponentialMovingAverage(_this.instruments[0].trades, method.method_length);
4061
- break;
4062
- }
4063
- case 'bb':
4064
- {
4065
- if (typeof method.method_length !== 'number' || typeof method.stddev !== 'number') return;
4066
- method.history = bollingerBands(_this.instruments[0].history, method.method_length, method.stddev);
4067
- method.trades = bollingerBands(_this.instruments[0].trades, method.method_length, method.stddev);
4068
- break;
4069
- }
4070
- case 'rsi':
4071
- case 'quantity':
4072
- case 'momentum':
4073
- if (method.target == 'lower') {
4074
- m_chartspaces.chart.percent = 70;
4075
- m_chartspaces.lowerChart.percent = 30;
4076
- }
4077
- break;
4078
- case 'news':
4079
- break;
4080
- default:
4081
- if (typeof method.history !== 'undefined' && typeof method.trades !== 'undefined') {
4082
- if (!Array.isArray(method.history) || !Array.isArray(method.trades)) {
4083
- return -1;
4084
- }
4085
- }
4086
- break;
4087
- }
4088
- _this.settings.indicators.push(method);
4089
- _this.drawChart();
4090
- };*/
4091
-
4092
-
4093
- /* _this.addIndicator = function(method) {
4094
- if (typeof method !== 'object' || method == null || typeof method.method == undefined) return;
4095
- if (indicatorAlreadyExists(method)) return;
4096
- switch (method.method) {
4097
- case 'sma':
4098
- {
4099
- if (typeof method.method_length !== 'number') return;
4100
- }
4101
- break;
4102
- case 'ema':
4103
- {
4104
- if (typeof method.method_length !== 'number') return;
4105
- break;
4106
- }
4107
- case 'bb':
4108
- {
4109
- if (typeof method.method_length !== 'number' || typeof method.stddev !== 'number') return;
4110
- break;
4111
- }
4112
- case 'rsi':
4113
- case 'quantity':
4114
- case 'momentum':
4115
- if (method.target == 'lower') {
4116
- m_chartspaces.chart.percent = 70;
4117
- m_chartspaces.lowerChart.percent = 30;
4118
- }
4119
- break;
4120
- case 'news':
4121
- break;
4122
- default:
4123
- method.timeseries.sort(function(a, b) {
4124
- return a.timestamp - b.timestamp;
4125
- });
4126
- break;
4127
- }
4128
- if (typeof method.type === 'undefined') method.type = INDICATOR;
4129
- _this.settings.indicators.unshift(method);
4130
- _this.drawChart();
4131
- };
4132
- */
4133
3485
  function getXhrJson(url) {
4134
3486
  var req = new XMLHttpRequest();
4135
3487
  req.onload = function() {
@@ -4215,8 +3567,6 @@ function Milli_Chart(settings) {
4215
3567
  }
4216
3568
  _this.settings.target.style.height = (_this.settings.target.parentNode.offsetHeight - offset) + 'px';
4217
3569
  _this.settings.target.style.width = _this.settings.target.parentNode.offsetWidth + 'px';
4218
- //_this.settings.target.style.height = (_this.settings.target.parentNode.offsetHeight - offset) * 1 + 'px';
4219
- //_this.settings.target.style.width = _this.settings.target.parentNode.offsetWidth * 1 + 'px';
4220
3570
  m_canvas.setRect(_this.settings.target.offsetHeight, _this.settings.target.offsetWidth);
4221
3571
  }
4222
3572
 
@@ -4281,17 +3631,24 @@ function Milli_Chart(settings) {
4281
3631
  var rect = m_canvas.getBoundingClientRect();
4282
3632
  var x = getScaledSetting(evt.clientX) - getScaledSetting(rect.left) - 1;
4283
3633
  var y = getScaledSetting(evt.clientY) - getScaledSetting(rect.top);
4284
-
4285
3634
  for (let i = 0; i < _this.settings.indicators.length; i++) {
3635
+ let newsarr = [];
4286
3636
  var width = m_ctx.measureText(_this.settings.indicators[i].indicator).width;
4287
3637
  for (let s = 0; s < _this.settings.indicators[i].timeseries.length; s++) {
4288
- if (x >= parseInt(_this.settings.indicators[i].timeseries[s].pos.x) - (width / 2) && x <= parseInt(_this.settings.indicators[i].timeseries[s].pos.x) + (width / 2)) {
4289
- if (y >= _this.settings.indicators[i].timeseries[s].pos.y && y <= _this.settings.indicators[i].timeseries[s].pos.y + width) {
4290
- if (typeof _this.settings.indicators[i].onclick === 'function') _this.settings.indicators[i].onclick.call(_this.settings.indicators[i]);
4291
- }
4292
- break;
3638
+ if(typeof _this.settings.indicators[i].timeseries[s].pos !== 'undefined') {
3639
+ if (x >= parseInt(_this.settings.indicators[i].timeseries[s].pos.x) - (width / 2) && x <= parseInt(_this.settings.indicators[i].timeseries[s].pos.x) + (width / 2)) {
3640
+ if (y >= _this.settings.indicators[i].timeseries[s].pos.y && y <= _this.settings.indicators[i].timeseries[s].pos.y + width) {
3641
+ if (typeof _this.settings.indicators[i].onclick === 'function') {
3642
+ newsarr.push({ date : new Date(_this.settings.indicators[i].timeseries[s].timestamp),newsid: _this.settings.indicators[i].timeseries[s].newsid});
3643
+ }
3644
+ }
3645
+ }// else if( x > parseInt(_this.settings.indicators[i].timeseries[s].pos.x) + (width / 2)) break;
4293
3646
  }
4294
3647
  }
3648
+ if(newsarr.length > 0) {
3649
+ _this.settings.indicators[i].onclick(_this.instruments[0].insref,newsarr);
3650
+ return;
3651
+ }
4295
3652
  }
4296
3653
 
4297
3654
 
@@ -4480,16 +3837,16 @@ function Milli_Chart(settings) {
4480
3837
  calcAnalyizis = true;
4481
3838
  if (instr.pricetype == 'price') {
4482
3839
  update = true;
4483
- data.price = parseFloat(json['12']); // eller 201 för tradeyield
4484
- data.open = parseFloat(json['12']); // eller 201 för tradeyield
4485
- data.high = parseFloat(json['12']); // eller 201 för tradeyield
4486
- data.low = parseFloat(json['12']); // eller 201 för tradeyield
3840
+ data.price = parseFloat(json['12']);
3841
+ data.open = parseFloat(json['12']);
3842
+ data.high = parseFloat(json['12']);
3843
+ data.low = parseFloat(json['12']);
4487
3844
  data.quantity = typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
4488
3845
  } else if (instr.pricetype == 'yield') {
4489
- data.price = parseFloat(json['201']); // eller 201 för tradeyield
4490
- data.open = parseFloat(json['201']); // eller 201 för tradeyield
4491
- data.high = parseFloat(json['201']); // eller 201 för tradeyield
4492
- data.low = parseFloat(json['201']); // eller 201 för tradeyield
3846
+ data.price = parseFloat(json['201']);
3847
+ data.open = parseFloat(json['201']);
3848
+ data.high = parseFloat(json['201']);
3849
+ data.low = parseFloat(json['201']);
4493
3850
  data.quantity = typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
4494
3851
  update = true;
4495
3852
  }
@@ -4663,7 +4020,8 @@ function Milli_Chart(settings) {
4663
4020
  'rect': 'all',
4664
4021
  'translate': 'all',
4665
4022
  'createRadialGradient': 'all',
4666
- 'createLinearGradient': 'all'
4023
+ 'createLinearGradient': 'all',
4024
+ 'drawImage': [1,2,3,4]
4667
4025
  };
4668
4026
 
4669
4027
  if (context.pixelRatio === 1) return;
@@ -4877,19 +4235,29 @@ function Milli_Chart(settings) {
4877
4235
  _this.drawChart();
4878
4236
  })();
4879
4237
 
4880
- window.addEventListener('resize', function() {
4238
+ window.addEventListener('resize', function(a) {
4881
4239
  if (m_canvas != null) {
4882
4240
  setChartSize();
4241
+ //console.log("windowresize",m_chartspaces);
4883
4242
  _this.drawChart();
4884
4243
  }
4885
4244
  });
4245
+
4246
+ /* function parentResize(a) {
4247
+ console.log('a',a);
4248
+ if(m_canvas != null) {
4249
+ setChartSize();
4250
+ console.log(m_chartspaces);
4251
+ _this.drawChart();
4252
+ }
4253
+ };
4886
4254
 
4887
4255
  if(_this.settings.target.parentNode) {
4888
- const observer = new MutationObserver(_this.resizeEnd);
4256
+ const observer = new MutationObserver(parentResize);
4889
4257
  const observerConfig = { attributes: true };
4890
4258
  observer.observe(_this.settings.target.parentNode, observerConfig);
4891
4259
  }
4892
-
4260
+ */
4893
4261
  };
4894
4262
 
4895
4263
  function Milli_OptionsList(settings) {
@@ -6338,6 +5706,21 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
6338
5706
  // internal and external
6339
5707
  // return array with MDF_F_FIELD,type,align, name var, overridable decimal bitwise [1 = override output,2 = can override,4 = no decimals,8 can be shortened to M, K etc], 16 = override NULL with 0 , 32 = can color diff
6340
5708
  switch (name) {
5709
+ case '1104':
5710
+ case 'adtv1mprc':
5711
+ return [1104, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
5712
+ case '1105':
5713
+ case 'adtv1wprc':
5714
+ return [1105, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
5715
+ case '1106':
5716
+ case 'adtv1yprc':
5717
+ return [1106, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
5718
+ case '1107':
5719
+ case 'adtv3mprc':
5720
+ return [1107, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
5721
+ case '1108':
5722
+ case 'adtvytdprc':
5723
+ return [1108, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
6341
5724
  case '222':
6342
5725
  case 'accountsreceivable':
6343
5726
  return [222, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
@@ -6763,9 +6146,18 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
6763
6146
  case '181':
6764
6147
  case 's4':
6765
6148
  return [181, 'string', 'left', widget.get_lang_text(name) || name, 0]; // Position
6149
+ case '389':
6150
+ case 's6':
6151
+ return [389, 'string', 'left', widget.get_lang_text(name) || name, 0]; //
6152
+ case '390':
6153
+ case 's7':
6154
+ return [390, 'string', 'left', widget.get_lang_text(name) || name, 0]; //
6766
6155
  case '393':
6767
6156
  case 's10':
6768
6157
  return [393, 'string', 'left', widget.get_lang_text(name) || name, 0]; // comment
6158
+ case '713':
6159
+ case 's12':
6160
+ return [713, 'string', 'left', widget.get_lang_text(name) || name, 0]; // comment
6769
6161
  case '127':
6770
6162
  case 'sales':
6771
6163
  return [127, 'numeric', 'right', widget.get_lang_text(name) || name, 8];