Реализация настройки параметров торгового бота в мобильном приложении
Торговый бот работает на сервере, мобильное приложение — это его панель управления. Пользователь приходит не программировать бота, а настраивать: выставить тейк-профит, стоп-лосс, размер позиции, выбрать пары. Интерфейс должен быть предсказуемым, а неверные значения — не уходить на сервер.
Структура параметров
Параметры торгового бота делятся на несколько групп, и каждая требует своего подхода к UI:
Числовые с ограничениями. Тейк-профит в процентах (0.1–50%), размер ордера в USDT (минимум диктует биржа), плечо для фьючерсов (1x–125x). Для таких параметров — TextField с валидацией на лету плюс слайдер для быстрого выбора распространённых значений.
Перечисления. Тип ордера (limit/market/stop), направление (long/short/both), таймфрейм для сигнала. Здесь — Picker / DropdownMenu / сегментированные кнопки.
Торговые пары. Пользователь выбирает из списка доступных пар на бирже. Список подгружается через API биржи, кэшируется, поддерживает поиск.
// Flutter — форма параметров с валидацией
class BotSettingsForm extends ConsumerStatefulWidget { ... }
class _BotSettingsFormState extends ConsumerState<BotSettingsForm> {
final _formKey = GlobalKey<FormState>();
late TextEditingController _takeProfitController;
late TextEditingController _stopLossController;
@override
Widget build(BuildContext context) {
return Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: _takeProfitController,
keyboardType: const TextInputType.numberWithOptions(decimal: true),
inputFormatters: [FilteringTextInputFormatter.allow(RegExp(r'^\d+\.?\d{0,2}'))],
validator: (value) {
final v = double.tryParse(value ?? '');
if (v == null || v < 0.1 || v > 50) return 'Допустимо: 0.1 – 50%';
return null;
},
decoration: const InputDecoration(
labelText: 'Тейк-профит (%)',
suffixText: '%',
),
),
// ... другие поля
ElevatedButton(
onPressed: _submit,
child: const Text('Сохранить'),
),
],
),
);
}
void _submit() {
if (!_formKey.currentState!.validate()) return;
final params = BotParams(
takeProfit: double.parse(_takeProfitController.text),
stopLoss: double.parse(_stopLossController.text),
);
ref.read(botSettingsProvider.notifier).save(params);
}
}
Подтверждение перед отправкой и защита от случайных изменений
Изменение параметров работающего бота — опасная операция. Если бот сейчас держит открытые позиции, смена стоп-лосса или размера ордера может повлечь непредвиденные ордера. Поэтому перед отправкой — подтверждение с показом diff: «Тейк-профит: 2% → 3.5%».
Дополнительно: некоторые параметры можно менять только при остановленном боте (например, торговые пары или тип стратегии). Такие поля блокируются в UI, если bot.status == RUNNING, с пояснением «Остановите бота для изменения».
Оптимистичное обновление vs. ожидание ответа
Для операций с настройками делаем pessimistic update: сначала запрос на сервер, при успехе — обновляем UI. Не оптимистично, потому что если бот отверг параметры (например, минимальный ордер на бирже — $10, а пользователь ввёл $5), нужно сразу показать ошибку с сервера, а не откатывать.
На Riverpod (Flutter) паттерн через AsyncNotifier:
class BotSettingsNotifier extends AsyncNotifier<BotSettings> {
@override
Future<BotSettings> build() => ref.read(botRepositoryProvider).getSettings(botId);
Future<void> save(BotParams params) async {
state = const AsyncLoading();
state = await AsyncValue.guard(
() => ref.read(botRepositoryProvider).updateSettings(botId, params),
);
}
}
Что входит в работу
- Форма настроек с валидацией всех числовых полей (min/max, precision)
- Выбор торговых пар с поиском и подгрузкой из API биржи
- Блокировка опасных полей при активном боте
- Confirmation dialog с diff изменений
- Сохранение черновика в SharedPreferences / UserDefaults (если пользователь не сохранил)
Сроки
4–6 рабочих дней в зависимости от числа параметров и сложности валидационных правил. Стоимость рассчитывается индивидуально после анализа требований.







