The core architecture
REST can be sufficient for slower workflows; WebSocket streams are useful when the strategy requires event-driven market updates.
Entry and exit conditions should be isolated from exchange-specific request code so the trading logic remains testable.
Order placement, cancellation, status checks and exchange responses need explicit handling rather than assuming every request succeeds.
Position sizing, exposure limits, protective exits and maximum concurrent positions should be enforced independently of the entry signal.
Critical position and lifecycle information should survive a process restart instead of existing only in memory.
Logs, alerts and status endpoints make it possible to diagnose the bot without logging into the server for every question.
API keys should have the minimum permissions required
A trading bot normally needs trading access, but withdrawal permissions are a different risk category and should not be enabled merely because an API supports them. Secrets should stay outside public web files and source code repositories.
Restart recovery is part of trading logic
After a restart, the bot should reconcile persisted state with exchange state before making new decisions. Otherwise a process restart can create duplicate orders, forgotten positions or incorrect trade-management behavior.
Build for failure, not only for the happy path
Rate limits, network errors, rejected orders, partial fills, stale data and exchange maintenance are operational realities. A bot should define how it behaves when the expected response is unavailable.