Trading Bot Parameter Settings in Mobile App
The trading bot runs on the server, the mobile application is its control panel. Users don't come to program the bot, but to configure it: set take-profit, stop-loss, position size, select pairs. The interface should be predictable, and invalid values should never reach the server.
Parameter Structure
Trading bot parameters are divided into several groups, each requiring its own UI approach:
Numeric with constraints. Take-profit in percentage (0.1–50%), order size in USDT (minimum dictated by the exchange), leverage for futures (1x–125x). For such parameters—TextField with live validation plus a slider for quick selection of common values.
Enumerations. Order type (limit/market/stop), direction (long/short/both), timeframe for signal. Here—Picker / DropdownMenu / segmented buttons.
Trading pairs. User selects from available pairs on the exchange. List is loaded via exchange API, cached, supports search.
// Flutter — settings form with validation
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 'Allowed: 0.1 – 50%';
return null;
},
decoration: const InputDecoration(
labelText: 'Take Profit (%)',
suffixText: '%',
),
),
// ... other fields
ElevatedButton(
onPressed: _submit,
child: const Text('Save'),
),
],
),
);
}
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);
}
}
Confirmation Before Submission and Protection from Accidental Changes
Changing parameters of a running bot is a risky operation. If the bot currently holds open positions, changing stop-loss or order size could trigger unexpected orders. So before submission—confirmation showing a diff: "Take Profit: 2% → 3.5%".
Additionally: some parameters can only be changed when the bot is stopped (for example, trading pairs or strategy type). Such fields are locked in the UI if bot.status == RUNNING, with an explanation "Stop the bot to change".
Optimistic vs. Pessimistic Updates
For settings operations, we do pessimistic updates: first send request to server, on success—update UI. Not optimistic, because if the bot rejects parameters (for example, minimum order on exchange is $10, but user entered $5), we need to immediately show the server error rather than reverting.
On Riverpod (Flutter), the pattern is via 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),
);
}
}
What's Included
- Settings form with validation of all numeric fields (min/max, precision)
- Trading pair selection with search and loading from exchange API
- Locking dangerous fields when bot is active
- Confirmation dialog with diff of changes
- Draft saving to SharedPreferences / UserDefaults (if user hasn't saved)
Timeline
4–6 business days depending on the number of parameters and complexity of validation rules. Cost is calculated individually after requirements analysis.







