Newer
Older
scalping-bot / src / main / java / com / scalping / bot / controller / BotController.java
package com.scalping.bot.controller;

import com.scalping.bot.analysis.TechnicalAnalyzer;
import com.scalping.bot.api.BybitApiClient;
import com.scalping.bot.api.OrderManager;
import com.scalping.bot.api.StateManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/api/bot")
public class BotController {
    private final BybitApiClient apiClient;
    private final OrderManager orderManager;
    private final TechnicalAnalyzer analyzer;
    private final StateManager stateManager;
    private volatile boolean isRunning = false;

    public BotController(BybitApiClient apiClient, OrderManager orderManager,
                         TechnicalAnalyzer analyzer, StateManager stateManager) {
        this.apiClient = apiClient;
        this.orderManager = orderManager;
        this.analyzer = analyzer;
        this.stateManager = stateManager;
    }

    @PostMapping("/start")
    public Map<String, Object> startBot() {
        isRunning = true;
        List<StateManager.TradeState> recovered = stateManager.recoverAllTrades();
        log.info("Bot started. Recovered {} trades", recovered.size());
        return Map.of("status", "started", "recoveredTrades", recovered.size());
    }

    @PostMapping("/stop")
    public Map<String, String> stopBot() {
        isRunning = false;
        log.info("Bot stopped");
        return Map.of("status", "stopped");
    }

    @PostMapping("/place-order")
    public Map<String, Object> placeOrder(@RequestParam String symbol, @RequestParam double quantity,
                                          @RequestParam double price) {
        boolean success = orderManager.placeOrder(symbol, quantity, price, OrderManager.Order.OrderType.LIMIT);
        return Map.of("success", success, "symbol", symbol, "quantity", quantity, "price", price);
    }

    @GetMapping("/status")
    public Map<String, Object> getStatus() {
        return Map.of(
                "running", isRunning,
                "activeOrders", orderManager.getActiveOrderCount(),
                "timestamp", System.currentTimeMillis()
        );
    }

    @GetMapping("/market/{symbol}")
    public Map<String, Object> getMarketData(@PathVariable String symbol) throws Exception {
        BybitApiClient.MarketData data = apiClient.getLatestPrice(symbol);
        return Map.of(
                "symbol", data.symbol(),
                "price", data.lastPrice(),
                "volume", data.volume(),
                "timestamp", data.timestamp()
        );
    }

    @GetMapping("/analytics")
    public Map<String, Object> getAnalytics() {
        return Map.of(
                "activeOrders", orderManager.getAllActiveOrders().size(),
                "isRunning", isRunning,
                "serverTime", System.currentTimeMillis()
        );
    }
}