@millistream/millistream-widgets 1.0.36 → 1.0.38
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 +623 -104
- package/package.json +1 -1
package/millistream-widgets.js
CHANGED
|
@@ -24,16 +24,6 @@ function Milli_Chart(settings) {
|
|
|
24
24
|
x: {},
|
|
25
25
|
ly: {}
|
|
26
26
|
};
|
|
27
|
-
let testscale = {
|
|
28
|
-
valuePerPixel: 0,
|
|
29
|
-
minValue: 0,
|
|
30
|
-
maxValue: 0,
|
|
31
|
-
lowValue: 0,
|
|
32
|
-
highValue: 0,
|
|
33
|
-
lineLength: 0,
|
|
34
|
-
decimals: 0, // behövs den?
|
|
35
|
-
tickSize: 0
|
|
36
|
-
};
|
|
37
27
|
_this.settings = {
|
|
38
28
|
adjusted: true,
|
|
39
29
|
absoluteScaling: false,
|
|
@@ -504,12 +494,19 @@ function Milli_Chart(settings) {
|
|
|
504
494
|
return true;
|
|
505
495
|
}
|
|
506
496
|
|
|
507
|
-
function calcHighLow(scaleinfoY, scaleinfoY2) {
|
|
497
|
+
/*function calcHighLow(scaleinfoY, scaleinfoY2) {
|
|
508
498
|
scaleinfoY.lowValue = null;
|
|
509
499
|
scaleinfoY.highValue = null;
|
|
510
500
|
scaleinfoY2.lowValue = null;
|
|
511
501
|
scaleinfoY2.highValue = null;
|
|
512
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
|
+
|
|
513
510
|
var data, i;
|
|
514
511
|
var useCloseprice = false;
|
|
515
512
|
var today = new Date().getTime();
|
|
@@ -543,9 +540,6 @@ function Milli_Chart(settings) {
|
|
|
543
540
|
let lowprice = data[i].lowprice * _this.instruments[s].factor;
|
|
544
541
|
|
|
545
542
|
//quantity = 0;
|
|
546
|
-
/*if (data[i].quantity !== 'undefined') {
|
|
547
|
-
quantity = data[i].quantity;
|
|
548
|
-
}*/
|
|
549
543
|
if (data[i].timestamp < _this.scaleinfoX.startTimeStamp) {
|
|
550
544
|
if (chartType == 'history') {
|
|
551
545
|
//_this.instruments[s].startValue = price; // skall inte sättas eftersom vi inte ritar den i history
|
|
@@ -663,8 +657,8 @@ function Milli_Chart(settings) {
|
|
|
663
657
|
scaleinfoY2.highValue = (scaleinfoY.highValue - _this.instruments[0].startValue) / _this.instruments[0].startValue * 100;
|
|
664
658
|
return 1;
|
|
665
659
|
}
|
|
666
|
-
|
|
667
|
-
function calcHighLow2(scale, cs, css, factorInfo) {
|
|
660
|
+
*/
|
|
661
|
+
/* function calcHighLow2(scale, cs, css, factorInfo) {
|
|
668
662
|
scale.lowValue = null;
|
|
669
663
|
scale.highValue = null;
|
|
670
664
|
|
|
@@ -698,10 +692,6 @@ function Milli_Chart(settings) {
|
|
|
698
692
|
// only calc on visible data
|
|
699
693
|
var price = data[i].price * _this.instruments[s].factor;
|
|
700
694
|
|
|
701
|
-
//quantity = 0;
|
|
702
|
-
/*if (data[i].quantity !== 'undefined') {
|
|
703
|
-
quantity = data[i].quantity;
|
|
704
|
-
}*/
|
|
705
695
|
if (data[i].timestamp < _this.scaleinfoX.startTimeStamp) {
|
|
706
696
|
if (chartType == 'history') {
|
|
707
697
|
_this.instruments[s].startValue = price;
|
|
@@ -830,7 +820,301 @@ function Milli_Chart(settings) {
|
|
|
830
820
|
}
|
|
831
821
|
return true;
|
|
832
822
|
}
|
|
823
|
+
*/
|
|
824
|
+
|
|
825
|
+
function calcHighLow(scaleinfoY, scaleinfoY2) {
|
|
826
|
+
scaleinfoY.lowValue = null;
|
|
827
|
+
scaleinfoY.highValue = null;
|
|
828
|
+
scaleinfoY2.lowValue = null;
|
|
829
|
+
scaleinfoY2.highValue = null;
|
|
830
|
+
|
|
831
|
+
var data, i;
|
|
832
|
+
var useCloseprice = false;
|
|
833
|
+
var today = new Date().getTime();
|
|
834
|
+
today -= today % 86400000;
|
|
835
|
+
var lastTradeDate = new Date().getTime();
|
|
836
|
+
var todaysOpenTime = new Date(new Date().toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z').getTime();
|
|
837
|
+
|
|
838
|
+
if (typeof _this.instruments[0].trades !== 'undefined' && _this.instruments[0].trades.length > 0) {
|
|
839
|
+
lastTradeDate = new Date(_this.instruments[0].trades[_this.instruments[0].trades.length - 1].timestamp).getTime();
|
|
840
|
+
lastTradeDate -= lastTradeDate % 86400000;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
var quote_timestamp = _this.instruments[0].quotedate + _this.instruments[0].quotetime;
|
|
844
|
+
|
|
845
|
+
if(chartType == 'trades' && (_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && !m_zoom.mousedown.timestamp ) {
|
|
846
|
+
if ((_this.instruments[0].quotedate == today && quote_timestamp > todaysOpenTime) || _this.instruments[0].quotedate == lastTradeDate) {
|
|
847
|
+
useCloseprice = true;
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
//console.log(chartType,_this.instruments[0],quote_timestamp,todaysOpenTime,_this.instruments[0].quotedate,today,useCloseprice,_this.instruments[0].closeprice1d,_this.instruments[0].factor);
|
|
851
|
+
|
|
852
|
+
/*if ((_this.instruments[0].quotedate == today && quote_timestamp > todaysOpenTime) || _this.instruments[0].quotedate == lastTradeDate) {
|
|
853
|
+
useCloseprice = true;
|
|
854
|
+
}*/
|
|
833
855
|
|
|
856
|
+
for (var s = 0; s < _this.instruments.length; s++) {
|
|
857
|
+
if (_this.instruments[s].insref == 0) continue;
|
|
858
|
+
_this.instruments[s].startValue = null;
|
|
859
|
+
data = _this.instruments[s][chartType];
|
|
860
|
+
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
|
+
}
|
|
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;
|
|
1098
|
+
for (s = 0; s < data.length; s++) {
|
|
1099
|
+
if (data[s].timestamp < _this.scaleinfoX.startTimeStamp) {
|
|
1100
|
+
continue;
|
|
1101
|
+
}
|
|
1102
|
+
if (data[s].timestamp > _this.scaleinfoX.endTimeStamp) {
|
|
1103
|
+
break;
|
|
1104
|
+
}
|
|
1105
|
+
if (typeof data[s].datapoints !== 'undefined') {
|
|
1106
|
+
for (var x = 0; x < data[i].datapoints.length; x++) {
|
|
1107
|
+
if (data[s].datapoints[x] < scaleinfoY.lowValue) scaleinfoY.lowValue = data[s].datapoints[x];
|
|
1108
|
+
else
|
|
1109
|
+
if (data[s].datapoints[x] > scaleinfoY.highValue) scaleinfoY.highValue = data[s].datapoints[x];
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
scaleinfoY2.lowValue = (scaleinfoY.lowValue - _this.instruments[0].startValue) / _this.instruments[0].startValue * 100;
|
|
1115
|
+
scaleinfoY2.highValue = (scaleinfoY.highValue - _this.instruments[0].startValue) / _this.instruments[0].startValue * 100;
|
|
1116
|
+
return 1;
|
|
1117
|
+
}*/
|
|
834
1118
|
|
|
835
1119
|
function drawY2Legend(scaleinfoY, scaleinfoY2, x) { // percent
|
|
836
1120
|
if (_this.instruments[0].pricetype == 'yield') return;
|
|
@@ -1933,6 +2217,13 @@ function Milli_Chart(settings) {
|
|
|
1933
2217
|
var oldValue = undefined;
|
|
1934
2218
|
var newValue = undefined;
|
|
1935
2219
|
var offsetWidth = 0;
|
|
2220
|
+
let diff = 0;
|
|
2221
|
+
if(chartType == 'history')
|
|
2222
|
+
diff = _this.instruments[0].history[_this.instruments[0].history.length - 1].diff;
|
|
2223
|
+
else {
|
|
2224
|
+
diff = _this.instruments[0].trades[_this.instruments[0].trades.length - 1].diff;
|
|
2225
|
+
}
|
|
2226
|
+
|
|
1936
2227
|
if (_this.instruments[0].pricetype == 'yield') {
|
|
1937
2228
|
newValue = formatNiceNumber(obj.instruments[0].price, _this.settings.thousandseparator, _this.settings.decimalseparator, _this.settings.num_decimals, false);
|
|
1938
2229
|
if (m_y2LegendCss.textAlign == 'left') offsetWidth = 1;
|
|
@@ -1940,8 +2231,11 @@ function Milli_Chart(settings) {
|
|
|
1940
2231
|
newValue = formatNiceNumber(obj.instruments[0].price, _this.settings.thousandseparator, _this.settings.decimalseparator, _this.settings.num_decimals, false);
|
|
1941
2232
|
if (m_yLegendCss.textAlign == 'left') offsetWidth = 1;
|
|
1942
2233
|
} else if (_this.settings.drawy2axis && m_y2LegendCss.float == 'right') {
|
|
1943
|
-
if (
|
|
1944
|
-
else newValue = formatNiceNumber(
|
|
2234
|
+
if (diff > 0) newValue = '+' + formatNiceNumber(diff, _this.settings.thousandseparator, _this.settings.decimalseparator, 2, false) + '%';
|
|
2235
|
+
else newValue = formatNiceNumber(diff, _this.settings.thousandseparator, _this.settings.decimalseparator, 2, false) + '%';
|
|
2236
|
+
|
|
2237
|
+
/*if (obj.instruments[0].diff > 0) newValue = '+' + formatNiceNumber(obj.instruments[0].diff, _this.settings.thousandseparator, _this.settings.decimalseparator, 2, false) + '%';
|
|
2238
|
+
else newValue = formatNiceNumber(obj.instruments[0].diff, _this.settings.thousandseparator, _this.settings.decimalseparator, 2, false) + '%';*/
|
|
1945
2239
|
if (m_y2LegendCss.textAlign == 'left') offsetWidth = 1;
|
|
1946
2240
|
} else return;
|
|
1947
2241
|
if (typeof m_priceIndicator !== 'undefined') {
|
|
@@ -2364,17 +2658,22 @@ function Milli_Chart(settings) {
|
|
|
2364
2658
|
_this.scaleinfoX.endTimeStamp = new Date(_this.scaleinfoX.endTimeStamp.toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z').getTime();
|
|
2365
2659
|
} else {
|
|
2366
2660
|
// check that the last trade is not later than closetime
|
|
2661
|
+
|
|
2367
2662
|
var tradetimestamp = new Date(_this.instruments[0].trades[_this.instruments[0].trades.length - 1].timestamp).getTime();
|
|
2368
2663
|
var closetimestamp = new Date(new Date(_this.instruments[0].trades[_this.instruments[0].trades.length - 1].timestamp).toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketclose + 'Z').getTime();
|
|
2664
|
+
//console.log(tradetimestamp,closetimestamp);
|
|
2369
2665
|
if (closetimestamp < tradetimestamp)
|
|
2370
2666
|
_this.scaleinfoX.endTimeStamp = new Date(closetimestamp); // borde inte rita med closeprice1d då heller eller spelar det ingen roll?
|
|
2371
2667
|
else
|
|
2372
2668
|
_this.scaleinfoX.endTimeStamp = new Date(tradetimestamp);
|
|
2669
|
+
//console.log(new Date(_this.scaleinfoX.endTimeStamp));
|
|
2373
2670
|
}
|
|
2374
2671
|
if (_this.scaleinfoX.endTimeStamp - (_this.scaleinfoX.endTimeStamp % 86400000) > _this.instruments[0].quotedate) {
|
|
2375
2672
|
_this.scaleinfoX.endTimeStamp -= _this.scaleinfoX.endTimeStamp - _this.scaleinfoX.endTimeStamp % 86400000;
|
|
2376
2673
|
_this.scaleinfoX.endTimeStamp += _this.instruments[0].quotedate; // set enddate = last Quotedate
|
|
2674
|
+
//console.log('asdasd',new Date(_this.scaleinfoX.endTimeStamp));
|
|
2377
2675
|
}
|
|
2676
|
+
|
|
2378
2677
|
for (var i = 0; i < _this.settings.indicators.length; i++) {
|
|
2379
2678
|
if (_this.settings.indicators[i].type == FUTUREINDICATOR) {
|
|
2380
2679
|
let endDate = new Date(_this.settings.indicators[i].timeseries[0].timestamp).getTime();
|
|
@@ -2382,6 +2681,7 @@ function Milli_Chart(settings) {
|
|
|
2382
2681
|
}
|
|
2383
2682
|
}
|
|
2384
2683
|
}
|
|
2684
|
+
//console.log(new Date(_this.scaleinfoX.startTimeStamp),new Date(_this.scaleinfoX.endTimeStamp),new Date(_this.instruments[0].quotedate));
|
|
2385
2685
|
setTimeSpanData();
|
|
2386
2686
|
if (_this.settings.absoluteScaling == true) {
|
|
2387
2687
|
for (s = 1; s < _this.instruments.length; s++) _this.instruments[s].factor = 1;
|
|
@@ -2751,6 +3051,12 @@ function Milli_Chart(settings) {
|
|
|
2751
3051
|
instr.trades = [];
|
|
2752
3052
|
instr.hashmap.clear();
|
|
2753
3053
|
for (i = 0; i < data.trades.length; i++) {
|
|
3054
|
+
/*
|
|
3055
|
+
Kanske kan va nåt
|
|
3056
|
+
console.log(new Date(data.trades[i].timestamp),instr.opentimestamp,data.trades[i].timestamp,data.trades[i].timestamp % 86400000,instr.closetimestamp,data.trades[i].timestamp % 86400000);
|
|
3057
|
+
if(instr.closetimestamp < data.trades[i].timestamp % 86400000) console.log("timestamp",instr.closetimestamp,data.trades[i].timestamp % 86400000);
|
|
3058
|
+
*/
|
|
3059
|
+
|
|
2754
3060
|
if (data.trades[i].tradecode & 16) { // canceltrade
|
|
2755
3061
|
continue;
|
|
2756
3062
|
}
|
|
@@ -2775,9 +3081,12 @@ function Milli_Chart(settings) {
|
|
|
2775
3081
|
});
|
|
2776
3082
|
}
|
|
2777
3083
|
}
|
|
2778
|
-
if (typeof data.closeprice1d !== 'undefined') {
|
|
2779
|
-
|
|
3084
|
+
if (typeof data.closeprice1d !== 'undefined' && instr.pricetype != 'yield') {
|
|
3085
|
+
instr.closeprice1d = data.closeprice1d;
|
|
3086
|
+
} else if (typeof data.closeyield1d !== 'undefined' && instr.pricetype == 'yield') {
|
|
3087
|
+
instr.closeprice1d = data.closeyield1d;
|
|
2780
3088
|
}
|
|
3089
|
+
|
|
2781
3090
|
if (typeof data.history !== 'undefined') {
|
|
2782
3091
|
instr.history = [];
|
|
2783
3092
|
for (i = 0; i < data.history.length; i++) {
|
|
@@ -3175,6 +3484,18 @@ function Milli_Chart(settings) {
|
|
|
3175
3484
|
var nextDate;
|
|
3176
3485
|
var firstDataPoint = null;
|
|
3177
3486
|
var lastDataPoint = null;
|
|
3487
|
+
|
|
3488
|
+
var today = new Date().getTime();
|
|
3489
|
+
today -= today % 86400000;
|
|
3490
|
+
var todaysOpenTime = new Date(new Date().toISOString().substring(0, 10) + 'T' + _this.instruments[0].marketopen + 'Z').getTime();
|
|
3491
|
+
var lastTradeDate = new Date().getTime();
|
|
3492
|
+
|
|
3493
|
+
if (typeof _this.instruments[0].trades !== 'undefined' && _this.instruments[0].trades.length > 0) {
|
|
3494
|
+
lastTradeDate = new Date(_this.instruments[0].trades[_this.instruments[0].trades.length - 1].timestamp).getTime();
|
|
3495
|
+
lastTradeDate -= lastTradeDate % 86400000;
|
|
3496
|
+
}
|
|
3497
|
+
var quote_timestamp = _this.instruments[0].quotedate + _this.instruments[0].quotetime;
|
|
3498
|
+
|
|
3178
3499
|
for (var i = 0; i < len; i++) {
|
|
3179
3500
|
var currentDate = new Date(data[i].timestamp);
|
|
3180
3501
|
var tmpx = startpoint.x;
|
|
@@ -3204,7 +3525,8 @@ function Milli_Chart(settings) {
|
|
|
3204
3525
|
|
|
3205
3526
|
if (chartType != 'history' && _this.settings.previousDayClose && addedcloseprice1d == false && m_zoom.mouseup.timestamp == null && instrument == 0) { // only draw closeprice1d on today charts
|
|
3206
3527
|
currentDate = new Date(startDate);
|
|
3207
|
-
|
|
3528
|
+
|
|
3529
|
+
if ((_this.settings.chartlen == '1d' || _this.settings.chartlen == '0d') && ( (_this.instruments[0].quotedate == today && quote_timestamp > todaysOpenTime) || _this.instruments[0].quotedate == lastTradeDate)) { // plot the closeprice1d
|
|
3208
3530
|
endpoint.y = Math.round(m_chartspaces.chart.height - m_chartspaces.chart.marginBottom - (((parseFloat(_this.instruments[instrument].closeprice1d * _this.instruments[instrument].factor)) - scaleinfoY.minValue) / scaleinfoY.valuePerPixel)) + 0.5;
|
|
3209
3531
|
endpoint.x = m_chartspaces.chart.left + 0.5 - offset;
|
|
3210
3532
|
} else {
|
|
@@ -3458,52 +3780,6 @@ function Milli_Chart(settings) {
|
|
|
3458
3780
|
return timeseries;
|
|
3459
3781
|
}
|
|
3460
3782
|
|
|
3461
|
-
function calculateRSI(p, window) {
|
|
3462
|
-
// borde returnera ett object med high/low också
|
|
3463
|
-
let rsi = [];
|
|
3464
|
-
let up;
|
|
3465
|
-
let up_average;
|
|
3466
|
-
let up_average_old = 0;
|
|
3467
|
-
let sum_up = 0;
|
|
3468
|
-
|
|
3469
|
-
let down;
|
|
3470
|
-
let down_average;
|
|
3471
|
-
let sum_down = 0;
|
|
3472
|
-
let down_average_old = 0;
|
|
3473
|
-
|
|
3474
|
-
for (let i = 1; i < p.length; i++) {
|
|
3475
|
-
let change = p[i].price - p[i - 1].price;
|
|
3476
|
-
if (change > 0) {
|
|
3477
|
-
up = change;
|
|
3478
|
-
down = 0;
|
|
3479
|
-
} else if (change < 0) {
|
|
3480
|
-
down = Math.abs(change);
|
|
3481
|
-
up = 0;
|
|
3482
|
-
} else {
|
|
3483
|
-
up = 0;
|
|
3484
|
-
down = 0;
|
|
3485
|
-
}
|
|
3486
|
-
if (i < window) {
|
|
3487
|
-
sum_up += up;
|
|
3488
|
-
sum_down += down
|
|
3489
|
-
} else if (i == window) {
|
|
3490
|
-
up_average = sum_up / window;
|
|
3491
|
-
down_average = sum_down / window;
|
|
3492
|
-
up_average_old = up_average;
|
|
3493
|
-
down_average_old = down_average
|
|
3494
|
-
} else {
|
|
3495
|
-
up_average = (up_average_old * (window - 1) + up) / window;
|
|
3496
|
-
down_average = (down_average_old * (window - 1) + down) / window;
|
|
3497
|
-
up_average_old = up_average;
|
|
3498
|
-
down_average_old = down_average
|
|
3499
|
-
}
|
|
3500
|
-
if (i >= window) {
|
|
3501
|
-
var rs = up_average / down_average;
|
|
3502
|
-
rsi.push({ timestamp: p[i].timestamp, datapoints: [100 - 100 / (1 + rs)] });
|
|
3503
|
-
}
|
|
3504
|
-
}
|
|
3505
|
-
return rsi;
|
|
3506
|
-
}
|
|
3507
3783
|
|
|
3508
3784
|
function calculateBollingerBands(prices, window, stddev) {
|
|
3509
3785
|
// borde returnera ett object med high/low också
|
|
@@ -3531,6 +3807,27 @@ function Milli_Chart(settings) {
|
|
|
3531
3807
|
}
|
|
3532
3808
|
|
|
3533
3809
|
function simpleMovingAverage(prices, window, n = Infinity) {
|
|
3810
|
+
if (!prices || prices.length < window) {
|
|
3811
|
+
return [];
|
|
3812
|
+
}
|
|
3813
|
+
let index = window - 1;
|
|
3814
|
+
const length = prices.length + 1;
|
|
3815
|
+
|
|
3816
|
+
const simpleMovingAverages = [];
|
|
3817
|
+
|
|
3818
|
+
let numberOfSMAsCalculated = 0;
|
|
3819
|
+
|
|
3820
|
+
while (++index < length && numberOfSMAsCalculated++ < n) {
|
|
3821
|
+
const windowSlice = prices.slice(index - window, index);
|
|
3822
|
+
const sum = windowSlice.reduce((prev, curr) => prev + curr.price, 0);
|
|
3823
|
+
simpleMovingAverages.push({ timestamp: prices[index - 1].timestamp, datapoints: [sum / window] });
|
|
3824
|
+
if (typeof prices[index] == 'undefined' || prices[index].timestamp > new Date().getTime()) break;
|
|
3825
|
+
}
|
|
3826
|
+
return simpleMovingAverages;
|
|
3827
|
+
}
|
|
3828
|
+
|
|
3829
|
+
|
|
3830
|
+
/*function simpleMovingAverage(prices, window, n = Infinity) {
|
|
3534
3831
|
// borde returnera ett object med high/low också
|
|
3535
3832
|
if (!prices || prices.length < window) {
|
|
3536
3833
|
return [];
|
|
@@ -3551,10 +3848,30 @@ function Milli_Chart(settings) {
|
|
|
3551
3848
|
if (typeof prices[index] == 'undefined' || prices[index].timestamp > today) break;
|
|
3552
3849
|
}
|
|
3553
3850
|
return simpleMovingAverages;
|
|
3851
|
+
}*/
|
|
3852
|
+
function exponentialMovingAverage(prices, window) {
|
|
3853
|
+
if (!prices || prices.length < window) {
|
|
3854
|
+
return [];
|
|
3855
|
+
}
|
|
3856
|
+
let index = window - 1;
|
|
3857
|
+
let previousEmaIndex = 0;
|
|
3858
|
+
const length = prices.length;
|
|
3859
|
+
const smoothingFactor = 2 / (window + 1);
|
|
3860
|
+
const exponentialMovingAverages = [];
|
|
3861
|
+
|
|
3862
|
+
const [sma] = simpleMovingAverage(prices, window, 1);
|
|
3863
|
+
exponentialMovingAverages.push(sma);
|
|
3864
|
+
while (++index < length) {
|
|
3865
|
+
const value = prices[index].price;
|
|
3866
|
+
const previousEma = [exponentialMovingAverages[previousEmaIndex++].datapoints[0]];
|
|
3867
|
+
const currentEma = (value * smoothingFactor) + (previousEma * (1 - smoothingFactor));
|
|
3868
|
+
exponentialMovingAverages.push({ timestamp: prices[index].timestamp, datapoints: [currentEma] });
|
|
3869
|
+
if (typeof prices[index] == 'undefined' || prices[index].timestamp > new Date().getTime()) break;
|
|
3870
|
+
}
|
|
3871
|
+
return exponentialMovingAverages;
|
|
3554
3872
|
}
|
|
3555
3873
|
|
|
3556
|
-
function exponentialMovingAverage(prices, window) {
|
|
3557
|
-
// borde returnera ett object med high/low också
|
|
3874
|
+
/*function exponentialMovingAverage(prices, window) {
|
|
3558
3875
|
if (!prices || prices.length < window) {
|
|
3559
3876
|
return [];
|
|
3560
3877
|
}
|
|
@@ -3574,12 +3891,79 @@ function Milli_Chart(settings) {
|
|
|
3574
3891
|
exponentialMovingAverages.push({ timestamp: prices[index].timestamp, datapoints: [currentEma] });
|
|
3575
3892
|
}
|
|
3576
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;
|
|
3577
3914
|
}
|
|
3578
3915
|
|
|
3916
|
+
|
|
3917
|
+
function calculateRSI(p, window) {
|
|
3918
|
+
// borde returnera ett object med high/low också
|
|
3919
|
+
let rsi = [];
|
|
3920
|
+
let up;
|
|
3921
|
+
let up_average;
|
|
3922
|
+
let up_average_old = 0;
|
|
3923
|
+
let sum_up = 0;
|
|
3924
|
+
|
|
3925
|
+
let down;
|
|
3926
|
+
let down_average;
|
|
3927
|
+
let sum_down = 0;
|
|
3928
|
+
let down_average_old = 0;
|
|
3929
|
+
|
|
3930
|
+
for (let i = 1; i < p.length; i++) {
|
|
3931
|
+
let change = p[i].price - p[i - 1].price;
|
|
3932
|
+
if (change > 0) {
|
|
3933
|
+
up = change;
|
|
3934
|
+
down = 0;
|
|
3935
|
+
} else if (change < 0) {
|
|
3936
|
+
down = Math.abs(change);
|
|
3937
|
+
up = 0;
|
|
3938
|
+
} else {
|
|
3939
|
+
up = 0;
|
|
3940
|
+
down = 0;
|
|
3941
|
+
}
|
|
3942
|
+
if (i < window) {
|
|
3943
|
+
sum_up += up;
|
|
3944
|
+
sum_down += down
|
|
3945
|
+
} else if (i == window) {
|
|
3946
|
+
up_average = sum_up / window;
|
|
3947
|
+
down_average = sum_down / window;
|
|
3948
|
+
up_average_old = up_average;
|
|
3949
|
+
down_average_old = down_average
|
|
3950
|
+
} else {
|
|
3951
|
+
up_average = (up_average_old * (window - 1) + up) / window;
|
|
3952
|
+
down_average = (down_average_old * (window - 1) + down) / window;
|
|
3953
|
+
up_average_old = up_average;
|
|
3954
|
+
down_average_old = down_average
|
|
3955
|
+
}
|
|
3956
|
+
if (i >= window) {
|
|
3957
|
+
var rs = up_average / down_average;
|
|
3958
|
+
rsi.push({ timestamp: p[i].timestamp, datapoints: [100 - 100 / (1 + rs)] });
|
|
3959
|
+
}
|
|
3960
|
+
}
|
|
3961
|
+
console.log('RSI',rsi[rsi.length-1]);
|
|
3962
|
+
return rsi;
|
|
3963
|
+
}
|
|
3579
3964
|
_this.removeAllIndicators = function(j) {
|
|
3580
3965
|
_this.settings.indicators = [];
|
|
3581
3966
|
_this.drawChart();
|
|
3582
|
-
|
|
3583
3967
|
return false;
|
|
3584
3968
|
};
|
|
3585
3969
|
|
|
@@ -3657,6 +4041,95 @@ function Milli_Chart(settings) {
|
|
|
3657
4041
|
_this.drawChart();
|
|
3658
4042
|
};
|
|
3659
4043
|
|
|
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
|
+
*/
|
|
3660
4133
|
function getXhrJson(url) {
|
|
3661
4134
|
var req = new XMLHttpRequest();
|
|
3662
4135
|
req.onload = function() {
|
|
@@ -3776,8 +4249,10 @@ function Milli_Chart(settings) {
|
|
|
3776
4249
|
};
|
|
3777
4250
|
|
|
3778
4251
|
_this.resizeEnd = function(e, ui) {
|
|
3779
|
-
|
|
3780
|
-
|
|
4252
|
+
if(m_canvas != null) {
|
|
4253
|
+
setChartSize();
|
|
4254
|
+
_this.drawChart();
|
|
4255
|
+
}
|
|
3781
4256
|
};
|
|
3782
4257
|
|
|
3783
4258
|
_this.buildwidget = function(resp) {
|
|
@@ -3950,6 +4425,7 @@ function Milli_Chart(settings) {
|
|
|
3950
4425
|
update = true;
|
|
3951
4426
|
}
|
|
3952
4427
|
if (typeof json['1024'] !== 'undefined') {
|
|
4428
|
+
// verkar inte användas till nåt
|
|
3953
4429
|
instr.diff1dprc = parseFloat(json['1024']);
|
|
3954
4430
|
update = true;
|
|
3955
4431
|
}
|
|
@@ -3992,9 +4468,9 @@ function Milli_Chart(settings) {
|
|
|
3992
4468
|
}
|
|
3993
4469
|
obj.price = typeof price === 'undefined' ? obj.price : parseFloat(price);
|
|
3994
4470
|
obj.quantity = typeof quantity === 'undefined' ? obj.quantity : quantity;
|
|
3995
|
-
if (chartType == 'history') update = true;
|
|
3996
|
-
} else {
|
|
3997
|
-
if (json['3'] && json['36'] && (json['12'] || json['201'])) {
|
|
4471
|
+
if (chartType == 'history') update = true;
|
|
4472
|
+
} else if (mref == 'trade') {
|
|
4473
|
+
if (json['3'] && json['36'] && (json['12'] || json['201']) && (json['15'] && parseInt(json['15']) & 128)) {
|
|
3998
4474
|
timestamp = new Date(json['3'] + 'T' + json['36'].substring(0, 6) + '00' + 'Z').getTime();
|
|
3999
4475
|
var data = instr.hashmap.get(timestamp);
|
|
4000
4476
|
if (typeof data === 'undefined') {
|
|
@@ -4043,9 +4519,10 @@ function Milli_Chart(settings) {
|
|
|
4043
4519
|
}
|
|
4044
4520
|
}
|
|
4045
4521
|
}
|
|
4046
|
-
|
|
4522
|
+
}
|
|
4523
|
+
if (update) {
|
|
4524
|
+
if (calcAnalyizis && insref == _this.instruments[0].insref) { // recalc history as well?
|
|
4047
4525
|
for (var i = 0; i < _this.settings.indicators.length; i++) {
|
|
4048
|
-
//for (const [key, a] of m_analyzisMethod.entries()) {
|
|
4049
4526
|
switch (_this.settings.indicators[i].method) {
|
|
4050
4527
|
case 'sma':
|
|
4051
4528
|
_this.settings.indicators[i].trades = [];
|
|
@@ -4065,11 +4542,9 @@ function Milli_Chart(settings) {
|
|
|
4065
4542
|
}
|
|
4066
4543
|
}
|
|
4067
4544
|
}
|
|
4068
|
-
|
|
4069
|
-
_this.drawChart();
|
|
4070
|
-
}
|
|
4071
|
-
return;
|
|
4545
|
+
_this.drawChart();
|
|
4072
4546
|
}
|
|
4547
|
+
return;
|
|
4073
4548
|
};
|
|
4074
4549
|
|
|
4075
4550
|
// used by trader
|
|
@@ -4408,6 +4883,13 @@ function Milli_Chart(settings) {
|
|
|
4408
4883
|
_this.drawChart();
|
|
4409
4884
|
}
|
|
4410
4885
|
});
|
|
4886
|
+
|
|
4887
|
+
if(_this.settings.target.parentNode) {
|
|
4888
|
+
const observer = new MutationObserver(_this.resizeEnd);
|
|
4889
|
+
const observerConfig = { attributes: true };
|
|
4890
|
+
observer.observe(_this.settings.target.parentNode, observerConfig);
|
|
4891
|
+
}
|
|
4892
|
+
|
|
4411
4893
|
};
|
|
4412
4894
|
|
|
4413
4895
|
function Milli_OptionsList(settings) {
|
|
@@ -4594,32 +5076,69 @@ function Milli_OptionsList(settings) {
|
|
|
4594
5076
|
m_instruments.set(resp.instruments[i].insref, resp.instruments[i]);
|
|
4595
5077
|
let strike = null;
|
|
4596
5078
|
if (typeof expirys[resp.instruments[i].strikedate] === 'undefined') {
|
|
4597
|
-
expirys[resp.instruments[i].strikedate] = 1;
|
|
4598
5079
|
let strikedata = {};
|
|
4599
5080
|
strikedata.strikedate = resp.instruments[i].strikedate;
|
|
4600
5081
|
strikedata.expirationtype = resp.instruments[i].expirationtype;
|
|
4601
|
-
|
|
4602
|
-
let opts;
|
|
4603
|
-
switch (_this.settings.language) {
|
|
4604
|
-
case 'sv':
|
|
4605
|
-
opts = { day: 'numeric', month: 'short' };
|
|
4606
|
-
date = date.toLocaleDateString('sv-SE', opts);
|
|
4607
|
-
let parts = date.split(' ');
|
|
4608
|
-
date = parts[0] + ' ' + parts[1].substring(0, 3);
|
|
4609
|
-
break;
|
|
4610
|
-
default:
|
|
4611
|
-
opts = { month: 'short', day: 'numeric' };
|
|
4612
|
-
date = date.toLocaleDateString('en-US', opts);
|
|
4613
|
-
break;
|
|
4614
|
-
}
|
|
4615
|
-
//strikedata.date = date;*/
|
|
5082
|
+
|
|
4616
5083
|
strikedata.dte = resp.instruments[i].dte;
|
|
5084
|
+
strikedata.numOptions = 0;
|
|
4617
5085
|
m_strikedates.push(strikedata);
|
|
4618
|
-
|
|
5086
|
+
expirys[resp.instruments[i].strikedate] = strikedata;
|
|
5087
|
+
}
|
|
5088
|
+
if(resp.instruments[i].derivativeindicator != 3)
|
|
5089
|
+
expirys[resp.instruments[i].strikedate].numOptions++;
|
|
5090
|
+
/* 0
|
|
5091
|
+
:
|
|
5092
|
+
{strikedate: '2023-07-07', expirationtype: 2, dte: 3, numOptions: 137}
|
|
5093
|
+
1
|
|
5094
|
+
:
|
|
5095
|
+
{strikedate: '2023-07-14', expirationtype: 2, dte: 10, numOptions: 137}
|
|
5096
|
+
2
|
|
5097
|
+
:
|
|
5098
|
+
{strikedate: '2023-07-20', expirationtype: 1, dte: 16, numOptions: 0}
|
|
5099
|
+
3
|
|
5100
|
+
:
|
|
5101
|
+
{strikedate: '2023-07-21', expirationtype: 1, dte: 17, numOptions: 234}
|
|
5102
|
+
4
|
|
5103
|
+
:
|
|
5104
|
+
{strikedate: '2023-07-28', expirationtype: 2, dte: 24, numOptions: 131}
|
|
5105
|
+
5
|
|
5106
|
+
:
|
|
5107
|
+
{strikedate: '2023-08-17', expirationtype: 1, dte: 44, numOptions: 0}
|
|
5108
|
+
6
|
|
5109
|
+
:
|
|
5110
|
+
{strikedate: '2023-08-18', expirationtype: 1, dte: 45, numOptions: 102}
|
|
5111
|
+
7
|
|
5112
|
+
:
|
|
5113
|
+
{strikedate: '2023-09-15', expirationtype: 1, dte: 73, numOptions: 176}
|
|
5114
|
+
8
|
|
5115
|
+
:
|
|
5116
|
+
{strikedate: '2023-12-15', expirationtype: 1, dte: 164, numOptions: 154}
|
|
5117
|
+
9
|
|
5118
|
+
:
|
|
5119
|
+
{strikedate: '2024-03-15', expirationtype: 1, dte: 255, numOptions: 142}
|
|
5120
|
+
10
|
|
5121
|
+
:
|
|
5122
|
+
{strikedate: '2024-06-20', expirationtype: 1, dte: 352, numOptions: 110}
|
|
5123
|
+
11
|
|
5124
|
+
:
|
|
5125
|
+
{strikedate: '2024-09-20', expirationtype: 1, dte: 444, numOptions: 64}
|
|
5126
|
+
12
|
|
5127
|
+
:
|
|
5128
|
+
{strikedate: '2024-12-20', expirationtype: 1, dte: 535, numOptions: 112}
|
|
5129
|
+
13
|
|
5130
|
+
:
|
|
5131
|
+
{strikedate: '2025-12-19', expirationtype: 1, dte: 899, numOptions: 80}
|
|
5132
|
+
14
|
|
5133
|
+
:
|
|
5134
|
+
{strikedate: '2026-12-18', expirationtype: 1, dte: 1263, numOptions: 78}
|
|
5135
|
+
15
|
|
5136
|
+
:
|
|
5137
|
+
{strikedate: '2027-12-17', expirationtype: 1, dte: 1627, numOptions: 66}*/
|
|
4619
5138
|
let f = 0;
|
|
4620
5139
|
if (resp.instruments[i].strikeprice != null) {
|
|
4621
5140
|
for (let s = 0; s < m_strikes.length; s++) {
|
|
4622
|
-
if (m_strikes[s].strikedate == resp.instruments[i].strikedate && m_strikes[s].strikeprice == resp.instruments[i].strikeprice) {
|
|
5141
|
+
if (m_strikes[s].strikedate == resp.instruments[i].strikedate && m_strikes[s].strikeprice == resp.instruments[i].strikeprice ) {
|
|
4623
5142
|
strike = m_strikes[s];
|
|
4624
5143
|
break;
|
|
4625
5144
|
}
|
|
@@ -4643,6 +5162,7 @@ function Milli_OptionsList(settings) {
|
|
|
4643
5162
|
strike.puts = resp.instruments[i];
|
|
4644
5163
|
}
|
|
4645
5164
|
}
|
|
5165
|
+
console.log(m_strikedates);
|
|
4646
5166
|
m_strikepricedecimals = decimals == 1 ? 2 : decimals;
|
|
4647
5167
|
m_strikedates.sort(function(a, b) {
|
|
4648
5168
|
return a.strikedate.replace(/-/g, '') - b.strikedate.replace(/-/g, '');
|
|
@@ -7013,7 +7533,6 @@ function formatDate(date, format, widget) {
|
|
|
7013
7533
|
}
|
|
7014
7534
|
if (format == 'b dd') { // Jan 01
|
|
7015
7535
|
timeStamp = new Date(date);
|
|
7016
|
-
console.log(date,timeStamp);
|
|
7017
7536
|
mon = timeStamp.toDateString().split(' ');
|
|
7018
7537
|
day = timeStamp.getDate();
|
|
7019
7538
|
return mon[1] + ' ' + (day <= 9 ? '0' + day : day);
|