Comments 6
Робот построенный на Скользящих средних работает только на хорошем тренде,
При боковике, приводит к сливу счета.
И главное не увлечься оптимизацией торгового алгоритма на исторических данных, а то только на них он и будет показывать прибыль, а в реальном времени ничего.
Вообще в этом деле самое сложное это торговый алгоритм, это как Грааль, универсальных не существует, каждый алгоритм может будет работать на определенном тире рынка.
Если бы было так просто, то у же все бы использовали их, но с другой стороны это тут же привело бы к их "самовыражению".
Удачи.
Для этого я сделал небольшой хелпер-конвертер значений во float тип данных.
Гораздо интереснее обратный конвертер из units/nano в float - например, когда вы хотите вычислить целевую цену от входной - хотя бы для стоп-лосса как sourcePrice - 1%.
Например, вот тут вычисления опираются на floor, что в случае вычисленной цены типа 99.999999... даст {units : 99, nano : 999999999}, что слегка отличается от целевого ожидаемого {units : 100, nano : 0}.
Но самая большая проблема в этой реализации заключается в том, что такое представление целевой цены никак не соотносится с шагом цены инструмента (например, 0.02), и заявка с {units : 99, nano : 999999999} просто будет отклонена с ошибкой.
У меня получилось что-то типа вот такого:
const units2value = data => {
if (!data) {
return null;
}
const {units, nano} = data;
return !nano ? units : units + nano/1e9;
};
// minPriceIncrement берется из getInstrumentBy конкретного инструмента
const precision = -Math.floor(Math.log10(units2value(minPriceIncrement)));
const value2units = (value, p = precision) => {
if (value === undefined || value === null) {
return undefined;
}
if (Number.isInteger(value)) {
return {units : value, nano : 0};
}
let [
units
, nano
] = value
.toFixed(p) // ограничиваем значение целевой точностью
.split('.') // делим на целую и дробную части
.map((s, i) => Number(!i ? s : s.padEnd(9, '0'))); // nano расширяем до 9 цифр
const {
units : _units
, nano : _nano
} = minPriceIncrement;
if (p > 0 && !Number.isInteger(Math.log10(_nano))) { // округление до ближайшего шага цены
nano = Math.round(nano/_nano) * _nano;
if (nano == 1e9) { // защита от .999...
nano = 0;
units++;
}
}
return {units, nano : Math.sign(value) * nano};
};
Инвестиционные боты (почти) с нуля. Часть 1: теория и первые шаги реализации