@millistream/millistream-widgets 1.0.39 → 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 +185 -825
  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;
@@ -858,187 +537,39 @@ function Milli_Chart(settings) {
858
537
  _this.instruments[s].startValue = null;
859
538
  data = _this.instruments[s][chartType];
860
539
  if (useCloseprice) {
861
- _this.instruments[s].startValue = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
862
- }
863
- //var quantity = 0;
864
- let prevPrice = null;
865
- for (i = 0; i < data.length; i++) {
866
- // only calc on visible data
867
- var price = data[i].price * _this.instruments[s].factor;
868
- let highprice = data[i].highprice * _this.instruments[s].factor;
869
- let lowprice = data[i].lowprice * _this.instruments[s].factor;
870
-
871
- if (data[i].timestamp > _this.scaleinfoX.endTimeStamp) {
872
- break;
873
- }
874
- if (data[i].timestamp < _this.scaleinfoX.startTimeStamp) {
875
- if (chartType == 'history') {
876
- _this.instruments[s].startValue = price; // skall inte sättas eftersom vi inte ritar den i history, skall visst sättas // 2023-06-27
877
- scaleinfoY2.lowValue = 0;
878
- scaleinfoY2.highValue = 0;
879
- }
880
- //else if (_this.settings.chartlen != '1d' && _this.settings.chartlen != '0d' && !m_zoom.mousedown.timestamp) {
881
- else if (useCloseprice == false) {
882
- _this.instruments[s].startValue = price;
883
- }
884
- continue;
885
- }
886
- _this.instruments[s].endValue = price;
887
-
888
- if (chartType != 'history' && (data[i].timestamp % 86400000 < _this.instruments[0].opentimestamp || data[i].timestamp % 86400000 > _this.instruments[0].closetimestamp)) {
889
- // stämmer detta kan det bli överlapp vid sommartid/vintertid?
890
- continue;
891
- }
892
-
893
- if (_this.instruments[s].startValue == null) { // no value before this date , use this date?
894
- if (chartType == 'history') {
895
- _this.instruments[s].startValue = price;
896
- } else {
897
- if (isToday(new Date(data[i].timestamp)) && !m_zoom.mousedown.timestamp) {
898
- _this.instruments[s].startValue = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
899
- } else {
900
- _this.instruments[s].startValue = price;
901
- }
902
- }
903
- }
904
- if(_this.settings.type == 'ohlc' || _this.settings.type == 'candlestick') {
905
- if (scaleinfoY.lowValue == null || scaleinfoY.lowValue > lowprice) scaleinfoY.lowValue = lowprice;
906
- if (scaleinfoY.highValue == null || scaleinfoY.highValue < highprice) scaleinfoY.highValue = highprice;
907
- }
908
- else {
909
- if (scaleinfoY.lowValue == null || scaleinfoY.lowValue > price) scaleinfoY.lowValue = price;
910
- if (scaleinfoY.highValue == null || scaleinfoY.highValue < price) scaleinfoY.highValue = price;
911
- }
912
- let diff = (price - _this.instruments[s].startValue);
913
- if (diff != 0) diff = diff / _this.instruments[s].startValue * 100;
914
- if (_this.instruments[s].startValue == null) diff = 0;
915
- data[i].diff = diff;
916
- if (scaleinfoY2.lowValue == null || scaleinfoY2.lowValue > diff) scaleinfoY2.lowValue = diff;
917
- if (scaleinfoY2.highValue == null || scaleinfoY2.highValue < diff) scaleinfoY2.highValue = diff;
918
- }
919
- if (useCloseprice && !m_zoom.mousedown.timestamp) { // if closeprice is used calch high/low on it
920
- var cp = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
921
- if (scaleinfoY.lowValue > cp) scaleinfoY.lowValue = cp;
922
- else
923
- if (scaleinfoY.highValue < cp) scaleinfoY.highValue = cp;
924
- }
925
- if (chartType != 'history') {
926
- if (scaleinfoY2.lowValue > 0) {
927
- scaleinfoY2.lowValue = 0;
928
- } else {
929
- if (scaleinfoY2.highValue < 0) scaleinfoY2.highValue = 0;
930
- }
931
- }
932
- if (_this.instruments[s].startValue) {
933
- if (_this.instruments[s].startValue > scaleinfoY.highValue) scaleinfoY.highValue = _this.instruments[s].startValue;
934
- if (_this.instruments[s].startValue < scaleinfoY.lowValue) scaleinfoY.lowValue = _this.instruments[s].startValue;
935
- }
936
- }
937
- if (scaleinfoY.lowValue == null) {
938
- scaleinfoY.lowValue = 0;
939
- scaleinfoY.highValue = 100;
940
- scaleinfoY2.lowValue = 0;
941
- scaleinfoY2.highValue = 100;
942
- return;
943
- } else
944
- if (scaleinfoY.lowValue == scaleinfoY.highValue && scaleinfoY.lowValue == 0) {
945
- scaleinfoY.lowValue -= 1;
946
- scaleinfoY.highValue += 1;
947
- scaleinfoY.lowValue -= 1;
948
- scaleinfoY.highValue += 1;
949
- }
950
- // do we have any analyzis we need to take into account
951
- for (i = 0; i < _this.settings.indicators.length; i++) {
952
- 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
- }
540
+ _this.instruments[s].startValue = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
1014
541
  }
1015
- var quantity = 0;
1016
-
542
+ //var quantity = 0;
543
+ let prevPrice = null;
1017
544
  for (i = 0; i < data.length; i++) {
1018
545
  // only calc on visible data
1019
546
  var price = data[i].price * _this.instruments[s].factor;
1020
- quantity = 0;
1021
- if (data[i].quantity !== 'undefined') {
1022
- quantity = data[i].quantity;
547
+ let highprice = data[i].highprice * _this.instruments[s].factor;
548
+ let lowprice = data[i].lowprice * _this.instruments[s].factor;
549
+
550
+ if (data[i].timestamp > _this.scaleinfoX.endTimeStamp) {
551
+ break;
1023
552
  }
1024
553
  if (data[i].timestamp < _this.scaleinfoX.startTimeStamp) {
1025
- if (chartType == 'history') _this.instruments[s].startValue = price;
554
+ if (chartType == 'history') {
555
+ _this.instruments[s].startValue = price; // skall inte sättas eftersom vi inte ritar den i history, skall visst sättas // 2023-06-27
556
+ scaleinfoY2.lowValue = 0;
557
+ scaleinfoY2.highValue = 0;
558
+ }
1026
559
  //else if (_this.settings.chartlen != '1d' && _this.settings.chartlen != '0d' && !m_zoom.mousedown.timestamp) {
1027
- else if (useCloseprice == false || m_zoom.mousedown.timestamp) {
560
+ else if (useCloseprice == false) {
1028
561
  _this.instruments[s].startValue = price;
1029
562
  }
1030
563
  continue;
1031
564
  }
1032
- if (data[i].timestamp > _this.scaleinfoX.endTimeStamp) {
1033
- break;
1034
- }
565
+ _this.instruments[s].endValue = price;
1035
566
 
1036
567
  if (chartType != 'history' && (data[i].timestamp % 86400000 < _this.instruments[0].opentimestamp || data[i].timestamp % 86400000 > _this.instruments[0].closetimestamp)) {
1037
568
  // stämmer detta kan det bli överlapp vid sommartid/vintertid?
1038
569
  continue;
1039
570
  }
1040
571
 
1041
- if (_this.instruments[s].startValue == null) {
572
+ if (_this.instruments[s].startValue == null) { // no value before this date , use this date?
1042
573
  if (chartType == 'history') {
1043
574
  _this.instruments[s].startValue = price;
1044
575
  } else {
@@ -1049,19 +580,22 @@ function Milli_Chart(settings) {
1049
580
  }
1050
581
  }
1051
582
  }
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);
583
+ if(_this.settings.type == 'ohlc' || _this.settings.type == 'candlestick') {
584
+ if (scaleinfoY.lowValue == null || scaleinfoY.lowValue > lowprice) scaleinfoY.lowValue = lowprice;
585
+ if (scaleinfoY.highValue == null || scaleinfoY.highValue < highprice) scaleinfoY.highValue = highprice;
586
+ }
587
+ else {
588
+ if (scaleinfoY.lowValue == null || scaleinfoY.lowValue > price) scaleinfoY.lowValue = price;
589
+ if (scaleinfoY.highValue == null || scaleinfoY.highValue < price) scaleinfoY.highValue = price;
590
+ }
591
+ let diff = (price - _this.instruments[s].startValue);
1055
592
  if (diff != 0) diff = diff / _this.instruments[s].startValue * 100;
1056
593
  if (_this.instruments[s].startValue == null) diff = 0;
1057
594
  data[i].diff = diff;
1058
-
1059
595
  if (scaleinfoY2.lowValue == null || scaleinfoY2.lowValue > diff) scaleinfoY2.lowValue = diff;
1060
596
  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
597
  }
1064
- if ((_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && !m_zoom.mousedown.timestamp) { // if closeprice is used calch high/low on it
598
+ if (useCloseprice && !m_zoom.mousedown.timestamp) { // if closeprice is used calch high/low on it
1065
599
  var cp = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
1066
600
  if (scaleinfoY.lowValue > cp) scaleinfoY.lowValue = cp;
1067
601
  else
@@ -1079,22 +613,29 @@ function Milli_Chart(settings) {
1079
613
  if (_this.instruments[s].startValue < scaleinfoY.lowValue) scaleinfoY.lowValue = _this.instruments[s].startValue;
1080
614
  }
1081
615
  }
1082
-
1083
616
  if (scaleinfoY.lowValue == null) {
1084
617
  scaleinfoY.lowValue = 0;
1085
618
  scaleinfoY.highValue = 100;
1086
619
  scaleinfoY2.lowValue = 0;
1087
620
  scaleinfoY2.highValue = 100;
621
+ return;
1088
622
  } else
1089
623
  if (scaleinfoY.lowValue == scaleinfoY.highValue && scaleinfoY.lowValue == 0) {
1090
624
  scaleinfoY.lowValue -= 1;
1091
625
  scaleinfoY.highValue += 1;
626
+ scaleinfoY.lowValue -= 1;
627
+ scaleinfoY.highValue += 1;
1092
628
  }
1093
- console.log(_this.settings.indicators);
1094
629
  // do we have any analyzis we need to take into account
1095
630
  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;
631
+ if (_this.settings.indicators[i].method == 'rsi') continue;
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;
@@ -1366,75 +913,6 @@ function Milli_Chart(settings) {
1366
913
  return true;
1367
914
  }
1368
915
 
1369
- function drawYAxisNew(scale, cs, css, drawAxis, gridLines, factor) {
1370
- /*let scale = {};
1371
- if (false == calcHighLow2(scale, factor)) {
1372
- console.log('fail highlow');
1373
- return;
1374
- }*/
1375
- m_ctx.save();
1376
- m_ctx.strokeStyle = m_gridHorizontalCss.color;
1377
- m_ctx.font = css.fontWeight + ' ' + css.fontSize + ' ' + css.fontFamily;
1378
- m_ctx.fillStyle = css.color;
1379
- scale.lineLength = cs.bottom - cs.top;
1380
- /* let numticks = scale.lineLength / (getFontSize(css) * _this.settings.yAxisSpacing);
1381
- if (numticks > 8) numticks = 8; // limit to 8 items on Y legend ( this is not an absolut count, since we calculate nice legend numbers
1382
- scale.tickSize = getTickValue(scale.lowValue, scale.highValue, numticks);
1383
- scale.decimals = scale.tickSize.countDecimals();*/
1384
- //scale.decimals > 4 ? 4 : (scale.decimals < 2 ? 2 : scale.decimals);
1385
-
1386
-
1387
-
1388
-
1389
- /* let widestValue = (scale.lowValue < 0 ? '-' : '') + Math.max(Math.abs(scale.highValue), Math.abs(scale.lowValue));
1390
- let label = formatNiceNumber(widestValue, _this.settings.thousandseparator, _this.settings.decimalseparator, scale.decimals);
1391
- console.log('testw', label, )
1392
- if (drawAxis) {
1393
- if (css.float != 'right') {
1394
- 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å?
1395
- } else {
1396
- if (css.textAlign == 'right') {
1397
- 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å?
1398
- }
1399
- }
1400
- }
1401
- */
1402
-
1403
-
1404
-
1405
-
1406
- 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
1407
- m_ctx.save();
1408
- m_ctx.font = m_xLegendCss.fontWeight + ' ' + m_xLegendCss.fontSize + ' ' + m_xLegendCss.fontFamily;
1409
- if (getStringWidth(m_ctx, _this.settings.dateformat) / 2 + 5 > cs.left) {
1410
- cs.left = getStringWidth(m_ctx, _this.settings.dateformat) / 2 + 5;
1411
- }
1412
- m_ctx.restore();
1413
- }
1414
- // draw line
1415
- m_ctx.strokeStyle = m_gridVerticalCss.color;
1416
- m_ctx.beginPath();
1417
- m_ctx.moveTo(cs.left + 0.5, cs.top);
1418
- m_ctx.lineTo(cs.left + 0.5, cs.height - cs.marginBottom);
1419
- m_ctx.stroke();
1420
- m_ctx.closePath();
1421
- m_ctx.strokeStyle = m_gridHorizontalCss.color;
1422
- var x;
1423
- if (css.float == 'right')
1424
- x = cs.right;
1425
- else
1426
- x = cs.left;
1427
- if (css.textAlign == 'right') {
1428
- m_ctx.textAlign = 'left';
1429
- drawYLegendNew(scale, cs, x, css, drawAxis, gridLines, factor);
1430
- } else {
1431
- m_ctx.textAlign = 'right';
1432
- drawYLegendNew(scale, cs, x, css, drawAxis, gridLines), factor;
1433
- }
1434
- m_ctx.restore();
1435
- return scale;
1436
- }
1437
-
1438
916
  function drawYAxis(scaleinfoY, scaleinfoY2) {
1439
917
  m_ctx.save();
1440
918
  m_ctx.strokeStyle = m_gridHorizontalCss.color;
@@ -2411,6 +1889,11 @@ function Milli_Chart(settings) {
2411
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
2412
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
2413
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";
2414
1897
  remove = false;
2415
1898
  toolArray.push({ top: parseInt(_this.settings.indicators[x].toolTip.div.style.top), indicator: x });
2416
1899
  }
@@ -2420,6 +1903,7 @@ function Milli_Chart(settings) {
2420
1903
  if (_this.settings.indicators[x].toolTip.div && _this.settings.indicators[x].staticTooltip != true) {
2421
1904
  _this.settings.indicators[x].toolTip.div.parentNode.removeChild(_this.settings.indicators[x].toolTip.div);
2422
1905
  _this.settings.indicators[x].toolTip.div = undefined;
1906
+ m_canvas.style.cursor = "crosshair";
2423
1907
  }
2424
1908
 
2425
1909
  }
@@ -2581,7 +2065,7 @@ function Milli_Chart(settings) {
2581
2065
  _this.settings.indicators[i].timeseries = calculateBollingerBands(_this.instruments[0].trades, _this.settings.indicators[i].method_length, _this.settings.indicators[i].stddev | 2);
2582
2066
  break;
2583
2067
  case 'news':
2584
- _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);
2585
2069
  break;
2586
2070
  // future events osv?
2587
2071
  default:
@@ -2779,29 +2263,6 @@ function Milli_Chart(settings) {
2779
2263
  if (false == checkChartData(_this.instruments[0].history)) return;
2780
2264
  calculateIndicators();
2781
2265
 
2782
- /*let scaleY = {};
2783
- if (_this.settings.drawyaxis) {
2784
- if (false == calcHighLow2(scaleY, m_chartspaces.chart, m_yLegendCss)) {
2785
- console.log('fail highlow');
2786
- return;
2787
- }
2788
- }
2789
- let scaleY2 = {};
2790
- let factorInfo = {
2791
- name: 'diff',
2792
- actor: _this.instruments[0].startValue,
2793
- suffix: '%'
2794
- };
2795
- if (_this.settings.drawy2axis) {
2796
- if (false == calcHighLow2(scaleY2, m_chartspaces.chart, m_y2LegendCss, factorInfo)) {
2797
- console.log('fail highlow');
2798
- return;
2799
- }
2800
- }
2801
-
2802
- drawYAxisNew(scaleY, m_chartspaces.chart, m_yLegendCss, _this.settings.drawyaxis, _this.settings.gridHorizontalLines);
2803
- drawYAxisNew(scaleY2, m_chartspaces.chart, m_y2LegendCss, _this.settings.drawy2axis, false, factorInfo); *
2804
- */
2805
2266
  drawYAxis(scaleinfoY, scaleinfoY2);
2806
2267
  drawXAxisMonth(_this.scaleinfoX.startTimeStamp, _this.scaleinfoX.endTimeStamp);
2807
2268
 
@@ -2943,6 +2404,7 @@ function Milli_Chart(settings) {
2943
2404
  case 'rsi':
2944
2405
  if (chartType == 'history') _this.settings.indicators[i].timeseries = calculateRSI(_this.instruments[0].history, _this.settings.indicators[i].method_length);
2945
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);
2946
2408
  if (_this.settings.indicators[i].target == 'upper') {
2947
2409
  lowerScale = drawYAxisIndicator(_this.settings.indicators[i].timeseries, m_chartspaces.chart, false);
2948
2410
  plotIndicatorLine(_this.settings.indicators[i], lowerScale, m_chartspaces.chart);
@@ -3176,26 +2638,31 @@ function Milli_Chart(settings) {
3176
2638
  var startpoint = { x: 0, y: 0 };
3177
2639
  var endpoint = { x: 0, y: 0 };
3178
2640
  var startDate = _this.scaleinfoX.startTimeStamp;
3179
- var len = data.length;
3180
2641
  var lastdate = new Date(_this.scaleinfoX.startTimeStamp);
3181
2642
  var offset = 0;
3182
2643
  var maxy = 0;
3183
2644
  var ret = [];
3184
2645
  let num = 0;
3185
- for (var i = 0; i < len; i++) {
2646
+ for (var i = 0; i < data.length; i++) {
3186
2647
  var currentDate;
3187
2648
  var tmpx = startpoint.x;
3188
2649
  var tmp;
3189
- var timestamp = data[i].timestamp;
2650
+ var timestamp = typeof data[i].newstimestamp !== 'undefined' ? data[i].newstimestamp : data[i].timestamp;
3190
2651
  if (chartType == 'history') timestamp -= (timestamp % 86400000)
3191
2652
  if (timestamp < _this.scaleinfoX.startTimeStamp) {
3192
2653
  continue;
3193
2654
  }
3194
2655
  if (timestamp > _this.scaleinfoX.endTimeStamp) {
3195
- break;
2656
+ data.splice(i,1);
2657
+ i--;
2658
+ continue;
3196
2659
  }
3197
2660
 
3198
- 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--;
3199
2666
  continue;
3200
2667
  }
3201
2668
  var endtimeToday = new Date(timestamp);
@@ -3303,6 +2770,10 @@ function Milli_Chart(settings) {
3303
2770
  let data = method.timeseries;
3304
2771
  let num = calcAnalyzisLine(data, 0, undefined, cs, scale);
3305
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
+
3306
2777
  m_ctx.save();
3307
2778
  m_ctx.beginPath();
3308
2779
  m_ctx.closePath();
@@ -3310,10 +2781,13 @@ function Milli_Chart(settings) {
3310
2781
  m_ctx.strokeStyle = method.color;
3311
2782
  if (typeof method.lineStyle === 'string' && method.lineStyle == 'dash') m_ctx.setLineDash([3, 3]);
3312
2783
 
3313
- 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);
3314
2785
  let lastPos = null;
3315
- for (var i = data.length - 2; i >= 0; i--) {
3316
- 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
+ }
3317
2791
  m_ctx.lineTo(data[i].pos.x, data[i].pos.y);
3318
2792
  lastPos = data[i].pos;
3319
2793
  }
@@ -3323,7 +2797,7 @@ function Milli_Chart(settings) {
3323
2797
  }
3324
2798
  if (typeof method.callback === 'function') method.callback.call({ x: data[data.length - 1].pos.x, y: data[data.length - 1].pos.y });
3325
2799
  m_ctx.stroke();
3326
- m_ctx.lineTo(data[data.length - 1].pos.x, cs.bottom);
2800
+ m_ctx.lineTo(data[start].pos.x, cs.bottom);
3327
2801
  m_ctx.restore();
3328
2802
  }
3329
2803
 
@@ -3369,11 +2843,11 @@ function Milli_Chart(settings) {
3369
2843
  if (fabs(lastPos.x - data[i].pos.x) > width || fabs(lastPos.y > data[i].pos.y) > width) {
3370
2844
  m_ctx.fillText(method.indicator, data[i].pos.x - (width / 2), data[i].pos.y);
3371
2845
  lastPos = { x: data[i].pos.x, y: data[i].y };
3372
- 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 }];
3373
2847
  hlPos = i;
3374
2848
 
3375
2849
  } else {
3376
- 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 });
3377
2851
  }
3378
2852
  } else m_ctx.fillText(method.indicator, data[i].pos.x - (width / 2), data[i].pos.y);
3379
2853
 
@@ -3507,8 +2981,6 @@ function Milli_Chart(settings) {
3507
2981
  var hCurveLastPoint = null;
3508
2982
  var quantity = 0;
3509
2983
  var nextDate;
3510
- var firstDataPoint = null;
3511
- var lastDataPoint = null;
3512
2984
 
3513
2985
  var today = new Date().getTime();
3514
2986
  today -= today % 86400000;
@@ -3782,30 +3254,40 @@ function Milli_Chart(settings) {
3782
3254
  let timeseries = [];
3783
3255
  for (let i = 0; i < data.length; i++) {
3784
3256
  let s = 0;
3785
- 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) {
3786
3266
  let item = null;
3787
3267
  for (s; s < _this.instruments[0][chartType].length; s++) {
3788
3268
  if (chartType == 'history') {
3789
3269
  if ((data[i].timestamp - (data[i].timestamp % 86400000)) < _this.instruments[0].history[s].timestamp) break;
3790
3270
  if ((data[i].timestamp - (data[i].timestamp % 86400000)) >= _this.instruments[0].history[s].timestamp) {
3791
3271
  item = data[i];
3272
+ item.newstimestamp = newstimestamp;
3792
3273
  item.datapoints = [_this.instruments[0].history[s].price];
3793
3274
  }
3794
3275
  } else {
3795
- if ((data[i].timestamp) < _this.instruments[0].trades[s].timestamp) break;
3796
- 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) {
3797
3278
  item = data[i];
3279
+ item.newstimestamp = newstimestamp;
3798
3280
  item.datapoints = [_this.instruments[0].trades[s].price];
3799
3281
  }
3800
3282
  }
3801
3283
  }
3802
- timeseries.push(item);
3284
+ if(item) timeseries.push(item);
3803
3285
  }
3804
3286
  }
3287
+ console.log(timeseries);
3805
3288
  return timeseries;
3806
3289
  }
3807
3290
 
3808
-
3809
3291
  function calculateBollingerBands(prices, window, stddev) {
3810
3292
  // borde returnera ett object med high/low också
3811
3293
 
@@ -3851,29 +3333,6 @@ function Milli_Chart(settings) {
3851
3333
  return simpleMovingAverages;
3852
3334
  }
3853
3335
 
3854
-
3855
- /*function simpleMovingAverage(prices, window, n = Infinity) {
3856
- // borde returnera ett object med high/low också
3857
- if (!prices || prices.length < window) {
3858
- return [];
3859
- }
3860
- let index = window - 1;
3861
- const length = prices.length + 1;
3862
- const simpleMovingAverages = [];
3863
- let numberOfSMAsCalculated = 0;
3864
- const today = new Date().getTime();
3865
- const startDate = _this.scaleinfoX.startTimeStamp - (window * 86400000);
3866
- while (++index < length && numberOfSMAsCalculated < n) {
3867
- const windowSlice = prices.slice(index - window, index);
3868
- if (windowSlice[window - 1].timestamp > startDate) {
3869
- const sum = windowSlice.reduce((prev, curr) => prev + curr.price, 0);
3870
- simpleMovingAverages.push({ timestamp: prices[index - 1].timestamp, datapoints: [sum / window] });
3871
- numberOfSMAsCalculated++;
3872
- }
3873
- if (typeof prices[index] == 'undefined' || prices[index].timestamp > today) break;
3874
- }
3875
- return simpleMovingAverages;
3876
- }*/
3877
3336
  function exponentialMovingAverage(prices, window) {
3878
3337
  if (!prices || prices.length < window) {
3879
3338
  return [];
@@ -3896,49 +3355,6 @@ function Milli_Chart(settings) {
3896
3355
  return exponentialMovingAverages;
3897
3356
  }
3898
3357
 
3899
- /*function exponentialMovingAverage(prices, window) {
3900
- if (!prices || prices.length < window) {
3901
- return [];
3902
- }
3903
- let index = window - 1;
3904
- let previousEmaIndex = 0;
3905
- const length = prices.length;
3906
- const smoothingFactor = 2 / (window + 1);
3907
- const exponentialMovingAverages = [];
3908
-
3909
- const [sma] = simpleMovingAverage(prices, window, 1);
3910
- exponentialMovingAverages.push(sma);
3911
-
3912
- while (++index < length) {
3913
- const value = prices[index].price;
3914
- const previousEma = [exponentialMovingAverages[previousEmaIndex++].datapoints[0]];
3915
- const currentEma = (value * smoothingFactor) + (previousEma * (1 - smoothingFactor));
3916
- exponentialMovingAverages.push({ timestamp: prices[index].timestamp, datapoints: [currentEma] });
3917
- }
3918
- return exponentialMovingAverages;
3919
- }*/
3920
-
3921
- function bollingerBands(prices, window, stddev) {
3922
- if (!prices || prices.length < window) {
3923
- return [];
3924
- }
3925
-
3926
- let index = window - 1;
3927
- const length = prices.length + 1;
3928
- const standardDeviations = [];
3929
- while (++index < length) {
3930
- const windowSlice = prices.slice(index - window, index);
3931
- const mean = windowSlice.reduce((prev, curr) => prev + curr.price, 0) / window;
3932
- const variance = Math.sqrt(windowSlice.reduce((a, b) => a + (b.price - mean) ** 2, 0) / window) * stddev;
3933
- const uppervariance = mean + variance;
3934
- const lowervariance = mean - variance;
3935
- standardDeviations.push({ timestamp: prices[index - 1].timestamp, datapoints: [uppervariance, lowervariance, mean] });
3936
- if (typeof prices[index] == 'undefined' || prices[index].timestamp > new Date().getTime()) break;
3937
- }
3938
- return standardDeviations;
3939
- }
3940
-
3941
-
3942
3358
  function calculateRSI(p, window) {
3943
3359
  // borde returnera ett object med high/low också
3944
3360
  let rsi = [];
@@ -3985,6 +3401,7 @@ function Milli_Chart(settings) {
3985
3401
  }
3986
3402
  return rsi;
3987
3403
  }
3404
+
3988
3405
  _this.removeAllIndicators = function(j) {
3989
3406
  _this.settings.indicators = [];
3990
3407
  _this.drawChart();
@@ -4065,95 +3482,6 @@ function Milli_Chart(settings) {
4065
3482
  _this.drawChart();
4066
3483
  };
4067
3484
 
4068
- /*_this.addIndicator = function(method) {
4069
- if (typeof method !== 'object' || method == null || typeof method.type == undefined) return;
4070
- if (indicatorAlreadyExists(method)) return;
4071
-
4072
- switch (method.method) {
4073
- case 'sma':
4074
- {
4075
- if (typeof method.method_length !== 'number') return;
4076
- method.history = simpleMovingAverage(_this.instruments[0].history, method.method_length);
4077
- method.trades = simpleMovingAverage(_this.instruments[0].trades, method.method_length);
4078
- }
4079
- break;
4080
- case 'ema':
4081
- {
4082
- if (typeof method.method_length !== 'number') return;
4083
- method.history = exponentialMovingAverage(_this.instruments[0].history, method.method_length);
4084
- method.trades = exponentialMovingAverage(_this.instruments[0].trades, method.method_length);
4085
- break;
4086
- }
4087
- case 'bb':
4088
- {
4089
- if (typeof method.method_length !== 'number' || typeof method.stddev !== 'number') return;
4090
- method.history = bollingerBands(_this.instruments[0].history, method.method_length, method.stddev);
4091
- method.trades = bollingerBands(_this.instruments[0].trades, method.method_length, method.stddev);
4092
- break;
4093
- }
4094
- case 'rsi':
4095
- case 'quantity':
4096
- case 'momentum':
4097
- if (method.target == 'lower') {
4098
- m_chartspaces.chart.percent = 70;
4099
- m_chartspaces.lowerChart.percent = 30;
4100
- }
4101
- break;
4102
- case 'news':
4103
- break;
4104
- default:
4105
- if (typeof method.history !== 'undefined' && typeof method.trades !== 'undefined') {
4106
- if (!Array.isArray(method.history) || !Array.isArray(method.trades)) {
4107
- return -1;
4108
- }
4109
- }
4110
- break;
4111
- }
4112
- _this.settings.indicators.push(method);
4113
- _this.drawChart();
4114
- };*/
4115
-
4116
-
4117
- /* _this.addIndicator = function(method) {
4118
- if (typeof method !== 'object' || method == null || typeof method.method == undefined) return;
4119
- if (indicatorAlreadyExists(method)) return;
4120
- switch (method.method) {
4121
- case 'sma':
4122
- {
4123
- if (typeof method.method_length !== 'number') return;
4124
- }
4125
- break;
4126
- case 'ema':
4127
- {
4128
- if (typeof method.method_length !== 'number') return;
4129
- break;
4130
- }
4131
- case 'bb':
4132
- {
4133
- if (typeof method.method_length !== 'number' || typeof method.stddev !== 'number') return;
4134
- break;
4135
- }
4136
- case 'rsi':
4137
- case 'quantity':
4138
- case 'momentum':
4139
- if (method.target == 'lower') {
4140
- m_chartspaces.chart.percent = 70;
4141
- m_chartspaces.lowerChart.percent = 30;
4142
- }
4143
- break;
4144
- case 'news':
4145
- break;
4146
- default:
4147
- method.timeseries.sort(function(a, b) {
4148
- return a.timestamp - b.timestamp;
4149
- });
4150
- break;
4151
- }
4152
- if (typeof method.type === 'undefined') method.type = INDICATOR;
4153
- _this.settings.indicators.unshift(method);
4154
- _this.drawChart();
4155
- };
4156
- */
4157
3485
  function getXhrJson(url) {
4158
3486
  var req = new XMLHttpRequest();
4159
3487
  req.onload = function() {
@@ -4303,17 +3631,24 @@ function Milli_Chart(settings) {
4303
3631
  var rect = m_canvas.getBoundingClientRect();
4304
3632
  var x = getScaledSetting(evt.clientX) - getScaledSetting(rect.left) - 1;
4305
3633
  var y = getScaledSetting(evt.clientY) - getScaledSetting(rect.top);
4306
-
4307
3634
  for (let i = 0; i < _this.settings.indicators.length; i++) {
3635
+ let newsarr = [];
4308
3636
  var width = m_ctx.measureText(_this.settings.indicators[i].indicator).width;
4309
3637
  for (let s = 0; s < _this.settings.indicators[i].timeseries.length; s++) {
4310
- 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)) {
4311
- if (y >= _this.settings.indicators[i].timeseries[s].pos.y && y <= _this.settings.indicators[i].timeseries[s].pos.y + width) {
4312
- if (typeof _this.settings.indicators[i].onclick === 'function') _this.settings.indicators[i].onclick.call(_this.settings.indicators[i]);
4313
- }
4314
- 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;
4315
3646
  }
4316
3647
  }
3648
+ if(newsarr.length > 0) {
3649
+ _this.settings.indicators[i].onclick(_this.instruments[0].insref,newsarr);
3650
+ return;
3651
+ }
4317
3652
  }
4318
3653
 
4319
3654
 
@@ -4502,16 +3837,16 @@ function Milli_Chart(settings) {
4502
3837
  calcAnalyizis = true;
4503
3838
  if (instr.pricetype == 'price') {
4504
3839
  update = true;
4505
- data.price = parseFloat(json['12']); // eller 201 för tradeyield
4506
- data.open = parseFloat(json['12']); // eller 201 för tradeyield
4507
- data.high = parseFloat(json['12']); // eller 201 för tradeyield
4508
- 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']);
4509
3844
  data.quantity = typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
4510
3845
  } else if (instr.pricetype == 'yield') {
4511
- data.price = parseFloat(json['201']); // eller 201 för tradeyield
4512
- data.open = parseFloat(json['201']); // eller 201 för tradeyield
4513
- data.high = parseFloat(json['201']); // eller 201 för tradeyield
4514
- 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']);
4515
3850
  data.quantity = typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
4516
3851
  update = true;
4517
3852
  }
@@ -4685,7 +4020,8 @@ function Milli_Chart(settings) {
4685
4020
  'rect': 'all',
4686
4021
  'translate': 'all',
4687
4022
  'createRadialGradient': 'all',
4688
- 'createLinearGradient': 'all'
4023
+ 'createLinearGradient': 'all',
4024
+ 'drawImage': [1,2,3,4]
4689
4025
  };
4690
4026
 
4691
4027
  if (context.pixelRatio === 1) return;
@@ -4902,7 +4238,7 @@ function Milli_Chart(settings) {
4902
4238
  window.addEventListener('resize', function(a) {
4903
4239
  if (m_canvas != null) {
4904
4240
  setChartSize();
4905
- //console.log("windowresize",m_chartspaces);
4241
+ //console.log("windowresize",m_chartspaces);
4906
4242
  _this.drawChart();
4907
4243
  }
4908
4244
  });
@@ -6370,6 +5706,21 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
6370
5706
  // internal and external
6371
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
6372
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];
6373
5724
  case '222':
6374
5725
  case 'accountsreceivable':
6375
5726
  return [222, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
@@ -6795,9 +6146,18 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
6795
6146
  case '181':
6796
6147
  case 's4':
6797
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]; //
6798
6155
  case '393':
6799
6156
  case 's10':
6800
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
6801
6161
  case '127':
6802
6162
  case 'sales':
6803
6163
  return [127, 'numeric', 'right', widget.get_lang_text(name) || name, 8];