中文

Basic Function Examples

Basic Function Examples

The Tiger Open API SDK provides rich interfaces to call Tiger's services. This chapter will demonstrate the core functions of the Tiger API one by one: including querying market data, trading orders, and subscribing to market data.

Querying Market Data

The following is the simplest example of calling the Tiger API, demonstrating how to call the Open API to actively query stock market data. The following examples demonstrate how to call the Open API for trading and subscribing to market data respectively. In addition to the above basic functions, the Open API also supports querying and trading different underlying assets in multiple markets, as well as other complex requests. For other interfaces and requests supported by the Open API, please read the main documentation after the quick start to get the list and usage methods, and refer to the quick start and examples in the documentation for calling.

For easy copying and running, the following instructions are in the form of comments

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 = "./src/main/resources";
    // 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

Trading is another major function of the Open API. This example shows how to use the Open API to place a limit order for US stock AAPL:

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 = "./src/main/resources";
    // 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));
  }
}

Subscription

In addition to active queries, the Open API also supports obtaining market data and trading data in subscription-push mode. The usage is shown in the following example.

  • Asynchronous processing mechanism: All subscription requests are processed asynchronously.
  • Callback functions: You need to customize callback functions and bind them to specified events.
  • Push trigger: When events are triggered or the server pushes the latest information, the system will automatically call your callback function and pass in the returned data.
  • Data processing: Please implement the required data processing logic in your custom callback function.
  1. Define 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.enums.License;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
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 = "/data/tiger_config";
        // clientConfig.secretKey = "xxxxxx";// Required for institutional account traders
        client = WebSocketClient.getInstance().clientConfig(clientConfig).apiComposeCallback(new DefaultApiComposeCallback());
    }

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

    public void subscribe() {

        client.connect();

        Set<String> symbols = new HashSet<>();

        //Stock subscription
        symbols.add("AAPL");
        symbols.add("SPY");
        client.subscribeQuote(symbols);

        //Futures subscription
        symbols.add("ESmain");
        symbols.add("ES1906");
        client.subscribeFuture(symbols);

        //One form of options
        symbols.add("TSLA 20190614 200.0 CALL");
        //Another form of options (21 digits)
        symbols.add("SPY   190508C00290000");
        client.subscribeOption(symbols);

        //Subscribe to depth data
        client.subscribeDepthQuote(symbols);

        //Subscribe to tick-by-tick data
        client.subscribeTradeTick(symbols);

        //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();
    }
}