Написал индикатор DMI по инструкции
отсюда
Сам индикатор:
var DMI = function(period){
this.period = period||14;
this.upm = [];
this.dwm = [];
this.lastquote = null;
this.PDI = [];
this.MDI = [];
this.EMA = new EMA(this.period);
this.ATR = [];
}
DMI.prototype = {
reset: function(){
this.upm = [];
this.dwm = [];
this.lastquote = null;
this.PDI = [];
this.MDI = [];
this.EMA = new EMA(this.period);
this.TR = [];
this.ATR = [];
},
append: function(quote){//Добавление очередной котировки с последующими вычислениями
if (this.lastquote){
var um = quote.high - this.lastquote.high;
var dm = this.lastquote.low - quote.low;
//Вычисление истинного диапазона и среднего истинного диапазона ([url]http://berg.com.ua/indicators-overlays/atr/[/url])
this.TR.push(Math.max((quote.high - quote.low),(quote.high - this.lastquote.close),(this.lastquote.close - quote.low)));
if (this.TR.length >= this.period){
if (this.ATR.length == 0){
this.ATR.push(this.EMA.average(this.TR))
}else{
this.ATR.push((this.ATR[this.ATR.length - 1]*(this.period - 1) + this.TR[this.TR.length - 1])/this.period)
}
}
//Вычисление +DI (PDI) и -DI (MDI)
if (um > dm && um > 0){
this.upm.push(um);
}else{
this.upm.push(0);
}
if (dm > um && dm > 0){
this.dwm.push(dm);
}else{
this.dwm.push(0);
}
if (this.upm.length >= this.period){
this.PDI.push(100*this.EMA.getFromPrices(this.upm)[this.upm.length - this.period]/this.ATR[this.ATR.length - 1]);
this.MDI.push(100*this.EMA.getFromPrices(this.dwm)[this.dwm.length - this.period]/this.ATR[this.ATR.length - 1]);
}
// Вычисление ADX
var vals = [];
for (var i = 0; i < this.PDI.length; i++){
vals.push(100*Math.abs(this.PDI[i]-this.MDI[i])/(this.PDI[i]+this.MDI[i]))
}
var ADX = null;
if (vals.length >= this.period){
ADX = this.EMA.getFromPrices(vals)[vals.length - this.period];
}
this.lastquote = quote;
return {"PDI":this.PDI[this.PDI.length - 1]||null, "MDI":this.MDI[this.MDI.length - 1]||null, "ADX":ADX};
}else{
this.lastquote = quote;
return null;
}
},
// Вывод значений индикатора на конкретных котировках
getFromQuotes: function(quotes,outtype){
var DMI = [];
this.reset();
for (var i = 0; i<quotes.length; i++){
var tmp = (this.append(quotes[i]));
if (tmp){
DMI.push(tmp);
}
}
if (outtype){
return DMI;
}else{
var PDI = [];
var MDI = [];
var ADX = [];
for (var i = 0; i < DMI.length; i++){
PDI.push(DMI[i].PDI);
MDI.push(DMI[i].MDI);
ADX.push(DMI[i].ADX);
}
return {"PDI":PDI, "MDI":MDI, "ADX":ADX};
}
}
}
Вспомогательный индикатор EMA:
var EMA = function (period) {
this.period = period || 10;
}
EMA.prototype = {
getFromDeltas: function (deltas, initialprice) {
if (deltas.length <= this.period) {
throw ReferenceError('The number of deltas is not enough for such a period: ' + this.period.toString())
}
var price = initialprice || 0;
var prices = [price];
for (var i = 0; i < deltas.length; i++) {
price += deltas[i].value || deltas[i];
prices.push(price);
}
return this.getFromPrices(prices);
},
getFromQuotes: function (quotes) {
if (quotes.length <= this.period) {
throw ReferenceError('The number of quotes is not enough for such a period: ' + this.period.toString())
}
var initialprice = quotes[0].open;
var deltas = [];
for (var i = 0; i < quotes.length - 1; i++) {
deltas.push(quotes[i + 1].open - quotes[i].open);
}
deltas.push(quotes[quotes.length - 1].close - quotes[quotes.length - 1].open);
return this.getFromDeltas(deltas, initialprice);
},
getFromPrices: function (prices) {
if (prices.length < this.period) {
throw ReferenceError('The number of prices is not enough for such a period: ' + this.period.toString())
}
var a = 2 / (this.period + 1);
var EMA = [this.average(prices.slice(0, this.period))];
for (var i = this.period; i < prices.length; i++) {
EMA.push(a * (prices[i] - EMA[i - this.period]) + EMA[i - this.period]);
}
return EMA;
},
average: function (a) {
var sum = 0;
for (var i = 0; i < a.length; i++) {
sum = sum + a[i];
}
return sum / a.length
}
}
После вычислений на различных котировках значения не совпадают с реальными (которые на торговых платформах)
Пробежался с отладчиком, и все равно ошибок не нашел
Котировки использую в виде
[{
"open": 1.14178,
"high": 1.14203,
"low": 1.141695,
"close": 1.14203,
"created_at": "2018-10-27T00:00:00.000000Z"
}, {
"open": 1.14203,
"high": 1.142045,
"low": 1.14189,
"close": 1.141915,
"created_at": "2018-10-27T00:01:00.000000Z"
}
//, и так далее, по возрастанию времени
]
В чем может быть ошибка?
Заранее спасибо