Basic Functionality

TradeUP OpenAPI provides a rich set of interfaces to call TradeUP's services. This section will demonstrate the core functions of TradeUP OpenAPI, including querying quotes, subscribing to quotes, and executing trades.

Querying Market Data

The following is a sample implementation that calls TradeUP OpenAPI to actively query stock market data. The subsequent examples demonstrate how to call OpenAPI for trading and subscribing to market data.

In addition to the basic functionalities mentioned above, OpenAPI also supports querying and trading different instruments in the US market, as well as other complex requests. For other interfaces and requests supported by TradeUP OpenAPI, please see the full-length documentation after this Quick Start guide.

from tigeropen.common.consts import (Language,        # Language
                                Market,           # Market
                                BarPeriod,        # K-line period
                                QuoteRight)       # Dividend adjustment type
from tigeropen.tiger_open_config import TigerOpenClientConfig
from tigeropen.common.util.signature_utils import read_private_key
from tigeropen.quote.quote_client import QuoteClient
from tigeropen.tiger_open_config import TigerOpenClientConfig

client_config = TigerOpenClientConfig(props_path='/path/to/your/properties/file/')
# Another method 
# def get_client_config():
#    client_config = TigerOpenClientConfig()
#    # If it's a Windows system, add 'r' before the path string to prevent escape characters, e.g., read_private_key(r'C:\Users\admin\tiger.pem')
#    client_config.private_key = read_private_key('Fill in the path of the private key PEM file')
#    client_config.tiger_id = 'Replace with tiger id'
#    client_config.account = 'Replace with account, recommend using paper trading account'
#    client_config.language = Language.zh_CN  # Optional, defaults to English if not filled
#    # client_config.timezone = 'US/Eastern' # Optional timezone setting
#    return client_config
# Call the function defined above to generate the user configuration ClientConfig object
# client_config = get_client_config()

# Then pass in the configuration parameter object to initialize QuoteClient
quote_client = QuoteClient(client_config)

# After completing initialization, you can call quote_client methods to use the QuoteClient object's get_stock_brief method to query stock market data

# Call API to query stock market data
stock_price = quote_client.get_stock_briefs(['00700'])

# The market data query function will return a pandas.DataFrame object containing the current market snapshot, see return example. For specific field meanings, refer to the get_stock_briefs method description
print(stock_price)
  symbol  ask_price  ask_size  bid_price  bid_size  pre_close  latest_price  \
0  00700      326.4     15300      326.2     26100     321.80         326.4   

     latest_time    volume    open    high     low  status  
0  1547516984730   2593802  325.00  326.80  323.20  NORMAL 

Execute Trades

Trading is another core functionality of OpenAPI. This sample implementation demonstrates how to place a market order for a sample stock (XYZX).

from tigeropen.common.consts import (Language,        # Language
                                    Market,           # Market
                                    BarPeriod,        # K-line period
                                    QuoteRight)       # Dividend adjustment type
from tigeropen.tiger_open_config import TigerOpenClientConfig
from tigeropen.common.util.signature_utils import read_private_key
from tigeropen.trade.trade_client import TradeClient

client_config = TigerOpenClientConfig(props_path='/path/to/your/properties/file/')


# Then pass in the configuration parameter object to initialize TradeClient
trade_client = TradeClient(client_config)

from tigeropen.common.consts import Market, SecurityType, Currency
from tigeropen.common.util.contract_utils import stock_contract

# To place an order, you need to first initialize a contract object. The contract object stores contract information, see contract object for details. For methods to create contract objects, please refer to the documentation Basic Operations - Trading - Get Contract section, example as follows:
# Method 1: Directly construct contract object locally. 
contract = stock_contract(symbol='XYZX', currency='USD')

# Method 2: Online method to get Contract object, this method is only for stocks
stock_contract = trade_client.get_contracts(symbol='SPY')[0]

# The following are currently supported order type objects
from tigeropen.common.util.order_utils import (market_order,        # Market order
                                                limit_order,         # Limit order
                                                stop_order,          # Stop order
                                                stop_limit_order,    # Stop limit order
                                                )          

# Create order object, the order object stores account, target contract and other information needed for placing orders, see order object for details. Here we use limit order as an example
stock_order = limit_order(account=client_config.account,            # Trading account, can use standard, global, or paper trading account
                            contract = stock_contract,                # Contract object obtained in step 1
                            action = 'BUY',
                            quantity = 100,
                          limit_price = 100 )

# Submit order. Note: Before submitting the order, the order object's id is None, after successful submission, the order object's id will become the global order id
trade_client.place_order(stock_order)

print(stock_order)
Order({'account': '164644', 'id': 14275856193552384, 'order_id': None, 'parent_id': None, 'order_time': None, 'reason': None, 'trade_time': None, 'action': 'BUY', 'quantity': 100, 'filled': 0, 'avg_fill_price': 0, 'commission': None, 'realized_pnl': None, 'trail_stop_price': None, 'limit_price': 100, 'aux_price': None, 'trailing_percent': None, 'percent_offset': None, 'order_type': 'LMT', 'time_in_force': None, 'outside_rth': None, 'contract': SPY/STK/USD, 'status': 'NEW', 'remaining': 100})

Subscribe to Market Data

OpenAPI also supports a subscription-push method to receive market data and other information. Below is a sample implementation for subscribing to a sample XYZX stock market data, outputting market snapshots to the console, canceling subscription after 30 seconds, and then disconnecting from the server.

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.
import time
from tigeropen.push.push_client import PushClient
from tigeropen.push.pb.QuoteBasicData_pb2 import QuoteBasicData
from tigeropen.tiger_open_config import TigerOpenClientConfig
client_config = TigerOpenClientConfig(props_path='/path/to/your/properties/file/')


# First define callback functions, for simplicity in this example, we only use print to output the passed data

def on_quote_changed(frame: QuoteBasicData):
    """
    Market basic data callback
    example:
    symbol: "00700"
    type: BASIC
    timestamp: 1677742483530
    serverTimestamp: 1677742483586
    avgPrice: 365.37
    latestPrice: 363.8
    latestPriceTimestamp: 1677742483369
    latestTime: "03-02 15:34:43"
    preClose: 368.8
    volume: 12674730
    amount: 4630947968
    open: 368.2
    high: 369
    low: 362.4
    marketStatus: "Trading"
    mi {
      p: 363.8
      a: 365.37
      t: 1677742440000
      v: 27300
      h: 364
      l: 363.6
    }
    """
    print(frame)
    print(frame.latestPrice)

# Define callback function for subscription success/failure
def subscribe_callback(frame):
    """
    Subscription success/failure callback
    """
    print(f'subscribe callback:{frame}')

# Define callback function for unsubscription success event
def unsubscribe_callback(frame):
    """
    Unsubscription success/failure callback
    """
    print(f'unsubscribe callback:{frame}')

# Define callback function for connection establishment event
def connect_callback(frame):
    """Connection establishment callback"""
    print('connected')

def disconnect_callback():
    """Connection disconnection callback. Utilizing callback for reconnection"""
    for t in range(1, 20):
        try:
            print('disconnected, reconnecting')
            push_client.connect(client_config.tiger_id, client_config.private_key)
        except:
            print('connect failed, retry')
            time.sleep(t)
        else:
            print('reconnect success')
            return
    print('reconnect failed, please check your network')

if __name__ == "__main__":

    # Initialize PushClient
    protocol, host, port = client_config.socket_host_port
    push_client = PushClient(host, port, use_ssl=(protocol == 'ssl'), use_protobuf=True)

    # Bind callback functions, push-type methods are all asynchronous responses, need to bind callback functions to process data, bind market data change callback function below
    push_client.quote_changed = on_quote_changed
    # Bind subscription success/failure callback
    push_client.subscribe_callback = subscribe_callback
    # Unsubscription success/failure callback
    push_client.unsubscribe_callback = unsubscribe_callback
    # Disconnection reconnection callback
    push_client.disconnect_callback = disconnect_callback

    # Establish connection
    push_client.connect(client_config.tiger_id, client_config.private_key)
    # Subscribe to market data push
    push_client.subscribe_quote(['XYZX'])

    # Wait for push
    time.sleep(30)

    # Cancel subscription
    push_client.unsubscribe_quote()
    # Disconnect
    push_client.disconnect()