@millistream/millistream-widgets 1.0.38 → 1.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/millistream-widgets.js +203 -811
- 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;
|
|
@@ -950,151 +629,13 @@ function Milli_Chart(settings) {
|
|
|
950
629
|
// do we have any analyzis we need to take into account
|
|
951
630
|
for (i = 0; i < _this.settings.indicators.length; i++) {
|
|
952
631
|
if (_this.settings.indicators[i].method == 'rsi') continue;
|
|
953
|
-
if (_this.settings.indicators[i].method == 'quantity') continue;
|
|
954
|
-
if (_this.settings.indicators[i].method == 'news') continue;
|
|
955
|
-
if (_this.settings.indicators[i].target == 'lower') continue;
|
|
956
|
-
if (!_this.settings.indicators[i].timeseries || _this.settings.indicators[i].timeseries.length == 0) {
|
|
957
|
-
continue;
|
|
958
|
-
}
|
|
959
|
-
data = _this.settings.indicators[i].timeseries;
|
|
960
|
-
for (s = 0; s < data.length; s++) {
|
|
961
|
-
if (data[s].timestamp < _this.scaleinfoX.startTimeStamp) {
|
|
962
|
-
continue;
|
|
963
|
-
}
|
|
964
|
-
if (data[s].timestamp > _this.scaleinfoX.endTimeStamp) {
|
|
965
|
-
break;
|
|
966
|
-
}
|
|
967
|
-
if (typeof data[s].datapoints !== 'undefined') {
|
|
968
|
-
for (var x = 0; x < data[s].datapoints.length; x++) {
|
|
969
|
-
if (data[s].datapoints[x] < scaleinfoY.lowValue) {
|
|
970
|
-
scaleinfoY.lowValue = data[s].datapoints[x];
|
|
971
|
-
scaleinfoY2.lowValue = data[s].datapoints[x] - _this.instruments[0].startValue; // lower min diff to get full legend from bottom
|
|
972
|
-
} else {
|
|
973
|
-
if (data[s].datapoints[x] > scaleinfoY.highValue) {
|
|
974
|
-
scaleinfoY.highValue = data[s].datapoints[x];
|
|
975
|
-
scaleinfoY2.highValue = data[s].datapoints[x] - _this.instruments[0].startValue; // lower min diff to get full legend from bottom
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
|
-
}
|
|
982
|
-
scaleinfoY2.lowValue = (scaleinfoY.lowValue - _this.instruments[0].startValue) / _this.instruments[0].startValue * 100;
|
|
983
|
-
scaleinfoY2.highValue = (scaleinfoY.highValue - _this.instruments[0].startValue) / _this.instruments[0].startValue * 100;
|
|
984
|
-
return 1;
|
|
985
|
-
}
|
|
986
|
-
/*function calcHighLow() {
|
|
987
|
-
scaleinfoY.lowValue = null;
|
|
988
|
-
scaleinfoY.highValue = null;
|
|
989
|
-
scaleinfoY2.lowValue = null;
|
|
990
|
-
scaleinfoY2.highValue = null;
|
|
991
|
-
scaleinfoY.lowLowerChart = null;
|
|
992
|
-
scaleinfoY.highLowerChart = null;
|
|
993
|
-
var data, i;
|
|
994
|
-
var useCloseprice = false;
|
|
995
|
-
var today = new Date().getTime();
|
|
996
|
-
today -= today % 86400000;
|
|
997
|
-
var lastTradeDate = new Date().getTime();
|
|
998
|
-
var todaysOpenTime = new Date(new Date().toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z').getTime();
|
|
999
|
-
if (typeof _this.instruments[0].trades !== 'undefined' && _this.instruments[0].trades.length > 0) {
|
|
1000
|
-
lastTradeDate = new Date(_this.instruments[0].trades[_this.instruments[0].trades.length - 1].timestamp).getTime();
|
|
1001
|
-
lastTradeDate -= lastTradeDate % 86400000;
|
|
1002
|
-
}
|
|
1003
|
-
var quote_timestamp = _this.instruments[0].quotedate + _this.instruments[0].quotetime;
|
|
1004
|
-
|
|
1005
|
-
if ((_this.instruments[0].quotedate == today && quote_timestamp > todaysOpenTime) || _this.instruments[0].quotedate == lastTradeDate) useCloseprice = true;
|
|
1006
|
-
for (var s = 0; s < _this.instruments.length; s++) {
|
|
1007
|
-
if (_this.instruments[s].insref == 0) continue;
|
|
1008
|
-
_this.instruments[s].startValue = null;
|
|
1009
|
-
data = _this.instruments[s][chartType];
|
|
1010
|
-
if (chartType != 'history' && useCloseprice) {
|
|
1011
|
-
if ((_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && !m_zoom.mousedown.timestamp) {
|
|
1012
|
-
_this.instruments[s].startValue = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
var quantity = 0;
|
|
1016
|
-
|
|
1017
|
-
for (i = 0; i < data.length; i++) {
|
|
1018
|
-
// only calc on visible data
|
|
1019
|
-
var price = data[i].price * _this.instruments[s].factor;
|
|
1020
|
-
quantity = 0;
|
|
1021
|
-
if (data[i].quantity !== 'undefined') {
|
|
1022
|
-
quantity = data[i].quantity;
|
|
1023
|
-
}
|
|
1024
|
-
if (data[i].timestamp < _this.scaleinfoX.startTimeStamp) {
|
|
1025
|
-
if (chartType == 'history') _this.instruments[s].startValue = price;
|
|
1026
|
-
//else if (_this.settings.chartlen != '1d' && _this.settings.chartlen != '0d' && !m_zoom.mousedown.timestamp) {
|
|
1027
|
-
else if (useCloseprice == false || m_zoom.mousedown.timestamp) {
|
|
1028
|
-
_this.instruments[s].startValue = price;
|
|
1029
|
-
}
|
|
1030
|
-
continue;
|
|
1031
|
-
}
|
|
1032
|
-
if (data[i].timestamp > _this.scaleinfoX.endTimeStamp) {
|
|
1033
|
-
break;
|
|
1034
|
-
}
|
|
1035
|
-
|
|
1036
|
-
if (chartType != 'history' && (data[i].timestamp % 86400000 < _this.instruments[0].opentimestamp || data[i].timestamp % 86400000 > _this.instruments[0].closetimestamp)) {
|
|
1037
|
-
// stämmer detta kan det bli överlapp vid sommartid/vintertid?
|
|
1038
|
-
continue;
|
|
1039
|
-
}
|
|
1040
|
-
|
|
1041
|
-
if (_this.instruments[s].startValue == null) {
|
|
1042
|
-
if (chartType == 'history') {
|
|
1043
|
-
_this.instruments[s].startValue = price;
|
|
1044
|
-
} else {
|
|
1045
|
-
if (isToday(new Date(data[i].timestamp)) && !m_zoom.mousedown.timestamp) {
|
|
1046
|
-
_this.instruments[s].startValue = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
|
|
1047
|
-
} else {
|
|
1048
|
-
_this.instruments[s].startValue = price;
|
|
1049
|
-
}
|
|
1050
|
-
}
|
|
1051
|
-
}
|
|
1052
|
-
if (scaleinfoY.lowValue == null || scaleinfoY.lowValue > price) scaleinfoY.lowValue = price;
|
|
1053
|
-
if (scaleinfoY.highValue == null || scaleinfoY.highValue < price) scaleinfoY.highValue = price;
|
|
1054
|
-
var diff = (price - _this.instruments[s].startValue);
|
|
1055
|
-
if (diff != 0) diff = diff / _this.instruments[s].startValue * 100;
|
|
1056
|
-
if (_this.instruments[s].startValue == null) diff = 0;
|
|
1057
|
-
data[i].diff = diff;
|
|
1058
|
-
|
|
1059
|
-
if (scaleinfoY2.lowValue == null || scaleinfoY2.lowValue > diff) scaleinfoY2.lowValue = diff;
|
|
1060
|
-
if (scaleinfoY2.highValue == null || scaleinfoY2.highValue < diff) scaleinfoY2.highValue = diff;
|
|
1061
|
-
if (scaleinfoY.lowLowerChart == null || scaleinfoY.lowLowerChart > quantity) scaleinfoY.lowLowerChart = quantity;
|
|
1062
|
-
if (scaleinfoY.highLowerChart == null || scaleinfoY.highLowerChart < quantity) scaleinfoY.highLowerChart = quantity;
|
|
1063
|
-
}
|
|
1064
|
-
if ((_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && !m_zoom.mousedown.timestamp) { // if closeprice is used calch high/low on it
|
|
1065
|
-
var cp = parseFloat(_this.instruments[s].closeprice1d) * _this.instruments[s].factor;
|
|
1066
|
-
if (scaleinfoY.lowValue > cp) scaleinfoY.lowValue = cp;
|
|
1067
|
-
else
|
|
1068
|
-
if (scaleinfoY.highValue < cp) scaleinfoY.highValue = cp;
|
|
1069
|
-
}
|
|
1070
|
-
if (chartType != 'history') {
|
|
1071
|
-
if (scaleinfoY2.lowValue > 0) {
|
|
1072
|
-
scaleinfoY2.lowValue = 0;
|
|
1073
|
-
} else {
|
|
1074
|
-
if (scaleinfoY2.highValue < 0) scaleinfoY2.highValue = 0;
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
if (_this.instruments[s].startValue) {
|
|
1078
|
-
if (_this.instruments[s].startValue > scaleinfoY.highValue) scaleinfoY.highValue = _this.instruments[s].startValue;
|
|
1079
|
-
if (_this.instruments[s].startValue < scaleinfoY.lowValue) scaleinfoY.lowValue = _this.instruments[s].startValue;
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
if (scaleinfoY.lowValue == null) {
|
|
1084
|
-
scaleinfoY.lowValue = 0;
|
|
1085
|
-
scaleinfoY.highValue = 100;
|
|
1086
|
-
scaleinfoY2.lowValue = 0;
|
|
1087
|
-
scaleinfoY2.highValue = 100;
|
|
1088
|
-
} else
|
|
1089
|
-
if (scaleinfoY.lowValue == scaleinfoY.highValue && scaleinfoY.lowValue == 0) {
|
|
1090
|
-
scaleinfoY.lowValue -= 1;
|
|
1091
|
-
scaleinfoY.highValue += 1;
|
|
1092
|
-
}
|
|
1093
|
-
console.log(_this.settings.indicators);
|
|
1094
|
-
// do we have any analyzis we need to take into account
|
|
1095
|
-
for (i = 0; i < _this.settings.indicators.length; i++) {
|
|
1096
|
-
if (chartType == 'history') data = _this.settings.indicators[i].history;
|
|
1097
|
-
else data = _this.settings.indicators[i].trades;
|
|
632
|
+
if (_this.settings.indicators[i].method == 'quantity') continue;
|
|
633
|
+
if (_this.settings.indicators[i].method == 'news') continue;
|
|
634
|
+
if (_this.settings.indicators[i].target == 'lower') continue;
|
|
635
|
+
if (!_this.settings.indicators[i].timeseries || _this.settings.indicators[i].timeseries.length == 0) {
|
|
636
|
+
continue;
|
|
637
|
+
}
|
|
638
|
+
data = _this.settings.indicators[i].timeseries;
|
|
1098
639
|
for (s = 0; s < data.length; s++) {
|
|
1099
640
|
if (data[s].timestamp < _this.scaleinfoX.startTimeStamp) {
|
|
1100
641
|
continue;
|
|
@@ -1103,10 +644,16 @@ function Milli_Chart(settings) {
|
|
|
1103
644
|
break;
|
|
1104
645
|
}
|
|
1105
646
|
if (typeof data[s].datapoints !== 'undefined') {
|
|
1106
|
-
for (var x = 0; x < data[
|
|
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;
|
|
@@ -1145,7 +692,6 @@ function Milli_Chart(settings) {
|
|
|
1145
692
|
var count = 0;
|
|
1146
693
|
for (;;) {
|
|
1147
694
|
if (count++ > 10) {
|
|
1148
|
-
console.log('break out');
|
|
1149
695
|
break;
|
|
1150
696
|
}
|
|
1151
697
|
var v;
|
|
@@ -1206,7 +752,7 @@ function Milli_Chart(settings) {
|
|
|
1206
752
|
si.valuePerPixel = (si.maxValue - si.minValue) / si.lineLength;
|
|
1207
753
|
|
|
1208
754
|
if (isNaN(si.valuePerPixel) || !isFinite(si.valuePerPixel)) {
|
|
1209
|
-
console.log('cant draw valuePerPixel', si.valuePerPixel, si.lineLength, si.maxValue, si.minValue);
|
|
755
|
+
console.log('cant draw valuePerPixel', si.valuePerPixel, si.lineLength, si.maxValue, si.minValue,si.highValue,si.lowValue,m_yLegendCss,v);
|
|
1210
756
|
return false;
|
|
1211
757
|
}
|
|
1212
758
|
var textpos;
|
|
@@ -1367,75 +913,6 @@ function Milli_Chart(settings) {
|
|
|
1367
913
|
return true;
|
|
1368
914
|
}
|
|
1369
915
|
|
|
1370
|
-
function drawYAxisNew(scale, cs, css, drawAxis, gridLines, factor) {
|
|
1371
|
-
/*let scale = {};
|
|
1372
|
-
if (false == calcHighLow2(scale, factor)) {
|
|
1373
|
-
console.log('fail highlow');
|
|
1374
|
-
return;
|
|
1375
|
-
}*/
|
|
1376
|
-
m_ctx.save();
|
|
1377
|
-
m_ctx.strokeStyle = m_gridHorizontalCss.color;
|
|
1378
|
-
m_ctx.font = css.fontWeight + ' ' + css.fontSize + ' ' + css.fontFamily;
|
|
1379
|
-
m_ctx.fillStyle = css.color;
|
|
1380
|
-
scale.lineLength = cs.bottom - cs.top;
|
|
1381
|
-
/* let numticks = scale.lineLength / (getFontSize(css) * _this.settings.yAxisSpacing);
|
|
1382
|
-
if (numticks > 8) numticks = 8; // limit to 8 items on Y legend ( this is not an absolut count, since we calculate nice legend numbers
|
|
1383
|
-
scale.tickSize = getTickValue(scale.lowValue, scale.highValue, numticks);
|
|
1384
|
-
scale.decimals = scale.tickSize.countDecimals();*/
|
|
1385
|
-
//scale.decimals > 4 ? 4 : (scale.decimals < 2 ? 2 : scale.decimals);
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
/* let widestValue = (scale.lowValue < 0 ? '-' : '') + Math.max(Math.abs(scale.highValue), Math.abs(scale.lowValue));
|
|
1391
|
-
let label = formatNiceNumber(widestValue, _this.settings.thousandseparator, _this.settings.decimalseparator, scale.decimals);
|
|
1392
|
-
console.log('testw', label, )
|
|
1393
|
-
if (drawAxis) {
|
|
1394
|
-
if (css.float != 'right') {
|
|
1395
|
-
cs.left = 10 + Math.round(m_ctx.measureText(label).width); // + 'px'; // räkna fram hur hur mycket plats Y värdena tar och sätt margin till det, skall vi göra så?
|
|
1396
|
-
} else {
|
|
1397
|
-
if (css.textAlign == 'right') {
|
|
1398
|
-
cs.right = m_canvas.getWidth() - (10 + Math.round(m_ctx.measureText(label).width)); // + 'px'; // räkna fram hur hur mycket plats Y värdena tar och sätt margin till det, skall vi göra så?
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
|
-
}
|
|
1402
|
-
*/
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
if (css.float != 'right' && drawAxis) { // do we need to add space for half a date? ie prices are to tiny so date will be trunkated
|
|
1408
|
-
m_ctx.save();
|
|
1409
|
-
m_ctx.font = m_xLegendCss.fontWeight + ' ' + m_xLegendCss.fontSize + ' ' + m_xLegendCss.fontFamily;
|
|
1410
|
-
if (getStringWidth(m_ctx, _this.settings.dateformat) / 2 + 5 > cs.left) {
|
|
1411
|
-
cs.left = getStringWidth(m_ctx, _this.settings.dateformat) / 2 + 5;
|
|
1412
|
-
}
|
|
1413
|
-
m_ctx.restore();
|
|
1414
|
-
}
|
|
1415
|
-
// draw line
|
|
1416
|
-
m_ctx.strokeStyle = m_gridVerticalCss.color;
|
|
1417
|
-
m_ctx.beginPath();
|
|
1418
|
-
m_ctx.moveTo(cs.left + 0.5, cs.top);
|
|
1419
|
-
m_ctx.lineTo(cs.left + 0.5, cs.height - cs.marginBottom);
|
|
1420
|
-
m_ctx.stroke();
|
|
1421
|
-
m_ctx.closePath();
|
|
1422
|
-
m_ctx.strokeStyle = m_gridHorizontalCss.color;
|
|
1423
|
-
var x;
|
|
1424
|
-
if (css.float == 'right')
|
|
1425
|
-
x = cs.right;
|
|
1426
|
-
else
|
|
1427
|
-
x = cs.left;
|
|
1428
|
-
if (css.textAlign == 'right') {
|
|
1429
|
-
m_ctx.textAlign = 'left';
|
|
1430
|
-
drawYLegendNew(scale, cs, x, css, drawAxis, gridLines, factor);
|
|
1431
|
-
} else {
|
|
1432
|
-
m_ctx.textAlign = 'right';
|
|
1433
|
-
drawYLegendNew(scale, cs, x, css, drawAxis, gridLines), factor;
|
|
1434
|
-
}
|
|
1435
|
-
m_ctx.restore();
|
|
1436
|
-
return scale;
|
|
1437
|
-
}
|
|
1438
|
-
|
|
1439
916
|
function drawYAxis(scaleinfoY, scaleinfoY2) {
|
|
1440
917
|
m_ctx.save();
|
|
1441
918
|
m_ctx.strokeStyle = m_gridHorizontalCss.color;
|
|
@@ -2412,6 +1889,11 @@ function Milli_Chart(settings) {
|
|
|
2412
1889
|
_this.settings.indicators[x].toolTip.div.style.left = _this.settings.indicators[x].timeseries[xx].pos.x / 1 + (pointerWidth / 2) + 'px'; // this i modified in the data for the instruments, but not for indicators
|
|
2413
1890
|
_this.settings.indicators[x].toolTip.div.style.top = _this.settings.indicators[x].timeseries[xx].pos.y / 1 + 'px'; // this i modified in the data for the instruments, but not for indicators
|
|
2414
1891
|
_this.settings.indicators[x].toolTip.div.innerHTML = _this.settings.indicators[x].toolTip.formatter.call(_this.settings.indicators[x].timeseries[xx]);
|
|
1892
|
+
|
|
1893
|
+
if (y >= _this.settings.indicators[x].timeseries[xx].pos.y && y <= _this.settings.indicators[x].timeseries[xx].pos.y + width)
|
|
1894
|
+
m_canvas.style.cursor = "pointer";
|
|
1895
|
+
else
|
|
1896
|
+
m_canvas.style.cursor = "crosshair";
|
|
2415
1897
|
remove = false;
|
|
2416
1898
|
toolArray.push({ top: parseInt(_this.settings.indicators[x].toolTip.div.style.top), indicator: x });
|
|
2417
1899
|
}
|
|
@@ -2421,6 +1903,7 @@ function Milli_Chart(settings) {
|
|
|
2421
1903
|
if (_this.settings.indicators[x].toolTip.div && _this.settings.indicators[x].staticTooltip != true) {
|
|
2422
1904
|
_this.settings.indicators[x].toolTip.div.parentNode.removeChild(_this.settings.indicators[x].toolTip.div);
|
|
2423
1905
|
_this.settings.indicators[x].toolTip.div = undefined;
|
|
1906
|
+
m_canvas.style.cursor = "crosshair";
|
|
2424
1907
|
}
|
|
2425
1908
|
|
|
2426
1909
|
}
|
|
@@ -2582,7 +2065,7 @@ function Milli_Chart(settings) {
|
|
|
2582
2065
|
_this.settings.indicators[i].timeseries = calculateBollingerBands(_this.instruments[0].trades, _this.settings.indicators[i].method_length, _this.settings.indicators[i].stddev | 2);
|
|
2583
2066
|
break;
|
|
2584
2067
|
case 'news':
|
|
2585
|
-
_this.settings.indicators[i].timeseries = calculateNews(_this.settings.indicators[i].news
|
|
2068
|
+
_this.settings.indicators[i].timeseries = calculateNews(_this.settings.indicators[i].news);
|
|
2586
2069
|
break;
|
|
2587
2070
|
// future events osv?
|
|
2588
2071
|
default:
|
|
@@ -2780,29 +2263,6 @@ function Milli_Chart(settings) {
|
|
|
2780
2263
|
if (false == checkChartData(_this.instruments[0].history)) return;
|
|
2781
2264
|
calculateIndicators();
|
|
2782
2265
|
|
|
2783
|
-
/*let scaleY = {};
|
|
2784
|
-
if (_this.settings.drawyaxis) {
|
|
2785
|
-
if (false == calcHighLow2(scaleY, m_chartspaces.chart, m_yLegendCss)) {
|
|
2786
|
-
console.log('fail highlow');
|
|
2787
|
-
return;
|
|
2788
|
-
}
|
|
2789
|
-
}
|
|
2790
|
-
let scaleY2 = {};
|
|
2791
|
-
let factorInfo = {
|
|
2792
|
-
name: 'diff',
|
|
2793
|
-
actor: _this.instruments[0].startValue,
|
|
2794
|
-
suffix: '%'
|
|
2795
|
-
};
|
|
2796
|
-
if (_this.settings.drawy2axis) {
|
|
2797
|
-
if (false == calcHighLow2(scaleY2, m_chartspaces.chart, m_y2LegendCss, factorInfo)) {
|
|
2798
|
-
console.log('fail highlow');
|
|
2799
|
-
return;
|
|
2800
|
-
}
|
|
2801
|
-
}
|
|
2802
|
-
|
|
2803
|
-
drawYAxisNew(scaleY, m_chartspaces.chart, m_yLegendCss, _this.settings.drawyaxis, _this.settings.gridHorizontalLines);
|
|
2804
|
-
drawYAxisNew(scaleY2, m_chartspaces.chart, m_y2LegendCss, _this.settings.drawy2axis, false, factorInfo); *
|
|
2805
|
-
*/
|
|
2806
2266
|
drawYAxis(scaleinfoY, scaleinfoY2);
|
|
2807
2267
|
drawXAxisMonth(_this.scaleinfoX.startTimeStamp, _this.scaleinfoX.endTimeStamp);
|
|
2808
2268
|
|
|
@@ -2944,6 +2404,7 @@ function Milli_Chart(settings) {
|
|
|
2944
2404
|
case 'rsi':
|
|
2945
2405
|
if (chartType == 'history') _this.settings.indicators[i].timeseries = calculateRSI(_this.instruments[0].history, _this.settings.indicators[i].method_length);
|
|
2946
2406
|
else _this.settings.indicators[i].timeseries = calculateRSI(_this.instruments[0].trades, _this.settings.indicators[i].method_length);
|
|
2407
|
+
console.log(_this.settings.indicators[i].timeseries);
|
|
2947
2408
|
if (_this.settings.indicators[i].target == 'upper') {
|
|
2948
2409
|
lowerScale = drawYAxisIndicator(_this.settings.indicators[i].timeseries, m_chartspaces.chart, false);
|
|
2949
2410
|
plotIndicatorLine(_this.settings.indicators[i], lowerScale, m_chartspaces.chart);
|
|
@@ -3177,27 +2638,31 @@ function Milli_Chart(settings) {
|
|
|
3177
2638
|
var startpoint = { x: 0, y: 0 };
|
|
3178
2639
|
var endpoint = { x: 0, y: 0 };
|
|
3179
2640
|
var startDate = _this.scaleinfoX.startTimeStamp;
|
|
3180
|
-
var len = data.length;
|
|
3181
2641
|
var lastdate = new Date(_this.scaleinfoX.startTimeStamp);
|
|
3182
2642
|
var offset = 0;
|
|
3183
2643
|
var maxy = 0;
|
|
3184
2644
|
var ret = [];
|
|
3185
2645
|
let num = 0;
|
|
3186
|
-
for (var i = 0; i <
|
|
2646
|
+
for (var i = 0; i < data.length; i++) {
|
|
3187
2647
|
var currentDate;
|
|
3188
2648
|
var tmpx = startpoint.x;
|
|
3189
2649
|
var tmp;
|
|
3190
|
-
var timestamp = data[i].timestamp;
|
|
2650
|
+
var timestamp = typeof data[i].newstimestamp !== 'undefined' ? data[i].newstimestamp : data[i].timestamp;
|
|
3191
2651
|
if (chartType == 'history') timestamp -= (timestamp % 86400000)
|
|
3192
2652
|
if (timestamp < _this.scaleinfoX.startTimeStamp) {
|
|
3193
2653
|
continue;
|
|
3194
2654
|
}
|
|
3195
2655
|
if (timestamp > _this.scaleinfoX.endTimeStamp) {
|
|
3196
|
-
|
|
3197
|
-
|
|
2656
|
+
data.splice(i,1);
|
|
2657
|
+
i--;
|
|
2658
|
+
continue;
|
|
3198
2659
|
}
|
|
3199
2660
|
|
|
3200
|
-
if (chartType != 'history' && (data[i].timestamp % 86400000 < _this.instruments[0].opentimestamp || data[i].timestamp % 86400000 > _this.instruments[0].closetimestamp)) {
|
|
2661
|
+
//if (chartType != 'history' && (data[i].timestamp % 86400000 < _this.instruments[0].opentimestamp || data[i].timestamp % 86400000 > _this.instruments[0].closetimestamp)) {
|
|
2662
|
+
if (chartType != 'history' && (timestamp % 86400000 < _this.instruments[0].opentimestamp || timestamp % 86400000 > _this.instruments[0].closetimestamp)) {
|
|
2663
|
+
// data outside tradinghours, removed from data so we do not get data entries without pos
|
|
2664
|
+
data.splice(i,1);
|
|
2665
|
+
i--;
|
|
3201
2666
|
continue;
|
|
3202
2667
|
}
|
|
3203
2668
|
var endtimeToday = new Date(timestamp);
|
|
@@ -3305,6 +2770,10 @@ function Milli_Chart(settings) {
|
|
|
3305
2770
|
let data = method.timeseries;
|
|
3306
2771
|
let num = calcAnalyzisLine(data, 0, undefined, cs, scale);
|
|
3307
2772
|
if (num == 0) return;
|
|
2773
|
+
let start = data.length-1;
|
|
2774
|
+
while(start > 0 && typeof data[start].pos === 'undefined') start--;
|
|
2775
|
+
if(start < 0) return;
|
|
2776
|
+
|
|
3308
2777
|
m_ctx.save();
|
|
3309
2778
|
m_ctx.beginPath();
|
|
3310
2779
|
m_ctx.closePath();
|
|
@@ -3312,10 +2781,13 @@ function Milli_Chart(settings) {
|
|
|
3312
2781
|
m_ctx.strokeStyle = method.color;
|
|
3313
2782
|
if (typeof method.lineStyle === 'string' && method.lineStyle == 'dash') m_ctx.setLineDash([3, 3]);
|
|
3314
2783
|
|
|
3315
|
-
m_ctx.moveTo(data[
|
|
2784
|
+
m_ctx.moveTo(data[start].pos.x, data[start].pos.y);
|
|
3316
2785
|
let lastPos = null;
|
|
3317
|
-
for (var i =
|
|
3318
|
-
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
|
+
}
|
|
3319
2791
|
m_ctx.lineTo(data[i].pos.x, data[i].pos.y);
|
|
3320
2792
|
lastPos = data[i].pos;
|
|
3321
2793
|
}
|
|
@@ -3325,7 +2797,7 @@ function Milli_Chart(settings) {
|
|
|
3325
2797
|
}
|
|
3326
2798
|
if (typeof method.callback === 'function') method.callback.call({ x: data[data.length - 1].pos.x, y: data[data.length - 1].pos.y });
|
|
3327
2799
|
m_ctx.stroke();
|
|
3328
|
-
m_ctx.lineTo(data[
|
|
2800
|
+
m_ctx.lineTo(data[start].pos.x, cs.bottom);
|
|
3329
2801
|
m_ctx.restore();
|
|
3330
2802
|
}
|
|
3331
2803
|
|
|
@@ -3371,11 +2843,11 @@ function Milli_Chart(settings) {
|
|
|
3371
2843
|
if (fabs(lastPos.x - data[i].pos.x) > width || fabs(lastPos.y > data[i].pos.y) > width) {
|
|
3372
2844
|
m_ctx.fillText(method.indicator, data[i].pos.x - (width / 2), data[i].pos.y);
|
|
3373
2845
|
lastPos = { x: data[i].pos.x, y: data[i].y };
|
|
3374
|
-
method.timeseries[i].hl = [{ timestamp: data[i].timestamp, headline: data[i].headline }];
|
|
2846
|
+
method.timeseries[i].hl = [{ timestamp: data[i].timestamp, headline: data[i].headline,newsid: data[i].newsid }];
|
|
3375
2847
|
hlPos = i;
|
|
3376
2848
|
|
|
3377
2849
|
} else {
|
|
3378
|
-
method.timeseries[hlPos].hl.push({ timestamp: data[i].timestamp, headline: data[i].headline });
|
|
2850
|
+
method.timeseries[hlPos].hl.push({ timestamp: data[i].timestamp, headline: data[i].headline,newsid: data[i].newsid });
|
|
3379
2851
|
}
|
|
3380
2852
|
} else m_ctx.fillText(method.indicator, data[i].pos.x - (width / 2), data[i].pos.y);
|
|
3381
2853
|
|
|
@@ -3389,29 +2861,56 @@ function Milli_Chart(settings) {
|
|
|
3389
2861
|
m_ctx.strokeStyle = method.color;
|
|
3390
2862
|
m_ctx.lineWidth = method.lineWidth | 1;
|
|
3391
2863
|
m_ctx.save();
|
|
2864
|
+
|
|
2865
|
+
// draw upper
|
|
3392
2866
|
m_ctx.beginPath();
|
|
2867
|
+
m_ctx.closePath();
|
|
3393
2868
|
let num = calcAnalyzisLine(data, 0, undefined, m_chartspaces.chart, scaleinfoY);
|
|
2869
|
+
m_ctx.moveTo(data[data.length - 1].pos.x, data[data.length - 1].pos.y);
|
|
3394
2870
|
for (let i = data.length - 1; i >= data.length - num; i--) {
|
|
3395
2871
|
m_ctx.lineTo(data[i].pos.x, data[i].pos.y);
|
|
3396
2872
|
}
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
m_ctx.lineTo(data[i].pos.x, data[i].pos.y);
|
|
3401
|
-
}
|
|
3402
|
-
m_ctx.closePath();
|
|
2873
|
+
m_ctx.stroke();
|
|
2874
|
+
|
|
2875
|
+
// draw the fill area
|
|
3403
2876
|
if (method.fill) {
|
|
2877
|
+
m_ctx.beginPath();
|
|
2878
|
+
m_ctx.moveTo(data[data.length - 1].pos.x, data[data.length - 1].pos.y);
|
|
2879
|
+
for (let i = data.length - 1; i >= data.length - num; i--) {
|
|
2880
|
+
m_ctx.lineTo(data[i].pos.x, data[i].pos.y);
|
|
2881
|
+
}
|
|
2882
|
+
|
|
2883
|
+
num = calcAnalyzisLine(data, 1, undefined, m_chartspaces.chart, scaleinfoY);
|
|
2884
|
+
|
|
2885
|
+
m_ctx.lineTo(data[data.length - num].pos.x, data[data.length - num].pos.y); // behöver döljas...
|
|
2886
|
+
for (let i = data.length - num +1; i < data.length; i++) {
|
|
2887
|
+
m_ctx.lineTo(data[i].pos.x, data[i].pos.y);
|
|
2888
|
+
}
|
|
2889
|
+
|
|
2890
|
+
m_ctx.closePath();
|
|
2891
|
+
|
|
3404
2892
|
m_ctx.fillStyle = method.fill;
|
|
3405
2893
|
m_ctx.fill();
|
|
3406
2894
|
}
|
|
3407
|
-
|
|
2895
|
+
// draw Lower
|
|
2896
|
+
m_ctx.beginPath();
|
|
2897
|
+
m_ctx.closePath();
|
|
2898
|
+
m_ctx.moveTo(data[data.length - num].pos.x, data[data.length - num].pos.y); // behöver döljas...
|
|
2899
|
+
for (let i = data.length - num; i < data.length; i++) {
|
|
2900
|
+
m_ctx.lineTo(data[i].pos.x, data[i].pos.y);
|
|
2901
|
+
}
|
|
2902
|
+
m_ctx.stroke();
|
|
2903
|
+
|
|
2904
|
+
// draw middle
|
|
3408
2905
|
m_ctx.beginPath();
|
|
3409
|
-
m_ctx.closePath();
|
|
2906
|
+
m_ctx.closePath();
|
|
2907
|
+
num = calcAnalyzisLine(data, 2, undefined, m_chartspaces.chart, scaleinfoY);
|
|
3410
2908
|
m_ctx.moveTo(data[data.length - num].x, data[data.length - num].y);
|
|
3411
2909
|
for (let i = data.length - num; i < data.length; i++) {
|
|
3412
2910
|
m_ctx.lineTo(data[i].pos.x, data[i].pos.y);
|
|
3413
2911
|
}
|
|
3414
2912
|
m_ctx.stroke();
|
|
2913
|
+
|
|
3415
2914
|
m_ctx.restore();
|
|
3416
2915
|
return;
|
|
3417
2916
|
}
|
|
@@ -3482,8 +2981,6 @@ function Milli_Chart(settings) {
|
|
|
3482
2981
|
var hCurveLastPoint = null;
|
|
3483
2982
|
var quantity = 0;
|
|
3484
2983
|
var nextDate;
|
|
3485
|
-
var firstDataPoint = null;
|
|
3486
|
-
var lastDataPoint = null;
|
|
3487
2984
|
|
|
3488
2985
|
var today = new Date().getTime();
|
|
3489
2986
|
today -= today % 86400000;
|
|
@@ -3757,30 +3254,40 @@ function Milli_Chart(settings) {
|
|
|
3757
3254
|
let timeseries = [];
|
|
3758
3255
|
for (let i = 0; i < data.length; i++) {
|
|
3759
3256
|
let s = 0;
|
|
3760
|
-
|
|
3257
|
+
let newstimestamp = data[i].timestamp;
|
|
3258
|
+
if(data[i].timestamp < (data[i].timestamp - (data[i].timestamp % 86400000) + _this.instruments[0].opentimestamp)) {
|
|
3259
|
+
newstimestamp = data[i].timestamp - (data[i].timestamp % 86400000) + _this.instruments[0].opentimestamp;
|
|
3260
|
+
console.log('1', new Date(data[i].timestamp),new Date(newstimestamp));
|
|
3261
|
+
} else if(data[i].timestamp > (data[i].timestamp - (data[i].timestamp % 86400000) + _this.instruments[0].closetimestamp)) {
|
|
3262
|
+
newstimestamp = data[i].timestamp - (data[i].timestamp % 86400000) + _this.instruments[0].closetimestamp;
|
|
3263
|
+
console.log('2', new Date(data[i].timestamp),new Date(newstimestamp));
|
|
3264
|
+
}
|
|
3265
|
+
if (newstimestamp >= _this.scaleinfoX.startTimeStamp) {
|
|
3761
3266
|
let item = null;
|
|
3762
3267
|
for (s; s < _this.instruments[0][chartType].length; s++) {
|
|
3763
3268
|
if (chartType == 'history') {
|
|
3764
3269
|
if ((data[i].timestamp - (data[i].timestamp % 86400000)) < _this.instruments[0].history[s].timestamp) break;
|
|
3765
3270
|
if ((data[i].timestamp - (data[i].timestamp % 86400000)) >= _this.instruments[0].history[s].timestamp) {
|
|
3766
3271
|
item = data[i];
|
|
3272
|
+
item.newstimestamp = newstimestamp;
|
|
3767
3273
|
item.datapoints = [_this.instruments[0].history[s].price];
|
|
3768
3274
|
}
|
|
3769
3275
|
} else {
|
|
3770
|
-
if (
|
|
3771
|
-
if (
|
|
3276
|
+
if (newstimestamp < _this.instruments[0].trades[s].timestamp) break;
|
|
3277
|
+
if (newstimestamp >= _this.instruments[0].trades[s].timestamp) {
|
|
3772
3278
|
item = data[i];
|
|
3279
|
+
item.newstimestamp = newstimestamp;
|
|
3773
3280
|
item.datapoints = [_this.instruments[0].trades[s].price];
|
|
3774
3281
|
}
|
|
3775
3282
|
}
|
|
3776
3283
|
}
|
|
3777
|
-
timeseries.push(item);
|
|
3284
|
+
if(item) timeseries.push(item);
|
|
3778
3285
|
}
|
|
3779
3286
|
}
|
|
3287
|
+
console.log(timeseries);
|
|
3780
3288
|
return timeseries;
|
|
3781
3289
|
}
|
|
3782
3290
|
|
|
3783
|
-
|
|
3784
3291
|
function calculateBollingerBands(prices, window, stddev) {
|
|
3785
3292
|
// borde returnera ett object med high/low också
|
|
3786
3293
|
|
|
@@ -3826,29 +3333,6 @@ function Milli_Chart(settings) {
|
|
|
3826
3333
|
return simpleMovingAverages;
|
|
3827
3334
|
}
|
|
3828
3335
|
|
|
3829
|
-
|
|
3830
|
-
/*function simpleMovingAverage(prices, window, n = Infinity) {
|
|
3831
|
-
// borde returnera ett object med high/low också
|
|
3832
|
-
if (!prices || prices.length < window) {
|
|
3833
|
-
return [];
|
|
3834
|
-
}
|
|
3835
|
-
let index = window - 1;
|
|
3836
|
-
const length = prices.length + 1;
|
|
3837
|
-
const simpleMovingAverages = [];
|
|
3838
|
-
let numberOfSMAsCalculated = 0;
|
|
3839
|
-
const today = new Date().getTime();
|
|
3840
|
-
const startDate = _this.scaleinfoX.startTimeStamp - (window * 86400000);
|
|
3841
|
-
while (++index < length && numberOfSMAsCalculated < n) {
|
|
3842
|
-
const windowSlice = prices.slice(index - window, index);
|
|
3843
|
-
if (windowSlice[window - 1].timestamp > startDate) {
|
|
3844
|
-
const sum = windowSlice.reduce((prev, curr) => prev + curr.price, 0);
|
|
3845
|
-
simpleMovingAverages.push({ timestamp: prices[index - 1].timestamp, datapoints: [sum / window] });
|
|
3846
|
-
numberOfSMAsCalculated++;
|
|
3847
|
-
}
|
|
3848
|
-
if (typeof prices[index] == 'undefined' || prices[index].timestamp > today) break;
|
|
3849
|
-
}
|
|
3850
|
-
return simpleMovingAverages;
|
|
3851
|
-
}*/
|
|
3852
3336
|
function exponentialMovingAverage(prices, window) {
|
|
3853
3337
|
if (!prices || prices.length < window) {
|
|
3854
3338
|
return [];
|
|
@@ -3871,49 +3355,6 @@ function Milli_Chart(settings) {
|
|
|
3871
3355
|
return exponentialMovingAverages;
|
|
3872
3356
|
}
|
|
3873
3357
|
|
|
3874
|
-
/*function exponentialMovingAverage(prices, window) {
|
|
3875
|
-
if (!prices || prices.length < window) {
|
|
3876
|
-
return [];
|
|
3877
|
-
}
|
|
3878
|
-
let index = window - 1;
|
|
3879
|
-
let previousEmaIndex = 0;
|
|
3880
|
-
const length = prices.length;
|
|
3881
|
-
const smoothingFactor = 2 / (window + 1);
|
|
3882
|
-
const exponentialMovingAverages = [];
|
|
3883
|
-
|
|
3884
|
-
const [sma] = simpleMovingAverage(prices, window, 1);
|
|
3885
|
-
exponentialMovingAverages.push(sma);
|
|
3886
|
-
|
|
3887
|
-
while (++index < length) {
|
|
3888
|
-
const value = prices[index].price;
|
|
3889
|
-
const previousEma = [exponentialMovingAverages[previousEmaIndex++].datapoints[0]];
|
|
3890
|
-
const currentEma = (value * smoothingFactor) + (previousEma * (1 - smoothingFactor));
|
|
3891
|
-
exponentialMovingAverages.push({ timestamp: prices[index].timestamp, datapoints: [currentEma] });
|
|
3892
|
-
}
|
|
3893
|
-
return exponentialMovingAverages;
|
|
3894
|
-
}*/
|
|
3895
|
-
|
|
3896
|
-
function bollingerBands(prices, window, stddev) {
|
|
3897
|
-
if (!prices || prices.length < window) {
|
|
3898
|
-
return [];
|
|
3899
|
-
}
|
|
3900
|
-
|
|
3901
|
-
let index = window - 1;
|
|
3902
|
-
const length = prices.length + 1;
|
|
3903
|
-
const standardDeviations = [];
|
|
3904
|
-
while (++index < length) {
|
|
3905
|
-
const windowSlice = prices.slice(index - window, index);
|
|
3906
|
-
const mean = windowSlice.reduce((prev, curr) => prev + curr.price, 0) / window;
|
|
3907
|
-
const variance = Math.sqrt(windowSlice.reduce((a, b) => a + (b.price - mean) ** 2, 0) / window) * stddev;
|
|
3908
|
-
const uppervariance = mean + variance;
|
|
3909
|
-
const lowervariance = mean - variance;
|
|
3910
|
-
standardDeviations.push({ timestamp: prices[index - 1].timestamp, datapoints: [uppervariance, lowervariance, mean] });
|
|
3911
|
-
if (typeof prices[index] == 'undefined' || prices[index].timestamp > new Date().getTime()) break;
|
|
3912
|
-
}
|
|
3913
|
-
return standardDeviations;
|
|
3914
|
-
}
|
|
3915
|
-
|
|
3916
|
-
|
|
3917
3358
|
function calculateRSI(p, window) {
|
|
3918
3359
|
// borde returnera ett object med high/low också
|
|
3919
3360
|
let rsi = [];
|
|
@@ -3958,9 +3399,9 @@ function Milli_Chart(settings) {
|
|
|
3958
3399
|
rsi.push({ timestamp: p[i].timestamp, datapoints: [100 - 100 / (1 + rs)] });
|
|
3959
3400
|
}
|
|
3960
3401
|
}
|
|
3961
|
-
console.log('RSI',rsi[rsi.length-1]);
|
|
3962
3402
|
return rsi;
|
|
3963
3403
|
}
|
|
3404
|
+
|
|
3964
3405
|
_this.removeAllIndicators = function(j) {
|
|
3965
3406
|
_this.settings.indicators = [];
|
|
3966
3407
|
_this.drawChart();
|
|
@@ -4041,95 +3482,6 @@ function Milli_Chart(settings) {
|
|
|
4041
3482
|
_this.drawChart();
|
|
4042
3483
|
};
|
|
4043
3484
|
|
|
4044
|
-
/*_this.addIndicator = function(method) {
|
|
4045
|
-
if (typeof method !== 'object' || method == null || typeof method.type == undefined) return;
|
|
4046
|
-
if (indicatorAlreadyExists(method)) return;
|
|
4047
|
-
|
|
4048
|
-
switch (method.method) {
|
|
4049
|
-
case 'sma':
|
|
4050
|
-
{
|
|
4051
|
-
if (typeof method.method_length !== 'number') return;
|
|
4052
|
-
method.history = simpleMovingAverage(_this.instruments[0].history, method.method_length);
|
|
4053
|
-
method.trades = simpleMovingAverage(_this.instruments[0].trades, method.method_length);
|
|
4054
|
-
}
|
|
4055
|
-
break;
|
|
4056
|
-
case 'ema':
|
|
4057
|
-
{
|
|
4058
|
-
if (typeof method.method_length !== 'number') return;
|
|
4059
|
-
method.history = exponentialMovingAverage(_this.instruments[0].history, method.method_length);
|
|
4060
|
-
method.trades = exponentialMovingAverage(_this.instruments[0].trades, method.method_length);
|
|
4061
|
-
break;
|
|
4062
|
-
}
|
|
4063
|
-
case 'bb':
|
|
4064
|
-
{
|
|
4065
|
-
if (typeof method.method_length !== 'number' || typeof method.stddev !== 'number') return;
|
|
4066
|
-
method.history = bollingerBands(_this.instruments[0].history, method.method_length, method.stddev);
|
|
4067
|
-
method.trades = bollingerBands(_this.instruments[0].trades, method.method_length, method.stddev);
|
|
4068
|
-
break;
|
|
4069
|
-
}
|
|
4070
|
-
case 'rsi':
|
|
4071
|
-
case 'quantity':
|
|
4072
|
-
case 'momentum':
|
|
4073
|
-
if (method.target == 'lower') {
|
|
4074
|
-
m_chartspaces.chart.percent = 70;
|
|
4075
|
-
m_chartspaces.lowerChart.percent = 30;
|
|
4076
|
-
}
|
|
4077
|
-
break;
|
|
4078
|
-
case 'news':
|
|
4079
|
-
break;
|
|
4080
|
-
default:
|
|
4081
|
-
if (typeof method.history !== 'undefined' && typeof method.trades !== 'undefined') {
|
|
4082
|
-
if (!Array.isArray(method.history) || !Array.isArray(method.trades)) {
|
|
4083
|
-
return -1;
|
|
4084
|
-
}
|
|
4085
|
-
}
|
|
4086
|
-
break;
|
|
4087
|
-
}
|
|
4088
|
-
_this.settings.indicators.push(method);
|
|
4089
|
-
_this.drawChart();
|
|
4090
|
-
};*/
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
/* _this.addIndicator = function(method) {
|
|
4094
|
-
if (typeof method !== 'object' || method == null || typeof method.method == undefined) return;
|
|
4095
|
-
if (indicatorAlreadyExists(method)) return;
|
|
4096
|
-
switch (method.method) {
|
|
4097
|
-
case 'sma':
|
|
4098
|
-
{
|
|
4099
|
-
if (typeof method.method_length !== 'number') return;
|
|
4100
|
-
}
|
|
4101
|
-
break;
|
|
4102
|
-
case 'ema':
|
|
4103
|
-
{
|
|
4104
|
-
if (typeof method.method_length !== 'number') return;
|
|
4105
|
-
break;
|
|
4106
|
-
}
|
|
4107
|
-
case 'bb':
|
|
4108
|
-
{
|
|
4109
|
-
if (typeof method.method_length !== 'number' || typeof method.stddev !== 'number') return;
|
|
4110
|
-
break;
|
|
4111
|
-
}
|
|
4112
|
-
case 'rsi':
|
|
4113
|
-
case 'quantity':
|
|
4114
|
-
case 'momentum':
|
|
4115
|
-
if (method.target == 'lower') {
|
|
4116
|
-
m_chartspaces.chart.percent = 70;
|
|
4117
|
-
m_chartspaces.lowerChart.percent = 30;
|
|
4118
|
-
}
|
|
4119
|
-
break;
|
|
4120
|
-
case 'news':
|
|
4121
|
-
break;
|
|
4122
|
-
default:
|
|
4123
|
-
method.timeseries.sort(function(a, b) {
|
|
4124
|
-
return a.timestamp - b.timestamp;
|
|
4125
|
-
});
|
|
4126
|
-
break;
|
|
4127
|
-
}
|
|
4128
|
-
if (typeof method.type === 'undefined') method.type = INDICATOR;
|
|
4129
|
-
_this.settings.indicators.unshift(method);
|
|
4130
|
-
_this.drawChart();
|
|
4131
|
-
};
|
|
4132
|
-
*/
|
|
4133
3485
|
function getXhrJson(url) {
|
|
4134
3486
|
var req = new XMLHttpRequest();
|
|
4135
3487
|
req.onload = function() {
|
|
@@ -4215,8 +3567,6 @@ function Milli_Chart(settings) {
|
|
|
4215
3567
|
}
|
|
4216
3568
|
_this.settings.target.style.height = (_this.settings.target.parentNode.offsetHeight - offset) + 'px';
|
|
4217
3569
|
_this.settings.target.style.width = _this.settings.target.parentNode.offsetWidth + 'px';
|
|
4218
|
-
//_this.settings.target.style.height = (_this.settings.target.parentNode.offsetHeight - offset) * 1 + 'px';
|
|
4219
|
-
//_this.settings.target.style.width = _this.settings.target.parentNode.offsetWidth * 1 + 'px';
|
|
4220
3570
|
m_canvas.setRect(_this.settings.target.offsetHeight, _this.settings.target.offsetWidth);
|
|
4221
3571
|
}
|
|
4222
3572
|
|
|
@@ -4281,17 +3631,24 @@ function Milli_Chart(settings) {
|
|
|
4281
3631
|
var rect = m_canvas.getBoundingClientRect();
|
|
4282
3632
|
var x = getScaledSetting(evt.clientX) - getScaledSetting(rect.left) - 1;
|
|
4283
3633
|
var y = getScaledSetting(evt.clientY) - getScaledSetting(rect.top);
|
|
4284
|
-
|
|
4285
3634
|
for (let i = 0; i < _this.settings.indicators.length; i++) {
|
|
3635
|
+
let newsarr = [];
|
|
4286
3636
|
var width = m_ctx.measureText(_this.settings.indicators[i].indicator).width;
|
|
4287
3637
|
for (let s = 0; s < _this.settings.indicators[i].timeseries.length; s++) {
|
|
4288
|
-
if
|
|
4289
|
-
if (
|
|
4290
|
-
if (
|
|
4291
|
-
|
|
4292
|
-
|
|
3638
|
+
if(typeof _this.settings.indicators[i].timeseries[s].pos !== 'undefined') {
|
|
3639
|
+
if (x >= parseInt(_this.settings.indicators[i].timeseries[s].pos.x) - (width / 2) && x <= parseInt(_this.settings.indicators[i].timeseries[s].pos.x) + (width / 2)) {
|
|
3640
|
+
if (y >= _this.settings.indicators[i].timeseries[s].pos.y && y <= _this.settings.indicators[i].timeseries[s].pos.y + width) {
|
|
3641
|
+
if (typeof _this.settings.indicators[i].onclick === 'function') {
|
|
3642
|
+
newsarr.push({ date : new Date(_this.settings.indicators[i].timeseries[s].timestamp),newsid: _this.settings.indicators[i].timeseries[s].newsid});
|
|
3643
|
+
}
|
|
3644
|
+
}
|
|
3645
|
+
}// else if( x > parseInt(_this.settings.indicators[i].timeseries[s].pos.x) + (width / 2)) break;
|
|
4293
3646
|
}
|
|
4294
3647
|
}
|
|
3648
|
+
if(newsarr.length > 0) {
|
|
3649
|
+
_this.settings.indicators[i].onclick(_this.instruments[0].insref,newsarr);
|
|
3650
|
+
return;
|
|
3651
|
+
}
|
|
4295
3652
|
}
|
|
4296
3653
|
|
|
4297
3654
|
|
|
@@ -4480,16 +3837,16 @@ function Milli_Chart(settings) {
|
|
|
4480
3837
|
calcAnalyizis = true;
|
|
4481
3838
|
if (instr.pricetype == 'price') {
|
|
4482
3839
|
update = true;
|
|
4483
|
-
data.price = parseFloat(json['12']);
|
|
4484
|
-
data.open = parseFloat(json['12']);
|
|
4485
|
-
data.high = parseFloat(json['12']);
|
|
4486
|
-
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']);
|
|
4487
3844
|
data.quantity = typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
|
|
4488
3845
|
} else if (instr.pricetype == 'yield') {
|
|
4489
|
-
data.price = parseFloat(json['201']);
|
|
4490
|
-
data.open = parseFloat(json['201']);
|
|
4491
|
-
data.high = parseFloat(json['201']);
|
|
4492
|
-
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']);
|
|
4493
3850
|
data.quantity = typeof json['13'] === 'undefined' ? 0 : parseInt(json['13']);
|
|
4494
3851
|
update = true;
|
|
4495
3852
|
}
|
|
@@ -4663,7 +4020,8 @@ function Milli_Chart(settings) {
|
|
|
4663
4020
|
'rect': 'all',
|
|
4664
4021
|
'translate': 'all',
|
|
4665
4022
|
'createRadialGradient': 'all',
|
|
4666
|
-
'createLinearGradient': 'all'
|
|
4023
|
+
'createLinearGradient': 'all',
|
|
4024
|
+
'drawImage': [1,2,3,4]
|
|
4667
4025
|
};
|
|
4668
4026
|
|
|
4669
4027
|
if (context.pixelRatio === 1) return;
|
|
@@ -4877,19 +4235,29 @@ function Milli_Chart(settings) {
|
|
|
4877
4235
|
_this.drawChart();
|
|
4878
4236
|
})();
|
|
4879
4237
|
|
|
4880
|
-
window.addEventListener('resize', function() {
|
|
4238
|
+
window.addEventListener('resize', function(a) {
|
|
4881
4239
|
if (m_canvas != null) {
|
|
4882
4240
|
setChartSize();
|
|
4241
|
+
//console.log("windowresize",m_chartspaces);
|
|
4883
4242
|
_this.drawChart();
|
|
4884
4243
|
}
|
|
4885
4244
|
});
|
|
4245
|
+
|
|
4246
|
+
/* function parentResize(a) {
|
|
4247
|
+
console.log('a',a);
|
|
4248
|
+
if(m_canvas != null) {
|
|
4249
|
+
setChartSize();
|
|
4250
|
+
console.log(m_chartspaces);
|
|
4251
|
+
_this.drawChart();
|
|
4252
|
+
}
|
|
4253
|
+
};
|
|
4886
4254
|
|
|
4887
4255
|
if(_this.settings.target.parentNode) {
|
|
4888
|
-
const observer = new MutationObserver(
|
|
4256
|
+
const observer = new MutationObserver(parentResize);
|
|
4889
4257
|
const observerConfig = { attributes: true };
|
|
4890
4258
|
observer.observe(_this.settings.target.parentNode, observerConfig);
|
|
4891
4259
|
}
|
|
4892
|
-
|
|
4260
|
+
*/
|
|
4893
4261
|
};
|
|
4894
4262
|
|
|
4895
4263
|
function Milli_OptionsList(settings) {
|
|
@@ -6338,6 +5706,21 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
6338
5706
|
// internal and external
|
|
6339
5707
|
// return array with MDF_F_FIELD,type,align, name var, overridable decimal bitwise [1 = override output,2 = can override,4 = no decimals,8 can be shortened to M, K etc], 16 = override NULL with 0 , 32 = can color diff
|
|
6340
5708
|
switch (name) {
|
|
5709
|
+
case '1104':
|
|
5710
|
+
case 'adtv1mprc':
|
|
5711
|
+
return [1104, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
|
|
5712
|
+
case '1105':
|
|
5713
|
+
case 'adtv1wprc':
|
|
5714
|
+
return [1105, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
|
|
5715
|
+
case '1106':
|
|
5716
|
+
case 'adtv1yprc':
|
|
5717
|
+
return [1106, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
|
|
5718
|
+
case '1107':
|
|
5719
|
+
case 'adtv3mprc':
|
|
5720
|
+
return [1107, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
|
|
5721
|
+
case '1108':
|
|
5722
|
+
case 'adtvytdprc':
|
|
5723
|
+
return [1108, 'numeric', 'right', widget.get_lang_text(name) || name, 0];
|
|
6341
5724
|
case '222':
|
|
6342
5725
|
case 'accountsreceivable':
|
|
6343
5726
|
return [222, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|
|
@@ -6763,9 +6146,18 @@ function MillistreamWidgetApi_getColumnInfo(widget, name) {
|
|
|
6763
6146
|
case '181':
|
|
6764
6147
|
case 's4':
|
|
6765
6148
|
return [181, 'string', 'left', widget.get_lang_text(name) || name, 0]; // Position
|
|
6149
|
+
case '389':
|
|
6150
|
+
case 's6':
|
|
6151
|
+
return [389, 'string', 'left', widget.get_lang_text(name) || name, 0]; //
|
|
6152
|
+
case '390':
|
|
6153
|
+
case 's7':
|
|
6154
|
+
return [390, 'string', 'left', widget.get_lang_text(name) || name, 0]; //
|
|
6766
6155
|
case '393':
|
|
6767
6156
|
case 's10':
|
|
6768
6157
|
return [393, 'string', 'left', widget.get_lang_text(name) || name, 0]; // comment
|
|
6158
|
+
case '713':
|
|
6159
|
+
case 's12':
|
|
6160
|
+
return [713, 'string', 'left', widget.get_lang_text(name) || name, 0]; // comment
|
|
6769
6161
|
case '127':
|
|
6770
6162
|
case 'sales':
|
|
6771
6163
|
return [127, 'numeric', 'right', widget.get_lang_text(name) || name, 8];
|