Skip to content

以下是几个 Java 开发的开源项目,支持对接 OKX(欧易)和币安(Binance)交易所 API,涵盖量化交易、行情分析、自动套利等功能,适合 Java 开发者使用:


1. XChange(推荐)

  • GitHub: https://github.com/knowm/XChange
  • 特点
    • 支持 50+ 交易所(包括 Binance、OKX、Coinbase、Kraken 等)。
    • 提供 REST + WebSocket 接口,适合高频交易。
    • 支持 现货、合约、期权 交易。
  • 代码示例(获取 BTC/USDT 行情)
    java
    import org.knowm.xchange.Exchange;
    import org.knowm.xchange.ExchangeFactory;
    import org.knowm.xchange.binance.BinanceExchange;
    import org.knowm.xchange.currency.CurrencyPair;
    import org.knowm.xchange.dto.marketdata.Ticker;
    import org.knowm.xchange.service.marketdata.MarketDataService;
    
    public class BinanceTickerExample {
        public static void main(String[] args) throws Exception {
            Exchange exchange = ExchangeFactory.INSTANCE.createExchange(BinanceExchange.class);
            MarketDataService marketDataService = exchange.getMarketDataService();
            Ticker ticker = marketDataService.getTicker(CurrencyPair.BTC_USDT);
            System.out.println("BTC/USDT 最新价格: " + ticker.getLast());
        }
    }
    import org.knowm.xchange.Exchange;
    import org.knowm.xchange.ExchangeFactory;
    import org.knowm.xchange.binance.BinanceExchange;
    import org.knowm.xchange.currency.CurrencyPair;
    import org.knowm.xchange.dto.marketdata.Ticker;
    import org.knowm.xchange.service.marketdata.MarketDataService;
    
    public class BinanceTickerExample {
        public static void main(String[] args) throws Exception {
            Exchange exchange = ExchangeFactory.INSTANCE.createExchange(BinanceExchange.class);
            MarketDataService marketDataService = exchange.getMarketDataService();
            Ticker ticker = marketDataService.getTicker(CurrencyPair.BTC_USDT);
            System.out.println("BTC/USDT 最新价格: " + ticker.getLast());
        }
    }
  • 适用场景
    • 量化交易、自动交易机器人、行情监控。

2. Binance Connector(官方 Java SDK)

  • GitHub: https://github.com/binance/binance-connector-java
  • 特点
    • Binance 官方维护,稳定性高。
    • 支持 REST + WebSocket 行情、交易、账户管理。
    • 适合 高频交易、量化策略开发
  • 代码示例(查询账户余额)
    java
    import com.binance.connector.client.impl.SpotClientImpl;
    import java.util.LinkedHashMap;
    
    public class BinanceAccountExample {
        public static void main(String[] args) {
            String apiKey = "YOUR_API_KEY";
            String secretKey = "YOUR_SECRET_KEY";
            
            SpotClientImpl client = new SpotClientImpl(apiKey, secretKey);
            LinkedHashMap<String, Object> params = new LinkedHashMap<>();
            String result = client.createTrade().account(params);
            System.out.println("账户信息: " + result);
        }
    }
    import com.binance.connector.client.impl.SpotClientImpl;
    import java.util.LinkedHashMap;
    
    public class BinanceAccountExample {
        public static void main(String[] args) {
            String apiKey = "YOUR_API_KEY";
            String secretKey = "YOUR_SECRET_KEY";
            
            SpotClientImpl client = new SpotClientImpl(apiKey, secretKey);
            LinkedHashMap<String, Object> params = new LinkedHashMap<>();
            String result = client.createTrade().account(params);
            System.out.println("账户信息: " + result);
        }
    }
  • 适用场景
    • Binance 交易所的自动化交易、高频策略。

3. OKX Java SDK(官方)

  • GitHub: https://github.com/okx/api-examples/tree/master/java
  • 特点
    • OKX 官方提供的 Java SDK,支持 REST + WebSocket
    • 涵盖 现货、合约、期权、杠杆交易
  • 代码示例(获取 BTC/USDT 行情)
    java
    import okhttp3.*;
    import java.io.IOException;
    
    public class OkxTickerExample {
        public static void main(String[] args) throws IOException {
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder()
                    .url("https://www.okx.com/api/v5/market/ticker?instId=BTC-USDT")
                    .build();
            Response response = client.newCall(request).execute();
            System.out.println("BTC/USDT 行情: " + response.body().string());
        }
    }
    import okhttp3.*;
    import java.io.IOException;
    
    public class OkxTickerExample {
        public static void main(String[] args) throws IOException {
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder()
                    .url("https://www.okx.com/api/v5/market/ticker?instId=BTC-USDT")
                    .build();
            Response response = client.newCall(request).execute();
            System.out.println("BTC/USDT 行情: " + response.body().string());
        }
    }
  • 适用场景
    • OKX 交易所的量化交易、自动交易机器人。

4. TA4J(技术分析库)

  • GitHub: https://github.com/ta4j/ta4j
  • 特点
    • 纯 Java 技术分析库,支持 EMA、RSI、MACD、布林带 等指标。
    • 可与 XChange 结合,实现量化策略回测。
  • 代码示例(计算 RSI 指标)
    java
    import org.ta4j.core.*;
    import org.ta4j.core.indicators.RSIIndicator;
    import org.ta4j.core.indicators.helpers.ClosePriceIndicator;
    
    public class RSIExample {
        public static void main(String[] args) {
            BarSeries series = new BaseBarSeriesBuilder().withName("BTC_USDT").build();
            // 添加K线数据(如从交易所API获取)
            ClosePriceIndicator closePrice = new ClosePriceIndicator(series);
            RSIIndicator rsi = new RSIIndicator(closePrice, 14);
            System.out.println("当前 RSI(14): " + rsi.getValue(series.getEndIndex()));
        }
    }
    import org.ta4j.core.*;
    import org.ta4j.core.indicators.RSIIndicator;
    import org.ta4j.core.indicators.helpers.ClosePriceIndicator;
    
    public class RSIExample {
        public static void main(String[] args) {
            BarSeries series = new BaseBarSeriesBuilder().withName("BTC_USDT").build();
            // 添加K线数据(如从交易所API获取)
            ClosePriceIndicator closePrice = new ClosePriceIndicator(series);
            RSIIndicator rsi = new RSIIndicator(closePrice, 14);
            System.out.println("当前 RSI(14): " + rsi.getValue(series.getEndIndex()));
        }
    }
  • 适用场景
    • 量化策略开发、回测、技术分析。

5. Cryptomator(加密存储,非交易)

  • GitHub: https://github.com/cryptomator/cryptomator
  • 特点
    • 开源文件加密工具,可用于 安全存储 API 密钥
    • 适用于需要保护交易数据的开发者。
  • 适用场景
    • 保护交易所 API Key、交易日志加密。

总结:Java 开源项目推荐

项目适用场景交易所支持特点
XChange多交易所API对接Binance, OKX, 50+灵活,适合量化交易
Binance ConnectorBinance 官方SDKBinance高频交易支持
OKX Java SDKOKX 官方SDKOKX合约、期权支持
TA4J技术分析、回测无(需结合XChange)EMA/RSI/MACD
CryptomatorAPI密钥加密存储安全存储

推荐组合

  1. XChange + TA4J → 量化策略开发(回测+实盘)。
  2. Binance Connector + OKX SDK → 高频套利交易。
  3. Cryptomator → 保护API密钥安全。

这些项目均开源,适合 Java 开发者构建自己的交易系统! 🚀

以下是基于 XChange + TA4J 的量化策略开发全流程指南,涵盖环境搭建、策略编写、回测与实盘部署,并提供完整代码示例:


1. 环境准备

(1) 安装依赖

bash
# 安装 XChange (交易所API) 和 TA4J (技术分析库)
pip install ccxt  # XChange的Python替代方案(Java版XChange需Maven)
# 安装 XChange (交易所API) 和 TA4J (技术分析库)
pip install ccxt  # XChange的Python替代方案(Java版XChange需Maven)

对于 Java 项目(使用Maven):

xml
<!-- pom.xml -->
<dependencies>
    <!-- XChange -->
    <dependency>
        <groupId>org.knowm.xchange</groupId>
        <artifactId>xchange-binance</artifactId>
        <version>5.0.15</version>
    </dependency>
    <!-- TA4J -->
    <dependency>
        <groupId>org.ta4j</groupId>
        <artifactId>ta4j-core</artifactId>
        <version>0.15</version>
    </dependency>
</dependencies>
<!-- pom.xml -->
<dependencies>
    <!-- XChange -->
    <dependency>
        <groupId>org.knowm.xchange</groupId>
        <artifactId>xchange-binance</artifactId>
        <version>5.0.15</version>
    </dependency>
    <!-- TA4J -->
    <dependency>
        <groupId>org.ta4j</groupId>
        <artifactId>ta4j-core</artifactId>
        <version>0.15</version>
    </dependency>
</dependencies>

2. 数据获取(XChange)

(1) 从交易所获取K线数据

java
import org.knowm.xchange.Exchange;
import org.knowm.xchange.ExchangeFactory;
import org.knowm.xchange.binance.BinanceExchange;
import org.knowm.xchange.dto.marketdata.Kline;
import org.knowm.xchange.service.marketdata.MarketDataService;
import java.util.List;

public class DataFetcher {
    public static void main(String[] args) throws Exception {
        // 初始化Binance交易所
        Exchange exchange = ExchangeFactory.INSTANCE.createExchange(BinanceExchange.class);
        MarketDataService marketDataService = exchange.getMarketDataService();

        // 获取BTC/USDT的1小时K线(最近100根)
        List<Kline> klines = marketDataService.getKlines("BTC/USDT", "1h", 100);
        System.out.println("最新K线收盘价: " + klines.get(klines.size() - 1).getClose());
    }
}
import org.knowm.xchange.Exchange;
import org.knowm.xchange.ExchangeFactory;
import org.knowm.xchange.binance.BinanceExchange;
import org.knowm.xchange.dto.marketdata.Kline;
import org.knowm.xchange.service.marketdata.MarketDataService;
import java.util.List;

public class DataFetcher {
    public static void main(String[] args) throws Exception {
        // 初始化Binance交易所
        Exchange exchange = ExchangeFactory.INSTANCE.createExchange(BinanceExchange.class);
        MarketDataService marketDataService = exchange.getMarketDataService();

        // 获取BTC/USDT的1小时K线(最近100根)
        List<Kline> klines = marketDataService.getKlines("BTC/USDT", "1h", 100);
        System.out.println("最新K线收盘价: " + klines.get(klines.size() - 1).getClose());
    }
}

(2) 转换为TA4J的BarSeries

java
import org.ta4j.core.*;
import org.ta4j.core.num.DoubleNum;
import java.time.ZonedDateTime;

public class DataConverter {
    public static BarSeries convertToTa4j(List<Kline> klines) {
        BarSeries series = new BaseBarSeriesBuilder().withName("BTC_USDT").build();
        for (Kline kline : klines) {
            Bar bar = new BaseBar(
                kline.getTime(),                              // 时间
                kline.getOpen(), kline.getHigh(),             // 开盘价、最高价
                kline.getLow(), kline.getClose(),            // 最低价、收盘价
                kline.getVolume(),                           // 成交量
                DoubleNum::valueOf                            // 数值类型
            );
            series.addBar(bar);
        }
        return series;
    }
}
import org.ta4j.core.*;
import org.ta4j.core.num.DoubleNum;
import java.time.ZonedDateTime;

public class DataConverter {
    public static BarSeries convertToTa4j(List<Kline> klines) {
        BarSeries series = new BaseBarSeriesBuilder().withName("BTC_USDT").build();
        for (Kline kline : klines) {
            Bar bar = new BaseBar(
                kline.getTime(),                              // 时间
                kline.getOpen(), kline.getHigh(),             // 开盘价、最高价
                kline.getLow(), kline.getClose(),            // 最低价、收盘价
                kline.getVolume(),                           // 成交量
                DoubleNum::valueOf                            // 数值类型
            );
            series.addBar(bar);
        }
        return series;
    }
}

3. 策略编写(TA4J)

(1) 双均线交叉策略

java
import org.ta4j.core.*;
import org.ta4j.core.indicators.SMAIndicator;
import org.ta4j.core.trading.rules.CrossedUpIndicatorRule;
import org.ta4j.core.trading.rules.CrossedDownIndicatorRule;

public class MovingAverageStrategy {
    public static Strategy buildStrategy(BarSeries series) {
        // 指标定义
        ClosePriceIndicator closePrice = new ClosePriceIndicator(series);
        SMAIndicator shortSma = new SMAIndicator(closePrice, 5);   // 5日均线
        SMAIndicator longSma = new SMAIndicator(closePrice, 20);   // 20日均线

        // 交易规则
        Rule entryRule = new CrossedUpIndicatorRule(shortSma, longSma);  // 短线上穿长线:买入
        Rule exitRule = new CrossedDownIndicatorRule(shortSma, longSma); // 短线下穿长线:卖出

        return new BaseStrategy(entryRule, exitRule);
    }
}
import org.ta4j.core.*;
import org.ta4j.core.indicators.SMAIndicator;
import org.ta4j.core.trading.rules.CrossedUpIndicatorRule;
import org.ta4j.core.trading.rules.CrossedDownIndicatorRule;

public class MovingAverageStrategy {
    public static Strategy buildStrategy(BarSeries series) {
        // 指标定义
        ClosePriceIndicator closePrice = new ClosePriceIndicator(series);
        SMAIndicator shortSma = new SMAIndicator(closePrice, 5);   // 5日均线
        SMAIndicator longSma = new SMAIndicator(closePrice, 20);   // 20日均线

        // 交易规则
        Rule entryRule = new CrossedUpIndicatorRule(shortSma, longSma);  // 短线上穿长线:买入
        Rule exitRule = new CrossedDownIndicatorRule(shortSma, longSma); // 短线下穿长线:卖出

        return new BaseStrategy(entryRule, exitRule);
    }
}

(2) RSI超买超卖策略

java
import org.ta4j.core.indicators.RSIIndicator;
import org.ta4j.core.trading.rules.UnderThresholdRule;
import org.ta4j.core.trading.rules.OverThresholdRule;

public class RsiStrategy {
    public static Strategy buildStrategy(BarSeries series) {
        ClosePriceIndicator closePrice = new ClosePriceIndicator(series);
        RSIIndicator rsi = new RSIIndicator(closePrice, 14);  // RSI(14)

        // RSI < 30 买入,RSI > 70 卖出
        Rule entryRule = new UnderThresholdRule(rsi, 30);
        Rule exitRule = new OverThresholdRule(rsi, 70);

        return new BaseStrategy(entryRule, exitRule);
    }
}
import org.ta4j.core.indicators.RSIIndicator;
import org.ta4j.core.trading.rules.UnderThresholdRule;
import org.ta4j.core.trading.rules.OverThresholdRule;

public class RsiStrategy {
    public static Strategy buildStrategy(BarSeries series) {
        ClosePriceIndicator closePrice = new ClosePriceIndicator(series);
        RSIIndicator rsi = new RSIIndicator(closePrice, 14);  // RSI(14)

        // RSI < 30 买入,RSI > 70 卖出
        Rule entryRule = new UnderThresholdRule(rsi, 30);
        Rule exitRule = new OverThresholdRule(rsi, 70);

        return new BaseStrategy(entryRule, exitRule);
    }
}

4. 回测引擎

java
import org.ta4j.core.*;
import org.ta4j.core.analysis.criteria.TotalProfitCriterion;

public class BacktestEngine {
    public static void run(BarSeries series, Strategy strategy) {
        // 初始化交易历史
        TradingRecord tradingRecord = new BaseTradingRecord();

        // 运行回测
        for (int i = series.getBeginIndex(); i <= series.getEndIndex(); i++) {
            if (strategy.shouldEnter(i)) {
                tradingRecord.enter(i, series.getBar(i).getClosePrice(), DoubleNum.valueOf(10)); // 买入10单位
            } else if (strategy.shouldExit(i)) {
                tradingRecord.exit(i, series.getBar(i).getClosePrice(), DoubleNum.valueOf(10));
            }
        }

        // 打印结果
        System.out.println("总交易次数: " + tradingRecord.getTradeCount());
        System.out.println("总盈亏: " + new TotalProfitCriterion().calculate(series, tradingRecord));
    }
}
import org.ta4j.core.*;
import org.ta4j.core.analysis.criteria.TotalProfitCriterion;

public class BacktestEngine {
    public static void run(BarSeries series, Strategy strategy) {
        // 初始化交易历史
        TradingRecord tradingRecord = new BaseTradingRecord();

        // 运行回测
        for (int i = series.getBeginIndex(); i <= series.getEndIndex(); i++) {
            if (strategy.shouldEnter(i)) {
                tradingRecord.enter(i, series.getBar(i).getClosePrice(), DoubleNum.valueOf(10)); // 买入10单位
            } else if (strategy.shouldExit(i)) {
                tradingRecord.exit(i, series.getBar(i).getClosePrice(), DoubleNum.valueOf(10));
            }
        }

        // 打印结果
        System.out.println("总交易次数: " + tradingRecord.getTradeCount());
        System.out.println("总盈亏: " + new TotalProfitCriterion().calculate(series, tradingRecord));
    }
}

5. 实盘交易(XChange)

java
import org.knowm.xchange.dto.trade.MarketOrder;
import org.knowm.xchange.service.trade.TradeService;

public class LiveTrader {
    public static void executeTrade(Exchange exchange, boolean isBuy, String symbol, double amount) {
        TradeService tradeService = exchange.getTradeService();
        MarketOrder order = new MarketOrder(
            isBuy ? Order.OrderType.BID : Order.OrderType.ASK,
            BigDecimal.valueOf(amount),
            new CurrencyPair(symbol)
        );
        try {
            String orderId = tradeService.placeMarketOrder(order);
            System.out.println("订单已提交,ID: " + orderId);
        } catch (Exception e) {
            System.err.println("交易失败: " + e.getMessage());
        }
    }
}
import org.knowm.xchange.dto.trade.MarketOrder;
import org.knowm.xchange.service.trade.TradeService;

public class LiveTrader {
    public static void executeTrade(Exchange exchange, boolean isBuy, String symbol, double amount) {
        TradeService tradeService = exchange.getTradeService();
        MarketOrder order = new MarketOrder(
            isBuy ? Order.OrderType.BID : Order.OrderType.ASK,
            BigDecimal.valueOf(amount),
            new CurrencyPair(symbol)
        );
        try {
            String orderId = tradeService.placeMarketOrder(order);
            System.out.println("订单已提交,ID: " + orderId);
        } catch (Exception e) {
            System.err.println("交易失败: " + e.getMessage());
        }
    }
}

6. 全流程整合

java
public class Main {
    public static void main(String[] args) throws Exception {
        // 1. 获取数据
        List<Kline> klines = DataFetcher.fetchKlines("BTC/USDT", "1h", 100);
        BarSeries series = DataConverter.convertToTa4j(klines);

        // 2. 构建策略
        Strategy strategy = MovingAverageStrategy.buildStrategy(series);

        // 3. 回测
        BacktestEngine.run(series, strategy);

        // 4. 实盘(需配置API密钥)
        Exchange exchange = ExchangeFactory.INSTANCE.createExchange(BinanceExchange.class);
        exchange.getExchangeSpecification().setApiKey("YOUR_API_KEY");
        exchange.getExchangeSpecification().setSecretKey("YOUR_SECRET");

        // 根据策略信号交易
        int lastIndex = series.getEndIndex();
        if (strategy.shouldEnter(lastIndex)) {
            LiveTrader.executeTrade(exchange, true, "BTC/USDT", 0.01);
        }
    }
}
public class Main {
    public static void main(String[] args) throws Exception {
        // 1. 获取数据
        List<Kline> klines = DataFetcher.fetchKlines("BTC/USDT", "1h", 100);
        BarSeries series = DataConverter.convertToTa4j(klines);

        // 2. 构建策略
        Strategy strategy = MovingAverageStrategy.buildStrategy(series);

        // 3. 回测
        BacktestEngine.run(series, strategy);

        // 4. 实盘(需配置API密钥)
        Exchange exchange = ExchangeFactory.INSTANCE.createExchange(BinanceExchange.class);
        exchange.getExchangeSpecification().setApiKey("YOUR_API_KEY");
        exchange.getExchangeSpecification().setSecretKey("YOUR_SECRET");

        // 根据策略信号交易
        int lastIndex = series.getEndIndex();
        if (strategy.shouldEnter(lastIndex)) {
            LiveTrader.executeTrade(exchange, true, "BTC/USDT", 0.01);
        }
    }
}

7. 进阶优化

(1) 参数优化

java
// 使用Walk-Forward优化均线周期
for (int shortPeriod = 5; shortPeriod <= 10; shortPeriod++) {
    for (int longPeriod = 20; longPeriod <= 50; longPeriod += 10) {
        Strategy tempStrategy = new MovingAverageStrategy(shortPeriod, longPeriod);
        BacktestEngine.run(series, tempStrategy);
    }
}
// 使用Walk-Forward优化均线周期
for (int shortPeriod = 5; shortPeriod <= 10; shortPeriod++) {
    for (int longPeriod = 20; longPeriod <= 50; longPeriod += 10) {
        Strategy tempStrategy = new MovingAverageStrategy(shortPeriod, longPeriod);
        BacktestEngine.run(series, tempStrategy);
    }
}

(2) 多线程回测

java
ExecutorService executor = Executors.newFixedThreadPool(4);
executor.submit(() -> BacktestEngine.run(series, strategy));
ExecutorService executor = Executors.newFixedThreadPool(4);
executor.submit(() -> BacktestEngine.run(series, strategy));

(3) 可视化结果

  • 使用 Matplotlib-JavaJFreeChart 绘制资金曲线:
    java
    // 示例:JFreeChart绘制净值曲线
    XYSeries equitySeries = new XYSeries("净值");
    for (Trade trade : tradingRecord.getTrades()) {
        equitySeries.add(trade.getExit().getIndex(), trade.getProfit().doubleValue());
    }
    // 示例:JFreeChart绘制净值曲线
    XYSeries equitySeries = new XYSeries("净值");
    for (Trade trade : tradingRecord.getTrades()) {
        equitySeries.add(trade.getExit().getIndex(), trade.getProfit().doubleValue());
    }

8. 关键注意事项

  1. 数据质量:确保K线数据无缺失(填充空白时段)。
  2. 手续费计算:在回测中扣除交易费用(Binance现货约0.1%)。
  3. 滑点控制:实盘使用限价单而非市价单。
  4. 风险控制:单笔交易不超过总资金的2%。

通过以上步骤,您已完成从数据获取到实盘交易的完整量化流程。XChange + TA4J 的组合尤其适合 中低频趋势跟踪策略(如均线、RSI)。如需高频交易,可改用 CCXT + 异步IO(Python)或 Alpaca API(美股)。