SpringBoot实战:稳定对接外汇黄金实时行情API

132 阅读3分钟

一、前言:专业行情数据对接的核心价值

对于量化交易、风控系统或实时监控应用,稳定的行情数据是生命线。本文将基于专业行情数据服务,展示如何用SpringBoot快速对接 外汇、贵金属、黄金、铂金、铑金 等实时行情api和K线数据。

获取授权的地址:http://39.107.99.235:1008/market

二、核心接口介绍

基于行情数据服务,我们主要对接以下核心接口:

1. HTTP实时行情接口

2. HTTP K线接口

3. 其他辅助接口

  • 产品分类接口:获取市场分类
  • 品种列表接口:获取可交易品种
  • WebSocket接口:实时推送(可选)

三、SpringBoot核心代码实现

3.1 实时行情获取服务

import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;

@Service
public class RealtimeQuoteService {
    
    // 实时行情接口地址
    private static final String QUOTE_URL = "http://39.107.99.235:1008/getQuote.php";
    private final RestTemplate restTemplate = new RestTemplate();
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    /**
     * 获取单个品种实时行情
     * @param symbol 品种代码,如:btcusdt, xauusd
     * @return 完整的行情数据
     */
    public Map<String, Object> getRealtimeQuote(String symbol) {
        try {
            String url = QUOTE_URL + "?code=" + symbol;
            
            // 设置gzip压缩头,提升传输效率
            HttpHeaders headers = new HttpHeaders();
            headers.set("Accept-Encoding", "gzip");
            HttpEntity<String> entity = new HttpEntity<>(headers);
            
            ResponseEntity<String> response = restTemplate.exchange(
                url, HttpMethod.GET, entity, String.class);
            
            if (response.getStatusCode().is2xxSuccessful()) {
                return objectMapper.readValue(response.getBody(), Map.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    /**
     * 批量获取多个品种行情
     * @param symbols 品种代码列表
     * @return 各品种行情数据
     */
    public Map<String, Map<String, Object>> getBatchQuotes(List<String> symbols) {
        Map<String, Map<String, Object>> result = new HashMap<>();
        
        // 使用并行流提升获取效率(注意频率限制)
        symbols.parallelStream().forEach(symbol -> {
            Map<String, Object> quote = getRealtimeQuote(symbol);
            if (quote != null) {
                result.put(symbol, quote);
            }
        });
        
        return result;
    }
}

3.1 K线数据获取服务

import org.springframework.stereotype.Service;
import java.util.List;

@Service
public class KlineDataService {
    
    // K线接口地址
    private static final String KLINE_URL = "http://39.107.99.235:1008/redis.php";
    private final RestTemplate restTemplate = new RestTemplate();
    
    /**
     * 获取K线数据
     * @param symbol 品种代码
     * @param interval 周期:1m, 5m, 15m, 30m, 1h, 1d, 1M
     * @param rows 获取条数
     * @return K线数据列表
     */
    public List<Object[]> getKlineData(String symbol, String interval, int rows) {
        try {
            String url = String.format("%s?code=%s&time=%s&rows=%d", 
                KLINE_URL, symbol, interval, rows);
            
            // 设置gzip压缩
            HttpHeaders headers = new HttpHeaders();
            headers.set("Accept-Encoding", "gzip");
            HttpEntity<String> entity = new HttpEntity<>(headers);
            
            ResponseEntity<String> response = restTemplate.exchange(
                url, HttpMethod.GET, entity, String.class);
            
            if (response.getStatusCode().is2xxSuccessful()) {
                ObjectMapper mapper = new ObjectMapper();
                return mapper.readValue(response.getBody(), List.class);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Collections.emptyList();
    }
    
    /**
     * K线数据字段说明
     * [时间戳, 开盘价, 最高价, 最低价, 收盘价, 时间字符串, 成交量]
     */
    public class KlineDTO {
        private Long timestamp;
        private Double open;
        private Double high;
        private Double low;
        private Double close;
        private String time;
        private Double volume;
        
        // 构造函数、getter、setter省略
    }
}

3.3 REST控制器(对外提供接口)

import org.springframework.web.bind.annotation.*;
import java.util.*;

@RestController
@RequestMapping("/api/market")
@Slf4j
public class MarketController {
    
    @Autowired
    private RealtimeQuoteService quoteService;
    
    @Autowired
    private KlineDataService klineService;
    
    /**
     * 获取黄金实时行情
     */
    @GetMapping("/gold/realtime")
    public Map<String, Object> getGoldPrice() {
        return quoteService.getRealtimeQuote("xauusd");
    }
    
    /**
     * 获取外汇实时行情
     */
    @GetMapping("/forex/realtime")
    public Map<String, Object> getForexPrice(@RequestParam String pair) {
        return quoteService.getRealtimeQuote(pair.toLowerCase());
    }
    
    /**
     * 获取K线数据
     */
    @GetMapping("/kline")
    public List<Object[]> getKline(
            @RequestParam String symbol,
            @RequestParam(defaultValue = "1h") String interval,
            @RequestParam(defaultValue = "100") int rows) {
        
        // 验证参数有效性
        List<String> validIntervals = Arrays.asList("1m", "5m", "15m", "30m", "1h", "1d", "1M");
        if (!validIntervals.contains(interval)) {
            throw new IllegalArgumentException("不支持的K线周期");
        }
        
        return klineService.getKlineData(symbol, interval, rows);
    }
    
    /**
     * 获取多个品种行情
     */
    @PostMapping("/batch-quotes")
    public Map<String, Map<String, Object>> getBatchQuotes(@RequestBody List<String> symbols) {
        // 限制最大请求品种数
        if (symbols.size() > 20) {
            throw new IllegalArgumentException("单次最多请求20个品种");
        }
        return quoteService.getBatchQuotes(symbols);
    }
}

四、总结

通过以上代码,你可以快速构建一个稳定可靠的行情数据服务系统。关键优势:

  1. 即拿即用:代码可直接运行,只需替换为你的测试地址

  2. 异常完备:包含频率控制、异常处理、缓存优化

  3. 扩展性强:支持轻松扩展更多数据接口

  4. 生产就绪:包含性能优化建议


技术栈:SpringBoot 2.7+ | JDK 11+ | Jackson | RestTemplate 适用场景:量化交易系统、风险监控、实时行情展示、数据分析平台