При написании стратегий JavaScript, из-за некоторых проблем самого языка сценариев, это часто приводит к проблемам численной точности в расчетах.1 - 0.8
или0.33 * 1.1
, данные об ошибке будут рассчитаны:
function main() {
var a = 1 - 0.8
Log(a)
var c = 0.33 * 1.1
Log(c)
}
Итак, как решить такие проблемы?
Максимальный прогресс значений с плавающей запятой составляет 17 знаков с запятой, но точность гораздо хуже, чем целых при выполнении операций; целые числа преобразуются в десятичные при выполнении операций; и при расчете десятичных операций в Java и JavaScript, оба Сначала преобразуйте десятичную запятую в соответствующую двоичную, часть десятичной не может быть полностью преобразована в двоичную, вот первая ошибка. После того, как десятичные преобразуются в двоичную, затем операция между двоичной выполняется, чтобы получить двоичный результат. Затем преобразуйте двоичный результат в десятичный, где обычно возникает вторая ошибка.
Чтобы решить эту проблему, я искал некоторые решения в Интернете, и проверил и использовал следующие решения для решения этой проблемы:
function mathService() {
// addition
this.add = function(a, b) {
var c, d, e;
try {
c = a.toString().split(".")[1].length; // Get the decimal length of a
} catch (f) {
c = 0;
}
try {
d = b.toString().split(".")[1].length; // Get the decimal length of b
} catch (f) {
d = 0;
}
//Find e first, multiply both a and b by e to convert to integer addition, then divide by e to restore
return e = Math.pow(10, Math.max(c, d)), (this.mul(a, e) + this.mul(b, e)) / e;
}
// multiplication
this.mul = function(a, b) {
var c = 0,
d = a.toString(), // Convert to string
e = b.toString(); // ...
try {
c += d.split(".")[1].length; // c Accumulate the fractional digit length of a
} catch (f) {}
try {
c += e.split(".")[1].length; // c Accumulate the length of decimal places of b
} catch (f) {}
// Convert to integer multiplication, then divide by 10^c, move decimal point, restore, use integer multiplication without losing accuracy
return Number(d.replace(".", "")) * Number(e.replace(".", "")) / Math.pow(10, c);
}
// Subtraction
this.sub = function(a, b) {
var c, d, e;
try {
c = a.toString().split(".")[1].length; // Get the decimal length of a
} catch (f) {
c = 0;
}
try {
d = b.toString().split(".")[1].length; // Get the decimal length of b
} catch (f) {
d = 0;
}
// Same as addition
return e = Math.pow(10, Math.max(c, d)), (this.mul(a, e) - this.mul(b, e)) / e;
}
// Division
this.div = function(a, b) {
var c, d, e = 0,
f = 0;
try {
e = a.toString().split(".")[1].length;
} catch (g) {}
try {
f = b.toString().split(".")[1].length;
} catch (g) {}
// Similarly, convert to integer, after operation, restore
return c = Number(a.toString().replace(".", "")), d = Number(b.toString().replace(".", "")), this.mul(c / d, Math.pow(10, f - e));
}
}
function main() {
var obj = new mathService()
var a = 1 - 0.8
Log(a)
var b = obj.sub(1, 0.8)
Log(b)
var c = 0.33 * 1.1
Log(c)
var d = obj.mul(0.33, 1.1)
Log(d)
}
Принцип заключается в том, чтобы преобразовать два операнда, которые должны быть рассчитаны, в целые числа для вычисления, чтобы избежать проблем с точностью.
Таким образом, когда мы хотим, чтобы программа разместить заказ, когда рыночная цена плюс минимальная точность цены, мы не должны беспокоиться о численной точности
function mathService() {
.... // Omitted
}
function main() {
var obj = new mathService()
var depth = exchange.GetDepth()
exchange.Sell(obj.add(depth.Bids[0].Price, 0.0001), depth.Bids[0].Amount, "Buy 1 order:", depth.Bids[0])
}
Интересующиеся трейдеры могут читать код, понимать процесс расчета, задавать вопросы, учиться вместе и развиваться вместе.