Class HttpTdaClient

java.lang.Object
com.studerw.tda.client.HttpTdaClient
All Implemented Interfaces:
TdaClient

public class HttpTdaClient extends Object implements TdaClient
HTTP implementation of TdaClient which uses OKHttp3 under the hood and uses the new OAuth based security. This is a thread safe class.
See Also:
  • Field Details

  • Constructor Details

    • HttpTdaClient

      public HttpTdaClient()
      Using this constructor will assume there are properties found at classpath:/tda-api.properties. This props file can include:
      • tda.token.refresh
      • tda.client_id (or sometimes referenced as Consumer Key and it should not have @AMER.OAUTHAP appended
      • tda.url=https://api.tdameritrade.com/v1
      • tda.debug.bytes.length=-1 (How many bytes of logging interceptor debug to print, -1 is unlimited)

      There are no defaults for the tda.token.refresh and tda.client_id (your consumer key). If they are not set, an exception will be thrown Note that the client id should not have appended the @AMER.OAUTHAP part that is used when refreshing your OAuth token.

    • HttpTdaClient

      public HttpTdaClient(Properties props)

      To avoid using a properties file, you can define anything that would be in tda-api.properties file. This includes:

      • tda.token.refresh
      • tda.client_id
      • tda.url=https://api.tdameritrade.com/v1
      • tda.debug.bytes.length=-1 (How many bytes of logging interceptor debug to print, -1 is unlimited)

      There are no defaults for tda.token.refresh and tda.client_id (consumer key). If they are not set, an exception will be thrown. Note that sometimes TDA uses Consumer Key instead of the term client id. They are the same. The client id should not have appended the @AMER.OAUTHAP part that is used when refreshing your OAuth token

      Parameters:
      props - required properties
  • Method Details

    • initTdaProps

      protected static Properties initTdaProps()
    • validateProps

      protected static void validateProps(Properties tdaProps)
      validates the necessary props like refresh token and client id (consumer key). If others are missing, just use friendly defaults.
      Parameters:
      tdaProps - the required props to validate
    • priceHistory

      public PriceHistory priceHistory(String symbol)
      Description copied from interface: TdaClient

      Retrieve historical intraday and end of day quote data for an equity, index, mutual fund, forex, option chain, etc. See AssetType for possible types, though your account must explicitly have access for some of these. TDA has not implemented all the API calls either (Sep 2019).

      • periodType: day
      • period: 10
      • frequencyType: minute
      • frequency: 1
      Specified by:
      priceHistory in interface TdaClient
      Parameters:
      symbol - uppercase symbol
      Returns:
      PriceHistory using all other TDA default request parameters. This appears to be a quote every minute for 10 days.
    • priceHistory

      public PriceHistory priceHistory(PriceHistReq priceHistReq)
      Description copied from interface: TdaClient

      Retrieve historical intraday and end of day quote data for an equity, index, mutual fund, forex, option chain, etc. See AssetType for possibly types, though your account must explicitly have access for some of these. TDA has not implemented all the API calls either (Sep 2019). Note that some of the parameters within the PriceHistReq param be null, and then some of the other arguments will be assumed by the non null parameters.

      Specified by:
      priceHistory in interface TdaClient
      Parameters:
      priceHistReq - validated object of request parameters
      Returns:
      PriceHistory with a list of Candle Candles based on the frequency and period / date length.
    • fetchQuotes

      public List<Quote> fetchQuotes(List<String> symbols)
      Description copied from interface: TdaClient

      Fetch detailed quote information for one or more symbols. Currently the API allows symbol types of Stocks, Options, Mutual Funds Indexes, and ETFs. Quotes are real-time for accounts subscribed to this service; otherwise, quotes are delayed according to exchange and TDA rules. The following types of Quote are actually returned and can be casted:

        Quote quote = client.fetchQuote("ATD");
        EquityQuote equityQuote = (EquityQuote)quote;
       
      Specified by:
      fetchQuotes in interface TdaClient
      Parameters:
      symbols - list of valid symbols. Max of 300 based on TDA docs. Index symbols need to be prefixed with a $, e.g. $INX or $SPX.X. Options are in a format like the following: MSFT_061518P60 for a put, or MSFT_061518C60 for a call. This is the Microsoft June 15, 2018 Put/Call at $60.
      Returns:
      list of quotes. The Quote is the base class, but all objects in the list can be cast to their actual types by looking at the AssetType attribute. field.
    • fetchQuote

      public Quote fetchQuote(String symbol)
      Description copied from interface: TdaClient

      Fetch Detailed quote information for one or more symbols. Currently the API allows symbol types of Stocks, Options, Mutual Funds and Indexes, and ETFs. Quotes are real-time for accounts subscribed to this service; otherwise, quotes are delayed according to exchange and TDA rules.

        Quote quote = client.fetchQuote("ATD");
        EquityQuote equityQuote = (EquityQuote)quote;
       
      Specified by:
      fetchQuote in interface TdaClient
      Parameters:
      symbol - list of valid symbols. Max of 300 based on TDA docs. Index symbols need to be prefixed with a $, e.g. $INX or $SPX.X. Options are in a format like the following: MSFT_061518P60 for a put, or MSFT_061518C60 for a call. This is the Microsoft June 15, 2018 Put/Call at $60.
      Returns:
      a quote. The Quote is the base class, but all quotes can be cast to their actual types by looking at the com.studerw.tda.model.quote.Quote.assetType field.
    • getAccount

      public SecuritiesAccount getAccount(String accountId, boolean positions, boolean orders)
      Description copied from interface: TdaClient
      Fetch an account by the id. By default, balances are included. Positions and Orders can also be included based on the parameters.
      Specified by:
      getAccount in interface TdaClient
      Parameters:
      accountId - the account. Most users only have a single account
      positions - whether to include positions
      orders - whether to include orders
      Returns:
      SecuritiesAccount with the passed id.
    • getAccounts

      public List<SecuritiesAccount> getAccounts(boolean positions, boolean orders)
      Description copied from interface: TdaClient
      Fetch all your accounts. By default, balances are included. Positions and Orders can also be included based on the parameters.
      Specified by:
      getAccounts in interface TdaClient
      Parameters:
      positions - whether to include positions
      orders - whether to include orders
      Returns:
      List of all the user's SecuritiesAccount.
    • getMarketHours

      public List<Hours> getMarketHours(List<Hours.MarketType> marketTypes)
      Specified by:
      getMarketHours in interface TdaClient
    • getMarketHours

      public List<Hours> getMarketHours(List<Hours.MarketType> marketTypes, LocalDateTime date)
      Description copied from interface: TdaClient
      Fetch market hours.
      Specified by:
      getMarketHours in interface TdaClient
      Parameters:
      marketTypes - the market of the hours to return Valid markets are EQUITY, OPTION, FUTURE, BOND, FOREX.
      date - the date of the market hours (default is now)
      Returns:
      Hours
    • placeOrder

      public void placeOrder(String accountId, Order order)
      Description copied from interface: TdaClient
      Place an Order.
      Specified by:
      placeOrder in interface TdaClient
      Parameters:
      accountId - the account under which the order is to be placed
      order - the order to place
      See Also:
    • placeOrderReturnId

      public Optional<Long> placeOrderReturnId(String accountId, Order order)
      Description copied from interface: TdaClient
      Place an Order and return the order ID. According to TDA docs, this order ID can be obtained from the response within a location header. Users need to check the response code as it is wrapped in a Optional.

      Note the documentation on the official TDA site is not all that clear on what kinds of orders and in which cases the order ID will and will not be returned.

      For example, if the TDA system is overloaded, the order may be queued and the ID cannot yet be known by the time the call must return (it is synchronous). Users are then required to poll for the new order using TdaClient.fetchOrders() or similar.

      In order to deal with this case without throwing an exception we return the ID wrapped in a Optional. We do this instead of throwing an exception to differentiate between an order that likely failed and one that will eventually be placed but didn't have the order ID at the time of return. Users need check the Optional themselves and handle accordingly.

      Specified by:
      placeOrderReturnId in interface TdaClient
      Parameters:
      accountId - the account under which the order is to be placed
      order - the order to place
      Returns:
      the order ID wrapped in an Optional which will be empty if the order ID was not returned by TDA, but the call otherwise returned a successful response. It's likely the order will eventually be placed, and users will need to poll for that ordeer ID using existing methods.
      See Also:
    • fetchOrders

      public List<Order> fetchOrders(String accountId, OrderRequest orderRequest)
      Description copied from interface: TdaClient

      Fetch all orders for a given account using the criteria of the orderRequest. You can just use a blank order to use sane defaults.

         Order order = client.fetchOrders("123456789", new OrderRequest());
       
      Specified by:
      fetchOrders in interface TdaClient
      Parameters:
      accountId - the orders from only this account
      orderRequest - the request.
      Returns:
      list of orders specified by the OrderRequest param.
    • fetchOrders

      public List<Order> fetchOrders(OrderRequest orderRequest)
      Description copied from interface: TdaClient

      Fetch all orders for all accounts using the criteria of the orderRequest. You can use a blank order to use sane defaults.

         Order order = client.fetchOrders(new OrderRequest());
       
      Specified by:
      fetchOrders in interface TdaClient
      Parameters:
      orderRequest - the request.
      Returns:
      list of orders specified by the OrderRequest param.
    • fetchOrders

      public List<Order> fetchOrders()
      Description copied from interface: TdaClient
      Fetch all orders for all accounts using TDA defaults.
      Specified by:
      fetchOrders in interface TdaClient
      Returns:
      list of orders for all accounts, using TDA default criteria.
    • fetchOrder

      public Order fetchOrder(String accountId, Long orderId)
      Description copied from interface: TdaClient
      This call assumes the order under the given parameters definitely exists. If not, a RuntimeException is thrown as, behind the scenes, the TDA API will return a 404 response.
      Specified by:
      fetchOrder in interface TdaClient
      Parameters:
      accountId - account under which the order was originally placed
      orderId - the id of the order
      Returns:
      Order or a RuntimeException if it doesn't exist.
    • cancelOrder

      public void cancelOrder(String accountId, String orderId)
      Description copied from interface: TdaClient
      Cancel an order by account Id and order Id.
      Specified by:
      cancelOrder in interface TdaClient
      Parameters:
      accountId - the account under which this order was placed
      orderId - the order to cancel
    • getBond

      public Instrument getBond(String cusip)
      Description copied from interface: TdaClient
      Get basic info for a bond via its CUSIP number.
      Specified by:
      getBond in interface TdaClient
      Parameters:
      cusip - (committee on uniform securities identification procedures numbers).
      Returns:
      Basic data of the bond including the price.
      See Also:
    • queryInstruments

      public List<Instrument> queryInstruments(Query query)
      Description copied from interface: TdaClient

      Query TDA for Instruments using symbol, name, description, cusip, etc. Apparently the following instrument types are queryable: Instrument.AssetType.

      The following QueryTypes can be made:

      • SYMBOL_SEARCH: retrieve an instrument using the exact symbol name or CUSIP
      • SYMBOL_REGEX: Retrieve instrument data for all symbols matching regex. For example XYZ.* will return all symbols beginning with XYZ
      • DESCRIPTION_SEARCH: Retrieve instrument data for instruments whose description contains the word supplied. Example: Bank will return all instruments with Bank in the description.
      • DESCRIPTION_REGEX: Search description with full regex support. For example XYZ.[A-C] returns all instruments whose descriptions contain a word beginning with XYZ followed by a character A through C.
      Specified by:
      queryInstruments in interface TdaClient
      Parameters:
      query - contains the type of query and the search string.
      Returns:
      List of 0 or more instruments that matched the query. If you want the full data of an instrument, you must use TdaClient.getFundamentalData(java.lang.String) using the exact CUSIP or symbol. Note that Instrument.getBondPrice() will return null for any instruments not of type BOND.
      See Also:
    • getFundamentalData

      public FullInstrument getFundamentalData(String id)
      Description copied from interface: TdaClient
      Get full fundamental data for a specific security via its CUSIP number or ticker symbol (e.g. MSFT). Not all CUSIP numbers work, for example those referencing BONDs, at least as of Nov. 2019.
      Specified by:
      getFundamentalData in interface TdaClient
      Parameters:
      id - CUSIP number or symbol (e.g. MSFT)
      Returns:
      full fundamentals of an instrument using a CUSIP or symbol. The Instrument.getBondPrice() will be empty unless it is a bond referenced by cusip.
      See Also:
    • fetchMovers

      public List<Mover> fetchMovers(MoversReq moversReq)
      Description copied from interface: TdaClient
      Note that this call can return an empty list on days the market is closed. Top 10 (up or down) movers by value or percent for a particular market
      Specified by:
      fetchMovers in interface TdaClient
      Parameters:
      moversReq - Index must be set, the other fields can be null which will use TDA defaults.
      Returns:
      List of top 10 market movers defined by the request.
    • getOptionChain

      public OptionChain getOptionChain(OptionChainReq chainRequest)
      Specified by:
      getOptionChain in interface TdaClient
      Parameters:
      chainRequest - - should be upper case (e.g. MSFT)
      Returns:
      an option chain using all TDA Default parameters
    • getOptionChain

      public OptionChain getOptionChain(String symbol)
      Specified by:
      getOptionChain in interface TdaClient
      Parameters:
      symbol - - should be upper case (e.g. MSFT)
      Returns:
      an option chain using all TDA Default parameters
    • fetchTransactions

      public List<Transaction> fetchTransactions(String accountId, TransactionRequest request)
      Specified by:
      fetchTransactions in interface TdaClient
      Parameters:
      accountId - the account under which these transactions occurred
      request - transaction request which may be empty or using one or more parameters. If you add a startDate then you do need an endDate and vice versa.
      Returns:
      list of all transactions
    • getTransaction

      public Transaction getTransaction(String accountId, Long transactionId)
      Specified by:
      getTransaction in interface TdaClient
      Parameters:
      accountId - the account under which this transactions occurred
      transactionId - transaction id
      Returns:
      single transaction
    • getPreferences

      public Preferences getPreferences(String accountId)
      Description copied from interface: TdaClient
      Get preferences for a specific account
      Specified by:
      getPreferences in interface TdaClient
      Parameters:
      accountId - user's account id
      Returns:
      user's preferences
    • getUserPrincipals

      public UserPrincipals getUserPrincipals(UserPrincipals.Field... fields)
      Specified by:
      getUserPrincipals in interface TdaClient
      Parameters:
      fields - zero or more additonal UserPrincipals.Field fields to return.
      Returns:
      user principals
    • fetchTransactions

      public List<Transaction> fetchTransactions(String accountId)
      Specified by:
      fetchTransactions in interface TdaClient
      Parameters:
      accountId - the account under which these transactions occurred
      Returns:
      list of all transactions
    • getInstrumentByCUSIP

      public Instrument getInstrumentByCUSIP(String id)
      Description copied from interface: TdaClient
      Get basic data for an instrument via its CUSIP number. Data includes attributes such as description, possible symbol, exchange, etc.

      Apparently the following instrument types are able to be looked up: Instrument.AssetType.

      Specified by:
      getInstrumentByCUSIP in interface TdaClient
      Parameters:
      id - (committee on uniform securities identification procedures numbers).
      Returns:
      Basic data using a security's CUSIP. The Instrument.getBondPrice() will return null unless the cusip parameter references a bond.
      See Also:
    • getSubscriptionKeys

      protected StreamerSubscriptionKeys getSubscriptionKeys(List<String> accountsIds)
    • baseUrl

      protected okhttp3.HttpUrl.Builder baseUrl(String... pathSegments)