@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.
- package/millistream-widgets.js +185 -825
- package/package.json +2 -2
package/millistream-widgets.js
CHANGED
|
@@ -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
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
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')
|
|
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
|
|
560
|
+
else if (useCloseprice == false) {
|
|
1028
561
|
_this.instruments[s].startValue = price;
|
|
1029
562
|
}
|
|
1030
563
|
continue;
|
|
1031
564
|
}
|
|
1032
|
-
|
|
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
|
|
1053
|
-
|
|
1054
|
-
|
|
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 (
|
|
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 (
|
|
1097
|
-
|
|
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[
|
|
1107
|
-
if (data[s].datapoints[x] < scaleinfoY.lowValue)
|
|
1108
|
-
|
|
1109
|
-
|
|
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
|
|
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 <
|
|
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
|
-
|
|
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[
|
|
2784
|
+
m_ctx.moveTo(data[start].pos.x, data[start].pos.y);
|
|
3314
2785
|
let lastPos = null;
|
|
3315
|
-
for (var i =
|
|
3316
|
-
if (typeof data[i].pos === 'undefined')
|
|
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[
|
|
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
|
-
|
|
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 (
|
|
3796
|
-
if (
|
|
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
|
|
4311
|
-
if (
|
|
4312
|
-
if (
|
|
4313
|
-
|
|
4314
|
-
|
|
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']);
|
|
4506
|
-
data.open = parseFloat(json['12']);
|
|
4507
|
-
data.high = parseFloat(json['12']);
|
|
4508
|
-
data.low = parseFloat(json['12']);
|
|
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']);
|
|
4512
|
-
data.open = parseFloat(json['201']);
|
|
4513
|
-
data.high = parseFloat(json['201']);
|
|
4514
|
-
data.low = parseFloat(json['201']);
|
|
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];
|