Розробка API для управління торговим ботом
Торговий бот без API управління — моноліт: щоб змінити параметр, потрібно лезти на сервер, редагувати конфіг, перезапускати. Management API вирішує це: бот керується віддалено через HTTP або WebSocket, параметри змінюються на льоту без перезапуску.
Архітектура Management API
Основні ендпоінти
// Bot lifecycle
POST /api/v1/bot/start - запустити бота
POST /api/v1/bot/stop - зупинити
POST /api/v1/bot/pause - пауза (не відкриває нові позиції)
GET /api/v1/bot/status - поточний статус
// Конфігурація
GET /api/v1/bot/config - поточні параметри
PUT /api/v1/bot/config - оновити параметри (hot reload)
// Моніторинг
GET /api/v1/bot/stats - P&L, метрики
GET /api/v1/bot/positions - відкриті позиції
GET /api/v1/bot/trades?from=&to= - історія сділок
GET /api/v1/bot/logs?level=&limit= - логи в реальному часі
// Ручні операції
POST /api/v1/bot/close-all - примусово закрити всі позиції
POST /api/v1/bot/cancel-pending - відмінити pending ордери
Hot Reload конфігурації
type BotConfig struct {
mu sync.RWMutex
Symbol string `json:"symbol"`
Timeframe string `json:"timeframe"`
PositionSizePct float64 `json:"position_size_pct"`
StopLossPct float64 `json:"stop_loss_pct"`
TakeProfitPct float64 `json:"take_profit_pct"`
MaxPositions int `json:"max_positions"`
Enabled bool `json:"enabled"`
}
func (c *BotConfig) Update(newConfig map[string]interface{}) error {
c.mu.Lock()
defer c.mu.Unlock()
// Валідація
if sl, ok := newConfig["stop_loss_pct"].(float64); ok {
if sl < 0.1 || sl > 50 {
return errors.New("stop_loss_pct повинен бути між 0.1 та 50")
}
c.StopLossPct = sl
}
if pct, ok := newConfig["position_size_pct"].(float64); ok {
if pct < 1 || pct > 100 {
return errors.New("position_size_pct повинен бути між 1 та 100")
}
c.PositionSizePct = pct
}
// Бот підхопить нові параметри на наступному циклі
return nil
}
// Handler для PUT /config
func (h *Handler) UpdateConfig(w http.ResponseWriter, r *http.Request) {
var updates map[string]interface{}
json.NewDecoder(r.Body).Decode(&updates)
if err := h.bot.Config.Update(updates); err != nil {
writeError(w, 400, err.Error())
return
}
writeJSON(w, map[string]interface{}{
"success": true,
"config": h.bot.Config.Get(),
})
}
WebSocket для real-time моніторингу
// Бот публікує события в канал, API транслює через WebSocket
type BotEvent struct {
Type string `json:"type"` // trade, signal, error, status_change
Timestamp int64 `json:"ts"`
Data interface{} `json:"data"`
}
func (api *ManagementAPI) StreamEvents(w http.ResponseWriter, r *http.Request) {
conn, _ := upgrader.Upgrade(w, r, nil)
defer conn.Close()
subscription := api.bot.EventBus.Subscribe()
defer api.bot.EventBus.Unsubscribe(subscription)
for {
select {
case event := <-subscription:
conn.WriteJSON(event)
case <-r.Context().Done():
return
}
}
}
Аутентифікація Management API
Management API керує реальними грошима — доступ повинен бути строго обмежений:
func authMiddleware(secret string) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
if !strings.HasPrefix(token, "Bearer ") {
writeError(w, 401, "Unauthorized")
return
}
if token[7:] != secret {
writeError(w, 401, "Invalid token")
return
}
next.ServeHTTP(w, r)
})
}
}
Bind тільки на localhost або через VPN — Management API не повинен бути відкритий в інтернет напрямку.
Dashboard (опціональний UI)
Простий веб-інтерфейс для управління ботом:
// React компонент управління ботом
function BotDashboard() {
const [status, setStatus] = useState<BotStatus | null>(null);
// WebSocket для real-time оновлень
useEffect(() => {
const ws = new WebSocket(`ws://localhost:8080/ws/events`);
ws.onmessage = (e) => {
const event = JSON.parse(e.data);
if (event.type === 'status_change') setStatus(event.data);
if (event.type === 'trade') addTrade(event.data);
};
return () => ws.close();
}, []);
const toggleBot = async () => {
await fetch(`/api/v1/bot/${status?.running ? 'stop' : 'start'}`, { method: 'POST' });
};
return (
<div>
<StatusCard status={status} onToggle={toggleBot} />
<PnLChart />
<OpenPositions />
<ConfigEditor onSave={(config) => updateConfig(config)} />
</div>
);
}
Management API для торгового бота з hot reload конфігом, WebSocket стрімінгом та базовим dashboard розробляється за 2–3 тижні.







