Реализация Grid-бота в мобильном приложении
Grid-бот выставляет сетку ордеров выше и ниже текущей цены: продаёт на каждом уровне вверх, покупает на каждом уровне вниз. Интерфейс управления таким ботом требует визуализации сетки — пользователь должен видеть, где стоят ордера, какие исполнились, какой PnL принёс каждый уровень.
Параметры Grid-стратегии
Минимальный набор параметров для настройки:
- Диапазон — нижняя и верхняя граница сетки в USDT (например, 60,000 — 70,000 для BTC)
- Количество уровней — 10 уровней означает шаг (70,000 − 60,000) / 10 = $1,000
- Размер ордера — $100 на каждый уровень
- Тип сетки — арифметическая (равный шаг в USD) или геометрическая (равный шаг в %)
Геометрическая сетка корректна для волатильных активов: шаг $500 имеет смысл при BTC на $10,000, но ничтожен при $60,000. При геометрической сетке уровни рассчитываются как lower * (upper/lower)^(i/n).
// Android — вычисление уровней сетки
fun calculateGridLevels(
lower: Double,
upper: Double,
count: Int,
type: GridType
): List<Double> = when (type) {
GridType.ARITHMETIC -> {
val step = (upper - lower) / count
(0..count).map { i -> lower + step * i }
}
GridType.GEOMETRIC -> {
val ratio = (upper / lower).pow(1.0 / count)
(0..count).map { i -> lower * ratio.pow(i.toDouble()) }
}
}
Пользователь вводит диапазон и число уровней — приложение сразу показывает предпросмотр: вот уровни, вот шаг между ними, вот суммарный капитал, который потребуется на все ордера.
Визуализация сетки
Это главный UI-вызов. Нужен кастомный виджет: горизонтальные линии уровней сетки на фоне ценового графика. Исполненные ордера — зелёные/красные маркеры. Текущая цена — пульсирующая линия.
На Flutter это CustomPainter:
class GridChartPainter extends CustomPainter {
final List<GridLevel> levels;
final List<PricePoint> priceHistory;
final double currentPrice;
@override
void paint(Canvas canvas, Size size) {
final priceRange = levels.last.price - levels.first.price;
final priceToY = (double price) =>
size.height - (price - levels.first.price) / priceRange * size.height;
// Рисуем уровни сетки
for (final level in levels) {
final y = priceToY(level.price);
final paint = Paint()
..color = level.hasFilled ? Colors.green.withOpacity(0.3) : Colors.grey.withOpacity(0.2)
..strokeWidth = 1;
canvas.drawLine(Offset(0, y), Offset(size.width, y), paint);
// Лейбл цены
final tp = TextPainter(
text: TextSpan(text: level.price.toStringAsFixed(0), style: const TextStyle(fontSize: 10)),
textDirection: TextDirection.ltr,
)..layout();
tp.paint(canvas, Offset(4, y - 12));
}
// Ценовая линия
final pricePaint = Paint()..color = Colors.blue..strokeWidth = 1.5;
for (int i = 1; i < priceHistory.length; i++) {
canvas.drawLine(
Offset(size.width * (i-1) / priceHistory.length, priceToY(priceHistory[i-1].price)),
Offset(size.width * i / priceHistory.length, priceToY(priceHistory[i].price)),
pricePaint,
);
}
}
@override
bool shouldRepaint(GridChartPainter old) =>
old.currentPrice != currentPrice || old.levels != levels;
}
Статистика Grid-бота
Grid PnL — суммарный доход от исполненных пар ордеров (купил на нижнем уровне, продал на верхнем). Каждая сработавшая пара приносит шаг_сетки × размер_ордера. При 10 уровнях и $1,000 шаге: каждый проход туда-обратно = $1,000 прибыли с позиции $100 ордер.
Floating PnL — нереализованная прибыль/убыток от того, что цена вышла за диапазон. Если BTC упал ниже нижней границы сетки — бот держит все купленные ордера в убытке до возврата цены в диапазон.
Также показываем: количество исполненных пар ордеров, число активных ордеров сейчас, капитал в работе.
Что входит в работу
- Форма настройки с выбором типа сетки и предпросмотром уровней
- Кастомный виджет визуализации сетки (CustomPainter)
- Дашборд: Grid PnL, Floating PnL, число исполненных пар
- История исполненных ордеров с группировкой по парам
- Real-time обновление статуса ордеров через WebSocket
Сроки
6–8 рабочих дней — кастомный виджет сетки занимает значительную часть. Стоимость рассчитывается индивидуально после анализа требований.







