Налаштування параметрів торгового бота в мобільному додатку
Торговий бот працює на сервері, мобільний додаток є його панеллю керування. Користувачі приходять не програмувати бота, а налаштовувати його: встановити take-profit, stop-loss, розмір позиції, вибрати пари. Інтерфейс повинен бути передбачуваним, а невірні значення ніколи не повинні дійти до сервера.
Структура параметрів
Параметри торгового бота розділені на кілька груп, кожна вимагає свого підходу до UI:
Числові з обмеженнями. Take-profit у відсотках (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: 'Take Profit (%)',
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);
}
}
Підтвердження перед відправленням та захист від випадкових змін
Зміна параметрів працюючого бота — ризикована операція. Якщо бот наразі утримує відкриті позиції, зміна stop-loss або розміру ордера може спричинити неочікувані ордери. Тому перед відправленням — підтвердження з показом diff: «Take Profit: 2% → 3.5%».
Крім того: деякі параметри можна змінювати лише коли бот зупинений (наприклад, торгові пари або тип стратегії). Такі поля заблоковані в UI, якщо bot.status == RUNNING, з поясненням «Зупиніть бота для зміни».
Оптимістичне та песимістичне оновлення
Для операцій налаштувань робимо песимістичне оновлення: спочатку надсилаємо запит на сервер, при успіху — оновлюємо 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, точність)
- Вибір торгових пар з пошуком та завантаженням з API біржі
- Блокування небезпечних полів коли бот активний
- Діалог підтвердження з diff змін
- Збереження чернетки до SharedPreferences / UserDefaults (якщо користувач не зберіг)
Терміни
4–6 робочих днів залежно від кількості параметрів та складності правил валідації. Вартість розраховується індивідуально після аналізу вимог.







