Basic Function Examples

The Tiger OpenAPI Java SDK provides APIs for retrieving Market Data, placing orders, and subscribing to streaming updates.

Retrieve Market Data

The following example retrieves daily candlestick bars for AAPL. Later examples place an order and subscribe to streaming updates. See the API reference for other markets, instruments, and request types.

The code comments include the configuration steps required to run each example.

import com.tigerbrokers.stock.openapi.client.config.ClientConfig;
import com.tigerbrokers.stock.openapi.client.https.client.TigerHttpClient;
import com.tigerbrokers.stock.openapi.client.https.request.quote.QuoteKlineRequest;
import com.tigerbrokers.stock.openapi.client.https.response.quote.QuoteKlineResponse;
import com.tigerbrokers.stock.openapi.client.struct.enums.KType;
import com.tigerbrokers.stock.openapi.client.struct.enums.RightOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class QuoteDemo {

  private static final TigerHttpClient client;

  static {
    ClientConfig clientConfig = ClientConfig.DEFAULT_CONFIG;
    // Storage path for the configuration file tiger_openapi_config.properties exported from the developer platform. The tiger_openapi_token.properties file for TBHK license is also in this directory
    clientConfig.configFilePath = "your_config_directory_path";
    // clientConfig.secretKey = "xxxxxx"; // Required field secret key for institutional account traders
    client = TigerHttpClient.getInstance().clientConfig(clientConfig);
  }

  public static void main(String[] args) {
    new QuoteDemo().kline();
  }

  public void kline() {
    List<String> symbols = new ArrayList<>();
    symbols.add("AAPL");
    QuoteKlineRequest request =
        QuoteKlineRequest.newRequest(symbols, KType.day, "2022-10-01", "2022-12-25")
            .withLimit(1000)
            .withRight(RightOption.br);
    QuoteKlineResponse response = client.execute(request);
    if (response.isSuccess()) {
      System.out.println(Arrays.toString(response.getKlineItems().toArray()));
    } else {
      System.out.println("response error:" + response.getMessage());
    }
  }
}

Place Order

This example places a limit order for one share of AAPL at USD 100:

import com.alibaba.fastjson.JSONObject;
import com.tigerbrokers.stock.openapi.client.config.ClientConfig;
import com.tigerbrokers.stock.openapi.client.https.client.TigerHttpClient;
import com.tigerbrokers.stock.openapi.client.https.domain.contract.item.ContractItem;
import com.tigerbrokers.stock.openapi.client.https.request.trade.TradeOrderRequest;
import com.tigerbrokers.stock.openapi.client.https.response.trade.TradeOrderResponse;
import com.tigerbrokers.stock.openapi.client.struct.enums.ActionType;

public class TradeDemo {

  private static final TigerHttpClient client;

  static {
    ClientConfig clientConfig = ClientConfig.DEFAULT_CONFIG;
    // Storage path for the configuration file tiger_openapi_config.properties exported from the developer platform. The tiger_openapi_token.properties file for TBHK license is also in this directory
    clientConfig.configFilePath = "your_config_directory_path";
    // clientConfig.secretKey = "xxxxxx"; // Required field secret key for institutional account traders
    client = TigerHttpClient.getInstance().clientConfig(clientConfig);
  }

  public static void main(String[] args) {
    new TradeDemo().placeUsStockOrder();
  }

  public void placeUsStockOrder() {
    ContractItem contract = ContractItem.buildStockContract("AAPL", "USD");
    TradeOrderRequest request =
        TradeOrderRequest.buildLimitOrder(contract, ActionType.BUY, 1, 100.0);
    TradeOrderResponse response = client.execute(request);
    System.out.println(JSONObject.toJSONString(response));
  }
}

Subscribe to streaming updates

Tiger OpenAPI can stream Market Data and trading updates over a persistent TCP/TLS connection using Protobuf.

  • Subscription requests are asynchronous.
  • Implement callbacks for the events your application handles.
  • The SDK invokes the appropriate callback when the server sends an update.
  • Process the callback data according to your application's requirements.
  1. Implement the callback interface
import com.alibaba.fastjson.JSONObject;
import com.tigerbrokers.stock.openapi.client.socket.ApiComposeCallback;
import com.tigerbrokers.stock.openapi.client.socket.data.TradeTick;
import com.tigerbrokers.stock.openapi.client.socket.data.pb.AssetData;
import com.tigerbrokers.stock.openapi.client.socket.data.pb.KlineData;
import com.tigerbrokers.stock.openapi.client.socket.data.pb.OptionTopData;
import com.tigerbrokers.stock.openapi.client.socket.data.pb.OrderStatusData;
import com.tigerbrokers.stock.openapi.client.socket.data.pb.OrderTransactionData;
import com.tigerbrokers.stock.openapi.client.socket.data.pb.PositionData;
import com.tigerbrokers.stock.openapi.client.socket.data.pb.QuoteBBOData;
import com.tigerbrokers.stock.openapi.client.socket.data.pb.QuoteBasicData;
import com.tigerbrokers.stock.openapi.client.socket.data.pb.QuoteDepthData;
import com.tigerbrokers.stock.openapi.client.socket.data.pb.StockTopData;
import com.tigerbrokers.stock.openapi.client.socket.data.pb.TickData;
import com.tigerbrokers.stock.openapi.client.struct.SubscribedSymbol;
import com.tigerbrokers.stock.openapi.client.util.ApiLogger;
import com.tigerbrokers.stock.openapi.client.util.ProtoMessageUtil;

public class DefaultApiComposeCallback implements ApiComposeCallback {

  @Override
  public void orderStatusChange(OrderStatusData data) {
    ApiLogger.info("orderStatusChange:" + ProtoMessageUtil.toJson(data));
  }

  @Override
  public void orderTransactionChange(OrderTransactionData data) {
    ApiLogger.info("orderTransactionChange:" + ProtoMessageUtil.toJson(data));
  }

  @Override
  public void positionChange(PositionData data) {
    ApiLogger.info("positionChange:" + ProtoMessageUtil.toJson(data));
  }

  @Override
  public void assetChange(AssetData data) {
    ApiLogger.info("assetChange:" + ProtoMessageUtil.toJson(data));
  }

  @Override
  public void quoteChange(QuoteBasicData data) {
    ApiLogger.info("quoteChange:" + ProtoMessageUtil.toJson(data));
  }
  @Override
  public void quoteAskBidChange(QuoteBBOData data) {
    ApiLogger.info("quoteAskBidChange:" + ProtoMessageUtil.toJson(data));
  }

  @Override
  public void tradeTickChange(TradeTick data) {
    ApiLogger.info("tradeTickChange:" + JSONObject.toJSONString(data));
  }
  /*Full tick-by-tick market data callback*/
  @Override
  public void fullTickChange(TickData data) {
      ApiLogger.info("fullTickChange:" + ProtoMessageUtil.toJson(data));
  }
  /*Minute K-line data callback*/
  @Override
  public void klineChange(KlineData data) {
    ApiLogger.info("klineChange:" + ProtoMessageUtil.toJson(data));
  }

  @Override
  public void optionChange(QuoteBasicData data) {
    ApiLogger.info("optionChange:" + ProtoMessageUtil.toJson(data));
  }
  @Override
  public void optionAskBidChange(QuoteBBOData data) {
    ApiLogger.info("optionAskBidChange:" + ProtoMessageUtil.toJson(data));
  }

  @Override
  public void futureChange(QuoteBasicData data) {
    ApiLogger.info("futureChange:" + ProtoMessageUtil.toJson(data));
  }
  @Override
  public void futureAskBidChange(QuoteBBOData data) {
    ApiLogger.info("futureAskBidChange:" + ProtoMessageUtil.toJson(data));
  }

  @Override
  public void depthQuoteChange(QuoteDepthData data) {
    ApiLogger.info("depthQuoteChange:" + ProtoMessageUtil.toJson(data));
  }

  @Override
  public void stockTopPush(StockTopData data) {
    ApiLogger.info("stockTopPush, market:" + data.getMarket());
    for (StockTopData.TopData topData : data.getTopDataList()) {
      ApiLogger.info("stockTopPush, targetName:" + topData.getTargetName()
          + ", topList:" + ProtoMessageUtil.toJson(topData));
    }
  }

  @Override
  public void optionTopPush(OptionTopData data) {
    ApiLogger.info("optionTopPush, market:" + data.getMarket());
    for (OptionTopData.TopData topData : data.getTopDataList()) {
      ApiLogger.info("optionTopPush, targetName:" + topData.getTargetName()
          + ", topList:" + ProtoMessageUtil.toJson(topData));
    }
  }

  @Override
  public void subscribeEnd(int id, String subject, String result) {
    ApiLogger.info("subscribe " + subject + " end. id:" + id + ", " + result);
  }

  @Override
  public void cancelSubscribeEnd(int id, String subject, String result) {
    ApiLogger.info("cancel subscribe " + subject + " end. id:" + id + ", " + result);
  }

  @Override
  public void getSubscribedSymbolEnd(SubscribedSymbol subscribedSymbol) {
    ApiLogger.info("getSubscribedSymbolEnd:" + JSONObject.toJSONString(subscribedSymbol));
  }

  @Override
  public void error(String errorMsg) {
    ApiLogger.info("receive error:" + errorMsg);
  }

  @Override
  public void error(int id, int errorCode, String errorMsg) {
    ApiLogger.info("receive error id:" + id + ",errorCode:" + errorCode + ",errorMsg:" + errorMsg);
  }

  @Override
  public void connectionClosed() {
    ApiLogger.info("connection closed.");
  }

  @Override
  public void connectionKickout(int errorCode, String errorMsg) {
    ApiLogger.info(errorMsg + " and the connection is closed.");
  }

  @Override
  public void connectionAck() {
    ApiLogger.info("connect success.");
  }

  @Override
  public void connectionAck(int serverSendInterval, int serverReceiveInterval) {
    ApiLogger.info(
        "connect success,send interval:" + serverSendInterval + ",receive interval:" + serverReceiveInterval);
  }

  @Override
  public void hearBeat(String heartBeatContent) {
    ApiLogger.info(heartBeatContent);
  }

  @Override
  public void serverHeartBeatTimeOut(String channelId) {
    ApiLogger.info("serverHeartBeatTimeOut,channelId=" + channelId);
  }
}
  1. Subscribe

import com.tigerbrokers.stock.openapi.client.config.ClientConfig;
import com.tigerbrokers.stock.openapi.client.socket.WebSocketClient;
import com.tigerbrokers.stock.openapi.client.struct.Indicator;
import com.tigerbrokers.stock.openapi.client.struct.enums.Market;
import com.tigerbrokers.stock.openapi.client.struct.enums.OptionRankingIndicator;

import java.util.HashSet;
import java.util.Set;

public class SubscribeDemo {

    //When actually subscribing, you need to read the tiger_openapi_token.properties file to fill in tigerId and privateKey, and implement the ApiComposeCallback interface. In this example, it is DefaultApiComposeCallback. For implementation reference, see the above code, which simply outputs the returned data. You can adjust the callback function under @Override according to your needs
    private static ClientConfig clientConfig = ClientConfig.DEFAULT_CONFIG;
    private static WebSocketClient client;
    static {
        //Storage path for configuration files tiger_openapi_config.properties and tiger_openapi_token.properties exported from the developer information page
        clientConfig.configFilePath = "your_config_directory_path";
        // Enable full trade-tick payloads handled by fullTickChange
        clientConfig.useFullTick = true;
        // clientConfig.secretKey = "xxxxxx";// Required for institutional account traders
        client = WebSocketClient.getInstance().clientConfig(clientConfig).apiComposeCallback(new DefaultApiComposeCallback());
    }

    public static void main(String[] args) {
        SubscribeDemo subscribeDemo = new SubscribeDemo();
        subscribeDemo.subscribe();
    }

    public void subscribe() {

        client.connect();

        //Stock subscription
        Set<String> stockSymbols = new HashSet<>();
        stockSymbols.add("AAPL");
        stockSymbols.add("SPY");
        client.subscribeQuote(stockSymbols);

        //Futures subscription
        Set<String> futureSymbols = new HashSet<>();
        futureSymbols.add("ESmain");
        futureSymbols.add("ES1906");
        client.subscribeFuture(futureSymbols);

        //One form of options
        Set<String> optionSymbols = new HashSet<>();
        optionSymbols.add("TSLA 20190614 200.0 CALL");
        //Another form of options (21 digits)
        optionSymbols.add("SPY   190508C00290000");
        client.subscribeOption(optionSymbols);

        //Subscribe to stock depth data
        client.subscribeDepthQuote(stockSymbols);

        //Subscribe to stock trade ticks
        client.subscribeTradeTick(stockSymbols);

        //Subscribe to option rankings
        Market market = Market.US;
        Set<Indicator> indicators = new HashSet<>();
        //Option daily large order indicator
        indicators.add(OptionRankingIndicator.BigOrder);
        //Option daily cumulative turnover indicator
        indicators.add(OptionRankingIndicator.Amount);
        client.subscribeOptionTop(market, indicators);

        //Query subscription details
        client.getSubscribedSymbols();

        //It is recommended to disconnect after trading hours. When disconnecting, previous subscription records will be automatically unregistered
        //client.disconnect();
    }
}


Did this page help you?